StRoot  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
StHiMicroMaker.cxx
1 /***************************************************************************
2  *
3  * $Id: StHiMicroMaker.cxx,v 1.6 2015/08/29 00:00:42 perev Exp $
4  *
5  * Author: Bum Choi, UT Austin, Apr 2002
6  *
7  ***************************************************************************
8  *
9  * Description: This Maker creates the highpt uDST's from StEvent
10  * for highpt Analysis.
11  *
12  ***************************************************************************
13  *
14  * $Log: StHiMicroMaker.cxx,v $
15  * Revision 1.6 2015/08/29 00:00:42 perev
16  * ::isnan new gcc
17  *
18  * Revision 1.5 2003/04/30 20:37:32 perev
19  * Warnings cleanup. Modified lines marked VP
20  *
21  * Revision 1.4 2002/05/31 21:50:14 jklay
22  * Fixed the way centrality is calculated, see README
23  *
24  * Revision 1.3 2002/04/03 00:37:41 jklay
25  * Fixed some bugs, added new version of dcaz
26  *
27  * Revision 1.2 2002/04/02 23:35:14 jklay
28  * Added L3RichTrigger information
29  *
30  * Revision 1.1 2002/04/02 20:00:41 jklay
31  * Bums highpt uDST Maker
32  *
33  *
34  **************************************************************************/
35 #include "StHiMicroMaker.h"
36 
37 #include "TMath.h"
38 #include "TRandom.h"
39 
40 #include "StHighptPool/StHiMicroEvent/StHiMicroEvent.h"
41 #include "Helper.h"
42 
43 #include "StIOMaker/StIOMaker.h"
44 #include "StThreeVectorF.hh"
45 #include "StThreeVectorD.hh"
46 #include "StEventTypes.h"
47 #include "StMessMgr.h"
48 #include "SystemOfUnits.h" // tesla...
49 #include "StTpcDedxPidAlgorithm.h"
50 #include "StuProbabilityPidAlgorithm.h"
51 #include "StPhysicalHelixD.hh"
52 #include "StuRefMult.hh"
53 #define PR(x) cout << "##### StHiMicroMaker: " << (#x) << " = " << (x) << endl;
54 
55 
56 // increasing order
57 inline bool sortCmp(StTpcHit* p1, StTpcHit* p2){
58  return p1->position().perp()<p2->position().perp();
59 }
60 
61 
62 //
63 // The constructor. Initialize you data members here.
64 //
65 StHiMicroMaker::StHiMicroMaker(const Char_t *makerName)
66  : StMaker(makerName), mNEvent(0), mNAcceptedEvent(0),
67  mNAcceptedTrack(0),
68  mVertexZCut(200), mHitLoop(0)
69 {
70 }
71 
72 //
73 // Usually ok to leave this as it is.
74 //
75 StHiMicroMaker::~StHiMicroMaker()
76 {
77 /* noop */
78 }
79 
80 //
81 // Called once at the beginning.
82 // This is a good place to book histos and tuples.
83 //
84 Int_t StHiMicroMaker::InitRun(int runID) {
85  if (mDebug) gMessMgr->Info() << "StHiMicroMaker: InitRun()" << endm;
86  PR(runID);
87 
88  mIOMaker = (StIOMaker*)GetMaker("IO");
89 
90  if(mIOMaker) mInFileName = strrchr(mIOMaker->GetFile(),'/')+1;
91 
92  if(mDebug) cout << "##Creating StHiMicroEvent..." << endl;
93  mHiMicroEvent = new StHiMicroEvent;
94 
95  Int_t stat = openFile();
96 
97  return stat + StMaker::Init();
98 
99 // return kStOK;
100 }
101 //---------------------------
102 Int_t
103 StHiMicroMaker::Init()
104 {
105 
106  cout << "###StHiMicroMaker::Init():\n";
107 
108  const char* set = (mDebug) ? "ON" : "OFF";
109  cout << "\tDebug is " << set << endl;
110 
111  //Pretty much moved everything that was here to InitRun(int)
112 
113  if(mSaveAllEvents) { cout << "\t<I> Saving event info for events without a primary vertex!!" << endl; }
114 
115  return StMaker::Init();
116 
117 }
118 
119 //
120 // Called every event after Make(). Usually you do not
121 // need to do anything here. Leave it as it is.
122 //
123 void
124 StHiMicroMaker::Clear(Option_t *opt)
125 {
126  StMaker::Clear();
127 }
128 
129 //
130 // Called once at the end.
131 //
132 Int_t
134 {
135 
136  cout << "###StHiMicroMaker::Finish()\n";
137  cout << "\tTotal " << mNEvent << " events." << endl;
138  cout << "\tProcessed " << mNAcceptedEvent << " events." << endl;
139  cout << "\tTracks : " << mNAcceptedTrack << endl << endl;
140  closeFile();
141 
142  return StMaker::Finish();
143 }
144 
145 //
146 // This method is called every event. That's the
147 // right place to plug in your analysis.
148 //
149 Int_t
151 {
152  mNEvent++;
153 
154  //
155  // it it's a new file, close the old one and open a new one
156  //
157  TString curFileName;
158  if(mIOMaker) curFileName = strrchr(mIOMaker->GetFile(),'/')+1;
159  if(mInFileName!=curFileName){
160  if(mDebug) {
161  cout << "##New file found : " << curFileName << endl;
162  cout << "##Replacing " << mInFileName << endl;
163  }
164  closeFile();
165  mInFileName = curFileName;
166  openFile();
167  }
168 
169  //
170  // Get pointer to StEvent
171  //dd
172  StEvent* event;
173  event = (StEvent *) GetInputDS("StEvent");
174 
175  if (!event) return kStOK; // if no event, we're done
176 
177  //
178  // filter event - if no primary vertex, reject it
179  //
180  //31.May.2002 - If we keep events without the vertex, we can use vertexZ position
181  //from ZDC timing to assess the vertex finding efficiency - but need to skip track filling and just fill event info
182  if (accept(event)) {
183 
184  mNAcceptedEvent++;
185  //
186  // fill tracks and hits
187  //
188  //30.May.2002 nGoodEta is no longer used, as there is a common defintion
189  //from StEvent now...
190  // Int_t nGoodEta = fillTracks(event);
191  //
192  // fill StHiMicroEvent
193  //
194  //30.May.2002 nGoodEta is no longer used, as there is a common defintion
195  //from StEvent now...
196  fillEvent(event);
197  //
198  // fill the tree
199  //
200  mDSTTree->Fill();
201 
202  } else {
203 
204  if(mSaveAllEvents) { //If we really want them all...
205  fillEvent(event);
206  mDSTTree->Fill();
207  }
208  }
209 
210  mHiMicroEvent->Clear(); // clears all the clonesarrays
211  return kStOK;
212 }
213 //____________________
214 
215 void
216 StHiMicroMaker::fillEvent(StEvent* stEvent)
217 {
218  //Set it to some really big value, so it will be cut out by relevant analyses
219 // const StThreeVectorF& prVtxPos(999.,999.,999.);
220 
221  if (stEvent->primaryVertex()) {
222  mHiMicroEvent->SetVertexZ(stEvent->primaryVertex()->position().z());
223  mHiMicroEvent->SetVertexX(stEvent->primaryVertex()->position().x());
224  mHiMicroEvent->SetVertexY(stEvent->primaryVertex()->position().y());
225  mHiMicroEvent->SetOriginMult(stEvent->primaryVertex()->numberOfDaughters());
226  } else {
227  mHiMicroEvent->SetVertexZ(999.);
228  mHiMicroEvent->SetVertexX(999.);
229  mHiMicroEvent->SetVertexY(999.);
230  mHiMicroEvent->SetOriginMult(0);
231  }
232 
233  // beam stuff
234  if(stEvent->runInfo()){
235  mHiMicroEvent->SetCenterOfMassEnergy(stEvent->runInfo()->centerOfMassEnergy());
236  mHiMicroEvent->SetMagneticField(stEvent->runInfo()->magneticField());
237  mHiMicroEvent->SetBeamMassNumberEast(stEvent->runInfo()->beamMassNumber(east));
238  mHiMicroEvent->SetBeamMassNumberWest(stEvent->runInfo()->beamMassNumber(west));
239  }
240  else{
241  gMessMgr->Info() << "StHiMicroMaker: no Run Info, reverting to year 1 settings "
242  << endm;
243  mHiMicroEvent->SetCenterOfMassEnergy(130);
244  mHiMicroEvent->SetMagneticField(4.98);
245  mHiMicroEvent->SetBeamMassNumberEast(197);
246  mHiMicroEvent->SetBeamMassNumberWest(197);
247  }
248 
249  mHiMicroEvent->SetNUncorrectedNegativePrimaries(uncorrectedNumberOfNegativePrimaries(*stEvent));
250  mHiMicroEvent->SetNUncorrectedPrimaries(uncorrectedNumberOfPrimaries(*stEvent));
251 
252  //30.May.2002 - fixed this definition to match the rest of STAR
253  //same as mNuncorrectedNumberOfPrimaries
254  mHiMicroEvent->SetCentMult(mHiMicroEvent->NUncorrectedPrimaries());
255  mHiMicroEvent->SetCentrality(mHiMicroEvent->NUncorrectedPrimaries());
256 
257  mHiMicroEvent->SetRunId((Int_t) stEvent->runId());
258  mHiMicroEvent->SetEventId((Int_t) stEvent->id());
259 
260 //Get the number of Global tracks. Not sure if this is the best way, but it will work
261 //JLK
262 
263  StTrack *track;
264  StSPtrVecTrackNode& theNodes = stEvent->trackNodes();
265  long allcnt = 0; long goodcnt = 0; long goodFlagcnt = 0;
266  long goodAcnt = 0; long goodBcnt = 0; long goodCcnt = 0;
267  long goodDcnt = 0; long goodEcnt = 0;
268 
269  for (unsigned int i=0; i<theNodes.size(); i++) {
270  allcnt += theNodes[i]->entries(global);
271  track = theNodes[i]->track(global);
272 //goodGlobal checks globals against evr criteria for vertex finding
273  if (goodGlobal(track)) goodcnt++;
274  if (goodGlobalA(track)) goodAcnt++;
275  if (goodGlobalB(track)) goodBcnt++;
276  if (goodGlobalC(track)) goodCcnt++;
277  if (goodGlobalD(track)) goodDcnt++;
278  if (goodGlobalE(track)) goodEcnt++;
279  if (goodGlobalFlag(track)) goodFlagcnt++;
280  }
281  mHiMicroEvent->SetNAllGlobals(allcnt);
282  mHiMicroEvent->SetNGoodGlobals(goodcnt);
283  mHiMicroEvent->SetNFlagGlobals(goodFlagcnt);
284  mHiMicroEvent->SetNGoodGlobalsA(goodAcnt);
285  mHiMicroEvent->SetNGoodGlobalsB(goodBcnt);
286  mHiMicroEvent->SetNGoodGlobalsC(goodCcnt);
287  mHiMicroEvent->SetNGoodGlobalsD(goodDcnt);
288  mHiMicroEvent->SetNGoodGlobalsE(goodEcnt);
289 
290  //** 01/28/02 - trigger word added
291  StL0Trigger* pTrigger = stEvent->l0Trigger();
292  if(pTrigger){
293  mHiMicroEvent->SetL0TriggerWord(pTrigger->triggerWord());
294  }
295  StL3Trigger* pL3Trigger = stEvent->l3Trigger();
296  if(pL3Trigger){
297  mHiMicroEvent->SetL3UnbiasedTrigger(pL3Trigger->l3EventSummary()->unbiasedTrigger());
298  mHiMicroEvent->SetL3RichTrigger(false);
299 
300  //Now check for L3 Rich Trigger
301  const StPtrVecL3AlgorithmInfo& algoInfo = pL3Trigger->l3EventSummary()->algorithmsAcceptingEvent();
302  for (UInt_t i = 0; i < algoInfo.size(); i++) {
303  if(algoInfo[i]->id() == 4) mHiMicroEvent->SetL3RichTrigger(true);
304  }
305  }
306 
307  // taken from flow maker
308  //
309  Float_t ctb = -1., zdce = -1, zdcw = -1, zdcVertexZ = 999.;
310 
311  StTriggerDetectorCollection *triggers
312  = stEvent->triggerDetectorCollection();
313  if (triggers) {
314  StCtbTriggerDetector &CTB = triggers->ctb();
315  StZdcTriggerDetector &ZDC = triggers->zdc();
316  // get CTB
317  for (UInt_t slat=0; slat<CTB.numberOfSlats(); slat++) {
318  for (UInt_t tray=0; tray<CTB.numberOfTrays();tray++) {
319  ctb += CTB.mips(tray,slat,0);
320  }
321  }
322  //get ZDCe and ZDCw
323  zdce = ZDC.adcSum(east);
324  zdcw = ZDC.adcSum(west);
325  zdcVertexZ = ZDC.vertexZ();
326  }
327 
328  mHiMicroEvent->SetCTB(ctb);
329  mHiMicroEvent->SetZDCe(zdce);
330  mHiMicroEvent->SetZDCw(zdcw);
331  mHiMicroEvent->SetZDCVertexZ(zdcVertexZ);
332 
333  cout << "###StHiMicroMaker::fillEvent" << endl;
334  cout << "\tvertex z : " << mHiMicroEvent->VertexZ() << endl;
335  cout << "\tZDC vertex z : " << mHiMicroEvent->ZDCVertexZ() << endl;
336  cout << "\tmultiplicity : " << mHiMicroEvent->OriginMult() << endl;
337  cout << "\tuncorrected h- : " << mHiMicroEvent->NUncorrectedNegativePrimaries() << endl;
338  cout << "\tuncorrected Nch : " << mHiMicroEvent->NUncorrectedPrimaries() << endl;
339  cout << "\tNch centrality : " << mHiMicroEvent->Centrality() << endl;
340 
341 }
342 //____________________
343 Int_t
344 StHiMicroMaker::fillTracks(StEvent* stEvent)
345 {
346 
347  //
348  // centrality stuff
349  //
350  Int_t nGoodTrackEta(0);
351  Int_t nHi(0);
352 
353  //
354  // create the track and hit object to temporarily store the info.
355  // these will then be added to the clonesarray
356  //
357 
358  StHiMicroTrack* hiMicroTrack = new StHiMicroTrack;
359  StHiMicroHit* hiMicroHit = new StHiMicroHit;
360 
361  //
362  // pid stuff for contamination
363  //
364  //StuProbabilityPidAlgorithm uPid(*stEvent);
365  StTpcDedxPidAlgorithm tpcDedxAlgo;
366 
367 
368  //
369  // loop over primary tracks
370  //
371  StSPtrVecPrimaryTrack& prTracks = stEvent->primaryVertex(0)->daughters();
372 
373  for(UInt_t i=0; i<prTracks.size(); i++){
374  StPrimaryTrack* prTrack = prTracks[i];
375  if(!prTrack) {
376  cout << "No primary?" << endl;
377  continue;
378  }
379  //
380  // need the global info as well
381  //
382  StGlobalTrack* glTrack =
383  dynamic_cast<StGlobalTrack*>(prTracks[i]->node()->track(global));
384  if(!glTrack) {
385  cout << "Error! no global information?" << endl;
386  continue;
387  }
388 
389  //Okay, fill it but this is no longer used as we can get the
390  //info from Manuel's uncorrectedNumberOfPrimaries(*stEvent)
391  //30.May.2002
392  if(acceptCentrality(prTrack)) nGoodTrackEta++;
393 
394  //
395  // accept the track?
396  //
397  if(!accept(glTrack) && !accept(prTrack)) continue;
398 
399  nHi++;
400  if(mDebug){
401  cout << "Accepted track" << endl;
402  dump(prTrack,glTrack);
403  }
404  //
405  // sort the hits
406  //
407 
408  const StPtrVecHit& hhits = glTrack->detectorInfo()->hits(kTpcId);
409  Float_t firstZ(0),lastZ(0);
410  Short_t innerPadList(0);
411  Int_t firstPadrow(0), lastPadrow(0), outerPadList(0);
412  UInt_t firstSector(0), lastSector(0);
413  Double_t crossAngle(999);
414 
415  vector<StTpcHit*> vec;
416  int countHits=0;
417  // fill the vector
418  for(UInt_t i=0; i<hhits.size(); i++){
419  StTpcHit* hit = (StTpcHit*)hhits[i];
420  if(!hit) continue;
421  countHits++;
422  vec.push_back(hit);
423  }
424  sort(vec.begin(),vec.end(),sortCmp);
425  if(vec.size()){
426  firstZ=vec[0]->position().z(); lastZ=vec[vec.size()-1]->position().z();
427  firstPadrow=vec[0]->padrow(); lastPadrow=vec[vec.size()-1]->padrow();
428 
429 //JLK Do bit packing here. Basically set a mask for each bit to turn on or off according to the padrow numbers
430 // in the vec
431 
432  Short_t inner = 0;
433  Int_t outer = 0;
434  Int_t SET_ON;
435  for (UInt_t i=0; i < vec.size(); i++) {
436  //printf("vec[%d]->padrow()=%d",i,vec[i]->padrow());
437  Int_t val = vec[i]->padrow();
438  if (val < 14) { //Inner sector
439  SET_ON = 1 << val; //Moves "1" over by val places
440  inner = inner | SET_ON;
441  } else {
442  SET_ON = (1 << (val-14)); //Moves "1" over by val places
443  outer = outer | SET_ON;
444  }
445  innerPadList=inner; outerPadList=outer;
446  }
447  firstSector=vec[0]->sector(); lastSector=vec[vec.size()-1]->sector();
448  //crossAngle=crossingAngle(glTrack->helix(),vec[0],stEvent->runInfo()->magneticField());
449  }
450  else{
451  if(mDebug)
452  cout << "\tno hits" << endl;
453  //continue;
454  }
455 
456  //
457  // alias to the momentum and helix
458  //
459  const StThreeVectorF& prMom = prTrack->geometry()->momentum();
460  const StThreeVectorF& glMom = glTrack->geometry()->momentum();
461  const StPhysicalHelixD& prHelix = prTrack->geometry()->helix();
462  const StPhysicalHelixD& glHelix = glTrack->geometry()->helix();
463  //
464  //***** fill some track info *****
465  //
466 
467  hiMicroTrack->SetCurvPr(prTrack->geometry()->curvature());
468  hiMicroTrack->SetCurvGl(glTrack->geometry()->curvature());
469  hiMicroTrack->SetPtPr(prMom.perp());
470  hiMicroTrack->SetEtaPr(prMom.pseudoRapidity());
471  hiMicroTrack->SetPhiPr(prMom.phi());
472  hiMicroTrack->SetDipAnglePr(prTrack->geometry()->dipAngle());
473 
474  hiMicroTrack->SetPtGl(glMom.perp());
475  hiMicroTrack->SetEtaGl(glMom.pseudoRapidity());
476  hiMicroTrack->SetPhiGl(glMom.phi());
477  hiMicroTrack->SetDipAngleGl(glTrack->geometry()->dipAngle());
478 
479  //
480  // find the sign of the dca --Could just get this from StPhysicalHelix now - Jamie added it
481  //
482  Float_t dcaXYGl = computeXY(stEvent->primaryVertex()->position(),
483  glTrack);
484 
485  Float_t dcaXYPr = computeXY(stEvent->primaryVertex()->position(),
486  prTrack);
487 
488  hiMicroTrack->SetDcaGl(glHelix.distance(stEvent->primaryVertex(0)->position()));
489  hiMicroTrack->SetDcaPr(prHelix.distance(stEvent->primaryVertex(0)->position()));
490 
491  hiMicroTrack->SetDcaXYGl(dcaXYGl);
492  hiMicroTrack->SetDcaXYPr(dcaXYPr);
493 
494  hiMicroTrack->SetDcaZGl(dcaz(glHelix,
495  stEvent->primaryVertex()->position(),glTrack));
496 
497  hiMicroTrack->SetChi2(prTrack->fitTraits().chi2());
498 
499  //
500  // dedx
501  //
502  StDedxPidTraits* pid=0;
503  StPtrVecTrackPidTraits traits = prTrack->pidTraits(kTpcId);
504 
505  for (UInt_t i = 0; i < traits.size(); i++) {
506  pid = dynamic_cast<StDedxPidTraits*>(traits[i]);
507  if (pid && pid->method() == kTruncatedMeanId) break;
508  }
509 
510  hiMicroTrack->SetDedx((pid) ? pid->mean() : 0);
511  hiMicroTrack->SetDedxPts((pid) ? pid->numberOfPoints() : 0);
512 
513  hiMicroTrack->SetFitPts(glTrack->fitTraits().numberOfFitPoints(kTpcId));
514  hiMicroTrack->SetAllPts(glTrack->detectorInfo()->numberOfPoints(kTpcId));
515  hiMicroTrack->SetMaxPossPts(glTrack->numberOfPossiblePoints());
516  hiMicroTrack->SetFlag(glTrack->flag());
517  hiMicroTrack->SetCharge(glTrack->geometry()->charge());
518 
519  hiMicroTrack->SetFirstZ(firstZ);
520  hiMicroTrack->SetLastZ(lastZ);
521  hiMicroTrack->SetFirstPadrow(firstPadrow);
522  hiMicroTrack->SetInnerPadList(innerPadList);
523  hiMicroTrack->SetOuterPadList(outerPadList);
524  hiMicroTrack->SetLastPadrow(lastPadrow);
525  hiMicroTrack->SetFirstSector(firstSector);
526  hiMicroTrack->SetLastSector(lastSector);
527 
528  hiMicroTrack->SetCrossingAngle(crossAngle);
529 
530  //
531  // add the track!
532  //
533 
534  mHiMicroEvent->AddTrack(hiMicroTrack);
535 
536  // ****** find some hit info ******
537  //
538 
539  if (!mHitLoop) continue;
540 
541  const StPtrVecHit& hits = prTrack->detectorInfo()->hits(kTpcId);
542  for(UInt_t iHit=0 ; iHit<hits.size(); iHit++){
543  const StTpcHit* hit = dynamic_cast<StTpcHit*> (hits[iHit]);
544  if(!hit){
545  cout << "Not a tpc hit?" << endl;
546  continue;
547  }
548  if (!hit->usedInFit()) continue;
549  //
550  // repeat some info in the hits
551  //
552  hiMicroHit->SetPtPr(hiMicroTrack->PtPr());
553  hiMicroHit->SetPtGl(hiMicroTrack->PtGl());
554  hiMicroHit->SetEta(hiMicroTrack->EtaPr());
555  hiMicroHit->SetPhi(hiMicroTrack->PhiPr());
556  hiMicroHit->SetFitPts(hiMicroTrack->FitPts());
557  hiMicroHit->SetSDcaGl(hiMicroTrack->DcaGl());
558  hiMicroHit->SetDipAngle(hiMicroTrack->DipAnglePr());
559  hiMicroHit->SetExitZ(hiMicroTrack->LastZ());
560  hiMicroHit->SetCharge(hiMicroTrack->Charge());
561  //
562  // general hit info
563  //
564  hiMicroHit->SetR(hit->position().perp());
565  hiMicroHit->SetZ(hit->position().z());
566  hiMicroHit->SetPadRow( (Int_t) hit->padrow());
567  hiMicroHit->SetSector( (Int_t) hit->sector());
568  //
569  // residuals
570  //
571  Double_t sGl = glHelix.pathLength(hit->position());
572  Double_t sPr = prHelix.pathLength(hit->position());
573 
574  StThreeVectorF glHitPos(glHelix.at(sGl));
575  StThreeVectorF prHitPos(prHelix.at(sPr));
576 
577  hiMicroHit->SetZResGl(hit->position().z() - glHitPos.z());
578  hiMicroHit->SetZResPr(hit->position().z() - prHitPos.z());
579 
580  Float_t resXYGl = computeXY(hit->position(),glTrack);
581  Float_t resXYPr = computeXY(hit->position(),prTrack);
582  hiMicroHit->SetXYResGl(resXYGl);
583  hiMicroHit->SetXYResPr(resXYPr);
584  //
585  // add the hit!
586  //
587 
588  mHiMicroEvent->AddHit(hiMicroHit);
589  } // hit loop
590 
591  } // track loop
592 
593  if(hiMicroTrack) delete hiMicroTrack;
594  cout << "\t hi pt tracks : " << nHi << endl;
595  mNAcceptedTrack += nHi;
596 
597  return nGoodTrackEta;
598 
599 }
600 //____________________
601 void
602 StHiMicroMaker::dump(StTrack* prTrack,StTrack* glTrack)
603 {
604  cout << "\tptGl="
605  << glTrack->geometry()->momentum().perp()
606  << ",etaGl="
607  << glTrack->geometry()->momentum().pseudoRapidity()
608  << ",fitpts="
609  << glTrack->fitTraits().numberOfFitPoints(kTpcId)
610  << ",allpts="
611  << glTrack->detectorInfo()->numberOfPoints(kTpcId)<<endl
612  << "\t\t ptPr=" <<prTrack->geometry()->momentum().perp()
613  << ", etaPr="
614  << glTrack->geometry()->momentum().pseudoRapidity() <<endl;
615 }
616 //____________________
617 
618 Int_t
619 StHiMicroMaker::openFile()
620 {
621  cout << "###StHiMicroMaker::openFile()" << endl;
622 
623  //
624  // for the output root file, replace event.root with himicro.root
625  //
626  TString outFileName(mInFileName);
627 
628  //
629  // assume the extension is of the form ( {\..*?\.root} (perl regexp))
630  //
631 
632  char cTemp[100];
633  strcpy(cTemp,outFileName.Data());
634 
635  cout << "We think the filename is " << outFileName.Data() << endl;
636  TString replace;
637  if(strstr(cTemp,"dst.root")) replace=".dst.root";
638  else if(strstr(cTemp,"event.root")) replace=".event.root";
639  else { cout << "unknown extension " << endl; exit(1); }
640 
641  // outFileName.Replace(outFileName.Length(),
642  // replace.Length(),".himicro.root");
643  cout << replace << endl;
644 
645  outFileName.ReplaceAll(replace.Data(),".himicro.root");
646 
647  cout << outFileName << endl;
648 
649  outFileName.Prepend(mOutDir + "/");
650 
651  // use default compression 1
652  mDSTFile = new TFile(outFileName.Data(),"RECREATE");
653 
654  if(!mDSTFile){
655  gMessMgr->Error()
656  << "Cannot create = " << outFileName << endm;
657  return kStErr;
658  }
659  //mDSTFile->SetFormat(1);
660  cout << "\toutfile = " << outFileName << endl;
661 
662  //
663  // top level tree
664  //
665  if(mDebug)
666  cout << "##Creating the top level tree..." << endl;
667  mDSTTree = new TTree("StHiMicroTree","StHiMicroTree");
668  if(!mDSTTree){
669  gMessMgr->Error()
670  << "Cannot create mDSTTree" << endm;
671  return kStErr;
672  }
673  if(mDebug)cout << "##...done" << endl;
674  //#if ROOT_VERSION_CODE >= ROOT_VERSION(3,01,05)
675  // mDSTTree->SetBranchStyle(0);
676  //#endif
677  mDSTTree->SetAutoSave(10000000); // 10 MB
678 
679  // set the event branch
680  Int_t bufSZ = 64000;
681  mDSTTree->Branch("StHiMicroEvent","StHiMicroEvent",
682  &mHiMicroEvent, bufSZ,1);
683  return kStOk;
684 }
685 //__________________________
686 
687 Int_t
688 StHiMicroMaker::closeFile()
689 {
690  cout << "###StHiMicroMaker::closeFile()" << endl;
691 
692  cout << "##Writing " << mInFileName << endl;
693 
694  if(mDSTFile && mDSTFile->IsOpen()){
695  mDSTFile->Write();
696  mDSTFile->Close();
697  }
698 
699  cout << "##...done\n";
700  // SafeDelete(mMiniMcTree);
701 
702  return kStOk;
703 }
704 
705 
706 Float_t
707 StHiMicroMaker::computeXY(const StThreeVectorF& pos, const StTrack* track)
708 {
709  //
710  // find the distance between the center of the circle and pos.
711  // if this greater than the radius of curvature, then call
712  // it negative.
713  //
714  double xCenter = track->geometry()->helix().xcenter();
715  double yCenter = track->geometry()->helix().ycenter();
716  double radius = 1.0/track->geometry()->helix().curvature();
717 
718  double dPosCenter
719  = TMath::Sqrt( (pos.x()-xCenter) * (pos.x()-xCenter) +
720  (pos.y()-yCenter) * (pos.y()-yCenter));
721 
722  return (Float_t) radius - dPosCenter;
723 }
724 
725 
726 //
727 // i like this one better. dip angle in s-z plane
728 // should be exact assuming a circle in x-y
729 // (redundant StTrack* for debugging)
730 double StHiMicroMaker::dcaz(const StPhysicalHelixD& helix, const StThreeVectorF& point,
731  const StTrack* track)
732 {
733  double z0 = helix.origin().z();
734  double phi = atan2(point.y()-helix.ycenter(),
735  point.x()-helix.xcenter());
736  int h = helix.h(); // -sign(q*B) (+ := ccw looking down from +z)
737  double dphi = h*(phi-helix.phase());
738 
739  // half circle assumption
740  dphi = (fabs(dphi) < M_PI ) ? dphi :
741  ((dphi<0) ? 2*M_PI + dphi : 2*M_PI - dphi);
742 
743  double arclength= (1./helix.curvature()) * dphi;
744 
745  double dcaZ = (point.z() - (z0 + arclength*tan(helix.dipAngle())));
746  /*
747  if(gRandom->Rndm(1)<0.1){
748  cout << "--------" << endl;
749  cout << "zpoint=" << point.z() << endl;
750  if(track)
751  cout << "pt=" << track->geometry()->momentum().perp()
752  << ",fit pts=" << track->fitTraits().numberOfFitPoints(kTpcId)
753  << endl;
754 
755  cout << ">>>zdca=" << dcaZ
756  << ", dphi=" << dphi*180./M_PI
757  << ", z0=" << z0 << ",arclength=" << arclength << endl
758  << ", dip=" << helix.dipAngle()*180./M_PI
759  << ", arc/tan(dip)="<< arclength/tan(helix.dipAngle()) << endl
760  << ">>>dca.z= " << point.z()-helix.at(helix.pathLength(point)).z()
761  << endl;
762  cout << "--------" << endl;
763  }
764  */
765  return dcaZ;
766 
767 }
768 
769 double
770 StHiMicroMaker::dcaz(const StPhysicalHelixD& helix, const StThreeVectorF& point)
771 {
772  pairD path = helix.pathLength(point.perp());
773 
774  const StThreeVectorD& pos1 = helix.at(path.first);
775  const StThreeVectorD& pos2 = helix.at(path.second);
776  const StThreeVectorD dis1 = point - pos1;
777  const StThreeVectorD dis2 = point - pos2;
778 
779  double dcaZ = (dis1.mag() < dis2.mag()) ? dis1.z() : dis2.z();
780  if(::isnan(dcaZ)) return 999;
781  return dcaZ;
782 }
783 
784 
785 //____________________
786 //
787 // primary vertex exists
788 //
789 bool StHiMicroMaker::accept(StEvent* stEvent)
790 {
791 
792  return (stEvent->primaryVertex());
793 }
794 
795 
796 //____________________
797 //
798 bool StHiMicroMaker::accept(StTrack* track)
799 {
800 
801  return (track && track->flag() > 0 &&
802  track->geometry()->momentum().perp()>=1.5);
803 }
804 
805 //_____________________
806 //
807 bool StHiMicroMaker::acceptCentrality(StTrack *track)
808 {
809  return (track && track->flag() > 0 && track->fitTraits().numberOfFitPoints(kTpcId) >= 10 &&
810  fabs(track->geometry()->momentum().pseudoRapidity())<.5);
811 //Bum's code had 0.75, but for the newest centrality numbers from Zhangbu (Mar-2002), they use 0.5
812 
813 //JLK 30.May.2002 - just noticed a problem - need to cut on fitpts >= 10 to match Zhangbu's definition!!
814 }
815 
816 //_____________________
817 
818 bool StHiMicroMaker::goodGlobal(StTrack *track)
819 {
820  return (track && track->flag() > 0 && track->geometry()->charge() != 0 &&
821  track->fitTraits().numberOfFitPoints(kTpcId) >= 25);
822 
823 }
824 
825 bool StHiMicroMaker::goodGlobalA(StTrack *track)
826 {
827  return (track && track->flag() > 0 && track->geometry()->charge() != 0 &&
828  track->fitTraits().numberOfFitPoints(kTpcId) >= 10);
829 
830 }
831 
832 bool StHiMicroMaker::goodGlobalB(StTrack *track)
833 {
834  return (track && track->flag() > 0 && track->geometry()->charge() != 0 &&
835  track->fitTraits().numberOfFitPoints(kTpcId) >= 15);
836 
837 }
838 
839 bool StHiMicroMaker::goodGlobalC(StTrack *track)
840 {
841  return (track && track->flag() > 0 && track->geometry()->charge() != 0 &&
842  track->fitTraits().numberOfFitPoints(kTpcId) >= 20);
843 
844 }
845 
846 bool StHiMicroMaker::goodGlobalD(StTrack *track)
847 {
848  return (track && track->flag() > 0 && track->geometry()->charge() != 0 &&
849  track->fitTraits().numberOfFitPoints(kTpcId) >= 30);
850 
851 }
852 
853 bool StHiMicroMaker::goodGlobalE(StTrack *track)
854 {
855  return (track && track->geometry()->charge() != 0 &&
856  track->fitTraits().numberOfFitPoints(kTpcId) >= 25);
857 
858 }
859 
860 bool StHiMicroMaker::goodGlobalFlag(StTrack *track)
861 {
862  return (track && track->flag() > 0 );
863 
864 }
865 //
866 ClassImp(StHiMicroMaker)
int h() const
y-center of circle in xy-plane
Definition: StHelix.hh:174
virtual void Clear(Option_t *option="")
User defined functions.
Definition: StMaker.cxx:634
double distance(const StThreeVector< double > &p, bool scanPeriods=true) const
minimal distance between point and helix
Definition: StHelix.cc:240
pair< double, double > pathLength(double r) const
path length at given r (cylindrical r)
Definition: StHelix.cc:351
double ycenter() const
x-center of circle in xy-plane
Definition: StHelix.cc:215
const StThreeVector< double > & origin() const
-sign(q*B);
Definition: StHelix.hh:224
Definition: Stypes.h:40
virtual Int_t Finish()
Definition: StMaker.cxx:776
Definition: Stypes.h:44
double xcenter() const
aziumth in xy-plane measured from ring center
Definition: StHelix.cc:207
double phase() const
1/R in xy-plane
Definition: StHelix.hh:180
Definition: Stypes.h:41
void Clear(Option_t *option="")
User defined functions.