Hall C ROOT/C++ Analyzer (hcana)
THcDriftChamber.cxx
Go to the documentation of this file.
1 
13 #include "THcDriftChamber.h"
14 #include "THcDCPlaneCluster.h"
15 #include "THcDC.h"
16 #include "THcDCHit.h"
17 #include "THcGlobals.h"
18 #include "THcParmList.h"
19 #include "VarDef.h"
20 #include "VarType.h"
21 #include "THaTrack.h"
22 #include "TClonesArray.h"
23 #include "TMath.h"
24 #include "TVectorD.h"
25 #include "THcSpacePoint.h"
26 #include "THaApparatus.h"
27 
28 #include "THaTrackProj.h"
29 
30 #include <cstring>
31 #include <cstdio>
32 #include <cstdlib>
33 #include <iostream>
34 #include <iomanip>
35 
36 using namespace std;
37 
38 //_____________________________________________________________________________
40  const char* name, const char* description,
41  const Int_t chambernum, THaDetectorBase* parent ) :
42  THaSubDetector(name,description,parent)
43 {
44  // Constructor
45 
46  // fTrackProj = new TClonesArray( "THaTrackProj", 5 );
47  fTrackProj = NULL;
48  fNPlanes = 0; // No planes until we make them
49 
50  fChamberNum = chambernum;
51 
52  fSpacePoints = new TClonesArray("THcSpacePoint",10);
53  fXPlaneClusters = new TClonesArray("THcDCPlaneCluster",10);
54  fUPlaneClusters = new TClonesArray("THcDCPlaneCluster",10);
55  fVPlaneClusters = new TClonesArray("THcDCPlaneCluster",10);
56  fUXPlaneClusters = new TClonesArray("THcDCPlaneCluster",10);
57  fVXPlaneClusters = new TClonesArray("THcDCPlaneCluster",10);
58 
59 
60  fHMSStyleChambers = 0; // Default
61 }
62 
63 //_____________________________________________________________________________
65  THaSubDetector()
66 {
67  // Constructor
68  fTrackProj = NULL;
69  fSpacePoints = NULL;
70  fXPlaneClusters = NULL;
71  fUPlaneClusters = NULL;
72  fVPlaneClusters = NULL;
73  fUXPlaneClusters = NULL;
74  fVXPlaneClusters = NULL;
75  fIsInit = 0;
76 
77 }
78 //_____________________________________________________________________________
79 void THcDriftChamber::Setup(const char* name, const char* description)
80 {
81 
82 }
83 
84 //_____________________________________________________________________________
86 {
87  return 0;
88 }
89 
90 //_____________________________________________________________________________
91 THaAnalysisObject::EStatus THcDriftChamber::Init( const TDatime& date )
92 {
93  // static const char* const here = "Init()";
94 
95  Setup(GetName(), GetTitle());
96 
97  EStatus status;
98  // This triggers call of ReadDatabase and DefineVariables
99  if( (status = THaSubDetector::Init( date )) )
100  return fStatus=status;
101 
102  return fStatus = kOK;
103 }
104 
106 {
107  plane->SetPlaneIndex(fNPlanes);
108  fPlanes.push_back(plane);
109  // HMS Specific
110  // Hard code Y plane numbers. Eventually need to get from database
111  if (fHMSStyleChambers) {
112  if(fChamberNum == 1) {
113  YPlaneNum=2;
114  YPlanePNum=5;
115  if(plane->GetPlaneNum() == 2) YPlaneInd = fNPlanes;
116  if(plane->GetPlaneNum() == 5) YPlanePInd = fNPlanes;
117  } else {
118  YPlaneNum=8;
119  YPlanePNum=11;
120  if(plane->GetPlaneNum() == 8) YPlaneInd = fNPlanes;
121  if(plane->GetPlaneNum() == 11) YPlanePInd = fNPlanes;
122  }
123  } else {
124  // SOS Specific
125  // Hard code X plane numbers. Eventually need to get from database
126  if(fChamberNum == 1) {
127  XPlaneNum=3;
128  XPlanePNum=4;
129  if(plane->GetPlaneNum() == 3) XPlaneInd = fNPlanes;
130  if(plane->GetPlaneNum() == 4) XPlanePInd = fNPlanes;
131  } else {
132  XPlaneNum=9;
133  XPlanePNum=10;
134  if(plane->GetPlaneNum() == 9) XPlaneInd = fNPlanes;
135  if(plane->GetPlaneNum() == 10) XPlanePInd = fNPlanes;
136  }
137  }
138  fNPlanes++;
139  return;
140 }
141 
142 //_____________________________________________________________________________
144 {
145 
146  // cout << "THcDriftChamber::ReadDatabase()" << endl;
147  char prefix[2];
148  prefix[0]=tolower(GetApparatus()->GetName()[0]);
149  prefix[1]='\0';
150  DBRequest list[]={
151  {"_remove_sppt_if_one_y_plane",&fRemove_Sppt_If_One_YPlane, kInt,0,1},
152  {"dc_wire_velocity", &fWireVelocity, kDouble},
153  {"SmallAngleApprox", &fSmallAngleApprox, kInt,0,1},
154  {"stub_max_xpdiff", &fStubMaxXPDiff, kDouble,0,1},
155  {"debugflagpr", &fhdebugflagpr, kInt},
156  {"debugstubchisq", &fdebugstubchisq, kInt},
157  {Form("dc_%d_zpos",fChamberNum), &fZPos, kDouble},
158  {0}
159  };
161  fRatio_xpfp_to_xfp=1.0;
162  TString SHMS="p";
163  TString HMS="h";
164  TString test=prefix[0];
165  if (test==SHMS ) fRatio_xpfp_to_xfp=0.0018; // SHMS
166  if (test == HMS ) fRatio_xpfp_to_xfp=0.0011; // HMS
167  fRemove_Sppt_If_One_YPlane = 0; // Default
168  fStubMaxXPDiff = 999.; //
169  gHcParms->LoadParmValues((DBRequest*)&list,prefix);
170  // Get parameters parent knows about
171  fParent = GetParent();
172  fMinHits = static_cast<THcDC*>(fParent)->GetMinHits(fChamberNum);
173  fMaxHits = static_cast<THcDC*>(fParent)->GetMaxHits(fChamberNum);
174  fMinCombos = static_cast<THcDC*>(fParent)->GetMinCombos(fChamberNum);
175  fFixPropagationCorrection = static_cast<THcDC*>(fParent)->GetFixPropagationCorrectionFlag();
176 
177  fSpacePointCriterion = static_cast<THcDC*>(fParent)->GetSpacePointCriterion(fChamberNum);
178  fMaxDist = TMath::Sqrt(fSpacePointCriterion/2.0); // For easy space points
179 
180  if (fhdebugflagpr) cout << " cham = " << fChamberNum << " Set yplane num " << YPlaneNum << " "<< YPlanePNum << endl;
181  // Generate the HAA3INV matrix for all the acceptable combinations
182  // of hit planes. Try to make it as generic as possible
183  // pindex=0 -> Plane 1 missing, pindex5 -> plane 6 missing. Won't
184  // replicate the exact values used in the ENGINE, because the engine
185  // had one big list of matrices for both chambers, while here we will
186  // have a list just for one chamber. Also, call pindex, pmindex as
187  // we tend to use pindex as a plane index.
188  fCosBeta = new Double_t [fNPlanes];
189  fSinBeta = new Double_t [fNPlanes];
190  fTanBeta = new Double_t [fNPlanes];
191  fSigma = new Double_t [fNPlanes];
192  fPsi0 = new Double_t [fNPlanes];
193  fStubCoefs = new Double_t* [fNPlanes];
194  Int_t allplanes=0;
195  for(Int_t ip=0;ip<fNPlanes;ip++) {
196  fCosBeta[ip] = TMath::Cos(fPlanes[ip]->GetBeta());
197  fSinBeta[ip] = TMath::Sin(fPlanes[ip]->GetBeta());
198  fTanBeta[ip] = fSinBeta[ip]/fCosBeta[ip];
199  fSigma[ip] = fPlanes[ip]->GetSigma();
200  fPsi0[ip] = fPlanes[ip]->GetPsi0();
201  fStubCoefs[ip] = fPlanes[ip]->GetStubCoef();
202  allplanes |= 1<<ip;
203  }
204  // Unordered map introduced in C++-11
205  // Can use unordered_map if using C++-11
206  // May not want to use map a all for performance, but using it now
207  // for code clarity
208  for(Int_t ipm1=0;ipm1<fNPlanes+1;ipm1++) { // Loop over missing plane1
209  for(Int_t ipm2=ipm1;ipm2<fNPlanes+1;ipm2++) {
210  if(ipm1==ipm2 && ipm1<fNPlanes) continue;
211  TMatrixD AA3(3,3);
212  for(Int_t i=0;i<3;i++) {
213  for(Int_t j=i;j<3;j++) {
214  AA3[i][j] = 0.0;
215  for(Int_t ip=0;ip<fNPlanes;ip++) {
216  if(ipm1 != ip && ipm2 != ip) {
217  AA3[i][j] += fStubCoefs[ip][i]*fStubCoefs[ip][j];
218  }
219  }
220  AA3[j][i] = AA3[i][j];
221  }
222  }
223  Int_t bitpat = allplanes & ~(1<<ipm1) & ~(1<<ipm2);
224  // Should check that it is invertable
225  // if (fhdebugflagpr) cout << bitpat << " Determinant: " << AA3->Determinant() << endl;
226  AA3.Invert();
227  fAA3Inv[bitpat].ResizeTo(AA3);
228  fAA3Inv[bitpat] = AA3;
229  }
230  }
231 
232  fIsInit = true;
233  return kOK;
234 }
235 
236 //_____________________________________________________________________________
238 {
239  // Initialize global variables and lookup table for decoder
240 
241  if( mode == kDefine && fIsSetup ) return kOK;
242  fIsSetup = ( mode == kDefine );
243  // Register variables in global list
244 
245  RVarDef vars[] = {
246  { "maxhits", "Maximum hits allowed", "fMaxHits" },
247  { "spacepoints", "Space points of DC", "fNSpacePoints" },
248  { "nhit", "Number of DC hits", "fNhits" },
249  { "trawhit", "Number of True Raw hits", "fN_True_RawHits" },
250  { "sp_nhits", "", "fSpacePoints.THcSpacePoint.GetNHits()" },
251  { "stub_x", "", "fSpacePoints.THcSpacePoint.GetStubX()" },
252  { "stub_xp", "", "fSpacePoints.THcSpacePoint.GetStubXP()" },
253  { "stub_y", "", "fSpacePoints.THcSpacePoint.GetStubY()" },
254  { "stub_yp", "", "fSpacePoints.THcSpacePoint.GetStubYP()" },
255  { "ncombos", "", "fSpacePoints.THcSpacePoint.GetCombos()" },
256  { "U_pos", "", "fUPlaneClusters.THcDCPlaneCluster.GetX()" },
257  { "X_pos", "", "fXPlaneClusters.THcDCPlaneCluster.GetX()" },
258  { "V_pos", "", "fVPlaneClusters.THcDCPlaneCluster.GetX()" },
259  { "UX_posx", "", "fUXPlaneClusters.THcDCPlaneCluster.GetX()" },
260  { "UX_posy", "", "fUXPlaneClusters.THcDCPlaneCluster.GetY()" },
261  { "VX_posx", "", "fVXPlaneClusters.THcDCPlaneCluster.GetX()" },
262  { "VX_posy", "", "fVXPlaneClusters.THcDCPlaneCluster.GetY()" },
263  { 0 }
264  };
265  DefineVarsFromList( vars, mode );
266  //
267  std::vector<RVarDef> ve;
268  ve.push_back( { "sphit", "", "fSpHit.SpNHits" });
269  ve.push_back( { "sphit_index", "", "fSpHit.SpHitIndex" });
270  ve.push_back({0}); // Needed to specify the end of list
271  return DefineVarsFromList( ve.data(), mode );
272 
273  //return kOK;
274 
275 }
277 {
278  // Make a list of hits for whole chamber
279  fNhits = 0;
280  fHits.clear();
281  fHits.reserve(40);
282  fSpHit.clear();
283  for(Int_t ip=0;ip<fNPlanes;ip++) {
284  TClonesArray* hitsarray = fPlanes[ip]->GetHits();
285  for(Int_t ihit=0;ihit<fPlanes[ip]->GetNHits();ihit++) {
286  fHits.push_back(static_cast<THcDCHit*>(hitsarray->At(ihit)));
287  fNhits++;
288  }
289  }
290  // if (fhdebugflagpr) cout << "ThcDriftChamber::ProcessHits() " << fNhits << " hits" << endl;
291 }
292 
293 
295 {
296  cout << " Num of nits = " << fNhits << endl;
297  cout << " Num " << " Plane " << " Wire " << " Wire-Center " << " RAW TDC " << " Drift time" << endl;
298  for(Int_t ihit=0;ihit<fNhits;ihit++) {
299  THcDCHit* thishit = fHits[ihit];
300  cout << ihit << " " <<thishit->GetPlaneNum() << " " << thishit->GetWireNum() << " " << thishit->GetPos() << " " << thishit->GetRawTime() << " " << thishit->GetTime() << endl;
301  }
302 }
303 
305 {
306  //
307  fSpacePoints->Delete();
308  fXPlaneClusters->Clear("C");
309  fUPlaneClusters->Clear("C");
310  fVPlaneClusters->Clear("C");
311  fNSpacePoints=0;
315  if(fNhits >= fMinHits && fNhits < fMaxHits) {
316  if (fhdebugflagpr) cout << " in newfindspacepoints " << endl;
317  // first look for clusters pairs in X,U,V
318  for(Int_t ihit1=0;ihit1<fNhits;ihit1++) {
319  THcDCHit* hit1=fHits[ihit1];
320  THcDriftChamberPlane* plane1 = hit1->GetWirePlane();
321  for(Int_t ihit2=ihit1+1;ihit2<fNhits;ihit2++) {
322  THcDCHit* hit2=fHits[ihit2];
323  THcDriftChamberPlane* plane2 = hit2->GetWirePlane();
324  Double_t determinate = plane1->GetXsp()*plane2->GetYsp()
325  -plane1->GetYsp()*plane2->GetXsp();
326  if(hit1->GetPlaneIndex() != hit2->GetPlaneIndex() && TMath::Abs(determinate) < 0.1 && abs(hit1->GetPos() - hit2->GetPos() ) < 0.6) {
327  THcDCPlaneCluster* clus;
328  if (hit1->GetPlaneIndex() ==0 || hit1->GetPlaneIndex() ==1) clus = (THcDCPlaneCluster*)fUPlaneClusters->ConstructedAt(fNUPlaneClusters++);
329  if (hit1->GetPlaneIndex() ==2 || hit1->GetPlaneIndex() ==3) clus = (THcDCPlaneCluster*)fXPlaneClusters->ConstructedAt(fNXPlaneClusters++);
330  if (hit1->GetPlaneIndex() ==4 || hit1->GetPlaneIndex() ==5) clus = (THcDCPlaneCluster*)fVPlaneClusters->ConstructedAt(fNVPlaneClusters++);
331  clus->AddHit(hit1);
332  clus->AddHit(hit2);
333  if (fhdebugflagpr) cout << ihit1 << " " << hit1->GetPos()<< " " << ihit2 << " " << hit2->GetPos() << " " << plane1->GetYsp()<< " " << plane1->GetXsp()<< " " << plane2->GetYsp()<< " " << plane2->GetXsp() << endl;
334  Double_t x = (hit1->GetPos() + hit2->GetPos())/2.;
335  Double_t y = 0.;
336  clus->SetXY(x,y);
337  hit1->IncrNPlaneClust();
338  hit2->IncrNPlaneClust();
339  }
340  }
341  if (hit1->GetNPlaneClust() == 0) {
342  if (fhdebugflagpr) cout << " No match found" << endl;
343  THcDCPlaneCluster* clus;
344  if (hit1->GetPlaneIndex() ==0 || hit1->GetPlaneIndex() ==1) clus = (THcDCPlaneCluster*)fUPlaneClusters->ConstructedAt(fNUPlaneClusters++);
345  if (hit1->GetPlaneIndex() ==2 || hit1->GetPlaneIndex() ==3) clus = (THcDCPlaneCluster*)fXPlaneClusters->ConstructedAt(fNXPlaneClusters++);
346  if (hit1->GetPlaneIndex() ==4 || hit1->GetPlaneIndex() ==5) clus = (THcDCPlaneCluster*)fVPlaneClusters->ConstructedAt(fNVPlaneClusters++);
347  clus->AddHit(hit1);
348  if (fhdebugflagpr) cout << ihit1 << " " << hit1->GetPos()<< " " << plane1->GetYsp()<< " " << plane1->GetXsp()<< endl;
349  Double_t x = hit1->GetPos();
350  Double_t y = 0.;
351  clus->SetXY(x,y);
352  hit1->IncrNPlaneClust();
353  }
354  }
355  if (fhdebugflagpr) {
356  cout << " NUmber of U clusters = " << fNUPlaneClusters << endl;
357  for (Int_t nc=0;nc<fNUPlaneClusters;nc++) {
359  cout << " nc = " << nc << " nhits = " << clus->GetNHits() << endl;
360  }
361  cout << " NUmber of V clusters = " << fNVPlaneClusters<< endl;
362  for (Int_t nc=0;nc<fNVPlaneClusters;nc++) {
364  cout << " nc = " << nc << " nhits = " << clus->GetNHits()<< endl;
365  }
366  cout << " NUmber of X clusters = " << fNXPlaneClusters << endl;
367  for (Int_t nc=0;nc<fNXPlaneClusters;nc++) {
369  cout << " nc = " << nc << " nhits = " << clus->GetNHits()<< endl;
370  }
371  }
372  //
375  fUXPlaneClusters->Clear("C");
376  fVXPlaneClusters->Clear("C");
377  if (fNUPlaneClusters>0) {
378  for (Int_t ncu=0;ncu<fNUPlaneClusters;ncu++) {
379  THcDCPlaneCluster *uclus = static_cast<THcDCPlaneCluster*>(fUPlaneClusters->At(ncu));
380  THcDCHit* uhit = uclus->GetHit(0);
381  Double_t upos=uclus->GetX();
382  THcDriftChamberPlane* uplane = uhit->GetWirePlane();
383  for (Int_t ncx=0;ncx<fNXPlaneClusters;ncx++) {
384  THcDCPlaneCluster *xclus = static_cast<THcDCPlaneCluster*>(fXPlaneClusters->At(ncx));
385  THcDCHit* xhit = xclus->GetHit(0);
386  Double_t xpos=xclus->GetX();
387  if ((uclus->GetNHits()+xclus->GetNHits())>2) {
388  THcDriftChamberPlane* xplane = xhit->GetWirePlane();
389  Double_t determinate = uplane->GetXsp()*xplane->GetYsp()-uplane->GetYsp()*xplane->GetXsp();
390  Double_t x = (upos*xplane->GetYsp()- xpos*uplane->GetYsp())/determinate;
391  Double_t y = (xpos*uplane->GetXsp()- upos*xplane->GetXsp())/determinate;
393  for (Int_t ih=0;ih<uclus->GetNHits();ih++) {
394  THcDCHit* temphit = uclus->GetHit(ih);
395  clus->AddHit(temphit);
396  }
397  for (Int_t ih=0;ih<xclus->GetNHits();ih++) {
398  THcDCHit* temphit = xclus->GetHit(ih);
399  clus->AddHit(temphit);
400  }
401  clus->SetXY(x,y);
402  }
403  }
404  }
405  }
406  //
407  if (fNVPlaneClusters>0) {
408  for (Int_t ncv=0;ncv<fNVPlaneClusters;ncv++) {
409  THcDCPlaneCluster *vclus = static_cast<THcDCPlaneCluster*>(fVPlaneClusters->At(ncv));
410  THcDCHit* vhit = vclus->GetHit(0);
411  Double_t vpos=vclus->GetX();
412  THcDriftChamberPlane* vplane = vhit->GetWirePlane();
413  for (Int_t ncx=0;ncx<fNXPlaneClusters;ncx++) {
414  THcDCPlaneCluster *xclus = static_cast<THcDCPlaneCluster*>(fXPlaneClusters->At(ncx));
415  THcDCHit* xhit = xclus->GetHit(0);
416  Double_t xpos=xclus->GetX();
417  if ((vclus->GetNHits()+xclus->GetNHits())>2) {
418  THcDriftChamberPlane* xplane = xhit->GetWirePlane();
419  Double_t determinate = vplane->GetXsp()*xplane->GetYsp()-vplane->GetYsp()*xplane->GetXsp();
420  Double_t x = (vpos*xplane->GetYsp()- xpos*vplane->GetYsp())/determinate;
421  Double_t y = (xpos*vplane->GetXsp()- vpos*xplane->GetXsp())/determinate;
423  for (Int_t ih=0;ih<vclus->GetNHits();ih++) {
424  THcDCHit* temphit = vclus->GetHit(ih);
425  clus->AddHit(temphit);
426  }
427  for (Int_t ih=0;ih<xclus->GetNHits();ih++) {
428  THcDCHit* temphit = xclus->GetHit(ih);
429  clus->AddHit(temphit);
430  }
431  clus->SetXY(x,y);
432  }
433  }
434  }
435  }
436  //
437  if (fhdebugflagpr) {
438  cout << " NUmber of UX clusters = " << fNUXPlaneClusters << endl;
439  for (Int_t nc=0;nc<fNUXPlaneClusters;nc++) {
441  cout << " nc = " << nc << " nhits = " << clus->GetNHits() << endl;
442  }
443  cout << " NUmber of VX clusters = " << fNVXPlaneClusters<< endl;
444  for (Int_t nc=0;nc<fNVXPlaneClusters;nc++) {
446  cout << " nc = " << nc << " nhits = " << clus->GetNHits()<< endl;
447  }
448  }
449  //
450  vector <THcDCHit*> UX_uHits;
451  vector <THcDCHit*> UX_xHits;
452  vector <THcDCHit*> VX_vHits;
453  vector <THcDCHit*> VX_xHits;
454  for (Int_t nc=0;nc<fNUXPlaneClusters;nc++) {
455  UX_uHits.clear();
456  UX_xHits.clear();
457  THcDCPlaneCluster *uxclus = static_cast<THcDCPlaneCluster*>(fUXPlaneClusters->At(nc));
458  Double_t ux_posx = uxclus->GetX();
459  Double_t ux_posy = uxclus->GetY();
460  for (Int_t ih=0;ih<uxclus->GetNHits();ih++) {
461  THcDCHit* hit1 = uxclus->GetHit(ih);
462  if (hit1->GetPlaneIndex() ==0 || hit1->GetPlaneIndex() ==1) UX_uHits.push_back(hit1);
463  if (hit1->GetPlaneIndex() ==2 || hit1->GetPlaneIndex() ==3) UX_xHits.push_back(hit1);
464  }
465  for (Int_t nc2=0;nc2<fNVXPlaneClusters;nc2++) {
466  VX_vHits.clear();
467  VX_xHits.clear();
468  THcDCPlaneCluster *vxclus = static_cast<THcDCPlaneCluster*>(fVXPlaneClusters->At(nc2));
469  Double_t vx_posx = vxclus->GetX();
470  Double_t vx_posy = vxclus->GetY();
471  Double_t dist2= pow(ux_posx-vx_posx,2) + pow(ux_posy-vx_posy,2) ;
472  for (Int_t ih=0;ih<vxclus->GetNHits();ih++) {
473  THcDCHit* hit1 = vxclus->GetHit(ih);
474  if (hit1->GetPlaneIndex() ==4 || hit1->GetPlaneIndex() ==5) VX_vHits.push_back(hit1);
475  if (hit1->GetPlaneIndex() ==2 || hit1->GetPlaneIndex() ==3) VX_xHits.push_back(hit1);
476  }
477  Bool_t Xhits_match = kFALSE ;
478  if (fhdebugflagpr) cout << " vx_xhits = " << VX_xHits.size() << " ux_xhits = "<< UX_xHits.size() << endl;
479  if (VX_xHits.size() == UX_xHits.size() && UX_xHits.size()==1) {
480  if (VX_xHits[0] == UX_xHits[0]) Xhits_match = kTRUE;
481  } else if (VX_xHits.size() == UX_xHits.size() && UX_xHits.size()==2) {
482  if (VX_xHits[0] == UX_xHits[0] && VX_xHits[1] == UX_xHits[1]) Xhits_match = kTRUE;
483  if (VX_xHits[0] == UX_xHits[1] && VX_xHits[1] == UX_xHits[0]) Xhits_match = kTRUE;
484  }
485  if (fhdebugflagpr) cout << " Xhits_match = " << Xhits_match << " dist2 = " << dist2 << " spcrit = " << fSpacePointCriterion << " VX_x " << vx_posx<< " UX_x " << ux_posx<< " VX_y " << vx_posy<< " UX_y " << ux_posy << endl;
486  Int_t TotHits = UX_uHits.size()+UX_xHits.size()+VX_vHits.size();
487  if (dist2 <= fSpacePointCriterion && Xhits_match && TotHits>=fMinHits) {
488  if (fhdebugflagpr) cout << " Make spacepoint " << endl;
490  sp->Clear();
491  Double_t xt = (ux_posx + vx_posx)/2.;
492  Double_t yt = (ux_posy + vx_posy)/2.;
493  sp->SetXY(xt, yt);
494  sp->SetCombos(1);
495  for (UInt_t ih=0;ih<UX_uHits.size();ih++) { sp->AddHit(UX_uHits[ih]);}
496  for (UInt_t ih=0;ih<UX_xHits.size();ih++) { sp->AddHit(UX_xHits[ih]);}
497  for (UInt_t ih=0;ih<VX_vHits.size();ih++) { sp->AddHit(VX_vHits[ih]);}
498  fSpHit.SpNHits.push_back(sp->GetNHits());
499  for(Int_t ihit1=0;ihit1<fNhits;ihit1++) {
500  THcDCHit* hit1=fHits[ihit1];
501  for(Int_t isph=0;isph<sp->GetNHits();isph++) {
502  THcDCHit* hitsp=sp->GetHit(isph);
503  if (hitsp==hit1) fSpHit.SpHitIndex.push_back(ihit1);
504  }
505  }
506  }
507  }
508  }
509  //
510 
511  //
512  } //fNhits >= fMinHits && fNhits < fMaxH
513  if (fhdebugflagpr) cout << " leave newfindspacepoints nsp = " << fNSpacePoints<< endl;
514 
515  //
516  return(fNSpacePoints);
517 }
518 
520 {
560  // fSpacePoints->Clear();
561  if (fhdebugflagpr) cout << " In old findspacepoint " << endl;
562  fSpacePoints->Delete();
563 
564  Int_t plane_hitind=0;
565  Int_t planep_hitind=0;
566 
567 
568  fNSpacePoints=0;
569  fEasySpacePoint = 0;
570  if(fNhits >= fMinHits && fNhits < fMaxHits) {
571  for(Int_t ihit=0;ihit<fNhits;ihit++) {
572  THcDCHit* thishit = fHits[ihit];
573  Int_t ip=thishit->GetPlaneNum(); // This is the absolute plane mumber
574  if(ip==YPlaneNum && fHMSStyleChambers) plane_hitind = ihit;
575  if(ip==YPlanePNum && fHMSStyleChambers) planep_hitind = ihit;
576  if(ip==XPlaneNum && !fHMSStyleChambers) plane_hitind = ihit;
577  if(ip==XPlanePNum && !fHMSStyleChambers) planep_hitind = ihit;
578  }
579  Int_t PlaneInd=0,PlanePInd=0;
580  if (fHMSStyleChambers) {
581  PlaneInd=YPlaneInd;
582  PlanePInd=YPlanePInd;
583  } else {
584  PlaneInd=XPlaneInd;
585  PlanePInd=XPlanePInd;
586  }
587  if(fPlanes[PlaneInd]->GetNHits() == 1 && fPlanes[PlanePInd]->GetNHits() == 1
588  && pow( (fHits[plane_hitind]->GetPos() - fHits[planep_hitind]->GetPos()),2)
590  && fNhits <= 6) { // An easy case, probably one hit per plane
591  if(fHMSStyleChambers) fEasySpacePoint = FindEasySpacePoint_HMS(plane_hitind, planep_hitind);
592  if(!fHMSStyleChambers) fEasySpacePoint = FindEasySpacePoint_SOS(plane_hitind, planep_hitind);
593  }
594  if(!fEasySpacePoint) { // It's not easy
596  }
597  // We have our space points for this chamber
598  if(fNSpacePoints > 0) {
599  if(fHMSStyleChambers) {
600  if(fRemove_Sppt_If_One_YPlane == 1) {
601  // The routine is specific to HMS
602  //Int_t ndest=
603  DestroyPoorSpacePoints(); // Only for HMS?
604  // Loop over space points and remove those with less than 4 planes
605  // hit and missing hits in Y,Y' planes
606  }
607  Int_t nadded=SpacePointMultiWire(); // Only for HMS?
608  if (nadded) if (fhdebugflagpr) cout << nadded << " Space Points added with SpacePointMultiWire()" << endl;
609  }
610  ChooseSingleHit();
612  // if(fNSpacePoints == 0) if (fhdebugflagpr) cout << "SelectSpacePoints() killed SP" << endl;
613  }
614  // if (fhdebugflagpr) cout << fNSpacePoints << " Space Points remain" << endl;
615  }
616  //
617  for (Int_t nsp=0;nsp<fNSpacePoints;nsp++) {
619  fSpHit.SpNHits.push_back(sp->GetNHits());
620  for(Int_t ihit1=0;ihit1<fNhits;ihit1++) {
621  THcDCHit* hit1=fHits[ihit1];
622  for(Int_t isph=0;isph<sp->GetNHits();isph++) {
623  THcDCHit* hitsp=sp->GetHit(isph);
624  if (hitsp==hit1) fSpHit.SpHitIndex.push_back(ihit1);
625  }
626  }
627  }
628 
629  //
630  return(fNSpacePoints);
631 }
632 
633 //_____________________________________________________________________________
634 // HMS Specific
636 {
646  Int_t easy_space_point=0;
647  Double_t yt = (fHits[yplane_hitind]->GetPos() + fHits[yplanep_hitind]->GetPos())/2.0;
648  Double_t xt = 0.0;
649  Int_t num_xhits = 0;
651 
652  for(Int_t ihit=0;ihit<fNhits;ihit++) {
653  THcDCHit* thishit = fHits[ihit];
654  if(ihit!=yplane_hitind && ihit!=yplanep_hitind) { // x-like hit
655  // ysp and xsp are from h_generate_geometry
656  x_pos[ihit] = (thishit->GetPos()
657  -yt*thishit->GetWirePlane()->GetYsp())
658  /thishit->GetWirePlane()->GetXsp();
659  xt += x_pos[ihit];
660  num_xhits++;
661  } else {
662  x_pos[ihit] = 0.0;
663  }
664  }
665  xt = (num_xhits>0?xt/num_xhits:0.0);
666  easy_space_point = 1; // Assume we have an easy space point
667  // Rule it out if x points don't cluster well enough
668  for(Int_t ihit=0;ihit<fNhits;ihit++) {
669  if(ihit!=yplane_hitind && ihit!=yplanep_hitind) { // select x-like hit
670  if(TMath::Abs(xt-x_pos[ihit]) >= fMaxDist)
671  { easy_space_point=0; break;}
672  }
673  }
674  if(easy_space_point) { // Register the space point
676  sp->Clear();
677  sp->SetXY(xt, yt);
678  sp->SetCombos(0);
679  for(Int_t ihit=0;ihit<fNhits;ihit++) {
680  sp->AddHit(fHits[ihit]);
681  }
682  }
683  return(easy_space_point);
684 }
685 // SOS Specific
687 {
697  Int_t easy_space_point=0;
698  Double_t xt = (fHits[xplane_hitind]->GetPos() + fHits[xplanep_hitind]->GetPos())/2.0;
699  Double_t yt = 0.0;
700  Int_t num_yhits = 0;
702 
703  for(Int_t ihit=0;ihit<fNhits;ihit++) {
704  THcDCHit* thishit = fHits[ihit];
705  if(ihit!=xplane_hitind && ihit!=xplanep_hitind) { // y-like hit
706  // ysp and xsp are from h_generate_geometry
707  y_pos[ihit] = (thishit->GetPos()
708  -xt*thishit->GetWirePlane()->GetXsp())
709  /thishit->GetWirePlane()->GetYsp();
710  yt += y_pos[ihit];
711  num_yhits++;
712  } else {
713  y_pos[ihit] = 0.0;
714  }
715  }
716  yt = (num_yhits>0?yt/num_yhits:0.0);
717  easy_space_point = 1; // Assume we have an easy space point
718  // Rule it out if x points don't cluster well enough
719  for(Int_t ihit=0;ihit<fNhits;ihit++) {
720  if(ihit!=xplane_hitind && ihit!=xplanep_hitind) { // select y-like hit
721  if(TMath::Abs(yt-y_pos[ihit]) >= fMaxDist)
722  { easy_space_point=0; break;}
723  }
724  }
725  if(easy_space_point) { // Register the space point
727  sp->Clear();
728  sp->SetXY(xt, yt);
729  sp->SetCombos(0);
730  for(Int_t ihit=0;ihit<fNhits;ihit++) {
731  sp->AddHit(fHits[ihit]);
732  }
733  }
734  return(easy_space_point);
735 }
736 
737 //_____________________________________________________________________________
738 // Generic
740 {
741  Int_t MAX_NUMBER_PAIRS=1000; // Where does this get set?
742  struct Pair {
743  THcDCHit* hit1;
744  THcDCHit* hit2;
745  Double_t x, y;
746  };
747  Pair pairs[MAX_NUMBER_PAIRS];
748  //
749  Int_t ntest_points=0;
750  for(Int_t ihit1=0;ihit1<fNhits-1;ihit1++) {
751  THcDCHit* hit1=fHits[ihit1];
752  THcDriftChamberPlane* plane1 = hit1->GetWirePlane();
753  for(Int_t ihit2=ihit1+1;ihit2<fNhits;ihit2++) {
754  if(ntest_points < MAX_NUMBER_PAIRS) {
755  THcDCHit* hit2=fHits[ihit2];
756  THcDriftChamberPlane* plane2 = hit2->GetWirePlane();
757  Double_t determinate = plane1->GetXsp()*plane2->GetYsp()
758  -plane1->GetYsp()*plane2->GetXsp();
759  if(TMath::Abs(determinate) > 0.3) { // 0.3 is sin(alpha1-alpha2)=sin(17.5)
760  pairs[ntest_points].hit1 = hit1;
761  pairs[ntest_points].hit2 = hit2;
762  pairs[ntest_points].x = (hit1->GetPos()*plane2->GetYsp()
763  - hit2->GetPos()*plane1->GetYsp())
764  /determinate;
765  pairs[ntest_points].y = (hit2->GetPos()*plane1->GetXsp()
766  - hit1->GetPos()*plane2->GetXsp())
767  /determinate;
768  ntest_points++;
769  }
770  }
771  }
772  }
773  Int_t ncombos=0;
774  struct Combo {
775  Pair* pair1;
776  Pair* pair2;
777  };
778  Combo combos[10*MAX_NUMBER_PAIRS];
779  for(Int_t ipair1=0;ipair1<ntest_points-1;ipair1++) {
780  for(Int_t ipair2=ipair1+1;ipair2<ntest_points;ipair2++) {
781  if(ncombos < 10*MAX_NUMBER_PAIRS) {
782  Double_t dist2 = pow(pairs[ipair1].x - pairs[ipair2].x,2)
783  + pow(pairs[ipair1].y - pairs[ipair2].y,2);
784  if(dist2 <= fSpacePointCriterion) {
785  combos[ncombos].pair1 = &pairs[ipair1];
786  combos[ncombos].pair2 = &pairs[ipair2];
787  ncombos++;
788  }
789  }
790  }
791  }
792  // Loop over all valid combinations and build space points
793  //if (fhdebugflagpr) cout << "looking for hard Space Point combos = " << ncombos << endl;
794  for(Int_t icombo=0;icombo<ncombos;icombo++) {
795  THcDCHit* hits[4];
796  hits[0]=combos[icombo].pair1->hit1;
797  hits[1]=combos[icombo].pair1->hit2;
798  hits[2]=combos[icombo].pair2->hit1;
799  hits[3]=combos[icombo].pair2->hit2;
800  // Get Average Space point xt, yt
801  Double_t xt = (combos[icombo].pair1->x + combos[icombo].pair2->x)/2.0;
802  Double_t yt = (combos[icombo].pair1->y + combos[icombo].pair2->y)/2.0;
803  // Loop over space points
804 
805  if(fNSpacePoints > 0) {
806  Int_t add_flag=1;
807  for(Int_t ispace=0;ispace<fNSpacePoints;ispace++) {
808  THcSpacePoint* sp = (THcSpacePoint*)(*fSpacePoints)[ispace];
809  if(sp->GetNHits() > 0) {
810  Double_t sqdist_test = pow(xt - sp->GetX(),2) + pow(yt - sp->GetY(),2);
811  // I (who is I) want to be careful if sqdist_test is bvetween 1 and
812  // 3 fSpacePointCriterion. Let me ignore not add a new point the
813  if(sqdist_test < 3*fSpacePointCriterion) {
814  add_flag = 0; // do not add a new space point
815  }
816  if(sqdist_test < fSpacePointCriterion) {
817  // This is a real match
818  // Add the new hits to the existing space point
819  Int_t iflag[4];
820  iflag[0]=0;iflag[1]=0;iflag[2]=0;iflag[3]=0;
821  // Find out which of the four hits in the combo are already
822  // in the space point under consideration so that we don't
823  // add duplicate hits to the space point
824  for(Int_t isp_hit=0;isp_hit<sp->GetNHits();isp_hit++) {
825  for(Int_t icm_hit=0;icm_hit<4;icm_hit++) { // Loop over combo hits
826  if(sp->GetHit(isp_hit)==hits[icm_hit]) {
827  iflag[icm_hit] = 1;
828  }
829  }
830  }
831  // Remove duplicated pionts in the combo so we don't add
832  // duplicate hits to the space point
833  for(Int_t icm1=0;icm1<3;icm1++) {
834  for(Int_t icm2=icm1+1;icm2<4;icm2++) {
835  if(hits[icm1]==hits[icm2]) {
836  iflag[icm2] = 1;
837  }
838  }
839  }
840  // Add the unique combo hits to the space point
841  for(Int_t icm=0;icm<4;icm++) {
842  if(iflag[icm]==0) {
843  sp->AddHit(hits[icm]);
844  }
845  }
846  sp->IncCombos();
847  // cout << " number of combos = " << sp->GetCombos() << endl;
848  // Terminate loop since this combo can only belong to one space point
849  break;
850  }
851  }
852  }// End of loop over existing space points
853  // Create a new space point if more than 2*space_point_criteria
854  if(fNSpacePoints < MAX_SPACE_POINTS) {
855  if(add_flag) {
856  //if (fhdebugflagpr) cout << " add glag = " << add_flag << " space pts = " << fNSpacePoints << endl ;
857  THcSpacePoint* sp = (THcSpacePoint*)fSpacePoints->ConstructedAt(fNSpacePoints++);
858  sp->Clear();
859  sp->SetXY(xt, yt);
860  sp->SetCombos(1);
861  sp->AddHit(hits[0]);
862  sp->AddHit(hits[1]);
863  if(hits[0] != hits[2] && hits[1] != hits[2]) {
864  sp->AddHit(hits[2]);
865  }
866  if(hits[0] != hits[3] && hits[1] != hits[3]) {
867  sp->AddHit(hits[3]);
868  }
869  }
870  }
871  } else {// Create first space point
872  // This duplicates code above. Need to see if we can restructure
873  // to avoid
875  sp->Clear();
876  sp->SetXY(xt, yt);
877  sp->SetCombos(1);
878  sp->AddHit(hits[0]);
879  sp->AddHit(hits[1]);
880  if(hits[0] != hits[2] && hits[1] != hits[2]) {
881  sp->AddHit(hits[2]);
882  }
883  if(hits[0] != hits[3] && hits[1] != hits[3]) {
884  sp->AddHit(hits[3]);
885  }
886  //if (fhdebugflagpr) cout << "1st hard Space Point " << xt << " " << yt << " Space point # =" << fNSpacePoints << " combos = " << sp->GetCombos() << endl;
887  }//End check on 0 space points
888  }//End loop over combos
889  //if (fhdebugflagpr) cout << " finished findspacept # of sp pts = " << fNSpacePoints << endl;
890  return(fNSpacePoints);
891 }
892 
893 //_____________________________________________________________________________
894 // HMS Specific?
896 {
897  Int_t nhitsperplane[fNPlanes];
898 
899  Int_t spacepointsgood[fNSpacePoints];
900  Int_t ngood=0;
901 
902  for(Int_t i=0;i<fNSpacePoints;i++) {
903  spacepointsgood[i] = 0;
904  }
905  for(Int_t isp=0;isp<fNSpacePoints;isp++) {
906  Int_t nplanes_hit = 0;
907  for(Int_t ip=0;ip<fNPlanes;ip++) {
908  nhitsperplane[ip] = 0;
909  }
910  // Count # hits in each plane for this space point
911  THcSpacePoint* sp = (THcSpacePoint*)(*fSpacePoints)[isp];
912  for(Int_t ihit=0;ihit<sp->GetNHits();ihit++) {
913  THcDCHit* hit=sp->GetHit(ihit);
914  // hit_order(hit) = ihit;
915  Int_t ip = hit->GetPlaneIndex();
916  nhitsperplane[ip]++;
917  }
918  // Count # planes that have hits
919  for(Int_t ip=0;ip<fNPlanes;ip++) {
920  if(nhitsperplane[ip] > 0) {
921  nplanes_hit++;
922  }
923  }
924  if(nplanes_hit >= fMinHits && nhitsperplane[YPlaneInd]>0
925  && nhitsperplane[YPlanePInd] > 0) {
926  spacepointsgood[ngood++] = isp; // Build list of good points
927  } else {
928  // if (fhdebugflagpr) cout << "Missing Y-hit!!";
929  }
930  }
931 
932  // Remove the bad space points
933  Int_t nremoved=fNSpacePoints-ngood;
934  fNSpacePoints = ngood;
935  for(Int_t isp=0;isp<fNSpacePoints;isp++) { // New index num ber
936  Int_t osp=spacepointsgood[isp]; // Original index number
937  if(osp > isp) {
938  // Does this work, or do we have to copy each member?
939  // If it doesn't we should overload the = operator
940  //(*fSpacePoints)[isp] = (*fSpacePoints)[osp];
941  THcSpacePoint* spi = (THcSpacePoint*)(*fSpacePoints)[isp];
942  THcSpacePoint* spo = (THcSpacePoint*)(*fSpacePoints)[osp];
943  spi->Clear();
944  Double_t xt,yt;
945  xt=spo->GetX();
946  yt=spo->GetY();
947  spi->SetXY(xt, yt);
948  for(Int_t ihit=0;ihit<spo->GetNHits();ihit++) {
949  THcDCHit* hit = spo->GetHit(ihit);
950  spi->AddHit(hit);
951  }
952  }
953  }
954  return nremoved;
955 }
956 
957 //_____________________________________________________________________________
958 // HMS Specific?
960 {
973  Int_t nhitsperplane[fNPlanes];
974  THcDCHit* hits_plane[fNPlanes][MAX_HITS_PER_POINT];
975 
976  Int_t nsp_check;
977  //Int_t nplanes_single;
978 
979  Int_t nsp_tot=fNSpacePoints;
980  Int_t nsp_totl=fNSpacePoints;
981  //if (fhdebugflagpr) cout << "Start Multiwire # of sp pts = " << nsp_totl << endl;
982 
983  for(Int_t isp=0;isp<nsp_totl;isp++) {
984  Int_t nplanes_hit = 0; // Number of planes with hits
985  Int_t nplanes_mult = 0; // Number of planes with multiple hits
986  Int_t nsp_new = 1;
987  Int_t newsp_num=0;
988  //if (fhdebugflagpr) cout << "Looping thru space pts at # = " << isp << " total = " << fNSpacePoints << endl;
989 
990  for(Int_t ip=0;ip<fNPlanes;ip++) {
991  nhitsperplane[ip] = 0;
992  for(Int_t ih=0;ih<MAX_HITS_PER_POINT;ih++) {
993  hits_plane[ip][ih] = 0;
994  }
995  }
996  // Sort Space Points hits by plane
997  THcSpacePoint* sp = (THcSpacePoint*)(*fSpacePoints)[isp];
998  for(Int_t ihit=0;ihit<sp->GetNHits();ihit++) { // All hits in SP
999  THcDCHit* hit=sp->GetHit(ihit);
1000  // hit_order Make a hash
1001  // hash(hit) = ihit;
1002  Int_t ip = hit->GetPlaneIndex();
1003  hits_plane[ip][nhitsperplane[ip]++] = hit;
1004  //if (fhdebugflagpr) cout << " hit = " << ihit+1 << " plane index = " << ip << " nhitsperplane = " << nhitsperplane[ip] << endl;
1005  }
1006  for(Int_t ip=0;ip<fNPlanes;ip++) {
1007  if(nhitsperplane[ip] > 0) {
1008  nplanes_hit++;
1009  nsp_new *= nhitsperplane[ip];
1010  if(nhitsperplane[ip] > 1) nplanes_mult++;
1011  //if (fhdebugflagpr) cout << "Found plane with multi hits plane =" << ip+1 << " nplane_hit = "<< nplanes_hit << " nsp_new = " <<nsp_new << " nplane_mult = "<< nplanes_mult << endl;
1012  }
1013  }
1014  --nsp_new;
1015  nsp_check=nsp_tot + nsp_new;
1016  //nplanes_single = nplanes_hit - nplanes_mult;
1017  //if (fhdebugflagpr) cout << " # of new space points = " << nsp_new << " total now = " << nsp_tot<< endl;
1018  // Check if cloning conditions are met
1019  Int_t ntot = 0;
1020  if(nplanes_hit >= 4 && nplanes_mult < 4 && nplanes_mult >0
1021  && nsp_check < 20) {
1022  //if (fhdebugflagpr) cout << " Cloning space point " << endl;
1023  // Order planes by decreasing # of hits
1024 
1025  Int_t maxplane[fNPlanes];
1026  for(Int_t ip=0;ip<fNPlanes;ip++) {
1027  maxplane[ip] = ip;
1028  }
1029  // Sort by decreasing # of hits
1030  for(Int_t ip1=0;ip1<fNPlanes-1;ip1++) {
1031  for(Int_t ip2=ip1+1;ip2<fNPlanes;ip2++) {
1032  if(nhitsperplane[maxplane[ip2]] > nhitsperplane[maxplane[ip1]]) {
1033  Int_t temp = maxplane[ip1];
1034  maxplane[ip1] = maxplane[ip2];
1035  maxplane[ip2] = temp;
1036  }
1037  }
1038  }
1039  // First fill clones with 1 hit each from the 3 planes with the most hits
1040  for(Int_t n1=0;n1<nhitsperplane[maxplane[0]];n1++) {
1041  for(Int_t n2=0;n2<nhitsperplane[maxplane[1]];n2++) {
1042  for(Int_t n3=0;n3<nhitsperplane[maxplane[2]];n3++) {
1043  ntot++;
1044  newsp_num = fNSpacePoints; //
1045  //if (fhdebugflagpr) cout << " new space pt num = " << newsp_num << " " << fNSpacePoints << endl;
1046  //THcSpacePoint* newsp;
1047  if(n1==0 && n2==0 && n3==0) {
1048  newsp_num = isp; // Copy over the original SP
1049  THcSpacePoint* newsp = (THcSpacePoint*)fSpacePoints->ConstructedAt(newsp_num);//= (THcSpacePoint*)(*fSpacePoints)[newsp_num];
1050  //if (fhdebugflagpr) cout << " Copy over original SP " << endl;
1051  // newsp = sp;
1052  Int_t combos_save=sp->GetCombos();
1053  newsp->Clear(); // Clear doesn't clear X, Y
1054  // if (fhdebugflagpr) cout << " original sp #hits combos X y " << sp->GetCombos() << sp->GetNHits() << sp->GetX() << " " << sp->GetY() << endl;
1055  newsp->SetXY(sp->GetX(), sp->GetY());
1056  newsp->SetCombos(combos_save);
1057  newsp->AddHit(hits_plane[maxplane[0]][n1]);
1058  newsp->AddHit(hits_plane[maxplane[1]][n2]);
1059  newsp->AddHit(hits_plane[maxplane[2]][n3]);
1060  newsp->AddHit(hits_plane[maxplane[3]][0]);
1061  if(nhitsperplane[maxplane[4]] == 1) {
1062  newsp->AddHit(hits_plane[maxplane[4]][0]);
1063  if(nhitsperplane[maxplane[5]] == 1)
1064  newsp->AddHit(hits_plane[maxplane[5]][0]);
1065  }
1066  } else {
1067  // if (fhdebugflagpr) cout << " setting other sp " << "# space pts now = " << fNSpacePoints << endl;
1068  THcSpacePoint* newsp = (THcSpacePoint*)fSpacePoints->ConstructedAt(newsp_num);
1069  fNSpacePoints++;
1070  Int_t combos_save=sp->GetCombos();
1071  newsp->Clear();
1072  newsp->SetXY(sp->GetX(), sp->GetY());
1073  newsp->SetCombos(combos_save);
1074  newsp->AddHit(hits_plane[maxplane[0]][n1]);
1075  newsp->AddHit(hits_plane[maxplane[1]][n2]);
1076  newsp->AddHit(hits_plane[maxplane[2]][n3]);
1077  newsp->AddHit(hits_plane[maxplane[3]][0]);
1078  if(nhitsperplane[maxplane[4]] == 1) {
1079  newsp->AddHit(hits_plane[maxplane[4]][0]);
1080  if(nhitsperplane[maxplane[5]] == 1)
1081  newsp->AddHit(hits_plane[maxplane[5]][0]);
1082  }
1083  }
1084  }
1085  }
1086  }
1087  // In the ENGINE, we loop over the clones and order the hits in the
1088  // same order as the parent SP. It is not done here because it is a little
1089  // tricky. Is it necessary?
1090  nsp_tot += (ntot-1);
1091  } else {
1092  ntot=1; // space point not to be cloned
1093  }
1094  }
1095  assert (nsp_tot > 0); // program terminates if nsp_tot <=0
1096  Int_t nadded=0;
1097  if(nsp_tot <= 20) {
1098  nadded = nsp_tot - fNSpacePoints;
1099  // fNSpacePoints = nsp_tot;
1100  }
1101  //if (fhdebugflagpr) cout << " Added space pts " << nadded << " total space pts = " << fNSpacePoints << endl;
1102 
1103  // In Fortran, fill in zeros.
1104  return(nadded);
1105 }
1106 
1107 //_____________________________________________________________________________
1108 // Generic
1110 {
1115  for(Int_t isp=0;isp<fNSpacePoints;isp++) {
1116  THcSpacePoint* sp = (THcSpacePoint*)(*fSpacePoints)[isp];
1117  Int_t startnum = sp->GetNHits();
1118  Int_t goodhit[startnum];
1119  for(Int_t ihit=0;ihit<startnum;ihit++) {
1120  goodhit[ihit] = 1;
1121  }
1122  // For each plane, mark all hits longer than the shortest drift time
1123  for(Int_t ihit1=0;ihit1<startnum-1;ihit1++) {
1124  THcDCHit* hit1 = sp->GetHit(ihit1);
1125  Int_t plane1=hit1->GetPlaneIndex();
1126  Double_t tdrift1 = hit1->GetTime();
1127  for(Int_t ihit2=ihit1+1;ihit2<startnum;ihit2++) {
1128  THcDCHit* hit2 = sp->GetHit(ihit2);
1129  Int_t plane2=hit2->GetPlaneIndex();
1130  Double_t tdrift2 = hit2->GetTime();
1131  if(plane1 == plane2) {
1132  if(tdrift1 > tdrift2) {
1133  goodhit[ihit1] = 0;
1134  } else {
1135  goodhit[ihit2] = 0;
1136  }
1137  }
1138  }
1139  }
1140  // Gather the remaining hits
1141  Int_t finalnum = 0;
1142  for(Int_t ihit=0;ihit<startnum;ihit++) {
1143  if(goodhit[ihit] > 0) { // Keep this hit
1144  if (ihit > finalnum) { // Move hit
1145  sp->ReplaceHit(finalnum++, sp->GetHit(ihit));
1146  } else {
1147  finalnum++ ;
1148  }
1149  }
1150  }
1151  sp->SetNHits(finalnum);
1152  // if (fhdebugflagpr) cout << " choose single hit start # of hits = " << startnum << " final # = " <<finalnum << endl;
1153  }
1154 }
1155 //_____________________________________________________________________________
1156 // Generic
1158 {
1165  Int_t sp_count=0;
1166  //
1167  //
1168  for(Int_t isp=0;isp<fNSpacePoints;isp++) {
1169  // Include fEasySpacePoint because ncombos not filled in
1170  THcSpacePoint* sp = (THcSpacePoint*)(*fSpacePoints)[isp];
1171  if(sp->GetCombos() >= fMinCombos || fEasySpacePoint) {
1172  if(sp->GetNHits() >= fMinHits) {
1173  if(isp > sp_count) {
1174  // (*fSpacePoints)[sp_count] = (*fSpacePoints)[isp];
1175  THcSpacePoint* sp1 = (THcSpacePoint*)(*fSpacePoints)[sp_count];
1176  sp1->Clear();
1177  Double_t xt,yt;
1178  xt=sp->GetX();
1179  yt=sp->GetY();
1180  sp1->SetXY(xt, yt);
1181  sp1->SetCombos(sp->GetCombos());
1182  for(Int_t ihit=0;ihit<sp->GetNHits();ihit++) {
1183  THcDCHit* hit = sp->GetHit(ihit);
1184  sp1->AddHit(hit);
1185  }
1186  }
1187  sp_count++;
1188  }
1189  }
1190  }
1191  fNSpacePoints = sp_count;
1192  //for(Int_t isp=0;isp<fNSpacePoints;isp++) {
1193  // THcSpacePoint* sp = (THcSpacePoint*)(*fSpacePoints)[isp];
1194  //if (fhdebugflagpr) cout << " sp pt = " << isp+1 << " # of hits = " << sp->GetNHits() << endl;
1195  //for(Int_t ihit=0;ihit<sp->GetNHits();ihit++) {
1196  //THcDCHit* hit = sp->GetHit(ihit);
1197  //THcDriftChamberPlane* plane=hit->GetWirePlane();
1198  // if (fhdebugflagpr) cout << ihit+1 << "selecting " << plane->GetPlaneNum() << " " << plane->GetChamberNum() << " " << hit->GetTime() << " " << hit->GetDist() << " " << plane->GetCentralTime() << " " << plane->GetDriftTimeSign() << endl;
1199  // }
1200  // }
1201 }
1202 
1204 {
1217  //if (fhdebugflagpr) cout << "In correcthittimes fNSpacePoints = " << fNSpacePoints << endl;
1218 
1219  for(Int_t isp=0;isp<fNSpacePoints;isp++) {
1220  THcSpacePoint* sp = (THcSpacePoint*)(*fSpacePoints)[isp];
1221  Double_t x = sp->GetX();
1222  Double_t y = sp->GetY();
1223  for(Int_t ihit=0;ihit<sp->GetNHits();ihit++) {
1224  THcDCHit* hit = sp->GetHit(ihit);
1225  THcDriftChamberPlane* plane=hit->GetWirePlane();
1226 
1227  // How do we know this correction only gets applied once? Is
1228  // it determined that a given hit can only belong to one space point?
1229  Double_t time_corr = plane->GetReadoutX() ?
1230  y*plane->GetReadoutCorr()/fWireVelocity :
1231  x*plane->GetReadoutCorr()/fWireVelocity;
1232 
1233  // This applies the wire velocity correction for new SHMS chambers --hszumila, SEP17
1234  if (!fHMSStyleChambers){
1235  Int_t pln = hit->GetPlaneNum();
1236  Int_t readoutSide = hit->GetReadoutSide();
1237 
1238  Double_t posn = hit->GetPos();
1239  //The following values are determined from param file as permutations on planes 5 and 10
1240  Int_t readhoriz = plane->GetReadoutLR();
1241  Int_t readvert = plane->GetReadoutTB();
1242 
1243  //+x is up and +y is beam right!
1244  double alpha = static_cast<THcDC*>(fParent)->GetAlphaAngle(pln);
1245  double xc = posn*TMath::Sin(alpha);
1246  double yc = posn*TMath::Cos(alpha);
1247 
1248  Double_t wireDistance = plane->GetReadoutX() ?
1249  (abs(y-yc))*abs(plane->GetReadoutCorr()) :
1250  (abs(x-xc))*abs(plane->GetReadoutCorr());
1251 
1252  //Readout side is based off wiring diagrams
1253  switch (readoutSide){
1254  case 1: //readout from top of chamber
1255  if (x>xc){wireDistance = -readvert*wireDistance;}
1256  else{wireDistance = readvert*wireDistance;}
1257 
1258  break;
1259  case 2://readout from right of chamber
1260  if (y>yc){wireDistance = -readhoriz*wireDistance;}
1261  else{wireDistance = readhoriz*wireDistance;}
1262 
1263  break;
1264  case 3: //readout from bottom of chamber
1265  if (xc>x){wireDistance= -readvert*wireDistance;}
1266  else{wireDistance = readvert*wireDistance;}
1267 
1268  break;
1269  case 4: //readout from left of chamber
1270  if(yc>y){wireDistance = -readhoriz*wireDistance;}
1271  else{wireDistance = readhoriz*wireDistance;}
1272 
1273  break;
1274  default:
1275  wireDistance = 0.0;
1276  }
1277 
1278  Double_t timeCorrection = wireDistance/fWireVelocity;
1279 
1280  if(fFixPropagationCorrection==0) { // ENGINE behavior
1281  Double_t time=hit->GetTime();
1282  hit->SetTime(time - timeCorrection);
1283  hit->ConvertTimeToDist();
1284  } else {
1285  Double_t time=hit->GetTime();
1286  Double_t dist=hit->GetDist();
1287 
1288  hit->SetTime(time - timeCorrection);
1289  //double usingOldTime = time-time_corr;
1290  //hit->SetTime(time- time_corr);
1291 
1292  hit->ConvertTimeToDist();
1293  sp->SetHitDist(ihit, hit->GetDist());
1294 
1295  hit->SetTime(time); // Restore time
1296  hit->SetDist(dist); // Restore distance
1297  }
1298 
1299  } else {
1301 
1302  // if (fhdebugflagpr) cout << "Correcting hit " << hit << " " << plane->GetPlaneNum() << " " << isp << "/" << ihit << " " << x << "," << y << endl;
1303  // Fortran ENGINE does not do this check, so hits can get "corrected"
1304  // multiple times if they belong to multiple space points.
1305  // To reproduce the precise ENGINE behavior, remove this if condition.
1306  if(fFixPropagationCorrection==0) { // ENGINE behavior
1307  hit->SetTime(hit->GetTime() - plane->GetCentralTime()
1308  + plane->GetDriftTimeSign()*time_corr);
1309  hit->ConvertTimeToDist();
1310  // hit->SetCorrectedStatus(1);
1311  } else {
1312  // New behavior: Save corrected distance with the hit in the space point
1313  // so that the same hit can have a different correction depending on
1314  // which space point it is in.
1315  //
1316  // This is a hack now because the converttimetodist method is connected to the hit
1317  // so I compute the corrected time and distance, and then restore the original
1318  // time and distance. Can probably add a method to hit that does a conversion on a time
1319  // but does not modify the hit data.
1320  Double_t time=hit->GetTime();
1321  Double_t dist=hit->GetDist();
1322  hit->SetTime(time - plane->GetCentralTime()
1323  + plane->GetDriftTimeSign()*time_corr);
1324  hit->ConvertTimeToDist();
1325  sp->SetHitDist(ihit, hit->GetDist());
1326  hit->SetTime(time); // Restore time
1327  hit->SetDist(dist); // Restore distance
1328  }
1329  }
1330  }
1331  }
1332 }
1334 // From http://graphics.stanford.edu/~seander/bithacks.html
1335 {
1336  x = x - ((x >> 1) & 0x55555555);
1337  x = (x & 0x33333333) + ((x >> 2) & 0x33333333);
1338  return (((x + (x >> 4)) & 0x0F0F0F0F) * 0x01010101) >> 24;
1339 }
1340 
1341 //_____________________________________________________________________________
1343 {
1350  for(Int_t isp=0; isp<fNSpacePoints; isp++) {
1351  // Build a bit pattern of which planes are hit
1352  THcSpacePoint* sp = (THcSpacePoint*)(*fSpacePoints)[isp];
1353  Int_t nhits = sp->GetNHits();
1354  UInt_t bitpat = 0; // Bit pattern of which planes are hit
1355  Double_t maxchi2= 1.0e10;
1356  Double_t minchi2 = maxchi2;
1357  Double_t tmp_minchi2=maxchi2;
1358  Double_t minxp = 0.25;
1359  Int_t hasy1 = -1;
1360  Int_t hasy2 = -1;
1361  Int_t plusminusknown[nhits];
1362  Int_t plusminusbest[nhits];
1363  Int_t plusminus[nhits]; // ENGINE makes this array float. Why?
1364  Int_t tmp_plusminus[nhits];
1365  Int_t plane_list[nhits];
1366  Double_t stub[4];
1367  Double_t tmp_stub[4];
1368  Int_t nplusminus;
1369 
1370  if(nhits < 0) {
1371  if (fhdebugflagpr) cout << "THcDriftChamber::LeftRight() nhits < 0" << endl;
1372  } else if (nhits==0) {
1373  if (fhdebugflagpr) cout << "THcDriftChamber::LeftRight() nhits = 0" << endl;
1374  }
1375  for(Int_t ihit=0;ihit < nhits;ihit++) {
1376  THcDCHit* hit = sp->GetHit(ihit);
1377  Int_t pindex = hit->GetPlaneIndex();
1378  plane_list[ihit] = pindex;
1379 
1380  bitpat |= 1<<pindex;
1381 
1382  plusminusknown[ihit] = 0;
1383 
1384  if(pindex == YPlaneInd) hasy1 = ihit;
1385  if(pindex == YPlanePInd) hasy2 = ihit;
1386  }
1387  nplusminus = 1<<nhits;
1388  if(fHMSStyleChambers) {
1389  Int_t smallAngOK = (hasy1>=0) && (hasy2>=0);
1390  if(fSmallAngleApprox !=0 && smallAngOK) { // to small Angle L/R for Y,Y' planes
1391 
1392  if(sp->GetHit(hasy2)->GetPos() <=
1393  sp->GetHit(hasy1)->GetPos()) {
1394  plusminusknown[hasy1] = -1;
1395  plusminusknown[hasy2] = 1;
1396  } else {
1397  plusminusknown[hasy1] = 1;
1398  plusminusknown[hasy2] = -1;
1399  }
1400  nplusminus = 1<<(nhits-2);
1401  // if (fhdebugflagpr) cout << " Small angle approx = " << smallAngOK << " " << plusminusknown[hasy1] << endl;
1402  //if (fhdebugflagpr) cout << "pm = " << plusminusknown[hasy2] << " " << hasy1 << " " << hasy2 << endl;
1403  //if (fhdebugflagpr) cout << " Plane index " << YPlaneInd << " " << YPlanePInd << endl;
1404  }
1405  } else { // SOS Style
1406  if(fSmallAngleApprox !=0) {
1407  // Brookhaven style chamber L/R code
1408  Int_t npaired=0;
1409  for(Int_t ihit1=0;ihit1 < nhits;ihit1++) {
1410  THcDCHit* hit1 = sp->GetHit(ihit1);
1411  Int_t pindex1=hit1->GetPlaneIndex();
1412  if((pindex1%2)==0) { // Odd plane (or even index)
1413  for(Int_t ihit2=0;ihit2<nhits;ihit2++) {
1414  THcDCHit* hit2 = sp->GetHit(ihit2);
1415  if(hit2->GetPlaneIndex()-pindex1 == 1 && TMath::Abs(hit2->GetPos()-hit1->GetPos())<0.51) { // Adjacent plane
1416  if(hit2->GetPos() <= hit1->GetPos() ) {
1417  plusminusknown[ihit1] = -1;
1418  plusminusknown[ihit2] = 1;
1419  } else {
1420  plusminusknown[ihit1] = 1;
1421  plusminusknown[ihit2] = -1;
1422  }
1423  npaired+=2;
1424  }
1425  }
1426  }
1427  }
1428  nplusminus = 1 << (nhits-npaired);
1429  }//end if fSmallAngleApprox!=0
1430  }//end else SOS style
1431  if(nhits < 2) {
1432  if (fdebugstubchisq) cout << "THcDriftChamber::LeftRight: numhits-2 < 0" << endl;
1433  } else if (nhits == 2) {
1434  if (fdebugstubchisq) cout << "THcDriftChamber::LeftRight: numhits-2 = 0" << endl;
1435  }
1436  Int_t nplaneshit = Count1Bits(bitpat);
1437  if (fhdebugflagpr) cout << " num of pm = " << nplusminus << " num of hits =" << nhits << endl;
1438  // Use bit value of integer word to set + or -
1439  // Loop over all combinations of left right.
1440  for(Int_t pmloop=0;pmloop<nplusminus;pmloop++) {
1441  Int_t iswhit = 1;
1442  for(Int_t ihit=0;ihit<nhits;ihit++) {
1443  if(plusminusknown[ihit]!=0) {
1444  plusminus[ihit] = plusminusknown[ihit];
1445  } else {
1446  // Max hits per point has to be less than 32.
1447  if(pmloop & iswhit) {
1448  plusminus[ihit] = 1;
1449  } else {
1450  plusminus[ihit] = -1;
1451  }
1452  iswhit <<= 1;
1453  }
1454  }
1455  if ( (nplaneshit >= fNPlanes-1) || (nplaneshit >= fNPlanes-2 && !fHMSStyleChambers)) {
1456  Double_t chi2;
1457  chi2 = FindStub(nhits, sp,plane_list, bitpat, plusminus, stub);
1458  if (fdebugstubchisq) cout << " pmloop = " << pmloop << " chi2 = " << chi2 << endl;
1459  if(chi2 < minchi2) {
1460  if (fStubMaxXPDiff<100. ) {
1461  // Take best chi2 IF x' of the stub agrees with x' as expected from x.
1462  // Sometimes an incorrect x' gives a good chi2 for the stub, even though it is
1463  // not the correct left/right combination for the real track.
1464  // Rotate x'(=stub(3)) to hut coordinates and compare to x' expected from x.
1465  // THIS ASSUMES STANDARD HMS TUNE!!!!, for which x' is approx. x/875.
1466  if(stub[2]*fTanBeta[plane_list[0]]==-1.0) {
1467  if (fhdebugflagpr) cout << "THcDriftChamber::LeftRight() Error 3" << endl;
1468  }
1469  Double_t xp_fit=stub[2]-fTanBeta[plane_list[0]]
1470  /(1+stub[2]*fTanBeta[plane_list[0]]);
1471  Double_t xp_expect = sp->GetX()*fRatio_xpfp_to_xfp;
1472  if(TMath::Abs(xp_fit-xp_expect)<fStubMaxXPDiff) {
1473  minchi2 = chi2;
1474  for(Int_t ihit=0;ihit<nhits;ihit++) {
1475  plusminusbest[ihit] = plusminus[ihit];
1476  }
1477  sp->SetStub(stub);
1478  } else { // Record best stub failing angle cut
1479  if (chi2 < tmp_minchi2) {
1480  tmp_minchi2 = chi2;
1481  for(Int_t ihit=0;ihit<nhits;ihit++) {
1482  tmp_plusminus[ihit] = plusminus[ihit];
1483  }
1484  for(Int_t i=0;i<4;i++) {
1485  tmp_stub[i] = stub[i];
1486  }
1487  }
1488  }
1489  } else { // Not HMS specific
1490  minchi2 = chi2;
1491  for(Int_t ihit=0;ihit<nhits;ihit++) {
1492  plusminusbest[ihit] = plusminus[ihit];
1493  }
1494  sp->SetStub(stub);
1495  }
1496  }
1498  } else if (nplaneshit >= fNPlanes-2 && fHMSStyleChambers) { // Two planes missing
1499  Double_t chi2 = FindStub(nhits, sp,plane_list, bitpat, plusminus, stub);
1500  //if(debugging)
1501  if (fhdebugflagpr) cout << "pmloop=" << pmloop << " Chi2=" << chi2 << endl;
1502  // Isn't this a bad idea, doing == with reals
1503  if(stub[2]*fTanBeta[plane_list[0]] == -1.0) {
1504  if (fhdebugflagpr) cout << "THcDriftChamber::LeftRight() Error 3" << endl;
1505  }
1506  Double_t xp_fit=stub[2]-fTanBeta[plane_list[0]]
1507  /(1+stub[2]*fTanBeta[plane_list[0]]);
1508  if(TMath::Abs(xp_fit) <= minxp) {
1509  minxp = TMath::Abs(xp_fit);
1510  minchi2 = chi2;
1511  for(Int_t ihit=0;ihit<nhits;ihit++) {
1512  plusminusbest[ihit] = plusminus[ihit];
1513  }
1514  sp->SetStub(stub);
1515  }
1516  } else {
1517  if (fhdebugflagpr) cout << "Insufficient planes hit in THcDriftChamber::LeftRight()" << bitpat <<endl;
1518  }
1519  } // End loop of pm combinations
1520 
1521  if (minchi2 == maxchi2 && tmp_minchi2 == maxchi2) {
1522 
1523  } else {
1524  if(minchi2 == maxchi2 ) { // No track passed angle cut
1525  minchi2 = tmp_minchi2;
1526  for(Int_t ihit=0;ihit<nhits;ihit++) {
1527  plusminusbest[ihit] = tmp_plusminus[ihit];
1528  }
1529  sp->SetStub(tmp_stub);
1530  }
1531  Double_t *spstub = sp->GetStubP();
1532 
1533  // Calculate final coordinate based on plusminusbest
1534  // Update the hit positions in the space points
1535  for(Int_t ihit=0; ihit<nhits; ihit++) {
1536  // Save left/right status with the hit and in the spaleftce point
1537  // In THcDC will decide which to used based on fix_lr flag
1538  sp->GetHit(ihit)->SetLeftRight(plusminusbest[ihit]);
1539  sp->SetHitLR(ihit, plusminusbest[ihit]);
1540  }
1541 
1542  // Stubs are calculated in rotated coordinate system
1543  // (I think this rotates in case chambers not perpendicular to central ray)
1544  Int_t pindex=plane_list[0];
1545  if(spstub[2] - fTanBeta[pindex] == -1.0) {
1546  if (fhdebugflagpr) cout << "THcDriftChamber::LeftRight(): stub3 error" << endl;
1547  }
1548  stub[2] = (spstub[2] - fTanBeta[pindex])
1549  / (1.0 + spstub[2]*fTanBeta[pindex]);
1550  if(spstub[2]*fSinBeta[pindex] == -fCosBeta[pindex]) {
1551  if (fhdebugflagpr) cout << "THcDriftChamber::LeftRight(): stub4 error" << endl;
1552  }
1553  stub[3] = spstub[3]
1554  / (spstub[2]*fSinBeta[pindex]+fCosBeta[pindex]);
1555  stub[0] = spstub[0]*fCosBeta[pindex]
1556  - spstub[0]*stub[2]*fSinBeta[pindex];
1557  stub[1] = spstub[1]
1558  - spstub[1]*stub[3]*fSinBeta[pindex];
1559  sp->SetStub(stub);
1560  if (fhdebugflagpr) cout << " Left/Right space pt " << isp+1 << " " << stub[0]<< " " << stub[1] << " " << stub[2]<< " " << stub[3] << endl;
1561  }
1562  }
1563  // Option to print stubs
1564 }
1565 //_____________________________________________________________________________
1567  Int_t* plane_list, UInt_t bitpat,
1568  Int_t* plusminus, Double_t* stub)
1569 {
1570  // For a given combination of L/R, fit a stub to the space point
1571  // This method does a linear least squares fit of a line to the
1572  // hits in an individual chamber. It assumes that the y slope is 0
1573  // The wire coordinate is calculated by
1574  // wire center + plusminus*(drift distance).
1575  // Method is called in a loop over all combinations of plusminus
1576  Double_t zeros[] = {0.0,0.0,0.0};
1577  TVectorD TT; TT.Use(3, zeros); // X, X', Y
1578  Double_t dpos[nhits];
1579  for(Int_t ihit=0;ihit<nhits; ihit++) {
1580  dpos[ihit] = sp->GetHit(ihit)->GetPos()
1581  + plusminus[ihit]*sp->GetHitDist(ihit)
1582  - fPsi0[plane_list[ihit]];
1583  for(Int_t index=0;index<3;index++) {
1584  TT[index]+= dpos[ihit]*fStubCoefs[plane_list[ihit]][index]
1585  /fSigma[plane_list[ihit]];
1586  }
1587  }
1588  // fAA3Inv[bitpat].Print();
1589  // if (fhdebugflagpr) cout << TT[0] << " " << TT[1] << " " << TT[2] << endl;
1590  // TT.Print();
1591 
1592  TT *= fAA3Inv[bitpat];
1593  // if (fhdebugflagpr) cout << TT[0] << " " << TT[1] << " " << TT[2] << endl;
1594 
1595  // Calculate Chi2. Remember one power of sigma is in fStubCoefs
1596  stub[0] = TT[0];
1597  stub[1] = TT[1];
1598  stub[2] = TT[2];
1599  stub[3] = 0.0;
1600  Double_t chi2=0.0;
1601  for(Int_t ihit=0;ihit<nhits; ihit++) {
1602  chi2 += pow( dpos[ihit]/fSigma[plane_list[ihit]]
1603  - fStubCoefs[plane_list[ihit]][0]*stub[0]
1604  - fStubCoefs[plane_list[ihit]][1]*stub[1]
1605  - fStubCoefs[plane_list[ihit]][2]*stub[2]
1606  , 2);
1607  }
1608  return(chi2);
1609 }
1610 
1611 //_____________________________________________________________________________
1613 {
1614  // Destructor. Remove variables from global list.
1615 
1616  if (fhdebugflagpr) cout << fChamberNum << ": delete fSpacePoints: " << hex << fSpacePoints << endl;
1617  delete fSpacePoints;
1618  delete fXPlaneClusters;
1619  delete fUPlaneClusters;
1620  delete fVPlaneClusters;
1621  delete fUXPlaneClusters;
1622  delete fVXPlaneClusters;
1623  // Should delete the matrices
1624 
1625  if( fIsSetup )
1626  RemoveVariables();
1627  if( fIsInit )
1628  DeleteArrays();
1629  if (fTrackProj) {
1630  fTrackProj->Clear();
1631  delete fTrackProj; fTrackProj = 0;
1632  }
1633 }
1634 
1635 
1636 //_____________________________________________________________________________
1638 {
1639  // Delete member arrays. Used by destructor.
1640  delete [] fCosBeta; fCosBeta = NULL;
1641  delete [] fSinBeta; fSinBeta = NULL;
1642  delete [] fTanBeta; fTanBeta = NULL;
1643  delete [] fSigma; fSigma = NULL;
1644  delete [] fPsi0; fPsi0 = NULL;
1645  delete [] fStubCoefs; fStubCoefs = NULL;
1646 
1647 }
1648 
1649 //_____________________________________________________________________________
1650 inline
1652 {
1653  // Reset per-event data.
1654  // fNhits = 0;
1655 
1656  // fTrackProj->Clear();
1657  fNhits = 0;
1658 
1659 }
1660 
1661 //_____________________________________________________________________________
1663 {
1664  return(0);
1665 }
1666 
Drift chamber wire hit info.
Definition: THcDCHit.h:16
void SetPlaneIndex(Int_t index)
std::string GetName(const std::string &scope_name)
Int_t GetPlaneIndex() const
Definition: THcDCHit.h:59
double dist(Rotation3D const &r1, Rotation3D const &r2)
virtual Int_t NewFindSpacePoints(void)
Int_t DestroyPoorSpacePoints(void)
virtual Int_t DefineVariables(EMode mode=kDefine)
Double_t fStubMaxXPDiff
Int_t SpacePointMultiWire(void)
void SelectSpacePoints(void)
Double_t * GetStubP()
Definition: THcSpacePoint.h:68
SpacePointHitOutputData fSpHit
Double_t GetY()
Definition: THcSpacePoint.h:44
TClonesArray * fSpacePoints
const char Option_t
std::vector< THcDriftChamberPlane * > fPlanes
void SetStub(Double_t stub[4])
Definition: THcSpacePoint.h:60
THcDriftChamberPlane * GetWirePlane() const
Definition: THcDCHit.h:46
Class for a a single Hall C horizontal drift chamber plane.
Double_t * fCosBeta
#define MAX_SPACE_POINTS
virtual void AddPlane(THcDriftChamberPlane *plane)
virtual ~THcDriftChamber()
int Int_t
bool Bool_t
Int_t GetWireNum() const
Definition: THcDCHit.h:36
STL namespace.
Short_t Abs(Short_t d)
Double_t fRatio_xpfp_to_xfp
Analyze a package of horizontal drift chambers.
Definition: THcDC.h:23
void AddHit(THcDCHit *hit)
Definition: THcSpacePoint.h:33
virtual void PrintDecode(void)
Int_t FindEasySpacePoint_SOS(Int_t xplane_hitind, Int_t xplanep_hitind)
virtual Int_t Decode(const THaEvData &)
TVectorT< Double_t > & Use(Int_t lwb, Int_t upb, Double_t *data)
Double_t x[n]
Double_t ** fStubCoefs
TObject * ConstructedAt(Int_t idx)
Class for clusters in the same orientation planes (V,X or U)
TClonesArray * fVPlaneClusters
double pow(double, double)
virtual void LeftRight(void)
std::map< int, TMatrixD > fAA3Inv
void SetXY(Double_t x, Double_t y)
Definition: THcSpacePoint.h:31
virtual Int_t FindSpacePoints(void)
void Clear(Option_t *opt="")
Definition: THcSpacePoint.h:32
void AddHit(THcDCHit *hit)
void SetHitLR(Int_t ihit, Int_t lr)
Definition: THcSpacePoint.h:57
virtual Int_t ReadDatabase(const TDatime &date)
Int_t GetPlaneNum() const
Definition: THcDCHit.h:58
Int_t fRemove_Sppt_If_One_YPlane
Double_t GetHitDist(Int_t ihit)
Definition: THcSpacePoint.h:66
TMatrixT< Double_t > & Invert(Double_t *det=0)
void SetNHits(Int_t nhits)
Definition: THcSpacePoint.h:42
Double_t fSpacePointCriterion
Class representing a single hit DC.
Definition: THcSpacePoint.h:13
virtual void Clear(Option_t *option="")
TClonesArray * fUXPlaneClusters
Int_t GetCombos()
Definition: THcSpacePoint.h:71
virtual void Clear(Option_t *opt="")
#define MAX_HITS_PER_POINT
void SetTime(Double_t time)
Definition: THcDCHit.h:50
Int_t FindEasySpacePoint_HMS(Int_t yplane_hitind, Int_t yplanep_hitind)
virtual void ProcessHits(void)
void ChooseSingleHit(void)
virtual void Delete(Option_t *option="")
TClonesArray * fTrackProj
Double_t GetTime() const
Definition: THcDCHit.h:39
TClonesArray * fXPlaneClusters
Int_t fFixPropagationCorrection
unsigned int UInt_t
Int_t GetReadoutSide()
Definition: THcDCHit.h:63
char * Form(const char *fmt,...)
void IncrNPlaneClust()
Definition: THcDCHit.h:53
Double_t GetYsp() const
void SetLeftRight(Int_t lr)
Definition: THcDCHit.h:52
void SetXY(Double_t x, Double_t y)
THcDCHit * GetHit(Int_t ihit)
std::vector< THcDCHit * > fHits
virtual void CorrectHitTimes(void)
UInt_t Count1Bits(UInt_t x)
Int_t GetNHits()
Definition: THcSpacePoint.h:41
THcDCHit * GetHit(Int_t ihit)
Definition: THcSpacePoint.h:46
Double_t * fTanBeta
void Setup(const char *name, const char *description)
tuple list
Definition: SConscript.py:9
Double_t Cos(Double_t)
Double_t GetXsp() const
const Bool_t kFALSE
Double_t GetX()
Definition: THcSpacePoint.h:43
std::vector< Int_t > SpHitIndex
Int_t FindHardSpacePoints(void)
Double_t GetPos() const
Definition: THcDCHit.h:41
void IncCombos()
Definition: THcSpacePoint.h:69
Int_t LoadParmValues(const DBRequest *list, const char *prefix="")
Retrieve parameter values from the parameter cache.
double Double_t
void SetHitDist(Int_t ihit, Double_t dist)
Definition: THcSpacePoint.h:54
virtual EStatus Init(const TDatime &run_time)
Double_t y[n]
TClonesArray * fVXPlaneClusters
ClassImp(THcDCLookupTTDConv) THcDCLookupTTDConv
Int_t GetNPlaneClust() const
Definition: THcDCHit.h:54
virtual Double_t ConvertTimeToDist()
Definition: THcDCHit.cxx:34
Double_t Sin(Double_t)
void ReplaceHit(Int_t ihit, THcDCHit *hit)
Definition: THcSpacePoint.h:49
virtual Int_t ApplyCorrections(void)
Int_t GetRawTime() const
Definition: THcDCHit.h:37
Double_t fWireVelocity
Subdetector class for a single drift chamber with several planes.
void SetCombos(Int_t ncombos)
Definition: THcSpacePoint.h:70
R__EXTERN class THcParmList * gHcParms
Definition: THcGlobals.h:11
Double_t Sqrt(Double_t x)
TObject * At(Int_t idx) const
Double_t GetDist() const
Definition: THcDCHit.h:40
Int_t GetNHits() const
int ncx
Double_t * fSinBeta
TClonesArray * fUPlaneClusters
const Bool_t kTRUE
std::vector< Int_t > SpNHits
Double_t FindStub(Int_t nhits, THcSpacePoint *sp, Int_t *plane_list, UInt_t bitpat, Int_t *plusminus, Double_t *stub)
THaDetectorBase * fParent
void SetDist(Double_t dist)
Definition: THcDCHit.h:51