StRoot  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
StTofpMatchMaker.cxx
1 /***************************************************************************
2  *
3  * $Id: StTofpMatchMaker.cxx,v 1.15 2018/02/26 23:26:52 smirnovd Exp $
4  *
5  * Author: Frank Geurts
6  ***************************************************************************
7  *
8  * Description: Match Maker for TOFp detector
9  *
10  **************************************************************************/
11 #include <iostream>
12 #include "StEventTypes.h"
13 #include "Stypes.h"
14 #include "StThreeVectorD.hh"
15 #include "StThreeVectorF.hh"
16 #include "StHelix.hh"
17 #include "StTrackGeometry.h"
18 #include "StEventUtilities/StuRefMult.hh"
19 #include "PhysicalConstants.h"
20 #include "StPhysicalHelixD.hh"
21 #include "StTofUtil/StTofGeometry.h"
22 #include "StTofUtil/StTofSlatCollection.h"
23 #include "tables/St_pvpdStrobeDef_Table.h"
24 #include "TH1.h"
25 #include "TH2.h"
26 #include "TFile.h"
27 #include "TOrdCollection.h"
28 #include "StMessMgr.h"
29 #include "StMemoryInfo.hh"
30 #include "StTimer.hh"
31 #include "StTofUtil/tofPathLength.hh"
32 #include "StTofpMatchMaker.h"
33 
34 
35 
36 //---------------------------------------------------------------------------
38 StTofpMatchMaker::StTofpMatchMaker(const Char_t *name): StMaker(name){
39  // zero counters & pointers
40  mEventCounter = 0;
41  mAcceptedEventCounter = 0;
42  mTofEventCounter = 0;
43  mTofStrobeEventCounter = 0;
44  mAcceptAndStrobe = 0;
45  mAcceptAndBeam = 0;
46  mTofGeom = 0;
47 
48  // set default values
49  setValidAdcRange(0,1024);
50  setValidTdcRange(30,1200);
51  setOuterTrackGeometry();
52  setMinHitsPerTrack(0);
53  setMinFitPointsPerTrack(0);
54  setMaxDCA(9999.);
55 
56  createHistograms(kTRUE);
57  doPrintMemoryInfo = kFALSE;
58  doPrintCpuInfo = kFALSE;
59 }
60 
61 StTofpMatchMaker::~StTofpMatchMaker(){ /* nope */}
62 
63 void StTofpMatchMaker::Clear(Option_t *opt){StMaker::Clear();}
64 
65 //---------------------------------------------------------------------------
68  gMessMgr->Info("StTofpMatchMaker -- initializing ...","OS");
69  gMessMgr->Info("","OST") << "Valid TDC range: " << mMinValidTdc << " " << mMaxValidTdc << endm;
70  gMessMgr->Info("","OST") << "Valid ADC range: " << mMinValidAdc << " " << mMaxValidAdc << endm;
71  gMessMgr->Info("","OST") << "Minimum hits per track: " << mMinHitsPerTrack << endm;
72  gMessMgr->Info("","OST") << "Minimum fitpoints per track: " << mMinFitPointsPerTrack << endm;
73  gMessMgr->Info("","OST") << "Maximum DCA: " << mMaxDCA << endm;
74  if (!mOuterTrackGeometry)
75  gMessMgr->Warning("Warning: using standard trackgeometry()","OST");
76 
77  if(m_Mode) {
78  setHistoFileName("tofana.root");
79  } else {
80  setHistoFileName("");
81  }
82 
83  if (mHisto){
84  bookHistograms();
85  gMessMgr->Info("Histograms are booked","OST");
86  if (mHistoFileName!="")
87  gMessMgr->Info("","OST") << "Histograms will be stored in " << mHistoFileName.c_str() << endm;
88  }
89 
90  // reset event counters
91  mEventCounter = 0;
92  mAcceptedEventCounter = 0;
93  mTofEventCounter = 0;
94  mTofStrobeEventCounter = 0;
95  mAcceptAndStrobe = 0;
96  mAcceptAndBeam = 0;
97 
98  return kStOK;
99 }
100 
101 
102 //---------------------------------------------------------------------------
104 Int_t StTofpMatchMaker::InitRun(int runnumber){
105 
106  // determine TOF configuration from run#
107  mYear2 = (runnumber<4000000);
108  mYear3 = (runnumber>4000000&&runnumber<5000000);
109  mYear4 = (runnumber>5000000&&runnumber<6000000);
110  mYear5 = (runnumber>6000000);
111 
112  gMessMgr->Info("StTofpMatchMaker -- reinitializing TofGeometry (InitRun)","OS" );
113  mTofGeom = new StTofGeometry();
114  mTofGeom->init(this);
115 
116  gMessMgr->Info(" -- retrieving run parameters","OS");
117  TDataSet *mDbDataSet = GetDataBase("Calibrations/tof/pvpdStrobeDef");
118  if (!mDbDataSet){
119  gMessMgr->Error("unable to get TOF run parameters","OS");
120  // assert(mDbDataSet);
121  return kStErr;
122  }
123  St_pvpdStrobeDef* pvpdStrobeDef = static_cast<St_pvpdStrobeDef*>(mDbDataSet->Find("pvpdStrobeDef"));
124  if (!pvpdStrobeDef){
125  gMessMgr->Error("unable to find TOF run param table","OS");
126  // assert(pvpdStrobeDef);
127  return kStErr;
128  }
129  pvpdStrobeDef_st *strobeDef = static_cast<pvpdStrobeDef_st*>(pvpdStrobeDef->GetArray());
130  int numRows = pvpdStrobeDef->GetNRows();
131  if (NPVPD != numRows) gMessMgr->Warning("#tubes inconsistency in dbase");
132  for (int i=0;i<NPVPD;i++){
133  int ii = strobeDef[i].id - 1;
134  mStrobeTdcMin[ii] = strobeDef[i].strobeTdcMin;
135  mStrobeTdcMax[ii] = strobeDef[i].strobeTdcMax;
136  if (Debug())
137  LOG_INFO << "tube " << strobeDef[i].id << " min:"<< strobeDef[i].strobeTdcMin
138  <<" max:"<< strobeDef[i].strobeTdcMax<< endm;
139  }
140 
141 
142 
143  return kStOK;
144 }
145 
147 Int_t StTofpMatchMaker::FinishRun(int runnumber){
148  gMessMgr->Info("StTofpMatchMaker -- cleaning up geometry (FinishRun)","OS" );
149  if (mTofGeom) delete mTofGeom;
150  mTofGeom=0;
151  return kStOK;
152 }
153 
154 
155 //---------------------------------------------------------------------------
158  gMessMgr->Info("","OS") << "StTofpMatchMaker ----- RUN SUMMARY ----- (Finish)\n"
159  << "\tProcessed " << mEventCounter << " events."
160  << " Accepted " << mAcceptedEventCounter << " events."
161  << " Rejected " << mEventCounter - mAcceptedEventCounter << " events\n"
162  << "\tTOF events " << mTofEventCounter
163  << ". Beam " << mTofEventCounter - mTofStrobeEventCounter
164  << " Strobe " << mTofStrobeEventCounter
165  << "\n\t Accept & Strobe " << mAcceptAndStrobe << " events\n"
166  << "\t Accept & Beam " << mAcceptAndBeam << " events" << endm;
167 
168  if (mHistoFileName!="") writeHistogramsToFile();
169  return kStOK;
170 }
171 
172 
173 //---------------------------------------------------------------------------
176  gMessMgr->Info("StTofpMatchMaker -- welcome","OS");
177 
178  if(mYear5) {
179  gMessMgr->Info("StTofpMatchMaker -- no TOFp in and after Run 5","OS");
180  return kStOK;
181  }
182 
183  // event selection ...
184  StEvent *event = (StEvent *) GetInputDS("StEvent");
185  if (!validEvent(event)){
186  gMessMgr->Info("StTofpMatchMaker -- nothing to do ... bye-bye","OST");
187  return kStOK;
188  }
189 
190  // timing & memory info -only when requested-
191  StTimer timer;
192  if (doPrintCpuInfo) timer.start();
193  if (doPrintMemoryInfo) StMemoryInfo::instance()->snapshot();
194 
195  //.........................................................................
196  // check for tofCollection and fill local copy with ADC and TDC data
197  StTofCollection *theTof = event->tofCollection();
198  getTofData(theTof);
199 
200  //.........................................................................
201  // update TOFp slat counters
202  float sumAdcTofp(0.); int nAdcTofp(0), nTdcTofp(0), nAdcTdcTofp(0);
203  for (int i=0;i<NTOFP;i++){
204  sumAdcTofp += mTofpAdc[i];
205  bool tdcValid = validTdc(mTofpTdc[i]);
206  bool adcValid = validAdc(mTofpAdc[i]);
207  if (tdcValid) nTdcTofp++;
208  if (adcValid) nAdcTofp++;
209  if (adcValid && tdcValid) nAdcTdcTofp++;
210  }
211  if (Debug())
212  LOG_INFO << " TOFp #Adc:" << nAdcTofp << " #Tdc:" << nTdcTofp << endm;
213 
214  // update pVPD tubes counters
215  float sumAdcPvpd=0; int nAdcPvpd=0, nTdcPvpd=0;
216  for (int i=0;i<NPVPD;i++){
217  sumAdcPvpd += mPvpdAdc[i];
218  bool tdcValid = validTdc(mPvpdTdc[i]);
219  bool adcValid = validAdc(mPvpdAdc[i]);
220  if (tdcValid) nTdcPvpd++;
221  if (adcValid) nAdcPvpd++;
222  }
223  if (Debug())
224  LOG_INFO << " pVPD #Adc:" << nAdcPvpd << " #Tdc:" << nTdcPvpd << endm;
225 
226 
227 
228  if (Debug()){
229  // number of primary tracks
230  // (note: different meaning in event.root and richtof.root)
231  int refmult(0);
232  bool richTofMuDST = (event->summary()->numberOfExoticTracks() == -999);
233  if (richTofMuDST)
234  refmult = event->summary()->numberOfGoodTracks();
235  else
236  refmult = uncorrectedNumberOfPrimaries(*event);
237 
238  LOG_INFO << " #Tracks :" << event->summary()->numberOfTracks()
239  << "\n #goodPrimaryTracks:" << event->summary()->numberOfGoodPrimaryTracks()
240  << "\n #uncorr.prim.tracks :" << refmult << endm;
241  if (!richTofMuDST)
242  LOG_INFO << " #goodTracks (global):" << event->summary()->numberOfGoodTracks() << endm;
243  }
244 
245 
246 
247  //.........................................................................
248  // A. build vector of candidate slats with valid ADC signals
249  idVector validSlatIdVec;
250  for (int i=0;i<NTOFP;i++){
251  unsigned short slatId = mTofGeom->daqToSlatId(i);
252  float rawAdc = mTofpAdc[i];
253  float rawTdc = mTofpTdc[i];
254  if (mHisto) hTofpSlatIdA0->Fill(i+1);
255 
256  if (validAdc(rawAdc) && validTdc(rawTdc)){
257  validSlatIdVec.push_back(slatId);
258  if (mHisto) hTofpSlatIdA1->Fill(i+1);
259  }
260  }
261  gMessMgr->Info("","OST") << "A: #valid slats: " << validSlatIdVec.size() << endm;
262  // end of Sect.A
263  if(!validSlatIdVec.size()) return kStOK;
264 
265  //.........................................................................
266  // B. loop over global tracks and determine all slat-track matches
267  //
268  tofSlatHitVector allSlatsHitVec;
269  allSlatsHitVec.clear();
270  StSPtrVecTrackNode& nodes = event->trackNodes();
271  int nAllTracks=0;
272  for (unsigned int iNode=0; iNode<nodes.size(); iNode++){
273  tofSlatHitVector slatHitVec;
274  slatHitVec.clear();
275  StTrack *theTrack = nodes[iNode]->track(global);
276 
277  // make sure we have a track, a miniDST might have removed it...
278  if (validTrack(theTrack)){
279  nAllTracks++;
280  StPhysicalHelixD theHelix = trackGeometry(theTrack)->helix();
281 
282  idVector projTrayVec;
283  if(!mTofGeom->projTrayVector(theHelix, projTrayVec)) continue;
284 
285  Bool_t hitTofp = kFALSE;
286  for(size_t ii = 0; ii<projTrayVec.size(); ii++) {
287  if(projTrayVec[ii]==mTofpTrayId) hitTofp = kTRUE;
288  }
289  if(!hitTofp) continue;
290 
291  slatHitVec = mTofGeom->tofHelixToArray(theHelix, validSlatIdVec);
292  if (slatHitVec.size()>0 && mHisto) hTofpSlatHitVecSize->Fill(slatHitVec.size());
293 
294  for (size_t ii = 0; ii < slatHitVec.size(); ii++) {
295  slatHitVec[ii].trackIdVec.push_back(iNode);
296  allSlatsHitVec.push_back(slatHitVec[ii]);
297  if (mHisto){
298  int id = mTofGeom->slatIdToDaq(slatHitVec[ii].slatIndex);
299  float xhit = slatHitVec[ii].hitPosition.x();
300  float yhit = slatHitVec[ii].hitPosition.y();
301  float zhit = slatHitVec[ii].hitPosition.z();
302  float phihit = atan2(yhit,xhit);
303  hTofpSlatIdB1->Fill(id);
304  hTofpHitMap1->Fill(zhit,phihit);
305  }
306 
307  if (Debug()){
308  LOG_INFO << "B: trackid=";
309  idVectorIter ij = slatHitVec[ii].trackIdVec.begin();
310  while (ij != slatHitVec[ii].trackIdVec.end()) {LOG_INFO << " " << *ij; ij++;}
311  LOG_INFO << "\tind=" << mTofGeom->slatIdToDaq(slatHitVec[ii].slatIndex)
312  << "\thitprof="<< slatHitVec[ii].hitProfile
313  << "\ts="<<slatHitVec[ii].s << "\tthxy="<<slatHitVec[ii].theta_xy
314  << "\tthzr="<<slatHitVec[ii].theta_zr;
315  if (slatHitVec.size()>1) LOG_INFO << " M" << endm;
316  else LOG_INFO << endm;
317  }
318  }
319  } // existing global track
320  } // loop over nodes
321 
322  gMessMgr->Info("","OST") << "B: #matched/#avail/#total tracknodes: "
323  <<allSlatsHitVec.size() << "/" <<nAllTracks
324  << "/" << nodes.size() << endm;
325  // end of Sect.B
326  if(!allSlatsHitVec.size()) return kStOK;
327 
328  //.........................................................................
329  // C Neighbours -- identify crosstalk, geometry shifts (only fill histograms)
330  //
331  if (mHisto){
332  for (tofSlatHitVectorIter ij = allSlatsHitVec.begin();ij!=allSlatsHitVec.end(); ij++){
333  int slatId=ij->slatIndex;
334  int daqId= mTofGeom->slatIdToDaq(slatId);
335 
336  idVector slatNeighbours = mTofGeom->slatNeighboursWide(slatId);
337  idVector slatCloseNeighbours = mTofGeom->slatNeighbours(slatId);
338 
339  // loop over neighbour candidates
340  bool matchedNeighbours(false);
341  for (idVectorIter kk=slatNeighbours.begin();kk!=slatNeighbours.end();kk++){
342  // is the neighbour matched to a slat ...
343  for (tofSlatHitVectorIter jj = allSlatsHitVec.begin();jj!=allSlatsHitVec.end();jj++){
344  if (jj->slatIndex == *kk) matchedNeighbours=true;
345  }
346  }
347 
348  // scan for valid TDCs in case no matched neighbours were found
349  if (!matchedNeighbours){
350  bool tdcOK = validTdc(mTofpTdc[daqId-1]);
351  int nHitNeighbours(0),nNoHitNeighbours(0);
352 
353  for (idVectorIter kk=slatCloseNeighbours.begin();kk!=slatCloseNeighbours.end();kk++){
354  int neighborDaqId=mTofGeom->slatIdToDaq(*kk);
355  int neighborSlatId=*kk;
356  if (validTdc(mTofpTdc[neighborDaqId-1])){
357  int iEta = mTofGeom->tofSlat(neighborSlatId).ieta - mTofGeom->tofSlat(slatId).ieta;
358  int iPhi = mTofGeom->tofSlat(neighborSlatId).iphi - mTofGeom->tofSlat(slatId).iphi;
359 
360 
361  if (tdcOK){
362  hTofpMatchHit[daqId-1]->Fill(iEta,iPhi);
363  nHitNeighbours++;
364  }
365  else {
366  hTofpMatchNoHit[daqId-1]->Fill(iEta,iPhi);
367  nNoHitNeighbours++;
368  }
369  }
370  } // loop over close slat neighbours
371 
372  if (tdcOK){
373  hTofpMatchHit[daqId-1]->Fill(0.,0.,nHitNeighbours);
374  }
375  else{
376  hTofpMatchNoHit[daqId-1]->Fill(0.,0.,nNoHitNeighbours);
377  }
378 
379  } // no matched neighbrs
380  }
381  }
382  // end of Sect.C
383 
384 
385 
386  //.........................................................................
387  // D. sort hit vectors and deal with (discard) slats matched by multiple tracks
388  //
389  int nSingleHitSlats(0);
390  tofSlatHitVector singleHitSlatsVec;
391  StructSlatHit slatHit;
392 
393  tofSlatHitVector tempVec = allSlatsHitVec;
394  tofSlatHitVector erasedVec = tempVec;
395  while (tempVec.size() != 0) {
396  int nTracks = 0;
397  vector<StThreeVectorD> vPosition;
398  vector<vector<StThreeVectorD> > vLayerHitPositions;
399  vector<Int_t> vHitProfile;
400  vector<Float_t> vS, vTheta_xy, vTheta_zr;
401  idVector trackIdVec;
402 
403  tofSlatHitVectorIter tempIter=tempVec.begin();
404  tofSlatHitVectorIter erasedIter=erasedVec.begin();
405  while(erasedIter!= erasedVec.end()) {
406  if(tempIter->slatIndex == erasedIter->slatIndex) {
407  nTracks++;
408  // save all hit data in temporary vectors
409  trackIdVec.push_back(erasedIter->trackIdVec.back());
410  vPosition.push_back(erasedIter->hitPosition);
411  vLayerHitPositions.push_back(erasedIter->layerHitPositions);
412  vHitProfile.push_back(erasedIter->hitProfile);
413  vS.push_back(erasedIter->s);
414  vTheta_xy.push_back(erasedIter->theta_xy);
415  vTheta_zr.push_back(erasedIter->theta_zr);
416 
417  if (mHisto){
418  float xhit = erasedIter->hitPosition.x();
419  float yhit = erasedIter->hitPosition.y();
420  float zhit = erasedIter->hitPosition.z();
421  float phihit = atan2(yhit,xhit);
422  hTofpHitMap2->Fill(zhit,phihit);
423  }
424 
425  erasedVec.erase(erasedIter);
426  erasedIter--;
427  }
428  erasedIter++;
429  }
430 
431  if (mHisto){
432  int daqId = mTofGeom->slatIdToDaq(tempIter->slatIndex);
433  hTofpSlatIdD1->Fill(daqId);
434  }
435 
436  if (nTracks==1){
437  nSingleHitSlats++;
438  // for singly hit slat, copy data in singleHitSlatsVec
439  slatHit.slatIndex = tempIter->slatIndex;
440  slatHit.hitPosition = vPosition[0];
441  slatHit.layerHitPositions = vLayerHitPositions[0];
442  slatHit.trackIdVec = trackIdVec;
443  slatHit.hitProfile = vHitProfile[0];
444  slatHit.s = vS[0];
445  slatHit.theta_xy = vTheta_xy[0];
446  slatHit.theta_zr = vTheta_zr[0];
447 
448  singleHitSlatsVec.push_back(slatHit);
449 
450  if (mHisto){
451  int daqId = mTofGeom->slatIdToDaq(tempIter->slatIndex);
452  float xhit = slatHit.hitPosition.x();
453  float yhit = slatHit.hitPosition.y();
454  float zhit = slatHit.hitPosition.z();
455  float phihit = atan2(yhit,xhit);
456  hTofpSlatIdD2->Fill(daqId);
457  hTofpHitMap3->Fill(zhit,phihit);
458  }
459 
460  // debugging output
461  if (Debug()) {
462  LOG_INFO << "D: ind=" << mTofGeom->slatIdToDaq(slatHit.slatIndex)
463  << "\thitprof="<< slatHit.hitProfile << "\ts="<<slatHit.s
464  << "\tthxy="<<slatHit.theta_xy << "\tthzr="<<slatHit.theta_zr << "\ttrackid:";
465  idVectorIter ij=trackIdVec.begin();
466  while (ij != trackIdVec.end()) { LOG_INFO << " " << *ij; ij++; }
467  LOG_INFO <<endm;
468  }
469  }
470  else if (nTracks>1){
471  // for multiple hit slats either discard (yes) or
472  // find the most likely candidate.
473  } else
474  gMessMgr->Warning("","OST") << "D: no tracks extrapolate to matched slat ... should not happen!" << endm;
475 
476  tempVec = erasedVec;
477  }
478  gMessMgr->Info("","OST") << "D: #before/#after: " << allSlatsHitVec.size()
479  << "/" << singleHitSlatsVec.size() << endm;
480  //end of Sect.D
481 
482 
483 
484  //.........................................................................
485  // E. sort and deal singleHitSlatsVector for multiple slats associated to single tracks
486  //
487  tofSlatHitVector allMatchedSlatsVec;
488  tempVec = singleHitSlatsVec;
489  erasedVec = tempVec;
490  while (tempVec.size() != 0) {
491  StructSlatHit slatHit;
492  int nSlats = 0;
493  vector<StThreeVectorD> vPosition;
494  vector< vector<StThreeVectorD> > vLayerHitPositions;
495  vector<Int_t> vHitProfile;
496  vector<Float_t> vS, vTheta_xy, vTheta_zr;
497  idVector vTrackId;
498  vector<Int_t> slatIndex;
499 
500  tofSlatHitVectorIter tempIter=tempVec.begin();
501  tofSlatHitVectorIter erasedIter=erasedVec.begin();
502  while(erasedIter!= erasedVec.end()) {
503  if(tempIter->trackIdVec.back() == erasedIter->trackIdVec.back()) {
504  nSlats++;
505  // save all hit data in temporary vectors
506  slatIndex.push_back(erasedIter->slatIndex);
507  vTrackId.push_back(erasedIter->trackIdVec.back());
508  vPosition.push_back(erasedIter->hitPosition);
509  vLayerHitPositions.push_back(erasedIter->layerHitPositions);
510  vHitProfile.push_back(erasedIter->hitProfile);
511  vS.push_back(erasedIter->s);
512  vTheta_xy.push_back(erasedIter->theta_xy);
513  vTheta_zr.push_back(erasedIter->theta_zr);
514 
515  erasedVec.erase(erasedIter);
516  erasedIter--;
517  }
518  erasedIter++;
519  }
520 
521 
522  if (nSlats==1){
523  // for singly hit slat, copy data in singleHitSlatsVec
524  slatHit.slatIndex = slatIndex[0];
525  slatHit.hitPosition = vPosition[0];
526  slatHit.layerHitPositions = vLayerHitPositions[0];
527  slatHit.trackIdVec.push_back(vTrackId[0]);
528  slatHit.hitProfile = vHitProfile[0];
529  slatHit.s = vS[0];
530  slatHit.theta_xy = vTheta_xy[0];
531  slatHit.theta_zr = vTheta_zr[0];
532  slatHit.matchFlag = 0;
533 
534  allMatchedSlatsVec.push_back(slatHit);
535 
536  if (mHisto){
537  int daqId = mTofGeom->slatIdToDaq(slatIndex[0]);
538  hTofpSlatIdE1->Fill(daqId);
539  }
540 
541  // debugging output
542  if (Debug()) {
543  LOG_INFO << "E: ind=" << mTofGeom->slatIdToDaq(slatHit.slatIndex)
544  << "\thitprof="<< slatHit.hitProfile << "\ts="<<slatHit.s
545  << "\tthxy="<<slatHit.theta_xy << "\tthzr="<<slatHit.theta_zr << "\ttrackid:";
546  idVectorIter ij=vTrackId.begin();
547  while (ij != vTrackId.end()) { LOG_INFO << " " << *ij; ij++; }
548  LOG_INFO <<endm;
549  }
550  }
551  else if (nSlats>1){ // for multiple hit slats find the most likely candidate.
552  int thiscandidate(-99);
553  int thisMatchFlag(0);
554 
555  // 1. sort on hitprofile weight
556  int weight(0);
557  vector<int> weightCandidates;
558  thisMatchFlag = 1;
559  if (Debug()) LOG_INFO << "E: find ... weight ";
560  for (int i=0;i<nSlats;i++){
561  int hitWeight = vLayerHitPositions[i].size();
562  if (Debug()) LOG_INFO << mTofGeom->slatIdToDaq(slatIndex[i]) << "("<<hitWeight<<")"<<" ";
563  if (hitWeight>weight) {
564  weight=hitWeight;
565  weightCandidates.clear();
566  weightCandidates.push_back(i);
567  } else if (hitWeight == weight)
568  weightCandidates.push_back(i);
569  }
570  if (weightCandidates.size()==1){
571  thiscandidate = weightCandidates[0];
572  int daqId = mTofGeom->slatIdToDaq(slatIndex[thiscandidate]);
573  if (mHisto) hTofpSlatIdE2->Fill(daqId);
574  if (Debug()) LOG_INFO << "candidate =" << daqId << endm;
575  }
576 
577  // 2. if still undecided check on ss
578  if (weightCandidates.size()>1){
579  Float_t ss(0);
580  vector<int> ssCandidates;
581  thisMatchFlag = 2;
582  if (Debug()) LOG_INFO << " ss ";
583  for (unsigned int i=0;i<weightCandidates.size();i++){
584  int ii=weightCandidates[i];
585  if (Debug()) LOG_INFO << mTofGeom->slatIdToDaq(slatIndex[ii]) << " ";
586  if (vS[ii]>ss){
587  ss = vS[ii];
588  ssCandidates.clear();
589  ssCandidates.push_back(ii);
590  }else if (vS[ii]==ss)
591  ssCandidates.push_back(ii);
592  }
593  if (ssCandidates.size()==1){
594  thiscandidate = ssCandidates[0];
595  int daqId = mTofGeom->slatIdToDaq(slatIndex[thiscandidate]);
596  if (mHisto) hTofpSlatIdE3->Fill(daqId);
597  if (Debug()) LOG_INFO << "candidate =" << daqId << endm;
598  }
599 
600  // 3. if still undecided go for closest/first hit
601  if (ssCandidates.size()>1){
602  Int_t hitprof(0);
603  vector<int> profileCandidates;
604  thisMatchFlag = 3;
605  if (Debug()) LOG_INFO << " hprof ";
606  for (unsigned int i=0;i<ssCandidates.size();i++){
607  int ii=ssCandidates[i];
608  if (Debug()) LOG_INFO << mTofGeom->slatIdToDaq(slatIndex[ii]) << " ";
609  if (vHitProfile[ii]>hitprof){
610  hitprof = vHitProfile[ii];
611  profileCandidates.clear();
612  profileCandidates.push_back(ii);
613  }else if (vHitProfile[ii]==hitprof)
614  profileCandidates.push_back(ii);
615  }
616  if (profileCandidates.size()==1){
617  thiscandidate = profileCandidates[0];
618  int daqId = mTofGeom->slatIdToDaq(slatIndex[thiscandidate]);
619  if (mHisto) hTofpSlatIdE4->Fill(daqId);
620  if (Debug()) LOG_INFO << "candidate =" << daqId << endm;
621  }
622  else
623  if (Debug()) LOG_INFO << "none" << endm;
624  }
625 
626 
627  // forget it, and let user know of the non-decision
628  if (thiscandidate == -99 && Debug()){
629  LOG_INFO << "E: ind=";
630  for (unsigned int ii=0;ii<slatIndex.size();ii++)
631  LOG_INFO << mTofGeom->slatIdToDaq(slatIndex[ii]) << " ";
632  LOG_INFO << "\ttrkid:" << vTrackId[0] << " Unable to decide. ";
633  LOG_INFO << "(hitprofs:";
634  for (unsigned int ii=0;ii<slatIndex.size();ii++)
635  LOG_INFO << vHitProfile[ii] << " ";
636  LOG_INFO << " ss:";
637  for (unsigned int ii=0;ii<slatIndex.size();ii++)
638  LOG_INFO << vS[ii] << " ";
639  LOG_INFO << ")" << endm;
640  }
641 
642  }
643 
644 
645  if (thiscandidate>=0){
646  slatHit.slatIndex = slatIndex[thiscandidate];
647  slatHit.hitPosition = vPosition[thiscandidate];
648  slatHit.layerHitPositions = vLayerHitPositions[thiscandidate];
649  //slatHit.trackIdVec.clear();
650  slatHit.trackIdVec.push_back(vTrackId[thiscandidate]);
651  slatHit.hitProfile = vHitProfile[thiscandidate];
652  slatHit.s = vS[thiscandidate];
653  slatHit.theta_xy = vTheta_xy[thiscandidate];
654  slatHit.theta_zr = vTheta_zr[thiscandidate];
655  slatHit.matchFlag = thisMatchFlag;
656 
657  allMatchedSlatsVec.push_back(slatHit);
658 
659  if (mHisto){
660  int daqId = mTofGeom->slatIdToDaq(slatIndex[thiscandidate]);
661  hTofpSlatIdE5->Fill(daqId);
662  }
663 
664  // debugging output
665  if (Debug()) {
666  LOG_INFO << "E: ind=" << mTofGeom->slatIdToDaq(slatHit.slatIndex)
667  << "\thitprof="<< slatHit.hitProfile << "\ts="<<slatHit.s
668  << "\tthxy="<<slatHit.theta_xy << "\tthzr="<<slatHit.theta_zr << "\ttrackid:"
669  << vTrackId[thiscandidate] << endm;
670  }
671  }
672  } else
673  gMessMgr->Warning("","OS") << "E: no slats belong to this track ... should not happen!" << endm;
674 
675  tempVec = erasedVec;
676  }
677  gMessMgr->Info("","OST") << "E: #before/#after: " << singleHitSlatsVec.size()
678  << "/" << allMatchedSlatsVec.size() << endm;
679  // end of Sect.E
680 
681 
682 
683  //.........................................................................
684  // F. perform further selection and
685  // fill valid track histograms and SlatCollection
686  //
687  StTofSlatCollection *mSlatCollection = new StTofSlatCollection;
688  int nValidSingleHitSlats(0), nValidSinglePrimHitSlats(0);
689 
690  for (size_t ii=0; ii < allMatchedSlatsVec.size(); ii++){
691  int daqId = mTofGeom->slatIdToDaq(allMatchedSlatsVec[ii].slatIndex);
692  int jj = daqId-1;
693 
694  if (allMatchedSlatsVec[ii].trackIdVec.size()!=1)
695  gMessMgr->Warning("","OST") << "F: WHAT!?! mult.matched slat in single slat list " << daqId << endm;
696 
697  // 1. fill valid single track AND valid tdc histograms
698  if (validTdc(mTofpTdc[jj])) nValidSingleHitSlats++;
699 
700  // get track-id from slat hit vector
701  unsigned int trackNode = allMatchedSlatsVec[ii].trackIdVec[0];
702  StTrack *theTrack = nodes[trackNode]->track(primary);
703 
704  // 2. continue only if the (primary) track exists
705  if (validTofTrack(theTrack)){
706  nValidSinglePrimHitSlats++;
707  if (mHisto){
708  float xhit = allMatchedSlatsVec[ii].hitPosition.x();
709  float yhit = allMatchedSlatsVec[ii].hitPosition.y();
710  float zhit = allMatchedSlatsVec[ii].hitPosition.z();
711  float phihit = atan2(yhit,xhit);
712  hTofpHitMap4->Fill(zhit,phihit);
713  hTofpSlatIdF1->Fill(daqId);
714  }
715 
716  //--- store number of hits per track
717  int nHitsPerTrack = theTrack->topologyMap().numberOfHits(kTpcId);
718  if(mHisto) hTofpNumberOfTrackHits->Fill(nHitsPerTrack);
719 
720  // select the apropriate track geometry
721  StTrackGeometry *theTrackGeometry = trackGeometry(theTrack);
722 
723  //--- get momentum from track
724  const StThreeVectorF momentum = theTrackGeometry->momentum();
725  if (mHisto) hTofpPtTrack->Fill(momentum.perp());
726 
727  //--- calculate flight path
728  double pathLength = tofPathLength(&event->primaryVertex()->position(),
729  &allMatchedSlatsVec[ii].hitPosition,
730  theTrackGeometry->helix().curvature());
731 
732 
733  //--- calculate local hit position on slat based first, last and middle plane
734  // (middle plane is the average of first and last plane, which is mathematically
735  // the same as SlatHitVec.hitPosition ... )
736  StThreeVectorD *pInnerLayer, *pOuterLayer;
737  pInnerLayer = &(*(allMatchedSlatsVec[ii].layerHitPositions.begin()));
738  pOuterLayer = &(*(allMatchedSlatsVec[ii].layerHitPositions.end() - 1));
739 
740  //--- dig out from the dedx and rich pid traits (only for Debug mode)
741  float dedx(0.), cherang(0);
742  int dedx_np(0), cherang_nph(0);
743  if (Debug()){
744  StSPtrVecTrackPidTraits& traits = theTrack->pidTraits();
745  for (unsigned int it=0;it<traits.size();it++){
746  if (traits[it]->detector() == kTpcId){
747  StDedxPidTraits *pid = dynamic_cast<StDedxPidTraits*>(traits[it]);
748  if (pid && pid->method() ==kTruncatedMeanId){
749  dedx = pid->mean();
750  dedx_np = pid->numberOfPoints();
751  }
752  } else if (traits[it]->detector() == kRichId){
753  StRichPidTraits *pid = dynamic_cast<StRichPidTraits*>(traits[it]);
754  if (pid){
755  StRichSpectra* pidinfo = pid->getRichSpectra();
756  if (pidinfo && pidinfo->getCherenkovPhotons()>2){
757  cherang = pidinfo->getCherenkovAngle();
758  cherang_nph = pidinfo->getCherenkovPhotons();
759  }
760  }
761  }
762  }
763  }
764 
765  //--- calculate local hit position on slat based on average hitposition
766  float localHitPos = mTofGeom->slatHitPosition(&allMatchedSlatsVec[ii].hitPosition);
767 
768  // Fill TOF Slat Collection
769  //StTofSlat *tofSlat = new StTofSlat(jj+1,(int)mTofpAdc[jj],(int)mTofpTdc[jj],theTrack);
770  StTofSlat *tofSlat = new StTofSlat(jj+1,(int)mTofpAdc[jj],(int)mTofpTdc[jj],theTrack,
771  localHitPos, allMatchedSlatsVec[ii].hitProfile,
772  allMatchedSlatsVec[ii].matchFlag);
773  tofSlat->setPosition(allMatchedSlatsVec[ii].hitPosition);
774  mSlatCollection->push_back(tofSlat);
775 
776  // dump debug data
777  if (Debug()){
778  LOG_INFO << "F: ind=" << mTofGeom->slatIdToDaq(allMatchedSlatsVec[ii].slatIndex)
779  << "\ttrackid:";
780  idVectorIter ij=allMatchedSlatsVec[ii].trackIdVec.begin();
781  while (ij != allMatchedSlatsVec[ii].trackIdVec.end()) { LOG_INFO << " " << *ij; ij++; }
782  LOG_INFO << "\tR=" << 1/(theTrackGeometry->helix().curvature())
783  << "\tpT=" << momentum.perp() << "\tp=" << momentum.mag()
784  << "\thits="<< nHitsPerTrack << "\ts="<< pathLength
785  << "\t#fitp=" <<theTrack->fitTraits().numberOfFitPoints(kTpcId)
786  << "\t#trkp=" <<theTrack->detectorInfo()->numberOfPoints(kTpcId)
787  << " \tdedx=" << dedx
788  << " \tdca="<< theTrack->geometry()->helix().distance(event->primaryVertex()->position());
789  if (cherang!=0) LOG_INFO << " \trich="<< cherang << " (" << cherang_nph << ")";
790  LOG_INFO << endm;
791  }
792 
793  } // track exists
794  }
795 
796  storeMatchData(mSlatCollection,theTof);
797  delete mSlatCollection;
798 
799  gMessMgr->Info("","OST") << "F: #before/#after: " << allMatchedSlatsVec.size()
800  << "/" <<nValidSinglePrimHitSlats << endm;
801 
802  //check StEvent collections --
803  if (theTof->dataPresent())
804  gMessMgr->Info("- TofCollection: raw data container present","OST");
805  if (theTof->slatsPresent()){
806  gMessMgr->Info("- TofCollection: slat container present","OST");
807  if (Debug()){
808  StSPtrVecTofSlat& tmpSlatTofVec = theTof->tofSlats();
809  for (size_t i = 0; i < tmpSlatTofVec.size(); i++) {
810  StTofSlat* p = tmpSlatTofVec[i];
811  LOG_INFO << p->slatIndex() << " " << p->adc() << " " << p->tdc()
812  << " " << p->associatedTrack() << endm;
813  }
814  }
815  }
816  //-- end check
817 
818  // end of Sect.F
819 
820 
821  // fill occupancy plots
822  if (mHisto){
823  hTofpNumberOfValidAdc->Fill(nAdcTofp);
824  hTofpNumberOfValidTdc->Fill(nTdcTofp);
825  hTofpNumberOfValidSlats->Fill(nAdcTdcTofp);
826  hTofpNumberOfGlobalTracks->Fill(allSlatsHitVec.size());
827  hTofpNumberOfHitSlats->Fill(allMatchedSlatsVec.size());
828  hTofpNumberOfSingleHitTracks->Fill(nSingleHitSlats);
829  hTofpNumberOfSingleValidHitTracks->Fill(nValidSingleHitSlats);
830  }
831  gMessMgr->Info("","OST") << "#(slat tracks): " << allSlatsHitVec.size()
832  << " #(hit slats): " << allMatchedSlatsVec.size()
833  << " #slats (valid tdc): " << nTdcTofp
834  << " #(single hits): " << nSingleHitSlats
835  << " #(single valid hits): " << nValidSingleHitSlats
836  << " #(single prim valid hits): " << nValidSinglePrimHitSlats
837  << endm;
838 
839 
840 
841  if (doPrintMemoryInfo) {
842  StMemoryInfo::instance()->snapshot();
843  StMemoryInfo::instance()->print();
844  }
845  if (doPrintCpuInfo) {
846  timer.stop();
847  gMessMgr->Info("","OST") << "CPU time for StTofpMatchMaker::Make(): "
848  << timer.elapsedTime() << " sec\n" << endm;
849  }
850 
851  gMessMgr->Info("StTofpMatchMaker -- bye-bye","OS");
852  return kStOK;
853 }
854 
855 
856 //---------------------------------------------------------------------------
859  StTofCollection* tofCollection){
860  if(!tofCollection){
861  gMessMgr->Error("No TofCollection -- returning","OS");
862  return kStErr;
863  }
864 
865  for (size_t j=0;j<slatCollection->size();j++){
866  tofCollection->addSlat(slatCollection->getSlat(j));
867  if (Debug())
868  LOG_INFO << "storing " << j << " "
869  << slatCollection->getSlat(j)->slatIndex() << endm;
870  }
871  return kStOK;
872 }
873 
874 
875 //---------------------------------------------------------------------------
878  if (!tofCollection) return kStERR;
879  StSPtrVecTofData &tofData = tofCollection->tofData();
880 
881  // perform consistency check
882  bool dataOK(true);
883  gMessMgr->Info("TOF raw data consistency test","OS");
884  for (int i=0;i<48;i++){
885  if (tofData[i]->dataIndex() != mTofGeom->daqToSlatId(i)) {
886  dataOK = false;
887  gMessMgr->Warning("","OST") << "===>WARNING: " << tofData[i]->dataIndex() << " " << mTofGeom->daqToSlatId(i) << endm;
888  }
889  //if (Debug()) LOG_INFO << *tofData[i];
890  }
891  //LOG_INFO << " done" << endm;
892 
893  for (int i=0;i<NTOFP;i++){
894  mTofpAdc[i] = tofData[i]->adc();
895  mTofpTdc[i] = tofData[i]->tdc();
896  }
897 
898  if (mYear2){
899  // swap ADC channels 3 and 4 ... this should move to the DAQreader!
900  float tmp = mTofpAdc[3];
901  mTofpAdc[3] = mTofpAdc[2];
902  mTofpAdc[2] = tmp;
903  }
904 
905  for (int i=0;i<NPVPD;i++){
906  mPvpdAdc[i] = tofData[42+i]->adc();
907  mPvpdTdc[i] = tofData[42+i]->tdc();
908  if (mYear3||mYear4)
909  mPvpdAdcLoRes[i] = tofData[54+i]->adc();
910  }
911 
912  if (!dataOK) return kStWarn;
913 
914  return kStOK;
915 }
916 
917 
918 //---------------------------------------------------------------------------
920 void StTofpMatchMaker::bookHistograms(void){
921 
922 
923  //.........................................................................
924  // Book Hit Position Correction histograms
925  mHitPosHistNames = new TOrdCollection;
926  hTofpHitMap1 = new TH2D("tofpHitMap1","valid hit positions", 500,-250,0, 120,-1.23, -1.08);
927  mHitPosHistNames->AddLast(hTofpHitMap1);
928  hTofpHitMap2 = new TH2D("tofpHitMap2","valid hit positions", 500,-250,0, 120,-1.23, -1.08);
929  mHitPosHistNames->AddLast(hTofpHitMap2);
930  hTofpHitMap3 = new TH2D("tofpHitMap3","valid hit positions", 500,-250,0, 120,-1.23, -1.08);
931  mHitPosHistNames->AddLast(hTofpHitMap3);
932  hTofpHitMap4 = new TH2D("tofpHitMap4","valid hit positions", 500,-250,0, 120,-1.23, -1.08);
933  mHitPosHistNames->AddLast(hTofpHitMap4);
934  hTofpSlatHitVecSize = new TH1D("SlatMult","Slat Mult per Track",10,0,10);
935  mHitPosHistNames->AddLast(hTofpSlatHitVecSize);
936  hTofpSlatIdA0 = new TH1D("tofpSlatIdA0","events per slat",41,0.5,41.5);
937  mHitPosHistNames->AddLast(hTofpSlatIdA0);
938  hTofpSlatIdA1 = new TH1D("tofpSlatIdA1","valid slat",41,0.5,41.5);
939  mHitPosHistNames->AddLast(hTofpSlatIdA1);
940  hTofpSlatIdB1 = new TH1D("tofpSlatIdB1","#tracks match valid slat",41,0.5,41.5);
941  mHitPosHistNames->AddLast(hTofpSlatIdB1);
942  hTofpSlatIdD1 = new TH1D("tofpSlatIdD1","track match per valid slat",41,0.5,41.5);
943  mHitPosHistNames->AddLast(hTofpSlatIdD1);
944  hTofpSlatIdD2 = new TH1D("tofpSlatIdD2","single track match per slat",41,0.5,41.5);
945  mHitPosHistNames->AddLast(hTofpSlatIdD2);
946  hTofpSlatIdE1 = new TH1D("tofpSlatIdE1","one slat for one track match",41,0.5,41.5);
947  mHitPosHistNames->AddLast(hTofpSlatIdE1);
948  hTofpSlatIdE2 = new TH1D("tofpSlatIdE2","recovered from hitprof-weight",41,0.5,41.5);
949  mHitPosHistNames->AddLast(hTofpSlatIdE2);
950  hTofpSlatIdE3 = new TH1D("tofpSlatIdE3","recovered from ss",41,0.5,41.5);
951  mHitPosHistNames->AddLast(hTofpSlatIdE3);
952  hTofpSlatIdE4 = new TH1D("tofpSlatIdE4","recovered from closest hitplane",41,0.5,41.5);
953  mHitPosHistNames->AddLast(hTofpSlatIdE4);
954  hTofpSlatIdE5 = new TH1D("tofpSlatIdE5","total recovered slat per track match",41,0.5,41.5);
955  mHitPosHistNames->AddLast(hTofpSlatIdE5);
956  hTofpSlatIdF1 = new TH1D("tofpSlatIdF1","primary track match per slat",41,0.5,41.5);
957  mHitPosHistNames->AddLast(hTofpSlatIdF1);
958 
959 
960  //.........................................................................
961  // Book track related histograms
962  mTrackHistNames = new TOrdCollection;
963  hTofpNumberOfTrackHits = new TH1D("tofpNumberOfTrackHits","numberOfTrackHits",80,0,80);
964  mTrackHistNames->AddLast(hTofpNumberOfTrackHits);
965  hTofpPtTrack = new TH1D("tofpPtTrack","ptTrack",250,0.,10);
966  mTrackHistNames->AddLast(hTofpPtTrack);
967  hTofpDCATrackprimVertex = new TH1D("tofpDCATrackprimVertex","DCA distribution",6000,-30.,30.);
968  mTrackHistNames->AddLast(hTofpDCATrackprimVertex);
969 
970  mOccupancyHistNames = new TOrdCollection;
971  hTofpNumberOfValidAdc = new TH1D("tofpNumberOfValidTdc","numberOfValidTdc",41,0,41);
972  mOccupancyHistNames->AddLast(hTofpNumberOfValidAdc);
973  hTofpNumberOfValidTdc = new TH1D("tofpNumberOfValidAdc","numberOfValidAdc",41,0,41);
974  mOccupancyHistNames->AddLast(hTofpNumberOfValidTdc);
975  hTofpNumberOfValidSlats = new TH1D("tofpNumberOfValidSlats","numberOfValidSlats",41,0,41);
976  mOccupancyHistNames->AddLast(hTofpNumberOfValidSlats);
977  hTofpNumberOfGlobalTracks = new TH1D("tofpNumberOfGlobalTracks","numberOfGlobalTracks",50,0,50);
978  mOccupancyHistNames->AddLast(hTofpNumberOfGlobalTracks);
979  hTofpNumberOfHitSlats = new TH1D("tofpNumberOfHitSlats","numberOfHitSlats",50,0,50);
980  mOccupancyHistNames->AddLast(hTofpNumberOfHitSlats);
981  hTofpNumberOfSingleHitTracks = new TH1D("tofpNumberOfSingleHitTracks","numberOfSingleHitTracks",50,0,50);
982  mOccupancyHistNames->AddLast(hTofpNumberOfSingleHitTracks);
983  hTofpNumberOfSingleValidHitTracks = new TH1D("tofpNumberOfSingleValidTracks","numberOfSingleValidHitTracks",50,0,50);
984  mOccupancyHistNames->AddLast(hTofpNumberOfSingleValidHitTracks);
985 
986  mMatchHistNames = new TOrdCollection;
987  char buf[20];
988  for (int i=0;i<NTOFP;i++){
989  sprintf(buf,"tofpSlathit_%d",i+1);
990  hTofpMatchHit[i] = new TH2D(buf,buf,5,-2.5,2.5,5,-2.5,2.5);
991  hTofpMatchHit[i]->SetXTitle("iEta");
992  hTofpMatchHit[i]->SetYTitle("iPhi");
993  mMatchHistNames->AddLast(hTofpMatchHit[i]);
994  sprintf(buf,"tofpSlatnohit_%d",i+1);
995  hTofpMatchNoHit[i] = new TH2D(buf,buf,5,-2.5,2.5,5,-2.5,2.5);
996  hTofpMatchNoHit[i]->SetXTitle("iEta");
997  hTofpMatchNoHit[i]->SetYTitle("iPhi");
998  mMatchHistNames->AddLast(hTofpMatchNoHit[i]);
999  }
1000 
1001  return;
1002 }
1003 
1004 
1005 //---------------------------------------------------------------------------
1007 void StTofpMatchMaker::writeHistogramsToFile(){
1008  // Output file
1009  TFile *theHistoFile = new TFile(mHistoFileName.c_str(), "RECREATE");
1010  gMessMgr->Info("","OST") << "StTofpMatchMaker::writeHistogramsToFile()"
1011  << " histogram file " << mHistoFileName << endm;
1012 
1013  theHistoFile->mkdir("hitpos","hit position histograms");
1014  theHistoFile->cd("hitpos");
1015  mHitPosHistNames->Write();
1016  delete mHitPosHistNames; mHitPosHistNames=0;
1017 
1018  theHistoFile->mkdir("track","Tracking Plots");
1019  theHistoFile->cd("track");
1020  mTrackHistNames->Write();
1021  delete mTrackHistNames; mTrackHistNames=0;
1022 
1023  theHistoFile->mkdir("occup","Occupancy Plots");
1024  theHistoFile->cd("occup");
1025  mOccupancyHistNames->Write();
1026  delete mOccupancyHistNames; mOccupancyHistNames=0;
1027 
1028  theHistoFile->mkdir("match","Matching Plots");
1029  theHistoFile->cd("match");
1030  mMatchHistNames->Write();
1031  delete mMatchHistNames; mMatchHistNames=0;
1032 
1033  theHistoFile->Write();
1034  theHistoFile->Close();
1035 
1036  return;
1037 }
1038 
1039 
1040 //---------------------------------------------------------------------------
1042 bool StTofpMatchMaker::strobeEvent(StSPtrVecTofData& tofData){
1043  // determine strobe event from pVPD TDC data
1044 
1045  int nStrobedPvpdTdcs=0;
1046  for(int i=0;i<NPVPD;i++)
1047  if((tofData[42+i]->tdc()>mStrobeTdcMin[i]) &&
1048  (tofData[42+i]->tdc()<mStrobeTdcMax[i]))
1049  nStrobedPvpdTdcs++;
1050 
1051  if (nStrobedPvpdTdcs==NPVPD) return true;
1052 
1053  return false;
1054 }
1055 
1056 
1057 //---------------------------------------------------------------------------
1059 bool StTofpMatchMaker::validEvent(StEvent *event){
1060  mEventCounter++;
1061  // 1. must have non-zero pointer
1062  if (!event) return false;
1063 
1064  // 2. must have a valid primary vertex
1065  if (!event->primaryVertex()) return false;
1066  mAcceptedEventCounter++;
1067 
1068  // 3a. must have TOF collection
1069  if (!event->tofCollection()){
1070  gMessMgr->Info("TOF is not present","OST");
1071  return false;
1072  }
1073 
1074  // 3b. must have TOF raw data available
1075  if (!(event->tofCollection()->dataPresent())){
1076  gMessMgr->Info("TOF is present but no Raw Data","OST");
1077  if (!(event->tofCollection()->slatsPresent())){
1078  gMessMgr->Info(" and no Slat Data","OST");
1079  return false;
1080  }
1081  }
1082  mTofEventCounter++;
1083 
1084 
1085  // 4. must be a TOF beam event, i.e. a non-strobe event
1086  StSPtrVecTofData &tofData = event->tofCollection()->tofData();
1087  if (strobeEvent(tofData)){
1088  mTofStrobeEventCounter++;
1089  if (event->primaryVertex()) mAcceptAndStrobe++; // keep track of #valid strobed evts
1090  gMessMgr->Info("strobe event","OTS");
1091  return false;
1092  }
1093  mAcceptAndBeam++;
1094 
1095  // and we have a winner!
1096  gMessMgr->Info("TOF present ... and valid beam event","OTS");
1097 
1098  return true;
1099 }
1100 
1101 
1102 //---------------------------------------------------------------------------
1104 bool StTofpMatchMaker::validTrack(StTrack *track){
1105  // 1. no track, no go.
1106  if (!track) return false;
1107 
1108  // 2. track quality flag, should be >0
1109  if (track->flag()<=0) return false;
1110 
1111  // 3. minimum #hits per track
1112  if (track->topologyMap().numberOfHits(kTpcId) < mMinHitsPerTrack) return false;
1113  // 4. minimum #fit points per track
1114  if (track->fitTraits().numberOfFitPoints(kTpcId) < mMinFitPointsPerTrack) return false;
1115 
1116  return true;
1117 }
1118 
1119 
1120 //---------------------------------------------------------------------------
1122 bool StTofpMatchMaker::validTofTrack(StTrack *track){
1123  // select valid tracks for time-of-flight calculations
1124 
1125  // 1. track must exist
1126  if (!track) return false;
1127 
1128  // 2. track must be a primary track
1129  if (!dynamic_cast<StPrimaryTrack*>(track)) return false;
1130 
1131  // 3. DCA cut (obsolete?)
1132  double DCA= track->impactParameter();
1133  int charge = track->geometry()->charge();
1134  if (mHisto) hTofpDCATrackprimVertex->Fill(DCA*charge);
1135  if (DCA > mMaxDCA) {
1136  gMessMgr->Info("","OST") << "dca>max:" << DCA<< endm;
1137  return false;
1138  }
1139 
1140  return true;
1141 }
1142 
1143 
1144 //---------------------------------------------------------------------------
1147  // returns apropriate StTrackGeometry (standard or outerGeometry)
1148  if (!track) return 0;
1149  StTrackGeometry *thisTrackGeometry;
1150  if (mOuterTrackGeometry)
1151  thisTrackGeometry = track->outerGeometry();
1152  else
1153  thisTrackGeometry = track->geometry();
1154  return thisTrackGeometry;
1155 }
1156 
1157 
1158 //---------------------------------------------------------------------------
1159 
1160 /***************************************************************************
1161  *
1162  * $Log: StTofpMatchMaker.cxx,v $
1163  * Revision 1.15 2018/02/26 23:26:52 smirnovd
1164  * StTof: Remove outdated ClassImp macro
1165  *
1166  * Revision 1.14 2018/02/26 23:13:21 smirnovd
1167  * Move embedded CVS log messages to the end of file
1168  *
1169  * Revision 1.13 2012/12/14 06:36:02 geurts
1170  * Changed global database calls to direct table access and/or removed deprecated database access code.
1171  *
1172  * Revision 1.12 2007/04/17 23:01:03 dongx
1173  * replaced with standard STAR Loggers
1174  *
1175  * Revision 1.11 2005/04/12 17:32:45 dongx
1176  * update for year 5 data. Tofp removed, so do nothing in this maker from now on.
1177  *
1178  * Revision 1.10 2004/06/10 15:54:31 dongx
1179  * rename the defition of int vector
1180  *
1181  * Revision 1.9 2004/06/09 21:28:05 dongx
1182  * update matching : checking before projecting track, improve the speed by around an order of magnitude
1183  *
1184  * Revision 1.8 2004/04/10 04:32:39 dongx
1185  * fix a potential crashing of filling histo w/o mHisto
1186  *
1187  * Revision 1.7 2004/03/11 22:29:32 dongx
1188  * -remove assert()
1189  * -add member mYear4
1190  * -use m_Mode to control the output root file
1191  *
1192  * Revision 1.6 2003/12/05 08:17:27 geurts
1193  * changed default TDC and ADC ranges
1194  *
1195  * Revision 1.5 2003/09/17 19:40:12 geurts
1196  * zeroed event counters and one pointer
1197  *
1198  * Revision 1.4 2003/09/15 22:38:10 geurts
1199  * dBase updates:
1200  * - removed initLocalDb option
1201  * - introduced dBase parameters for strobe event definitions
1202  *
1203  * Revision 1.3 2003/09/13 19:15:52 geurts
1204  * Changed passing of StSPtrVecTofData for strobeEvent (see bugtracker ticket #172)
1205  *
1206  * Revision 1.2 2003/09/02 17:59:11 perev
1207  * gcc 3.2 updates + WarnOff
1208  *
1209  * Revision 1.1 2003/08/08 18:31:26 geurts
1210  * first release
1211  *
1212  */
Int_t m_Mode
counters
Definition: StMaker.h:81
Int_t storeMatchData(StTofSlatCollection *, StTofCollection *)
store local slat collection in StEvent&#39;s tofCollection
tofSlatGeom_st tofSlat(const Int_t slatId) const
return slat geometry structure for slatId
Int_t FinishRun(int)
FinishRun: clean up tofp geometry.
void Clear(Option_t *option="")
User defined functions.
virtual void Clear(Option_t *option="")
User defined functions.
Definition: StMaker.cxx:634
idVector slatNeighbours(const int)
returns idVector of 3x3 (max) neighbouring slatIds
idVector slatNeighboursWide(const int)
returns idVector of 5x5 (max) neighbouring slatIds
double distance(const StThreeVector< double > &p, bool scanPeriods=true) const
minimal distance between point and helix
Definition: StHelix.cc:240
tofSlatHitVector tofHelixToArray(const StPhysicalHelixD &helix, idVector slatIdVec)
finds slats in an array of trays which are crossed by a track-helix.
StTofpMatchMaker(const Char_t *name="tofpMatch")
default constructor, set default values
Time-of-Flight Geometry Utilities.
float slatHitPosition(StThreeVectorD *)
returns 1-D hit position on the TOFp slat (Zhit)
Int_t getTofData(StTofCollection *)
create a local copy of the raw tofp data tofData in StEvent&#39;s tofCollection
Int_t Finish()
Finish: dump usage statistics and write histograms to file.
Int_t Init()
Init: inform user of parameter settings and book histograms.
Definition: Stypes.h:42
Definition: Stypes.h:40
Int_t InitRun(int)
InitRun: (re-)initialize the tofp geometry.
StTrackGeometry * trackGeometry(StTrack *)
returns the proper track geometry, based on a global user setting
Int_t Make()
Make: match extrapolated TPC tracks to TOFp slats.
Definition: Stypes.h:44
virtual TDataSet * Find(const char *path) const
Definition: TDataSet.cxx:362
Definition: Stypes.h:45
void init()
initialize geometry class from XDF file and set-up DAQ/Slat mappings