StRoot  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
StFtpcTrackToStEvent.cc
1 /******************************************************************************
2  *
3  * $Id: StFtpcTrackToStEvent.cc,v 1.22 2013/07/23 13:38:46 didenko Exp $
4  *
5  * Author: Markus D. Oldenburg
6  * (changed version of StiStEventFiller by Manuel Calderon de la Barca Sanchez)
7  ******************************************************************************
8  *
9  *
10  **************************************************************************/
11 
12 //std
13 #include "Stiostream.h"
14 #include <algorithm>
15 #include <stdexcept>
16 using namespace std;
17 
18 // SCL
19 #include "StPhysicalHelix.hh"
20 #include "StThreeVector.hh"
21 #include "StThreeVectorF.hh"
22 #include "PhysicalConstants.h"
23 #include "SystemOfUnits.h"
24 #include "StTrackDefinitions.h"
25 #include "StTrackMethod.h"
26 #include "StDedxMethod.h"
27 
28 //StEvent
29 #include "StPrimaryVertex.h"
30 #include "StEventTypes.h"
31 #include "StDetectorId.h"
32 #include "StHelix.hh"
33 
34 //StFtpcTrackMaker
35 #include "StFtpcPoint.hh"
36 #include "StFtpcTrack.hh"
37 #include "StFtpcTrackingParams.hh"
38 #include "TObjArray.h"
39 
40 #include "StFtpcTrackToStEvent.hh"
41 
42 StFtpcTrackToStEvent::StFtpcTrackToStEvent() : mEvent(0), mTrackStore(0), mTrkNodeMap() {
43  // encoded method = 16 bits = 12 fitting and 4 finding, Refer
44  // to StTrackMethod.h and StTrackDefinitions.h in pams/global/inc/
45  // and StEvent/StEnumerations.h
46  unsigned short bit = 1 << ftpcConformal; // shifting the "1" exactly ftpcConformal places to the left
47  mStiEncoded = kHelix2StepId + bit; // adding that to the proper fitting Id
48 }
49 
50 StFtpcTrackToStEvent::~StFtpcTrackToStEvent()
51 {
52  //LOG_INFO <<"StFtpcTrackToStEvent::~StFtpcTrackToStEvent()"<<endm;
53 }
54 
85 
86  if (e==0 || t==0) {
87  LOG_WARN <<"StFtpcTrackToStEvent::FillEvent(). ERROR:"
88  <<"Null StEvent ("<<e<<") || TObjArray of tracks ("<<t<<"). Exit"<<endm;
89  return 0;
90  }
91 
92  mEvent = e;
93  mTrackStore = t;
94  mTrkNodeMap.clear();
95  StSPtrVecTrackNode& trNodeVec = mEvent->trackNodes();
96  StSPtrVecTrackDetectorInfo& detInfoVec = mEvent->trackDetectorInfo();
97  int errorCount=0;
98 
99  int fillTrackCount1=0;
100  int fillTrackCount2=0;
101 
102  int currentTrackKey = GetHighestTrackKey(trNodeVec);
103 
104  for (Int_t trackIt = 0; trackIt < mTrackStore->GetEntriesFast();++trackIt) {
105 
106  StFtpcTrack* kTrack = (StFtpcTrack*)mTrackStore->At(trackIt);
107  if (kTrack->GetP()<=1e-6) continue; //sanity check (VP)
109  FillDetectorInfo(detInfo, kTrack, kTRUE);
110  // track node where the new StTrack will reside
111  StTrackNode* trackNode = new StTrackNode;
112  // actual filling of StTrack from StFtpcTrack
113  StGlobalTrack* gTrack = new StGlobalTrack;
114 
115  try {
116  fillTrackCount1++;
117  FillTrack(gTrack, kTrack);
118  // filling successful, set up relationships between objects
119  detInfoVec.push_back(detInfo);
120  gTrack->setDetectorInfo(detInfo);
121  gTrack->setKey(++currentTrackKey);
122  trackNode->addTrack(gTrack);
123  trNodeVec.push_back(trackNode);
124  FillTopologyMap(gTrack, kTrack);
125  mTrkNodeMap.insert(map<StFtpcTrack*,StTrackNode*>::value_type (kTrack, trNodeVec.back()));
126  if (trackNode->entries(global)<1) {
127  LOG_WARN << "StFtpcTrackToStEvent::FillEvent() - ERROR - Track Node has no entries!" << endm;
128  }
129 
130  fillTrackCount2++;
131  }
132 
133  catch (runtime_error & rte ) {
134  LOG_WARN << "StFtpcTrackToStEvent::FillEvent() -W- runtime-e filling track"<<rte.what() << endm;
135  delete trackNode;
136  delete detInfo;
137  delete gTrack;
138  }
139 
140  catch (...) {
141  LOG_WARN << "StFtpcTrackToStEvent::FillEvent() - WARNING - Unknown exception filling track."<<endm;
142  delete trackNode;
143  delete detInfo;
144  delete gTrack;
145  }
146  }
147 
148  if (errorCount>4) {
149  LOG_WARN << "There were "<<errorCount<<"runtime_errors while filling StEvent"<<endm;
150  }
151 
152  return mEvent;
153 }
154 
155 
156 StEvent* StFtpcTrackToStEvent::FillEventPrimaries(StEvent* e, TObjArray* t) {
157 
158  if (!mTrkNodeMap.size()) {
159  LOG_WARN <<"StFtpcTrackToStEvent::FillEventPrimaries(): "
160  << "Mapping between the StTrackNodes and the StFtpcTracks is empty. Exit." << endm;
161  return 0;
162  }
163 
164  if (e==0 || t==0) {
165  LOG_WARN <<"StFtpcTrackToStEvent::FillEventPrimaries(): "
166  <<"Null StEvent ("<<e<<") || TObjArray of tracks ("<<t<<"). Exit"<<endm;
167  return 0;
168  }
169 
170  mEvent = e;
171  mTrackStore = t;
172  StPrimaryVertex* vertex = mEvent->primaryVertex(0);
173  StSPtrVecTrackDetectorInfo& detInfoVec = mEvent->trackDetectorInfo();
174 
175  if(!vertex) {
176  LOG_WARN <<"Failed to find a primary vertex. No primary FTPC tracks written to StEvent."<<endm;
177  return (StEvent*)NULL;
178  }
179 
180  int skippedCount=0;
181  // loop over StFtpcTracks
182  int mTrackN=0;
183  StFtpcTrack* kTrack;
184 
185  int fillTrackCount1=0;
186  int fillTrackCount2=0;
187 
188  for (Int_t trackIt = 0; trackIt<mTrackStore->GetEntriesFast();++trackIt,++mTrackN) {
189 
190  kTrack = (StFtpcTrack*)mTrackStore->At(trackIt);
191 
192  if (kTrack==0) {
193  throw runtime_error("StFtpcTrackToStEvent::FillEventPrimaries() -F- (StFtpcTrack*)mTrackStore->At(trackIt)");
194  }
195 
196  map<StFtpcTrack*, StTrackNode*>::iterator itKtrack = mTrkNodeMap.find(kTrack);
197 
198  if (itKtrack == mTrkNodeMap.end()) {
199  continue;
200 // throw runtime_error("StiStEventFiller::fillEventPrimaries() -F- itKtrack == mTrkNodeMap.end()");
201  }
202 
203  StTrackNode* currentTrackNode = (*itKtrack).second;
204  StGlobalTrack* currentGlobalTrack = static_cast<StGlobalTrack*>(currentTrackNode->track(global));
205 
206  if (kTrack->ComesFromMainVertex()) {
207 
208  fillTrackCount1++;
209 
210  if (currentTrackNode->entries()>10) {
211  throw runtime_error("StFtpcTrackToStEvent::FillEventPrimaries() -F- currentTrackNode->entries()>10");
212  }
213 
214  if (currentTrackNode->entries(global)<1) {
215  throw runtime_error("StFtpcTrackToStEvent::FillEventPrimaries() -F- currentTrackNode->entries(global)<1");
216  }
217 
218  // detector info
220  FillDetectorInfo(detInfo, kTrack, kFALSE);
221  StPrimaryTrack* pTrack = new StPrimaryTrack;
222 
223  try {
224  FillTrack(pTrack, kTrack);
225  // set up relationships between objects
226  detInfoVec.push_back(detInfo);
227  pTrack->setDetectorInfo(detInfo);
228  pTrack->setKey(currentGlobalTrack->key());
229  currentTrackNode->addTrack(pTrack); // StTrackNode::addTrack() calls track->setNode(this);
230  vertex->addDaughter(pTrack);
231  FillTopologyMap(pTrack, kTrack);
232  fillTrackCount2++;
233  }
234 
235  catch (runtime_error & rte ) {
236  LOG_WARN << "StFtpcTrackToStEvent::FillEventPrimaries() - runtime exception, filling track: "
237  << rte.what() << endm;
238  delete detInfo;
239  delete pTrack;
240  }
241 
242  catch (...) {
243  LOG_WARN << "StFtpcTrackToStEvent::FillEventPrimaries() - Unknown exception, filling track."<<endm;
244  delete detInfo;
245  delete pTrack;
246  }
247  } //end if primary
248  } // Ftpc track loop
249 
250  if (skippedCount>0) LOG_WARN << "StFtpcTrackToStEvent::FillEventPrimaries() -I- A total of "<<skippedCount<<" StFtpcTracks were skipped"<<endm;
251  mTrkNodeMap.clear(); // need to reset for the next event
252  return mEvent;
253 }
254 
255 
256 void StFtpcTrackToStEvent::FillDetectorInfo(StTrackDetectorInfo* detInfo, StFtpcTrack* track, Bool_t global) {
257 
258  TObjArray *hitVec = track->GetHits();
259 
260  detInfo->setFirstPoint(((StFtpcPoint*)hitVec->Last())->GetStFtpcHit()->position());
261  detInfo->setLastPoint(((StFtpcPoint*)hitVec->First())->GetStFtpcHit()->position());
262  detInfo->setNumberOfPoints(EncodedStEventFitPoints(track), track->GetDetectorId());
263 
264  for (Int_t iHit = hitVec->GetEntriesFast()-1; iHit >= 0; iHit--) { // revert order
265  StFtpcPoint *pt = (StFtpcPoint*)hitVec->At(iHit);
266  StHit *hh = dynamic_cast<StHit*>(pt->GetStFtpcHit());
267  if (hh) detInfo->addHit(hh, global);
268  }
269 }
270 
271 
272 void StFtpcTrackToStEvent::FillGeometry(StTrack* gTrack, StFtpcTrack* track, bool outer) {
273 
274  if (!gTrack) {
275  throw runtime_error("StFtpcTrackToStEvent::FillGeometry() -F- gTrack==0");
276  }
277 
278  if (!track) {
279  throw runtime_error("StFtpcTrackToStEvent::FillGeometry() -F- track==0");
280  }
281 
282  TVector3 hit;
283  StThreeVectorF origin(0., 0., 0.);
284 
285  if (outer) {
286  hit = track->GetLastPointOnTrack();
287  }
288 
289  else {
290  hit = track->GetFirstPointOnTrack();
291  }
292 
293  // radius at start of track (cm)
294  Double_t r0 = TMath::Sqrt(hit.X()*hit.X() + hit.Y()*hit.Y());
295 
296  // azimuthal angle at start of track (deg)
297  Double_t phi0 = TMath::ATan2(hit.Y(), hit.X());
298 
299  // z-coordinate at start of track
300  Double_t z0 = hit.Z();
301 
302  // momentum angle at start
303  Double_t psi = TMath::ATan2(track->GetPy(), track->GetPx());
304  if (psi < 0.0) {
305  psi += 2*TMath::Pi();
306  }
307 
308  origin.setX(r0 * TMath::Cos(phi0));
309  origin.setY(r0 * TMath::Sin(phi0));
310  origin.setZ(z0);
311 
312  // making some checks. Seems the curvature is infinity sometimes and
313  // the origin is sometimes filled with nan's...
314 
315  if (!finite(origin.x()) ||
316  !finite(origin.y()) ||
317  !finite(origin.z()) || !finite(track->curvature())) {
318  LOG_ERROR << "StFtpcTrackToStEvent::FillGeometry() Encountered non-finite numbers!!!! Bail out completely!!! " << endm;
319 
320  abort();
321  }
322 
323  if (outer) {
324 
325  // momentum angle at last point on track
326 
327  Double_t Ptotal = TMath::Sqrt(track->GetPt()*track->GetPt() + track->GetPz()*track->GetPz());
328  Double_t psiLast = psi + track->h()*track->curvature()*track->GetTrackLength()*(track->GetPt()/Ptotal);
329  if (psiLast < 0.0) {
330  psiLast += 2*TMath::Pi();
331  }
332 
333  StThreeVectorF P(track->GetPt() * TMath::Cos(psiLast), track->GetPt() * TMath::Sin(psiLast), track->GetPz());
334 
335  StTrackGeometry* geometry = new StHelixModel(short(track->GetCharge()),
336  psiLast,
337  track->curvature(),
338  TMath::ATan2(track->GetPz(),(track->GetPt()+1.e-10)), // dip angle
339  origin,
340  P,
341  track->h());
342 
343  gTrack->setOuterGeometry(geometry);
344  }
345 
346  else {
347 
348  StThreeVectorF P(track->GetPt() * TMath::Cos(psi), track->GetPt() * TMath::Sin(psi), track->GetPz());
349 
350  StTrackGeometry* geometry = new StHelixModel(short(track->GetCharge()),
351  psi,
352  track->curvature(),
353  TMath::ATan2(track->GetPz(),(track->GetPt()+1.e-10)), // dip angle
354  origin,
355  P,
356  track->h());
357 
358  gTrack->setGeometry(geometry);
359  }
360 
361  return;
362 }
363 
364 
365 void StFtpcTrackToStEvent::FillFitTraits(StTrack* gTrack, StFtpcTrack* track){
366  // mass
367  // this makes no sense right now... double massHyp = track->getMass(); // change: perhaps this mass is not set right?
368  unsigned short geantIdPidHyp = 9999;
369  //if (.13< massHyp<.14)
370  geantIdPidHyp = 0;
371  unsigned short nFitPoints = EncodedStEventFitPoints(track);
372  // chi square and covariance matrix, plus other stuff from the
373  // innermost track node
374  float chi2[2];
375  chi2[0] = track->GetChiSq()[0]/(nFitPoints-3.);
376  chi2[1] = track->GetChiSq()[1]/(nFitPoints-2.);
377 
378  float covMFloat[15];
379  for (Int_t i = 0; i < 15; i++) {
380  covMFloat[i] = 0.;
381  }
382 
383  // setFitTraits uses assignment operator of StTrackFitTraits, which is the default one,
384  // which does a memberwise copy. Therefore, constructing a local instance of
385  // StTrackFitTraits is fine, as it will get properly copied.
386  StTrackFitTraits fitTraits(geantIdPidHyp, nFitPoints, chi2, covMFloat);
387  fitTraits.setNumberOfFitPoints(nFitPoints, track->GetDetectorId()); // The vertex is not added as a fit point anymore.
388  fitTraits.setPrimaryVertexUsedInFit(gTrack->type() == primary); // The fitTraits are flagged as primary or global.
389  gTrack->setFitTraits(fitTraits);
390  return;
391 }
392 
393 
394 void StFtpcTrackToStEvent::FilldEdxInfo(StTrack* gTrack, StFtpcTrack* track) {
395 
396  double dEdx = track->GetdEdx();
397  double errordEdx = 0.;
398  double nPoints = track->GetNumdEdxHits();
399  short method;
400 
401  if (StFtpcTrackingParams::Instance()->IdMethod() == 0) {
402  method = kTruncatedMeanId;
403  }
404 
405  else if (StFtpcTrackingParams::Instance()->IdMethod() == 1) {
406  method = kEnsembleTruncatedMeanId;
407  }
408 
409  else {
410  method = kUndefinedMethodId;
411  }
412 
413  if(!finite(dEdx) || dEdx>9999) {
414  dEdx = 9999;
415  errordEdx = dEdx;
416  nPoints = 0;
417  LOG_WARN <<"StFtpcTrackToStEvent::Error: dEdx non-finite."<<endm;
418  }
419 
420  else if(!finite(errordEdx)) {
421  dEdx = 9999;
422  errordEdx = dEdx;
423  nPoints=0;
424  LOG_WARN <<"StFtpcTrackToStEvent::Error: errordEdx non-finite."<<endm;
425  }
426 
427  StTrackPidTraits* pidTrait = new StDedxPidTraits(track->GetDetectorId(),
428  static_cast<short>(method),
429  static_cast<unsigned short>(nPoints),
430  static_cast<float>(dEdx),
431  static_cast<float>(errordEdx));
432  gTrack->addPidTraits(pidTrait);
433  return;
434 }
435 
436 
437 void StFtpcTrackToStEvent::FillPidTraits(StTrack* gTrack, StFtpcTrack* track) {
438 
439  FilldEdxInfo(gTrack, track);
440 
441  return;
442 }
443 
444 
445 void StFtpcTrackToStEvent::FillTrack(StTrack* gTrack, StFtpcTrack* track) {
446 
447  if (gTrack->type()==global) {
448 
449  Int_t flag = 700;
450  if (track->ComesFromMainVertex()) { // primary track candidate
451  flag += 1; // 701
452  } // else 700
453 
454  if (TMath::Abs(track->GetCharge()) != 1.) {
455  flag = -flag+20;
456  }
457 
458  if (TMath::Abs(track->GetPt()) < 1.e-3) {
459  flag = -799;
460  }
461 
462  gTrack->setFlag(flag);
463  }
464 
465  else if (gTrack->type()==primary) { // is 'primary candidate' automatically
466  gTrack->setFlag(801);
467  }
468 
469  gTrack->setEncodedMethod(mStiEncoded);
470 
471  gTrack->setImpactParameter(ImpactParameter(track));
472  gTrack->setLength(track->GetTrackLength());
473  gTrack->setNumberOfPossiblePoints(static_cast<unsigned short>(track->GetNMax()), track->GetDetectorId());
474 
475  FillGeometry(gTrack, track, false); // inner geometry
476  FillGeometry(gTrack, track, true); // outer geometry
477  FillFitTraits(gTrack, track);
478  FillPidTraits(gTrack, track);
479 
480  return;
481 }
482 
483 unsigned short StFtpcTrackToStEvent::EncodedStEventFitPoints(StFtpcTrack* track) {
484  // need to write the fit points in StEvent following the convention
485  // 1*tpc + 1000*svt + 10000*ssd (Helen/Spiros Oct 29, 1999)
486  // FTPC fit point are not encoded. They use the plain number.
487 
488  return ((unsigned short)track->GetHits()->GetEntriesFast());
489 }
490 
491 
492 float StFtpcTrackToStEvent::ImpactParameter(StFtpcTrack* track) {
493 
494  if (!mEvent->primaryVertex()) {
495  return 3.e33;
496  }
497 
498  else {
499  return track->GetDca();
500  }
501 }
502 
503 
504 void StFtpcTrackToStEvent::FillTopologyMap(StTrack *gTrack, StFtpcTrack* ftpcTrack) {
505  unsigned long word0 = (gTrack->type()==primary) ? 1 : 0;
506  unsigned long word1 = (1<<31); // FTPC track flag
507 
508  for (Int_t i = 0; i < ftpcTrack->GetHits()->GetEntriesFast(); i++){
509  StFtpcPoint *pt = (StFtpcPoint*)ftpcTrack->GetHits()->At(i);
510  word0 |= (1<<pt->GetPadRow());
511  }
512 
513  StTrackTopologyMap newmap(word0, word1);
514  gTrack->setTopologyMap(newmap);
515 
516  return;
517 }
518 
519 
520 int StFtpcTrackToStEvent::GetHighestTrackKey(StSPtrVecTrackNode& trNodeVec) {
521  // get the highest used track key
522  // This was necessary to introduce since the highest track key is not
523  // allways the same as the size of the StSPtrVecTrackNode (tpt leaves holes
524  // in there).
525 
526  StTrack *globTrack;
527  Int_t highestKey = 0;
528  Int_t currentKey = 0;
529 
530  for (unsigned int j = 0; j < trNodeVec.size(); j++) {
531  globTrack = trNodeVec[j]->track(global);
532  if (globTrack==0) continue;
533 
534  currentKey = globTrack->key();
535  if (currentKey > highestKey) highestKey = currentKey;
536  }
537 
538  return highestKey;
539 }
StEvent * FillEvent(StEvent *, TObjArray *)
Definition: StHit.h:125
int h() const
y-center of circle in xy-plane
Definition: StHelix.hh:174