StRoot  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
StAssociationMaker.cxx
1 /*************************************************
2  *
3  * $Id: StAssociationMaker.cxx,v 1.62 2018/01/04 18:07:06 genevb Exp $
4  * $Log: StAssociationMaker.cxx,v $
5  * Revision 1.62 2018/01/04 18:07:06 genevb
6  * Better counting of MC track pings (common hits)
7  *
8  * Revision 1.61 2015/03/13 18:44:44 perev
9  * Roll back
10  *
11  * Revision 1.59 2014/06/24 20:57:35 jeromel
12  * Remove flush()
13  *
14  * Revision 1.58 2012/07/31 22:08:49 perev
15  * Track without detectorInfo ignored
16  *
17  * Revision 1.57 2011/07/19 19:11:15 perev
18  * Cleanup
19  *
20  * Revision 1.56 2011/06/03 17:14:09 fisyak
21  * Set FtpcHit IdTruth and QA
22  *
23  * Revision 1.55 2011/04/01 19:40:07 perev
24  * const++
25  *
26  * Revision 1.54 2010/10/11 19:15:25 fisyak
27  * remove find_if due to bug in logic of its usage
28  *
29  * Revision 1.53 2010/06/22 22:06:33 fine
30  * roll back the previous version to restore the nightly builds
31  *
32  * Revision 1.51 2009/11/10 20:19:36 fisyak
33  * Change default to ITTF
34  *
35  * Revision 1.50 2007/04/28 17:55:43 perev
36  * Redundant StChain.h removed
37  *
38  * Revision 1.49 2006/05/30 22:56:20 calderon
39  * The check for null StEvent pointer had been moved down, move it back up
40  * near the beginning of the Make() call, otherwise the pointer is used
41  * without a check.
42  *
43  * Revision 1.48 2005/11/22 21:44:16 fisyak
44  * Add Ssd to Associator, add IdTruth options for Svt and Ssd
45  *
46  * Revision 1.47 2005/09/28 21:31:46 fisyak
47  * Persistent StMcEvent
48  *
49  * Revision 1.46 2005/07/19 21:28:56 perev
50  * IdTruth
51  *
52  * Revision 1.45 2005/07/19 20:09:57 perev
53  * IdTruth changes
54  *
55  * Revision 1.44 2004/06/01 18:06:02 calderon
56  * Check for chiSquared values for the V0's when using/not using Est tracks.
57  *
58  * Revision 1.43 2004/03/26 23:26:34 calderon
59  * -Adding switch to control Association based on IdTruth or on Distance.
60  * -Adding debug2 output to print out all hits in a padrow, both reco and MC,
61  * along with the IdTruth, quality (StHit) and the parentTrack()->key() (StMcHit)
62  * as well as the hit coordiantes. This is useful for debugging, but produces
63  * lots of output, so it is only turned on in Debug()>=2.
64  *
65  * Revision 1.42 2004/02/13 22:39:39 calderon
66  * At Helen's request, during the opton for associating est tracks,
67  * if there is not an est track in the node, use the original global track.
68  *
69  * Revision 1.41 2004/02/08 00:08:14 calderon
70  * Added method useEstTracks() requested by Helen, for association of estGlobals.
71  *
72  * Revision 1.40 2004/01/24 03:31:09 calderon
73  * Changed the code to make it backward compatible.
74  *
75  * Revision 1.39 2004/01/13 21:04:54 fisyak
76  * use IdTruth information for hit matching if any
77  *
78  * Revision 1.38 2003/10/08 20:15:03 calderon
79  * using "Stiostream.h" and std::cout, std::ostream, as well as <cmath>.
80  *
81  * Revision 1.37 2003/09/02 17:55:28 perev
82  * gcc 3.2 updates + WarnOff
83  *
84  * Revision 1.36 2003/06/27 03:01:18 calderon
85  * The z cut now depends on z_mc.
86  * The parameterization is done in the parameter DB
87  * with a linearly increasing rms, symmetric in +/- z.
88  *
89  * Revision 1.35 2003/05/28 17:57:50 calderon
90  * No longer use find_if for FTPC to solve a bug for y<0 found by Frank Simon.
91  * Initialize tpcHitDistance and svtHitDistance to avoid a warning.
92  *
93  * Revision 1.34 2002/09/21 19:48:44 calderon
94  * change encoded method for IT tracks to 263 (was 32770 before)
95  *
96  * Revision 1.33 2002/04/11 22:11:10 calderon
97  * Changes to incorporate association of tracks from Sti
98  * Basically all that was needed was to add a flag to switch between
99  * Sti and regular EGR global tracks, and based on this flag, one looks for
100  * the proper bits to be set in the StTrack::encodedMethod() member function.
101  * Current default behaviour is still to use EGR global tracks, and the modification
102  * is done in the macro with a call to StAssociationMaker::useInTracker()
103  *
104  * Revision 1.32 2001/07/16 17:18:42 calderon
105  * Modification in the access of the L3 event at the beginning of loop.
106  *
107  * Revision 1.31 2001/05/09 21:25:59 calderon
108  * Added debug messages to see where do we exceed the size of the candidate vector
109  *
110  * Revision 1.30 2001/05/08 21:29:56 calderon
111  * Resize the candidates vector when we have more than 20 candidates.
112  *
113  * Revision 1.29 2001/04/27 18:41:47 calderon
114  * Update with switches to use L3 Trigger.
115  *
116  * Revision 1.28 2000/06/09 19:54:02 calderon
117  * use the new StMcHitComparisons
118  * use the message manager more extensively
119  * protection against the absence of hit collections
120  *
121  * Revision 1.27 2000/05/11 15:34:29 calderon
122  * added option to print memory usage using StMemoryInfo, useful
123  * for checking leaks. If used, a lot of status information is printed
124  * at several points in Make() and then in Clear(). Whatever is allocated
125  * during Make() should be accounted for in Clear(). By default memory is
126  * not checked, so there are a lot less output messages.
127  *
128  * Revision 1.26 2000/04/20 16:56:12 calderon
129  * Speed up the tpc matching algorithm by using a seed to tell the iterator
130  * where to start looping, instead of looping over every hit all the time.
131  * Change the name from "Associations" to "StAssociationMaker"
132  *
133  * Revision 1.25 2000/04/19 16:30:18 calderon
134  * return kStWarn when no StEvent or StMcEvent is found, instead of
135  * exit.
136  *
137  * Revision 1.24 2000/04/12 21:33:14 calderon
138  * return warnings instead of fatal when no maps are made
139  *
140  * Revision 1.23 2000/04/04 23:12:08 calderon
141  * Speed up FTPC Hit association, taking advantage of hit sorting
142  * and using the STL algorithm find_if.
143  *
144  * Revision 1.22 2000/03/29 16:14:08 calderon
145  * Keep storing Vertices in V0 map that come from event generator, and hence don't
146  * have a parent.
147  * Check that these vertices are not used for Xi map.
148  *
149  * Revision 1.21 2000/03/28 02:57:32 calderon
150  * Add additional check for V0 vertices: Make sure they also have a parent.
151  *
152  * Revision 1.20 2000/03/06 18:08:56 calderon
153  * Hit comparisons are used for both sorting the hits in the
154  * StMcEvent containers and for ordering the hits in the multimaps,
155  * so they are kept now in StMcEvent.
156  *
157  * Revision 1.19 2000/02/22 16:18:45 ullrich
158  * Applied temporary fix to cope with changed SVT hit
159  * storage scheme in StEvent.
160  *
161  * Revision 1.18 2000/01/18 20:53:37 calderon
162  * Changes to work with CC5
163  *
164  * Revision 1.17 2000/01/14 21:53:58 calderon
165  * Make sure the common hits for each detector are initialized to zero.
166  * (Thanks, Lee).
167  *
168  * Revision 1.16 2000/01/12 00:30:55 calderon
169  * Modified Kink Vertex association as per Lee's request.
170  *
171  * Revision 1.15 1999/12/14 07:07:41 calderon
172  * Added Ratio Number of Common Hits / Number of Reconstructed Hits for
173  * each detector.
174  * Numbering scheme from StEvent & StMcEvent as per SVT request
175  * Added Kink, V0 and Xi vertex associations.
176  *
177  * Revision 1.14 1999/12/08 00:00:24 calderon
178  * New version of StAssociationMaker.
179  * -Uses new StEvent / StMcEvent
180  * -Includes maps using reconstructed and monte carlo objects as keys for:
181  * TPC Hits
182  * SVT Hits
183  * FTPC Hits
184  * Tracks (using all 3 hit multimaps)
185  *
186  * Revision 1.13 1999/11/03 22:40:50 calderon
187  * Fix bug in Clear() : check pointers before deleting maps.
188  *
189  * Revision 1.12 1999/10/18 16:11:50 calderon
190  * Frank found 2 leaks that these changes will correct:
191  * -Delete the TrackPairInfos in the Clear() method
192  * -Correct the sub detector destructors to delete all
193  * instances to StLocalHit.
194  *
195  * Revision 1.11 1999/10/14 01:18:44 calderon
196  * -Delete StTrackPairInfo objects owned by trackMap in
197  * StAssociationMaker destructor.
198  * -Make sure there is a closestHit for filling the
199  * mLocalHitResolution histogram.
200  *
201  * Revision 1.10 1999/10/01 14:08:54 calderon
202  * Added Local Hit resolution Histogram. It is made by default
203  * without any requirement of association, to serve
204  * as a diagnostic.
205  * Before building track multimap, check the size of the
206  * tpc hit map. If it is too small, print out a warning
207  * and exit.
208  *
209  * Revision 1.9 1999/09/28 14:35:00 fisyak
210  * Remove cons dependence on non existing headers
211  *
212  * Revision 1.8 1999/09/23 21:25:18 calderon
213  * Added Log & Id
214  * Modified includes according to Yuri
215  *
216  * Revision 1.7 1999/09/15 18:40:56 calderon
217  * -If there is no StEvent or StMcEvent, print message to cerr and exit.
218  * -Update README for changes
219  *
220  * Revision 1.6 1999/09/09 23:51:21 calderon
221  * Made the following changes:
222  * StAssociationMaker
223  *
224  * -correct definition of multimap for Solaris/ObjectSpace
225  * -clear candidate vector at the end of reconstructed track loop
226  * -remove # of pings histogram
227  *
228  * StLocalHit
229  *
230  * -use math.h instead of cmath because of abs()
231  * -change abs() to fabs() everywhere
232  * -change bool's to int's so Solaris doesn't complain
233  *
234  * Revision 1.5 1999/07/30 16:19:13 calderon
235  * Use value_type typedef for inserting pairs in multimaps, Victor corrected iterators on HP in SL99h, Improved use of const for HP compilation
236  *
237  * Revision 1.4 1999/07/28 20:27:23 calderon
238  * Version with SL99f libraries
239  *
240  *
241  *************************************************/
242 
243 
244 #include "Stiostream.h"
245 #include <iterator>
246 #include <stdlib.h>
247 #include <string>
248 #include <vector>
249 #include <algorithm>
250 #include <cmath>
251 #if !defined(ST_NO_NAMESPACES)
252 using std::string;
253 using std::vector;
254 using std::cout;
255 using std::ostream;
256 #endif
257 #include "StAssociationMaker.h"
258 #include "StMcParameterDB.h"
259 #include "StTrackPairInfo.hh"
260 
261 #include "StGlobals.hh"
262 #include "PhysicalConstants.h"
263 #include "SystemOfUnits.h"
264 #include "StThreeVectorF.hh"
265 
266 #include "StMessMgr.h"
267 
268 #include "St_DataSet.h"
269 #include "St_DataSetIter.h"
270 #include "TH2.h"
271 
272 #include "StEventTypes.h"
273 
274 #include "StMcEventTypes.hh"
275 
276 #include "StMcEvent.hh"
277 
278 #include "StMemoryInfo.hh"
279 // // Define the comparison to be used in the multimaps
280 
281 // bool compTpcHit::operator()(const StTpcHit* h1, const StTpcHit* h2) const {
282 // if (h1->position().z() != h2->position().z()) {
283 // return h1->position().z() < h2->position().z();
284 // }
285 // else if (h1->position().y() != h2->position().y()) {
286 // return h1->position().y() < h2->position().y();
287 // }
288 // else return h1->position().x() < h2->position().x();
289 
290 // }
291 // bool compMcTpcHit::operator()(const StMcTpcHit* h1, const StMcTpcHit* h2) const {
292 // if (h1->position().z() != h2->position().z()) {
293 // return h1->position().z() < h2->position().z();
294 // }
295 // else if (h1->position().y() != h2->position().y()) {
296 // return h1->position().y() < h2->position().y();
297 // }
298 // else return h1->position().x() < h2->position().x();
299 
300 // }
301 // bool compSvtHit::operator()(const StSvtHit* h1, const StSvtHit* h2) const {
302 // if (h1->position().z() != h2->position().z()) {
303 // return h1->position().z() < h2->position().z();
304 // }
305 // else if (h1->position().y() != h2->position().y()) {
306 // return h1->position().y() < h2->position().y();
307 // }
308 // else return h1->position().x() < h2->position().x();
309 
310 // }
311 // bool compMcSvtHit::operator()(const StMcSvtHit* h1, const StMcSvtHit* h2) const {
312 // if (h1->position().z() != h2->position().z()) {
313 // return h1->position().z() < h2->position().z();
314 // }
315 // else if (h1->position().y() != h2->position().y()) {
316 // return h1->position().y() < h2->position().y();
317 // }
318 // else return h1->position().x() < h2->position().x();
319 
320 // }
321 // bool compFtpcHit::operator()(const StFtpcHit* h1, const StFtpcHit* h2) const {
322 // if (h1->position().z() != h2->position().z()) {
323 // return h1->position().z() < h2->position().z();
324 // }
325 // else if (h1->position().y() != h2->position().y()) {
326 // return h1->position().y() < h2->position().y();
327 // }
328 // else return h1->position().x() < h2->position().x();
329 
330 // }
331 // bool compMcFtpcHit::operator()(const StMcFtpcHit* h1, const StMcFtpcHit* h2) const {
332 // if (h1->position().z() != h2->position().z()) {
333 // return h1->position().z() < h2->position().z();
334 // }
335 // else if (h1->position().y() != h2->position().y()) {
336 // return h1->position().y() < h2->position().y();
337 // }
338 // else return h1->position().x() < h2->position().x();
339 
340 // }
341 
343 public:
344  bool operator()(const StMcTpcHit*) const;
345  void setReferenceZ(float z) { mRefZ = z; }
346  float mRefZ;
347 };
348 bool compFuncMcTpcHit::operator()(const StMcTpcHit* h) const {
349  // comparison is btw hits in the same padrow
350  return (h->position().z()) > mRefZ;
351 }
352 
354 public:
355  bool operator()(const StMcFtpcHit*) const;
356  void setReferencePhi(float phi) { mRefPhi = phi; }
357  float mRefPhi;
358 };
359 bool compFuncMcFtpcHit::operator()(const StMcFtpcHit* h) const {
360  // comparison is btw hits in the same plane, so
361  // z coordinate is irrelevant
362  return (h->position().phi()/degree) > mRefPhi;
363 }
364 
365 bool compTrack::operator()(const StGlobalTrack* t1, const StGlobalTrack* t2) const {
366  return t1 < t2;
367 }
368 
369 bool compMcTrack::operator()(const StMcTrack* t1, const StMcTrack* t2) const {
370  return t1 < t2;
371 }
372 bool compKinkVertex::operator()(const StKinkVertex* v1, const StKinkVertex* v2) const {
373  return v1 < v2;
374 }
375 bool compV0Vertex::operator()(const StV0Vertex* v1, const StV0Vertex* v2) const {
376  return v1 < v2;
377 }
378 bool compXiVertex::operator()(const StXiVertex* v1, const StXiVertex* v2) const {
379  return v1 < v2;
380 }
381 
382 bool compMcVertex::operator()(const StMcVertex* v1, const StMcVertex* v2) const {
383  return v1 < v2;
384 }
385 
386 // Print out Track pairs
387 ostream& operator<<(ostream& out,
388  const pair< const StGlobalTrack* const, StTrackPairInfo*>& p)
389 {
390  out << "const StGlobalTrack at : " << (void*)p.first << endl;
391  out << "const StMcTrack at : " << (void*)(p.second->partnerMcTrack()) << endl;
392  out << "Common TPC Hits : " << p.second->commonTpcHits() << endl;
393  out << "Common SVT Hits : " << p.second->commonSvtHits() << endl;
394  out << "Common SSD Hits : " << p.second->commonSsdHits() << endl;
395  out << "Common FTPC Hits : " << p.second->commonFtpcHits() << endl;
396 
397  return out;
398 }
399 ostream& operator<<(ostream& out,
400  const pair< const StMcTrack* const, StTrackPairInfo*>& p)
401 {
402  out << "const StMcTrack at : " << (void*)p.first << endl;
403  out << "const StGlobalTrack at : " << (void*)(p.second->partnerTrack()) << endl;
404  out << "Common TPC Hits : " << p.second->commonTpcHits() << endl;
405  out << "Common SVT Hits : " << p.second->commonSvtHits() << endl;
406  out << "Common SSD Hits : " << p.second->commonSsdHits() << endl;
407  out << "Common FTPC Hits : " << p.second->commonFtpcHits() << endl;
408 
409  return out;
410 }
411 
412 // Print out the Track multimaps
413 ostream& operator<<(ostream& out, const rcTrackMapType& tm)
414 {
415 #if __SUNPRO_CC != 0x500
416  copy(tm.begin(),tm.end(), ostream_iterator<rcTrackMapValType>(out,"\n"));
417 
418 #else
419  out << "Sorry, can't use ostream_iterator with this version of Stiostream.h !" << endl ;
420 #endif
421  return out;
422 }
423 
424 ostream& operator<<(ostream& out, const mcTrackMapType& tm)
425 {
426 #if __SUNPRO_CC != 0x500
427  copy(tm.begin(),tm.end(), ostream_iterator<mcTrackMapValType>(out,"\n"));
428 #else
429  out << "Sorry, can't use ostream_iterator with this version of Stiostream.h !" << endl ;
430 #endif
431  return out;
432 }
433 
434 
435 ClassImp(StAssociationMaker)
436 
437 
438  //_________________________________________________
439  StAssociationMaker::StAssociationMaker(const char *name, const char *title):StMaker(name,title)
440 {
441  // StAssociationMaker Constructor
442  // - zero all pointers defined in the header file
443 
444  mRcTpcHitMap = 0;
445  mMcTpcHitMap = 0;
446  mRcSvtHitMap = 0;
447  mMcSvtHitMap = 0;
448  mRcSsdHitMap = 0;
449  mMcSsdHitMap = 0;
450  mRcFtpcHitMap = 0;
451  mMcFtpcHitMap = 0;
452  mRcTrackMap = 0;
453  mMcTrackMap = 0;
454  mRcKinkMap = 0;
455  mMcKinkMap = 0;
456  mRcV0Map = 0;
457  mMcV0Map = 0;
458  mRcXiMap = 0;
459  mMcXiMap = 0;
460 
461  mTpcLocalHitResolution = 0;
462  mSvtHitResolution = 0;
463  mSsdHitResolution = 0;
464  mFtpcHitResolution = 0;
465 
466  doPrintMemoryInfo = kFALSE;
467  mL3TriggerOn = false;
468  mInTrackerOn = kTRUE;
469  mEstTracksOn = false;
470  mDistanceAssoc = kFALSE;
471 }
472 
473 //_________________________________________________
474 StAssociationMaker::~StAssociationMaker()
475 {
476  // StAssociationMaker Destructor
477  if(Debug()) gMessMgr->Info() << "Inside StAssociationMaker Destructor" << endm;
478 
479  if (mRcTpcHitMap) {
480  mRcTpcHitMap->clear();
481  SafeDelete(mRcTpcHitMap);
482  }
483  if (mMcTpcHitMap) {
484  mMcTpcHitMap->clear();
485  SafeDelete(mMcTpcHitMap);
486  }
487  if (mRcSvtHitMap) {
488  mRcSvtHitMap->clear();
489  SafeDelete(mRcSvtHitMap);
490  }
491  if (mMcSvtHitMap) {
492  mMcSvtHitMap->clear();
493  SafeDelete(mMcSvtHitMap);
494  }
495  if (mRcSsdHitMap) {
496  mRcSsdHitMap->clear();
497  SafeDelete(mRcSsdHitMap);
498  }
499  if (mMcSsdHitMap) {
500  mMcSsdHitMap->clear();
501  SafeDelete(mMcSsdHitMap);
502  }
503  if (mRcFtpcHitMap) {
504  mRcFtpcHitMap->clear();
505  SafeDelete(mRcFtpcHitMap);
506  }
507  if (mMcFtpcHitMap) {
508  mMcFtpcHitMap->clear();
509  SafeDelete(mMcFtpcHitMap);
510  }
511 
512  if (mRcTrackMap) {
513  // Delete the TrackPairInfos
514  // Careful, only delete them once!
515  for (rcTrackMapIter i=mRcTrackMap->begin(); i!=mRcTrackMap->end(); i++){
516  delete (*i).second;
517  }
518  // Delete the REC. TrackMap
519  mRcTrackMap->clear();
520  SafeDelete(mRcTrackMap);
521  }
522  if (mMcTrackMap) {
523  mMcTrackMap->clear();
524  SafeDelete(mMcTrackMap);
525  }
526  if (mRcKinkMap) {
527  mRcKinkMap->clear();
528  SafeDelete(mRcKinkMap);
529  }
530  if (mMcKinkMap) {
531  mMcKinkMap->clear();
532  SafeDelete(mMcKinkMap);
533  }
534  if (mRcV0Map) {
535  mRcV0Map->clear();
536  SafeDelete(mRcV0Map);
537  }
538  if (mMcV0Map) {
539  mMcV0Map->clear();
540  SafeDelete(mMcV0Map);
541  }
542  if (mRcXiMap) {
543  mRcXiMap->clear();
544  SafeDelete(mRcXiMap);
545  }
546  if (mMcXiMap) {
547  mMcXiMap->clear();
548  SafeDelete(mMcXiMap);
549  }
550 }
551 
552 //_____________________________________________________________________________
553 
554 void StAssociationMaker::Clear(const char* c)
555 {
556  // StAssociationMaker - Clear,
557  if (doPrintMemoryInfo)
558  StMemoryInfo::instance()->snapshot();
559 
560  // Delete TpcHitMap
561  if (mRcTpcHitMap) {
562  mRcTpcHitMap->clear();
563  SafeDelete(mRcTpcHitMap);
564  if (doPrintMemoryInfo)
565  cout << "Deleted Rec. Tpc Hit Map" << endl;
566  }
567  if (mMcTpcHitMap) {
568  mMcTpcHitMap->clear();
569  SafeDelete(mMcTpcHitMap);
570  if (doPrintMemoryInfo)
571  cout << "Deleted M.C. Tpc Hit Map" << endl;
572  }
573  if (mRcSvtHitMap) {
574  mRcSvtHitMap->clear();
575  SafeDelete(mRcSvtHitMap);
576  if (doPrintMemoryInfo)
577  cout << "Deleted Rec. Svt Hit Map" << endl;
578  }
579  if (mMcSvtHitMap) {
580  mMcSvtHitMap->clear();
581  SafeDelete(mMcSvtHitMap);
582  if (doPrintMemoryInfo)
583  cout << "Deleted M.C. Svt Hit Map" << endl;
584  }
585  if (mRcSsdHitMap) {
586  mRcSsdHitMap->clear();
587  SafeDelete(mRcSsdHitMap);
588  if (doPrintMemoryInfo)
589  cout << "Deleted Rec. Ssd Hit Map" << endl;
590  }
591  if (mMcSsdHitMap) {
592  mMcSsdHitMap->clear();
593  SafeDelete(mMcSsdHitMap);
594  if (doPrintMemoryInfo)
595  cout << "Deleted M.C. Ssd Hit Map" << endl;
596  }
597  if (mRcFtpcHitMap) {
598  mRcFtpcHitMap->clear();
599  SafeDelete(mRcFtpcHitMap);
600  if (doPrintMemoryInfo)
601  cout << "Deleted Rec. Ftpc Hit Map" << endl;
602  }
603  if (mMcFtpcHitMap) {
604  mMcFtpcHitMap->clear();
605  SafeDelete(mMcFtpcHitMap);
606  if (doPrintMemoryInfo)
607  cout << "Deleted M.C. Ftpc Hit Map" << endl;
608  }
609 
610  if (mRcTrackMap) {
611  // Delete the TrackPairInfos
612  // Careful, only delete them once!
613  for (rcTrackMapIter i=mRcTrackMap->begin(); i!=mRcTrackMap->end(); i++){
614  SafeDelete((*i).second);
615  }
616  // Delete the REC. TrackMap
617  mRcTrackMap->clear();
618  SafeDelete(mRcTrackMap);
619  if (doPrintMemoryInfo)
620  cout << "Deleted Rec. Track Map" << endl;
621  }
622  if (mMcTrackMap) {
623  mMcTrackMap->clear();
624  SafeDelete(mMcTrackMap);
625  if (doPrintMemoryInfo)
626  cout << "Deleted M.C. Track Map" << endl;
627 
628  }
629  if (mRcKinkMap) {
630  mRcKinkMap->clear();
631  SafeDelete(mRcKinkMap);
632  if (doPrintMemoryInfo)
633  cout << "Deleted Rec. Kink Map" << endl;
634  }
635  if (mMcKinkMap) {
636  mMcKinkMap->clear();
637  SafeDelete(mMcKinkMap);
638  if (doPrintMemoryInfo)
639  cout << "Deleted M.C. Kink Map" << endl;
640  }
641  if (mRcV0Map) {
642  mRcV0Map->clear();
643  SafeDelete(mRcV0Map);
644  if (doPrintMemoryInfo)
645  cout << "Deleted Rec. V0 Map" << endl;
646  }
647  if (mMcV0Map) {
648  mMcV0Map->clear();
649  SafeDelete(mMcV0Map);
650  if (doPrintMemoryInfo)
651  cout << "Deleted M.C. V0 Map" << endl;
652  }
653  if (mRcXiMap) {
654  mRcXiMap->clear();
655  SafeDelete(mRcXiMap);
656  if (doPrintMemoryInfo)
657  cout << "Deleted Rec. Xi Map" << endl;
658  }
659  if (mMcXiMap) {
660  mMcXiMap->clear();
661  SafeDelete(mMcXiMap);
662  if (doPrintMemoryInfo)
663  cout << "Deleted M.C. Xi Map" << endl;
664  }
665 
666  if (doPrintMemoryInfo) {
667  StMemoryInfo::instance()->snapshot();
668  StMemoryInfo::instance()->print();
669  }
670  StMaker::Clear(c);
671 }
672 
673 //_________________________________________________
675 {
676  return StMaker::Finish();
677 }
678 
679 //_________________________________________________
680 Int_t StAssociationMaker::Init()
681 {
682  // StAssociationMaker - Init
683  // Set up Histograms
684 
685  //
686  // TPC
687  //
688 
689  mTpcLocalHitResolution = new TH2F("TpcLocalHitResolution",
690  "Delta Z Vs Delta X for Nearby Hits",
691  50, -0.52, 0.52,
692  50, -0.24, 0.24);
693  mTpcLocalHitResolution->SetXTitle("Local (Xmc - Xrec) (cm)");
694  mTpcLocalHitResolution->SetYTitle("Zmc - Zrec (cm)");
695 
696  //
697  // SVT
698  //
699  mSvtHitResolution = new TH2F("SvtHitResolution",
700  "Delta Z Vs Delta X for Nearby Hits",
701  50, -0.12, 0.12,
702  50, -0.12, 0.12);
703  mSvtHitResolution->SetXTitle("Xmc - Xrec (cm)");
704  mSvtHitResolution->SetYTitle("Zmc - Zrec (cm)");
705  //
706  // SSD
707  //
708  mSsdHitResolution = new TH2F("SsdHitResolution",
709  "Delta Z Vs Delta X for Nearby Hits",
710  50, -0.12, 0.12,
711  50, -0.12, 0.12);
712  mSsdHitResolution->SetXTitle("Xmc - Xrec (cm)");
713  mSsdHitResolution->SetYTitle("Zmc - Zrec (cm)");
714 
715  //
716  // FTPC
717  //
718  mFtpcHitResolution = new TH2F("FtpcHitResolution",
719  "Delta Z Vs Delta X for Nearby Hits",
720  50, -0.32, 0.32,
721  50, -8, 0.8);
722  mFtpcHitResolution->SetXTitle("Rmc - Rrec (cm)");
723  mFtpcHitResolution->SetYTitle("PHImc - PHIrec (deg)");
724 
725  gMessMgr->Info() << "Cuts used in association for this run: " << endm;
726  gMessMgr->Info() << "\n" << *(StMcParameterDB::instance()) << "\n" << endm;
727  if (mInTrackerOn) {
728  gMessMgr->Info() << "Using IT Tracks in Association" << endm;
729  }
730  if (mEstTracksOn) {
731  gMessMgr->Info() << "Using EST Tracks in Association" << endm;
732  }
733  return StMaker::Init();
734 }
735 
736 //_________________________________________________
737 
739 {
740  gMessMgr->Info() << "AssociationMaker::Make()" << endm;
741  if (doPrintMemoryInfo)
742  StMemoryInfo::instance()->snapshot();
743 
744  if (mL3TriggerOn && mInTrackerOn) {
745  gMessMgr->Warning() << "AssociationMaker::Make(): L3 and IT Tracks are both on!" << endm;
746  return kStWarn;
747  }
748  if (mEstTracksOn && mInTrackerOn) {
749  gMessMgr->Warning() << "AssociationMaker::Make(): EST and IT Tracks are both on!" << endm;
750  return kStWarn;
751  }
752  if (Debug()) {
753  if (mDistanceAssoc==true) {
754  gMessMgr->Info() << "Using Distance Association" << endm;
755  }
756  else {
757  gMessMgr->Info() << "Using Id Association" << endm;
758  }
759 
760  }
761  //
762  // Get StEvent
763  //
764  StEvent* rEvent = 0;
765  rEvent = (StEvent*) GetInputDS("StEvent");
766  if (!rEvent) {
767  gMessMgr->Warning() << "No StEvent!!! " << endm;
768  gMessMgr->Warning() << "Bailing out ..." << endm;
769  return kStWarn;
770  }
771  // Make the pointers to collections.
772  // Tpc
773  StTpcHitCollection* rcTpcHitColl;
774  StMcTpcHitCollection* mcTpcHitColl;
775  // Svt
776  StSvtHitCollection* rcSvtHitColl;
777  StMcSvtHitCollection* mcSvtHitColl;
778  // Ssd
779  StSsdHitCollection* rcSsdHitColl;
780  StMcSsdHitCollection* mcSsdHitColl;
781  // Ftpc
782  StFtpcHitCollection* rcFtpcHitColl;
783  StMcFtpcHitCollection* mcFtpcHitColl;
784 
785 
786  // In order to make associations with the reconstructed L3 EVENT
787  // we use the L3 hit collections, the switch below selects
788  // the appropriate pointers.
789  StL3Trigger* rL3Event = 0;
790  if (!mL3TriggerOn) {
791  // This case is for normal case, use hit collections from StEvent
792  rcTpcHitColl = rEvent->tpcHitCollection();
793  rcSvtHitColl = rEvent->svtHitCollection();
794  rcSsdHitColl = rEvent->ssdHitCollection();
795  rcFtpcHitColl = rEvent->ftpcHitCollection();
796  }
797  else {
798  // This case is for using the L3 Event
799  if (rEvent){
800  rL3Event = rEvent->l3Trigger();
801  }
802 
803  if (rL3Event) {
804  rcTpcHitColl = rL3Event->tpcHitCollection();
805  }
806  else {
807  return kStWarn ;
808  }
809 
810  rcSvtHitColl = 0;
811  rcSsdHitColl = 0;
812  rcFtpcHitColl = 0;
813 
814  }
815 
816 
817  StSPtrVecTrackNode& rcTrackNodes = (!mL3TriggerOn) ? rEvent->trackNodes() : rL3Event->trackNodes();
818 
819  //
820  // Get StMcEvent
821  //
822  StMcEvent* mEvent = 0;
823  mEvent = (StMcEvent*) GetDataSet("StMcEvent");
824  if (!mEvent) {
825  gMessMgr->Error() << "No StMcEvent!!! " << endm;
826  gMessMgr->Error() << "Bailing out ..." << endm;
827  return kStWarn;
828  }
829 
830  //
831  // Get the Pointers to the Collections.
832  //
833 
834  mcTpcHitColl = mEvent->tpcHitCollection();
835  mcSvtHitColl = mEvent->svtHitCollection();
836  mcSsdHitColl = mEvent->ssdHitCollection();
837  mcFtpcHitColl = mEvent->ftpcHitCollection();
838 
839  // Get the pointer to the parameter DB,
840  // the definitions of the cuts
841  // should be done at the macro level.
842 
843  StMcParameterDB* parDB = StMcParameterDB::instance();
844 
845 
846  //
847  // Loop over TPC hits and make Associations
848  //
849  if (rcTpcHitColl && mcTpcHitColl) {
850  if (Debug()) gMessMgr->Info() << "Making TPC Hit Associations..." << endm;
851 
852  StTpcHit* rcTpcHit;
853  StMcTpcHit* mcTpcHit;
854 
855  // Instantiate the Tpc Hit maps
856  mRcTpcHitMap = new rcTpcHitMapType;
857  mMcTpcHitMap = new mcTpcHitMapType;
858 
859  int matchedR = 0;
860 
861  float tpcHitDistance = 9999;
862  if (Debug()) cout << "In Sector : ";
863 
864  for (unsigned int iSector=0;
865  iSector<rcTpcHitColl->numberOfSectors(); iSector++) {
866 
867  if (Debug()) cout << iSector + 1 << " ";
868  StTpcSectorHitCollection* tpcSectHitColl = rcTpcHitColl->sector(iSector);
869  for (unsigned int iPadrow=0;
870  iPadrow<tpcSectHitColl->numberOfPadrows();
871  iPadrow++) {
872  StTpcPadrowHitCollection* tpcPadRowHitColl = tpcSectHitColl->padrow(iPadrow);
873  //PR(iPadrow);
874  int padrowMatchesId = 0;
875  int padrowMatchesDi = 0;
876  if (Debug()>=2 && iPadrow>=0) {
877  cout << endl;
878  cout << "Padrow " << iPadrow+1 << endl;
879  cout << "Reco hit index \tX pos\tY pos\tZ pos\tmIdTruth" << endl;
880  // In debug2 mode, print out all the reco hits and all the MC hits in this padrow
881  for (unsigned int iHit=0;
882  iHit<tpcPadRowHitColl->hits().size();
883  iHit++) {
884  rcTpcHit = tpcPadRowHitColl->hits()[iHit];
885  int qatru=rcTpcHit->qaTruth(); int idtru= rcTpcHit->idTruth();
886  cout << iHit << "\t" << rcTpcHit->position() << "\t" << idtru << "\t" << qatru << endl;
887  } // reco hits in debug2
888  cout << "MC Hit Key\tX pos\tY pos\tZ pos\tparent key" << endl;
889  for (StMcTpcHitIterator jHit = mcTpcHitColl->sector(iSector)->padrow(iPadrow)->hits().begin();
890  jHit != mcTpcHitColl->sector(iSector)->padrow(iPadrow)->hits().end();
891  jHit++){
892  mcTpcHit = *jHit;
893  cout << mcTpcHit->key() << "\t" << mcTpcHit->position() << "\t" << mcTpcHit->parentTrack()->key() << endl;
894 
895  } // mc hits in debug2
896  }// end of debug2 mode
897  for (unsigned int iHit=0; iHit<tpcPadRowHitColl->hits().size(); iHit++){
898  //PR(iHit);
899 
900  rcTpcHit = tpcPadRowHitColl->hits()[iHit];
901 
902  // switch the algorithm based on the option
903  // in shorthand:
904  // if (distance Association || !idTruth) {
905  // do distance association
906  // } else {
907  // do id association
908  // }
909 
910  //gMessMgr->Info() << "Backward compatibility mode:: distance cut association" << endm;
911  // Set the reference z for the comparison function
912  // The comparison will be used to find the first Mc Hit
913  // with a z greater than this reference, so that we don't loop
914  // over the hits that we don't need to.
915  StMcHit* closestTpcHit = 0;
916 
917  float xDiff, yDiff, zDiff;
918  xDiff = yDiff = zDiff = -999;
919  for (StMcTpcHitIterator jHit = mcTpcHitColl->sector(iSector)->padrow(iPadrow)->hits().begin();
920  jHit != mcTpcHitColl->sector(iSector)->padrow(iPadrow)->hits().end();
921  jHit++){
922  //PR(jHit);
923  mcTpcHit = *jHit;
924  //int idMc = 0; // for case 2
925  //if (mcTpcHit->parentTrack()) idMc = mcTpcHit->parentTrack()->key(); // case 2
926  //if (idMc != rcTpcHit->idTruth()) continue; // case 2
927  //if (! mcTpcHit->parentTrack()->key()) { // no Id -> take one in the window
928  if (mDistanceAssoc || !rcTpcHit->idTruth()) {
929  xDiff = mcTpcHit->position().x()-rcTpcHit->position().x();
930  yDiff = mcTpcHit->position().y()-rcTpcHit->position().y();
931  zDiff = mcTpcHit->position().z()-rcTpcHit->position().z();
932  if (!closestTpcHit) {
933  tpcHitDistance=xDiff*xDiff+zDiff*zDiff;
934  closestTpcHit = mcTpcHit;
935  }
936  if (xDiff*xDiff+zDiff*zDiff<tpcHitDistance) {
937  tpcHitDistance = xDiff*xDiff+zDiff*zDiff;
938  closestTpcHit = mcTpcHit;
939  }
940 
941  if ( fabs(xDiff)>= parDB->xCutTpc() ||
942  fabs(yDiff)>= parDB->yCutTpc() ||
943  fabs(zDiff)>= parDB->zCutTpc(mcTpcHit->position().z())) continue;
944  } else
945  if (mcTpcHit->parentTrack()->key() != rcTpcHit->idTruth()) continue;
946  // Note: Association is within sector and pad row, so a Monte Carlo
947  // looper may have multiple Monte Carlo hits from one track associated
948  // to one and the same reconstructed hit!
949  // Make Associations Use maps,
950  mRcTpcHitMap->insert(rcTpcHitMapValType (rcTpcHit, mcTpcHit) );
951  mMcTpcHitMap->insert(mcTpcHitMapValType (mcTpcHit, rcTpcHit) );
952  rcTpcHit->SetBit(StMcHit::kMatched,1);
953  mcTpcHit->SetBit(StMcHit::kMatched,1);
954  ++matchedR;
955  ++padrowMatchesDi;
956  }
957  if (Debug()==2)
958  if (closestTpcHit)
959  mTpcLocalHitResolution->Fill(closestTpcHit->position().x()-
960  rcTpcHit->position().x(),
961  closestTpcHit->position().z()-
962  rcTpcHit->position().z() );
963  } // End of Hits in Padrow loop for MC Hits
964  if (Debug()>=2 && iPadrow>=0) {
965  cout << "Reco Hits in Padrow " << tpcPadRowHitColl->hits().size() << endl;
966  cout << "Id Matches in Padrow " << padrowMatchesId << endl;
967  cout << "Distance Matches in pr " << padrowMatchesDi << endl;
968  }
969  } // End of Hits in Padrow loop for Rec. Hits
970  } // End of Sector Loop for Rec. Hits
971  // check non associated Mc hits
972  if (Debug()) {
973  cout << "\n";
974  gMessMgr->Info() << "Number of Entries in TPC Hit Maps: " << mRcTpcHitMap->size()
975  << " counter " << matchedR << endm;
976  }
977  if (doPrintMemoryInfo) {
978  if (Debug()) gMessMgr->Info() << "End of TPC Hit Associations\n" << endm;
979  StMemoryInfo::instance()->snapshot();
980  StMemoryInfo::instance()->print();
981  }
982  }
983  //
984  // Loop over SVT hits and make Associations
985  //
986  if (rcSvtHitColl && mcSvtHitColl) {
987 
988  if (Debug()) gMessMgr->Info() << "Making SVT Hit Associations..." << endm;
989 
990  StSvtHit* rcSvtHit;
991  StMcSvtHit* mcSvtHit;
992 
993  // Instantiate the Svt Hit maps
994  mRcSvtHitMap = new rcSvtHitMapType;
995  mMcSvtHitMap = new mcSvtHitMapType;
996 
997  float svtHitDistance = 9999;
998  unsigned int nSvtHits = rcSvtHitColl->numberOfHits();
999  if (Debug()) cout << "In Barrel : ";
1000  for (unsigned int iBarrel=0; nSvtHits &&
1001  iBarrel<rcSvtHitColl->numberOfBarrels(); iBarrel++) {
1002 
1003  if (Debug()) cout << iBarrel + 1 << " ";
1004 
1005  for (unsigned int iLadder=0;
1006  iLadder<rcSvtHitColl->barrel(iBarrel)->numberOfLadders();
1007  iLadder++) {
1008  //PR(iLadder);
1009  for (unsigned int iWafer=0;
1010  iWafer<rcSvtHitColl->barrel(iBarrel)->ladder(iLadder)->numberOfWafers();
1011  iWafer++) {
1012  //PR(iWafer);
1013 
1014  for (unsigned int iHit=0;
1015  iHit<rcSvtHitColl->barrel(iBarrel)->ladder(iLadder)->wafer(iWafer)->hits().size();
1016  iHit++){
1017  //PR(iHit);
1018  rcSvtHit = rcSvtHitColl->barrel(iBarrel)->ladder(iLadder)->wafer(iWafer)->hits()[iHit];
1019 
1020  StMcSvtHit* closestSvtHit = 0;
1021  float newDist = 0;
1022  for (unsigned int jHit=0;
1023  jHit<mcSvtHitColl->barrel(iBarrel)->ladder(iLadder)->wafer(iWafer)->hits().size();
1024  jHit++){
1025  //PR(jHit);
1026  mcSvtHit = mcSvtHitColl->barrel(iBarrel)->ladder(iLadder)->wafer(iWafer)->hits()[jHit];
1027  if (mDistanceAssoc || !rcSvtHit->idTruth()) {
1028  float xDiff = mcSvtHit->position().x() - rcSvtHit->position().x();
1029  float yDiff = mcSvtHit->position().y() - rcSvtHit->position().y();
1030  float zDiff = mcSvtHit->position().z() - rcSvtHit->position().z();
1031  if ( zDiff > parDB->zCutSvt() ) break; //mc hits are sorted, save time!
1032 
1033  if (jHit==0) {
1034  svtHitDistance=xDiff*xDiff+yDiff*yDiff+zDiff*zDiff;
1035  closestSvtHit = mcSvtHit;
1036  }
1037  if ( (newDist = xDiff*xDiff+yDiff*yDiff+zDiff*zDiff) < svtHitDistance) {
1038  svtHitDistance = newDist;
1039  closestSvtHit = mcSvtHit;
1040  }
1041 
1042  if ( fabs(xDiff)>= parDB->xCutSvt() ||
1043  fabs(yDiff)>= parDB->yCutSvt() ||
1044  fabs(zDiff)>= parDB->zCutSvt()) continue;
1045  } else // new case, idTruth information exists
1046  if (mcSvtHit->parentTrack()->key() != rcSvtHit->idTruth()) continue;
1047  // Make Associations Use maps,
1048  mRcSvtHitMap->insert(rcSvtHitMapValType (rcSvtHit, mcSvtHit) );
1049  mMcSvtHitMap->insert(mcSvtHitMapValType (mcSvtHit, rcSvtHit) );
1050  rcSvtHit->SetBit(StMcHit::kMatched,1);
1051  mcSvtHit->SetBit(StMcHit::kMatched,1);
1052  } // End of Hits in Wafer loop for MC Hits
1053  if (closestSvtHit)
1054  mSvtHitResolution->Fill(closestSvtHit->position().x()-
1055  rcSvtHit->position().x(),
1056  closestSvtHit->position().z()-
1057  rcSvtHit->position().z() );
1058  } // End of Hits in Wafer loop for Rec. Hits
1059  } // End of Wafer Loop for Rec. Hits
1060  } // End of Ladder Loop for Rec. Hits
1061  } // End of Barrel Loop for Rec. Hits
1062 
1063  if (Debug()) {
1064  cout << "\n";
1065  gMessMgr->Info() << "Number of Entries in SVT Hit Maps: " << mRcSvtHitMap->size() << endm;
1066  }
1067  if (doPrintMemoryInfo) {
1068  if (Debug()) gMessMgr->Info() << "End of SVT Hit Associations\n" << endm;
1069  StMemoryInfo::instance()->snapshot();
1070  StMemoryInfo::instance()->print();
1071  }
1072  }
1073  //
1074  // Loop over SSD hits and make Associations
1075  //
1076  if (rcSsdHitColl && mcSsdHitColl) {
1077 
1078  if (Debug()) gMessMgr->Info() << "Making SSD Hit Associations..." << endm;
1079 
1080  StSsdHit* rcSsdHit;
1081  StMcSsdHit* mcSsdHit;
1082 
1083  // Instantiate the Ssd Hit maps
1084  mRcSsdHitMap = new rcSsdHitMapType;
1085  mMcSsdHitMap = new mcSsdHitMapType;
1086 
1087  float ssdHitDistance = 9999;
1088  unsigned int nSsdHits = rcSsdHitColl->numberOfHits();
1089  if (Debug()) cout << "In Ladder : ";
1090  for (unsigned int iLadder=0; nSsdHits &&
1091  iLadder<rcSsdHitColl->numberOfLadders(); iLadder++) {
1092 
1093  if (Debug()) cout << iLadder + 1 << " ";
1094 
1095  for (unsigned int iWafer=0;
1096  iWafer<rcSsdHitColl->ladder(iLadder)->numberOfWafers();
1097  iWafer++) {
1098  //PR(iWafer);
1099 
1100  for (unsigned int iHit=0;
1101  iHit<rcSsdHitColl->ladder(iLadder)->wafer(iWafer)->hits().size();
1102  iHit++){
1103  //PR(iHit);
1104  rcSsdHit = rcSsdHitColl->ladder(iLadder)->wafer(iWafer)->hits()[iHit];
1105 
1106  StMcSsdHit* closestSsdHit = 0;
1107  float newDist = 0;
1108  for (unsigned int jHit=0;
1109  jHit<mcSsdHitColl->ladder(iLadder)->wafer(iWafer)->hits().size();
1110  jHit++){
1111  //PR(jHit);
1112  mcSsdHit = mcSsdHitColl->ladder(iLadder)->wafer(iWafer)->hits()[jHit];
1113  float xDiff = mcSsdHit->position().x() - rcSsdHit->position().x();
1114  float yDiff = mcSsdHit->position().y() - rcSsdHit->position().y();
1115  float zDiff = mcSsdHit->position().z() - rcSsdHit->position().z();
1116  if ( zDiff > parDB->zCutSsd() ) break; //mc hits are sorted, save time!
1117 
1118  if (jHit==0) {
1119  ssdHitDistance=xDiff*xDiff+yDiff*yDiff+zDiff*zDiff;
1120  closestSsdHit = mcSsdHit;
1121  }
1122  if ( (newDist = xDiff*xDiff+yDiff*yDiff+zDiff*zDiff) < ssdHitDistance) {
1123  ssdHitDistance = newDist;
1124  closestSsdHit = mcSsdHit;
1125  }
1126  if (mDistanceAssoc || !rcSsdHit->idTruth()) {
1127  if ( fabs(xDiff)>= parDB->xCutSsd() ||
1128  fabs(yDiff)>= parDB->yCutSsd() ||
1129  fabs(zDiff)>= parDB->zCutSsd()) continue;
1130  } else
1131  if (mcSsdHit->parentTrack()->key() != rcSsdHit->idTruth()) continue;
1132  // Make Associations Use maps,
1133  mRcSsdHitMap->insert(rcSsdHitMapValType (rcSsdHit, mcSsdHit) );
1134  mMcSsdHitMap->insert(mcSsdHitMapValType (mcSsdHit, rcSsdHit) );
1135  rcSsdHit->SetBit(StMcHit::kMatched,1);
1136  mcSsdHit->SetBit(StMcHit::kMatched,1);
1137  } // End of Hits in Wafer loop for MC Hits
1138  if (closestSsdHit)
1139  mSsdHitResolution->Fill(closestSsdHit->position().x()-
1140  rcSsdHit->position().x(),
1141  closestSsdHit->position().z()-
1142  rcSsdHit->position().z() );
1143  } // End of Hits in Wafer loop for Rec. Hits
1144  } // End of Wafer Loop for Rec. Hits
1145  } // End of Ladder Loop for Rec. Hits
1146 
1147  if (Debug()) {
1148  cout << "\n";
1149  gMessMgr->Info() << "Number of Entries in SSD Hit Maps: " << mRcSsdHitMap->size() << endm;
1150  }
1151  if (doPrintMemoryInfo) {
1152  if (Debug()) gMessMgr->Info() << "End of SSD Hit Associations\n" << endm;
1153  StMemoryInfo::instance()->snapshot();
1154  StMemoryInfo::instance()->print();
1155  }
1156  }
1157  //
1158  // Loop over FTPC hits and make Associations
1159  //
1160  if (rcFtpcHitColl && mcFtpcHitColl) {
1161  if (Debug()) gMessMgr->Info() << "Making FTPC Hit Associations..." << endm;
1162 
1163  StFtpcHit* rcFtpcHit = 0;
1164  StMcFtpcHit* mcFtpcHit = 0;
1165 
1166  // Instantiate the Ftpc Hit maps
1167  mRcFtpcHitMap = new rcFtpcHitMapType;
1168  mMcFtpcHitMap = new mcFtpcHitMapType;
1169 
1170  float ftpcHitDistance = 0;
1171  float minHitDistance = 0;
1172  if (Debug()) cout << "In Plane : ";
1173  for (unsigned int iPlane=0;
1174  iPlane<rcFtpcHitColl->numberOfPlanes(); iPlane++) {
1175 
1176  if (Debug()) cout << iPlane + 1 << " ";
1177 
1178  for (unsigned int iSector=0;
1179  iSector<rcFtpcHitColl->plane(iPlane)->numberOfSectors();
1180  iSector++) {
1181 
1182  compFuncMcFtpcHit ftpcComp;
1183  //PR(iSector);
1184 
1185  for (unsigned int iHit=0;
1186  iHit<rcFtpcHitColl->plane(iPlane)->sector(iSector)->hits().size();
1187  iHit++){
1188  //PR(iHit);
1189 
1190  rcFtpcHit = rcFtpcHitColl->plane(iPlane)->sector(iSector)->hits()[iHit];
1191 
1192  ftpcComp.setReferencePhi((rcFtpcHit->position().phi()/degree) - parDB->phiCutFtpc());
1193 
1194  float rDiff, phiDiff, rDiffMin, phiDiffMin;
1195  rDiff = phiDiff = rDiffMin = phiDiffMin =0;
1196 
1197  //PR(mcFtpcHitColl->plane(iPlane)->hits().size());
1198 
1199  StMcFtpcHitIterator ftpcHitSeed = mcFtpcHitColl->plane(iPlane)->hits().begin();
1200  bool isFirst = true;
1201  for (StMcFtpcHitIterator jHit = ftpcHitSeed;
1202  jHit != mcFtpcHitColl->plane(iPlane)->hits().end();
1203  jHit++){
1204 
1205  mcFtpcHit = *jHit;
1206  rDiff = mcFtpcHit->position().perp() - rcFtpcHit->position().perp();
1207  phiDiff = (mcFtpcHit->position().phi() - rcFtpcHit->position().phi())/degree;
1208 
1209  if ( phiDiff > parDB->phiCutFtpc() ) break; //mc hits are sorted, save time!
1210 
1211  ftpcHitDistance = (mcFtpcHit->position() - rcFtpcHit->position()).mag2();
1212 
1213  if (isFirst) {
1214  minHitDistance=ftpcHitDistance;
1215  rDiffMin=rDiff;
1216  phiDiffMin=phiDiff;
1217  isFirst = false;
1218  }
1219  if (ftpcHitDistance < minHitDistance) {
1220  minHitDistance = ftpcHitDistance;
1221  rDiffMin=rDiff;
1222  phiDiffMin=phiDiff;
1223  }
1224 
1225  if ( fabs(rDiff)< parDB->rCutFtpc() && fabs(phiDiff) < parDB->phiCutFtpc()) {
1226  // Make Associations Use maps,
1227  mRcFtpcHitMap->insert(rcFtpcHitMapValType (rcFtpcHit, mcFtpcHit) );
1228  mMcFtpcHitMap->insert(mcFtpcHitMapValType (mcFtpcHit, rcFtpcHit) );
1229  rcFtpcHit->SetBit(StMcHit::kMatched,1);
1230  rcFtpcHit->setIdTruth(mcFtpcHit->parentTrack()->key(),100);
1231  mcFtpcHit->SetBit(StMcHit::kMatched,1);
1232  }
1233 
1234  } // End of Hits in PLANE loop for MC Hits
1235  if (!isFirst)
1236  mFtpcHitResolution->Fill(rDiffMin,phiDiffMin);
1237  } // End of Hits in Sector loop for Rec. Hits
1238  } // End of Sector Loop for Rec. Hits
1239  } // End of Plane Loop for Rec. Hits
1240 
1241  if (Debug()) {
1242  cout << "\n";
1243  gMessMgr->Info() << "Number of Entries in Ftpc Hit Maps: " << mRcFtpcHitMap->size() << endm;
1244  }
1245  if (doPrintMemoryInfo) {
1246  if (Debug()) gMessMgr->Info() << "End of FTPC Hit Associations\n" << endm;
1247  StMemoryInfo::instance()->snapshot();
1248  StMemoryInfo::instance()->print();
1249  }
1250 
1251  }
1252  //
1253  // Check that Hit Maps are big enough to Make Track Maps
1254  //
1255  bool smallTpcHitMap, smallSvtHitMap, smallSsdHitMap, smallFtpcHitMap;
1256  smallTpcHitMap = smallSvtHitMap = smallSsdHitMap = smallFtpcHitMap = false;
1257 
1258  if (mRcTpcHitMap && mRcTpcHitMap->size()>0 && mRcTpcHitMap->size() < parDB->reqCommonHitsTpc()) {
1259  gMessMgr->Warning() << "\n----------- WARNING ---------------\n"
1260  << " The Tpc Hit Map is too small for \n"
1261  << " any meaningful track association. \n"
1262  << " ------------------------------------ \n"
1263  << "Entries in Hit Map : " << mRcTpcHitMap->size() << "\n"
1264  << "Required Common Hits: " << parDB->reqCommonHitsTpc() << "\n"
1265  << "Suggest increase distance cuts." << endm;
1266  smallTpcHitMap = true;
1267  }
1268 
1269  if (mRcSvtHitMap && mRcSvtHitMap->size()>0 && mRcSvtHitMap->size() < parDB->reqCommonHitsSvt()) {
1270  gMessMgr->Warning() << "\n----------- WARNING ---------------\n"
1271  << " The Svt Hit Map is too small for \n"
1272  << " any meaningful track association. \n"
1273  << " ------------------------------------ \n"
1274  << "Entries in Hit Map : " << mRcSvtHitMap->size() << "\n"
1275  << "Required Common Hits: " << parDB->reqCommonHitsSvt() << "\n"
1276  << "Suggest increase distance cuts." << endm;
1277  smallSvtHitMap = true;
1278  }
1279  if (mRcSsdHitMap && mRcSsdHitMap->size()>0 && mRcSsdHitMap->size() < parDB->reqCommonHitsSsd()) {
1280  gMessMgr->Warning() << "\n----------- WARNING ---------------\n"
1281  << " The Ssd Hit Map is too small for \n"
1282  << " any meaningful track association. \n"
1283  << " ------------------------------------ \n"
1284  << "Entries in Hit Map : " << mRcSsdHitMap->size() << "\n"
1285  << "Required Common Hits: " << parDB->reqCommonHitsSsd() << "\n"
1286  << "Suggest increase distance cuts." << endm;
1287  smallSsdHitMap = true;
1288  }
1289  if (mRcFtpcHitMap && mRcFtpcHitMap->size()>0 && mRcFtpcHitMap->size() < parDB->reqCommonHitsFtpc()) {
1290  gMessMgr->Warning() << "\n----------- WARNING ---------------\n"
1291  << " The Ftpc Hit Map is too small for \n"
1292  << " any meaningful track association. \n"
1293  << " ------------------------------------ \n"
1294  << "Entries in Hit Map : " << mRcFtpcHitMap->size() << "\n"
1295  << "Required Common Hits: " << parDB->reqCommonHitsFtpc() << "\n"
1296  << "Suggest increase distance cuts." << endm;
1297  smallFtpcHitMap = true;
1298  }
1299 
1300  if ((smallTpcHitMap && smallSvtHitMap && smallSsdHitMap && smallFtpcHitMap) ||
1301  (!mRcTpcHitMap && !mRcSvtHitMap && mRcSsdHitMap && !mRcFtpcHitMap)) {
1302  gMessMgr->Error() << "No Useful Hit Map to make Track Associations" << endm;
1303  return kStWarn;
1304  }
1305 
1306  //
1307  // Start doing Track Associations ----------------------
1308  //
1309 
1310  StTrackNode* trkNode;
1311  const StGlobalTrack* rcTrack;
1312 
1313  StHit* rcHit;
1314  StTpcHit* rcKeyTpcHit;
1315  StSvtHit* rcKeySvtHit;
1316  StSsdHit* rcKeySsdHit;
1317  StFtpcHit* rcKeyFtpcHit;
1318 
1319  pair<rcTpcHitMapIter,rcTpcHitMapIter> boundsTpc;
1320  pair<rcSvtHitMapIter,rcSvtHitMapIter> boundsSvt;
1321  pair<rcSsdHitMapIter,rcSsdHitMapIter> boundsSsd;
1322  pair<rcFtpcHitMapIter,rcFtpcHitMapIter> boundsFtpc;
1323 
1324  rcTpcHitMapIter tpcHMIter;
1325  rcSvtHitMapIter svtHMIter;
1326  rcSsdHitMapIter ssdHMIter;
1327  rcFtpcHitMapIter ftpcHMIter;
1328 
1329  const StMcTpcHit* mcValueTpcHit;
1330  const StMcSvtHit* mcValueSvtHit;
1331  const StMcSsdHit* mcValueSsdHit;
1332  const StMcFtpcHit* mcValueFtpcHit;
1333 
1334  const StMcTrack* trackCand;
1335  StTrackPairInfo* trkPair;
1336 
1337  trackPing initializedTrackPing;
1338  initializedTrackPing.mcTrack = 0;
1339  initializedTrackPing.nPingsTpc = 0;
1340  initializedTrackPing.nPingsSvt = 0;
1341  initializedTrackPing.nPingsSsd = 0;
1342  initializedTrackPing.nPingsFtpc = 0;
1343 
1344 
1345  // Instantiate the Track map
1346  mRcTrackMap = new rcTrackMapType;
1347  mMcTrackMap = new mcTrackMapType;
1348  // Begin making associations
1349  if(Debug()) gMessMgr->Info() << "Making Track Associations..." << endm;
1350 
1351  //
1352  // Loop over tracks nodes in StEvent
1353  //
1354  unsigned int trkNodeI;
1355  for (trkNodeI = 0; trkNodeI < rcTrackNodes.size(); trkNodeI++){
1356 
1357 #ifndef ST_NO_TEMPLATE_DEF_ARGS
1358  vector<trackPing> candidates(20, initializedTrackPing);
1359 #else
1360  vector<trackPing, allocator<trackPing> > candidates(20, initializedTrackPing);
1361 #endif
1362  vector<const StMcTrack*> pingedMcTracks(16, 0);
1363  unsigned int nPingedMcTracks = 0;
1364 
1365  trkNode = rcTrackNodes[trkNodeI]; // For a by-pointer collection we need to dereference once
1366  if (!mEstTracksOn)
1367  rcTrack = dynamic_cast<const StGlobalTrack*>(trkNode->track(global));
1368  else { // Helen wants to keep the old global track from this node
1369  rcTrack = dynamic_cast<const StGlobalTrack*>(trkNode->track(global));
1370  }
1371  if (!rcTrack) continue;
1372 // If there are no Tpc Hits, skip trackif (!rcTrack->detectorInfo()) continue;
1373  if (!(rcTrack->detectorInfo())) {// There is no detectorInfo How it could be
1374 static int mykount=0; mykount++;
1375  Warning("Make","*** %d No detectorInfo, track ignored ***", mykount);
1376  continue;
1377  }
1378  if (!(rcTrack->detectorInfo()->hits().size())) continue;
1379  if (mInTrackerOn && rcTrack->encodedMethod()!=263) continue; //for IT Tracks, skip the old globals
1380  if (!mInTrackerOn && rcTrack->encodedMethod()==263) continue; //for old globals, skip the IT tracks
1381  unsigned int nCandidates = 0;
1382 
1383 
1384 
1385  //
1386  // Loop over the TPC hits of the track
1387  //
1388  if (mRcTpcHitMap) {
1389  StPtrVecHit recTpcHits = rcTrack->detectorInfo()->hits(kTpcId);
1390  unsigned int recTpcHitI;
1391  for (recTpcHitI = 0; recTpcHitI < recTpcHits.size(); recTpcHitI++) {
1392 
1393  rcHit = recTpcHits[recTpcHitI];
1394  rcKeyTpcHit = dynamic_cast<StTpcHit*>(rcHit);
1395 
1396  if (!rcKeyTpcHit) continue;
1397  nPingedMcTracks = 0;
1398  boundsTpc = mRcTpcHitMap->equal_range(rcKeyTpcHit);
1399 
1400  for (tpcHMIter=boundsTpc.first; tpcHMIter!=boundsTpc.second; ++tpcHMIter) {
1401 
1402  mcValueTpcHit = (*tpcHMIter).second;
1403  if (! mcValueTpcHit) continue; // I added 0 for unmatched RcTpcHit
1404  trackCand = mcValueTpcHit->parentTrack();
1405 
1406  // Skip any candidate Monte Carlo Tracks we already counted for this reconstructed hit
1407  // This can happen for Monte Carlo loopers that have multiple hits on the same pad row
1408  bool countedMcTrack = false;
1409  for (unsigned int iMcTrack = 0; iMcTrack<nPingedMcTracks; iMcTrack++) {
1410  if (trackCand == pingedMcTracks[iMcTrack]) {
1411  countedMcTrack = true;
1412  break;
1413  }
1414  }
1415  if (countedMcTrack) continue;
1416  if (nPingedMcTracks>=pingedMcTracks.size()) pingedMcTracks.resize(nPingedMcTracks+16,0);
1417  pingedMcTracks[nPingedMcTracks] = trackCand;
1418  nPingedMcTracks++;
1419 
1420  // At this point we have a candidate Monte Carlo Track
1421  // If there are no candidates, create the first candidate.
1422  // If already there, increment its nPings.
1423  // If doesn't match any of the previous candidates, create new candidate.
1424 
1425  if (nCandidates == 0) {
1426  candidates[0].mcTrack = trackCand;
1427  candidates[0].nPingsTpc = 1;
1428  nCandidates++;
1429 
1430  }
1431 
1432  else {
1433  for (unsigned int iCandidate=0; iCandidate<nCandidates; iCandidate++){
1434  if (trackCand==candidates[iCandidate].mcTrack){
1435  candidates[iCandidate].nPingsTpc++;
1436  break;
1437  }
1438  if (iCandidate == (nCandidates-1)){
1439  candidates[nCandidates].mcTrack = trackCand;
1440  candidates[nCandidates].nPingsTpc = 1;
1441  nCandidates++;
1442  // check that we don't overstep the bounds,
1443  // if so increase the size of the vector in steps of 20 candidates
1444  if (nCandidates>=candidates.size()) {
1445  candidates.resize(nCandidates+20, initializedTrackPing);
1446  if (Debug()) cout << "Resizing in the TPC hits of the track " << endl;
1447  }
1448  break;
1449  }
1450  } // candidate loop
1451 
1452  }
1453  } // mc hits in multimap
1454 
1455  } // Tpc Hits from Track from StEvent loop
1456  }
1457  //
1458  // Loop over the SVT hits of the track
1459  //
1460  if (mRcSvtHitMap) {
1461  StPtrVecHit recSvtHits = rcTrack->detectorInfo()->hits(kSvtId);
1462  unsigned int recSvtHitI;
1463  for (recSvtHitI = 0; recSvtHitI < recSvtHits.size(); recSvtHitI++) {
1464  // Loop over the SVT hits of the track
1465 
1466  rcHit = recSvtHits[recSvtHitI];
1467  rcKeySvtHit = dynamic_cast<StSvtHit*>(rcHit);
1468 
1469  if (!rcKeySvtHit) continue;
1470  nPingedMcTracks = 0;
1471  boundsSvt = mRcSvtHitMap->equal_range(rcKeySvtHit);
1472 
1473  for (svtHMIter=boundsSvt.first; svtHMIter!=boundsSvt.second; ++svtHMIter) {
1474 
1475  mcValueSvtHit = (*svtHMIter).second;
1476  trackCand = mcValueSvtHit->parentTrack();
1477 
1478  // Skip any candidate Monte Carlo Tracks we already counted for this reconstructed hit
1479  // This can happen for Monte Carlo loopers that have multiple hits on the same pad row
1480  bool countedMcTrack = false;
1481  for (unsigned int iMcTrack = 0; iMcTrack<nPingedMcTracks; iMcTrack++) {
1482  if (trackCand == pingedMcTracks[iMcTrack]) {
1483  countedMcTrack = true;
1484  break;
1485  }
1486  }
1487  if (countedMcTrack) continue;
1488  if (nPingedMcTracks>=pingedMcTracks.size()) pingedMcTracks.resize(nPingedMcTracks+16,0);
1489  pingedMcTracks[nPingedMcTracks] = trackCand;
1490  nPingedMcTracks++;
1491 
1492  // At this point we have a candidate Monte Carlo Track
1493  // If there are no candidates, create the first candidate.
1494  // If already there, increment its nPings.
1495  // If doesn't match any of the previous candidates, create new candidate.
1496 
1497  if (nCandidates == 0) {
1498  candidates[0].mcTrack = trackCand;
1499  candidates[0].nPingsSvt = 1;
1500  nCandidates++;
1501 
1502  }
1503 
1504  else {
1505  for (unsigned int iCandidate=0; iCandidate<nCandidates; iCandidate++){
1506  if (trackCand==candidates[iCandidate].mcTrack){
1507  candidates[iCandidate].nPingsSvt++;
1508  break;
1509  }
1510  if (iCandidate == (nCandidates-1)){
1511  candidates[nCandidates].mcTrack = trackCand;
1512  candidates[nCandidates].nPingsSvt = 1;
1513  nCandidates++;
1514  // check that we don't overstep the bounds,
1515  // if so increase the size of the vector in steps of 20 candidates
1516  if (nCandidates>=candidates.size()) {
1517  candidates.resize(nCandidates+20, initializedTrackPing);
1518  if (Debug()) cout << "Resizing in the SVT hits of the track " << endl;
1519  }
1520  break;
1521  }
1522  } // candidate loop
1523 
1524  }
1525  } // mc hits in multimap
1526 
1527  } // Svt Hits from Track from StEvent loop
1528  }
1529  //
1530  // Loop over the SSD hits of the track
1531  //
1532  if (mRcSsdHitMap) {
1533  StPtrVecHit recSsdHits = rcTrack->detectorInfo()->hits(kSsdId);
1534  unsigned int recSsdHitI;
1535  for (recSsdHitI = 0; recSsdHitI < recSsdHits.size(); recSsdHitI++) {
1536  // Loop over the SSD hits of the track
1537 
1538  rcHit = recSsdHits[recSsdHitI];
1539  rcKeySsdHit = dynamic_cast<StSsdHit*>(rcHit);
1540 
1541  if (!rcKeySsdHit) continue;
1542  nPingedMcTracks = 0;
1543  boundsSsd = mRcSsdHitMap->equal_range(rcKeySsdHit);
1544 
1545  for (ssdHMIter=boundsSsd.first; ssdHMIter!=boundsSsd.second; ++ssdHMIter) {
1546 
1547  mcValueSsdHit = (*ssdHMIter).second;
1548  trackCand = mcValueSsdHit->parentTrack();
1549 
1550  // Skip any candidate Monte Carlo Tracks we already counted for this reconstructed hit
1551  // This can happen for Monte Carlo loopers that have multiple hits on the same pad row
1552  bool countedMcTrack = false;
1553  for (unsigned int iMcTrack = 0; iMcTrack<nPingedMcTracks; iMcTrack++) {
1554  if (trackCand == pingedMcTracks[iMcTrack]) {
1555  countedMcTrack = true;
1556  break;
1557  }
1558  }
1559  if (countedMcTrack) continue;
1560  if (nPingedMcTracks>=pingedMcTracks.size()) pingedMcTracks.resize(nPingedMcTracks+16,0);
1561  pingedMcTracks[nPingedMcTracks] = trackCand;
1562  nPingedMcTracks++;
1563 
1564  // At this point we have a candidate Monte Carlo Track
1565  // If there are no candidates, create the first candidate.
1566  // If already there, increment its nPings.
1567  // If doesn't match any of the previous candidates, create new candidate.
1568 
1569  if (nCandidates == 0) {
1570  candidates[0].mcTrack = trackCand;
1571  candidates[0].nPingsSsd = 1;
1572  nCandidates++;
1573 
1574  }
1575 
1576  else {
1577  for (unsigned int iCandidate=0; iCandidate<nCandidates; iCandidate++){
1578  if (trackCand==candidates[iCandidate].mcTrack){
1579  candidates[iCandidate].nPingsSsd++;
1580  break;
1581  }
1582  if (iCandidate == (nCandidates-1)){
1583  candidates[nCandidates].mcTrack = trackCand;
1584  candidates[nCandidates].nPingsSsd = 1;
1585  nCandidates++;
1586  // check that we don't overstep the bounds,
1587  // if so increase the size of the vector in steps of 20 candidates
1588  if (nCandidates>=candidates.size()) {
1589  candidates.resize(nCandidates+20, initializedTrackPing);
1590  if (Debug()) cout << "Resizing in the SSD hits of the track " << endl;
1591  }
1592  break;
1593  }
1594  } // candidate loop
1595 
1596  }
1597  } // mc hits in multimap
1598 
1599  } // Ssd Hits from Track from StEvent loop
1600  }
1601  //
1602  // Loop over the FTPC hits of the track. Note that there are 2 loops,
1603  // one for the West and one for the East FTPC, but probably if there are hits in one
1604  // there won't be in the other one.
1605  //
1606 
1607  if (mRcFtpcHitMap) {
1608  StPtrVecHit recFtpcHitsW = rcTrack->detectorInfo()->hits(kFtpcWestId);
1609  StPtrVecHit recFtpcHitsE = rcTrack->detectorInfo()->hits(kFtpcEastId);
1610  unsigned int recFtpcHitI;
1611 
1612  // Loop over the West FTPC hits of the track
1613  for (recFtpcHitI = 0; recFtpcHitI < recFtpcHitsW.size(); recFtpcHitI++) {
1614 
1615  rcHit = recFtpcHitsW[recFtpcHitI];
1616  rcKeyFtpcHit = dynamic_cast<StFtpcHit*>(rcHit);
1617 
1618  if (!rcKeyFtpcHit) continue;
1619  nPingedMcTracks = 0;
1620  boundsFtpc = mRcFtpcHitMap->equal_range(rcKeyFtpcHit);
1621 
1622  for (ftpcHMIter=boundsFtpc.first; ftpcHMIter!=boundsFtpc.second; ++ftpcHMIter) {
1623 
1624  mcValueFtpcHit = (*ftpcHMIter).second;
1625  trackCand = mcValueFtpcHit->parentTrack();
1626 
1627  // Skip any candidate Monte Carlo Tracks we already counted for this reconstructed hit
1628  // This can happen for Monte Carlo loopers that have multiple hits on the same pad row
1629  bool countedMcTrack = false;
1630  for (unsigned int iMcTrack = 0; iMcTrack<nPingedMcTracks; iMcTrack++) {
1631  if (trackCand == pingedMcTracks[iMcTrack]) {
1632  countedMcTrack = true;
1633  break;
1634  }
1635  }
1636  if (countedMcTrack) continue;
1637  if (nPingedMcTracks>=pingedMcTracks.size()) pingedMcTracks.resize(nPingedMcTracks+16,0);
1638  pingedMcTracks[nPingedMcTracks] = trackCand;
1639  nPingedMcTracks++;
1640 
1641  // At this point we have a candidate Monte Carlo Track
1642  // If there are no candidates, create the first candidate.
1643  // If already there, increment its nPings.
1644  // If doesn't match any of the previous candidates, create new candidate.
1645 
1646  if (nCandidates == 0) {
1647  candidates[0].mcTrack = trackCand;
1648  candidates[0].nPingsFtpc = 1;
1649  nCandidates++;
1650 
1651  }
1652 
1653  else {
1654  for (unsigned int iCandidate=0; iCandidate<nCandidates; iCandidate++){
1655  if (trackCand==candidates[iCandidate].mcTrack){
1656  candidates[iCandidate].nPingsFtpc++;
1657  break;
1658  }
1659  if (iCandidate == (nCandidates-1)){
1660  candidates[nCandidates].mcTrack = trackCand;
1661  candidates[nCandidates].nPingsFtpc = 1;
1662  nCandidates++;
1663  // check that we don't overstep the bounds,
1664  // if so increase the size of the vector in steps of 20 candidates
1665  if (nCandidates>=candidates.size()) {
1666  candidates.resize(nCandidates+20, initializedTrackPing);
1667  if (Debug()) cout << "Resizing in the East FTPC hits of the track " << endl;
1668  }
1669  break;
1670  }
1671  } // candidate loop
1672 
1673  }
1674  } // mc ftpc hits in multimap
1675 
1676  } // West Ftpc Hits from Track from StEvent loop
1677 
1678  // Loop over the East FTPC hits of the track
1679  for (recFtpcHitI = 0; recFtpcHitI < recFtpcHitsE.size(); recFtpcHitI++) {
1680 
1681 
1682  rcHit = recFtpcHitsE[recFtpcHitI];
1683  rcKeyFtpcHit = dynamic_cast<StFtpcHit*>(rcHit);
1684 
1685  if (!rcKeyFtpcHit) continue;
1686  nPingedMcTracks = 0;
1687  boundsFtpc = mRcFtpcHitMap->equal_range(rcKeyFtpcHit);
1688 
1689  for (ftpcHMIter=boundsFtpc.first; ftpcHMIter!=boundsFtpc.second; ++ftpcHMIter) {
1690 
1691  mcValueFtpcHit = (*ftpcHMIter).second;
1692  trackCand = mcValueFtpcHit->parentTrack();
1693 
1694  // Skip any candidate Monte Carlo Tracks we already counted for this reconstructed hit
1695  // This can happen for Monte Carlo loopers that have multiple hits on the same pad row
1696  bool countedMcTrack = false;
1697  for (unsigned int iMcTrack = 0; iMcTrack<nPingedMcTracks; iMcTrack++) {
1698  if (trackCand == pingedMcTracks[iMcTrack]) {
1699  countedMcTrack = true;
1700  break;
1701  }
1702  }
1703  if (countedMcTrack) continue;
1704  if (nPingedMcTracks>=pingedMcTracks.size()) pingedMcTracks.resize(nPingedMcTracks+16,0);
1705  pingedMcTracks[nPingedMcTracks] = trackCand;
1706  nPingedMcTracks++;
1707 
1708  // At this point we have a candidate Monte Carlo Track
1709  // If there are no candidates, create the first candidate.
1710  // If already there, increment its nPings.
1711  // If doesn't match any of the previous candidates, create new candidate.
1712 
1713  if (nCandidates == 0) {
1714  candidates[0].mcTrack = trackCand;
1715  candidates[0].nPingsFtpc = 1;
1716  nCandidates++;
1717 
1718  }
1719 
1720  else {
1721  for (unsigned int iCandidate=0; iCandidate<nCandidates; iCandidate++){
1722  if (trackCand==candidates[iCandidate].mcTrack){
1723  candidates[iCandidate].nPingsFtpc++;
1724  break;
1725  }
1726  if (iCandidate == (nCandidates-1)){
1727  candidates[nCandidates].mcTrack = trackCand;
1728  candidates[nCandidates].nPingsFtpc = 1;
1729  nCandidates++;
1730  // check that we don't overstep the bounds,
1731  // if so increase the size of the vector in steps of 20 candidates
1732  if (nCandidates>=candidates.size()) {
1733  candidates.resize(nCandidates+20, initializedTrackPing);
1734  if (Debug()) cout << "Resizing in the West FTPC hits of the track " << endl;
1735  }
1736  break;
1737  }
1738  } // candidate loop
1739 
1740  }
1741  } // mc hits in multimap
1742 
1743  } // Ftpc Hits from Track from StEvent loop
1744  }
1745  //
1746  // Now we need to associate the tracks that meet the commonHits criteria.
1747  //
1748 
1749  if (nCandidates>20 || candidates.size()>20)
1750  cout << "We Have " << candidates.size() << " candidates!!! " << endl;
1751  if (candidates.size()<nCandidates) {
1752  cout << "The candidate track vector has grown more than expected!! " << endl;
1753  cout << "Something is wrong! We probably went out-of-bounds! " << endl;
1754  }
1755  for (unsigned int iCandidate=0; iCandidate<nCandidates; iCandidate++){
1756  //mNumberOfPings->Fill((float) candidates[iCandidate].nPings);
1757 
1758 
1759  if (candidates[iCandidate].nPingsTpc >= parDB->reqCommonHitsTpc() ||
1760  candidates[iCandidate].nPingsSvt >= parDB->reqCommonHitsSvt() ||
1761  candidates[iCandidate].nPingsSsd >= parDB->reqCommonHitsSsd() ||
1762  candidates[iCandidate].nPingsFtpc >= parDB->reqCommonHitsFtpc()){
1763  // We got a track pair !!
1764  // Add it to multimap
1765 
1766  trkPair = new StTrackPairInfo(rcTrack,
1767  candidates[iCandidate].mcTrack,
1768  candidates[iCandidate].nPingsTpc,
1769  candidates[iCandidate].nPingsSvt,
1770  candidates[iCandidate].nPingsSsd,
1771  candidates[iCandidate].nPingsFtpc);
1772  mRcTrackMap->insert(rcTrackMapValType (rcTrack, trkPair));
1773  mMcTrackMap->insert(mcTrackMapValType (candidates[iCandidate].mcTrack, trkPair));
1774 
1775  }
1776  }
1777 
1778  // Clear the candidate vector
1779  candidates.clear();
1780 
1781  }// StEvent track loop
1782  // print out the map
1783  if (Debug() > 1) {
1784  cout << "The RcTrack map is now" << endl << *mRcTrackMap << endl;
1785  cout << "The McTrack map is now" << endl << *mMcTrackMap << endl;
1786  }
1787 
1788  if(Debug()){
1789  gMessMgr->Info() << "Number of Entries in Track Maps: " << mRcTrackMap->size() << endm;
1790  }
1791  if (doPrintMemoryInfo) {
1792  cout << "End of Track Associations\n";
1793  StMemoryInfo::instance()->snapshot();
1794  StMemoryInfo::instance()->print();
1795  }
1796 
1797  //
1798  // Start doing Vertex Associations ----------------------
1799  //
1800  if (!mL3TriggerOn) {
1801  // Instantiate the Vertex maps
1802  mRcKinkMap = new rcKinkMapType;
1803  mMcKinkMap = new mcKinkMapType;
1804  mRcV0Map = new rcV0MapType;
1805  mMcV0Map = new mcV0MapType;
1806  mRcXiMap = new rcXiMapType;
1807  mMcXiMap = new mcXiMapType;
1808  // Begin making associations
1809  if(Debug()) gMessMgr->Info() << "Making Vertex Associations" << endm;
1810 
1811  StSPtrVecKinkVertex& kinks = rEvent->kinkVertices();
1812 
1813 
1814  if(Debug()) gMessMgr->Info() << "Kinks..." << endm;
1815 
1816  // Loop over Kinks
1817 
1818  pair<rcTrackMapIter, rcTrackMapIter> kinkBoundsDaughter, kinkBoundsParent;
1819 
1820  const StMcVertex* primary = mEvent->primaryVertex();
1821  for (StKinkVertexIterator kvi = kinks.begin(); kvi!=kinks.end(); kvi++) {
1822 
1823  StKinkVertex* rcKink = *kvi; // Got Kink ...
1824  StTrack* kinkDaughter = rcKink->daughter(0);
1825  const StGlobalTrack* gKinkDaughter = dynamic_cast<const StGlobalTrack*>(kinkDaughter);
1826  if (!gKinkDaughter) continue;
1827  // Got Daughter
1828  StTrack* kinkParent = rcKink->parent();
1829  const StGlobalTrack* gKinkParent = dynamic_cast<const StGlobalTrack*>(kinkParent);
1830  if (!gKinkParent) continue;
1831  // Got Parent
1832 
1833  kinkBoundsDaughter = mRcTrackMap->equal_range(gKinkDaughter);
1834  // Loop over associated tracks of the daughter
1835  for (rcTrackMapIter trkIter = kinkBoundsDaughter.first; trkIter!=kinkBoundsDaughter.second; trkIter++) {
1836  const StMcTrack* mcDaughter = (*trkIter).second->partnerMcTrack(); // Get associated daughter
1837 
1838  const StMcVertex* mcKink = mcDaughter->startVertex(); // Get Kink candidate
1839  if (mcKink == primary || mcKink == 0) continue; // Check that it's not primary
1840  const StMcTrack* mcParent = mcKink->parent();
1841 
1842  // Check that parents match
1843  kinkBoundsParent = mRcTrackMap->equal_range(gKinkParent);
1844  // loop over associated tracks of the parent
1845  for (rcTrackMapIter trkIter2 = kinkBoundsParent.first;
1846  trkIter2!=kinkBoundsParent.second; trkIter2++) {
1847  // Get associated parent
1848  if (mcParent == (*trkIter2).second->partnerMcTrack() ) {
1849 
1850  // Got a candidate!!
1851  mRcKinkMap->insert(rcKinkMapValType (rcKink, mcKink));
1852  mMcKinkMap->insert(mcKinkMapValType (mcKink, rcKink));
1853  }
1854  }
1855 
1856  }
1857  } // kink loop
1858  if(Debug()){
1859  gMessMgr->Info() << "Number of Entries in kink Maps: " << mRcKinkMap->size() << endm;
1860  }
1861  if (doPrintMemoryInfo) {
1862  cout << "End of kink Associations\n";
1863  StMemoryInfo::instance()->snapshot();
1864  StMemoryInfo::instance()->print();
1865  }
1866 
1867  if(Debug()) gMessMgr->Info() << "V0s..." << endm;
1868 
1869  StSPtrVecV0Vertex& v0s = rEvent->v0Vertices();
1870 
1871  // Loop over V0s
1872  for (StV0VertexIterator v0vi = v0s.begin(); v0vi!=v0s.end(); v0vi++) {
1873  StV0Vertex* rcV0 = *v0vi; // Got V0 ...
1874  StTrack* v0Daughter1 = rcV0->daughter(0);
1875  if (mEstTracksOn && rcV0->chiSquared()==-16) continue; //when Est runs, the X^2 is always -24 or less
1876  if (!mEstTracksOn && rcV0->chiSquared()<-16) continue; //when Est didn't run it's ALWAYS -16.
1877  const StGlobalTrack* gV0Daughter1 = dynamic_cast<const StGlobalTrack*>(v0Daughter1);
1878  if (!gV0Daughter1) continue;
1879  // Got Daughter1
1880  StTrack* v0Daughter2 = rcV0->daughter(1);
1881  const StGlobalTrack* gV0Daughter2 = dynamic_cast<const StGlobalTrack*>(v0Daughter2);
1882  if (!gV0Daughter2) continue;
1883  // Got Daughter2
1884  pair<rcTrackMapIter, rcTrackMapIter> v0Bounds1 = mRcTrackMap->equal_range(gV0Daughter1);
1885  pair<rcTrackMapIter, rcTrackMapIter> v0Bounds2 = mRcTrackMap->equal_range(gV0Daughter2);
1886  for (rcTrackMapIter trkIter1 = v0Bounds1.first; trkIter1!=v0Bounds1.second; trkIter1++) {
1887  const StMcTrack* mcDaughter1 = (*trkIter1).second->partnerMcTrack();
1888  for (rcTrackMapIter trkIter2 = v0Bounds2.first; trkIter2!=v0Bounds2.second; trkIter2++) {
1889  const StMcTrack* mcDaughter2 = (*trkIter2).second->partnerMcTrack();
1890  if (mcDaughter1->startVertex() == mcDaughter2->startVertex() &&
1891  mcDaughter1->startVertex() != primary &&
1892  mcDaughter1->startVertex() != 0) {
1893  // Got a V0 candidate
1894  mRcV0Map->insert(rcV0MapValType (rcV0, mcDaughter1->startVertex()));
1895  mMcV0Map->insert(mcV0MapValType (mcDaughter1->startVertex(), rcV0));
1896 
1897  }
1898  }
1899  }
1900 
1901  } // V0 loop
1902  if(Debug()) {
1903  gMessMgr->Info() << "Number of Entries in V0 Maps: " << mRcV0Map->size() << endm;
1904  }
1905  if (doPrintMemoryInfo) {
1906  cout << "End of V0 Associations\n";
1907  StMemoryInfo::instance()->snapshot();
1908  StMemoryInfo::instance()->print();
1909  }
1910 
1911  if(Debug()) gMessMgr->Info() << "Xis..." << endm;
1912 
1913  StSPtrVecXiVertex& xis = rEvent->xiVertices();
1914 
1915  // Loop over Xis
1916  for (StXiVertexIterator xvi = xis.begin(); xvi!=xis.end(); xvi++) {
1917  StXiVertex* rcXi = *xvi;
1918  if (mEstTracksOn && rcXi->chiSquared()==-16) continue; //when Est runs, the X^2 is always -24 or less
1919  if (!mEstTracksOn && rcXi->chiSquared()<-16) continue; //when Est didn't run it's ALWAYS -16.
1920  StV0Vertex* rcV0ofXi = rcXi->v0Vertex();
1921  StTrack* rcBachelor = rcXi->bachelor();
1922  const StGlobalTrack* gRcBachelor = dynamic_cast<const StGlobalTrack*>(rcBachelor);
1923  if (!gRcBachelor) continue;
1924  pair<rcTrackMapIter, rcTrackMapIter> xiBounds = mRcTrackMap->equal_range(gRcBachelor);
1925  for (rcTrackMapIter trkIter3 = xiBounds.first; trkIter3!= xiBounds.second; trkIter3++){
1926  const StMcTrack* mcBachelor = (*trkIter3).second->partnerMcTrack();
1927  const StMcVertex* mcXi = mcBachelor->startVertex();
1928  if (mcXi == primary || mcXi == 0) continue;
1929  pair<rcV0MapIter, rcV0MapIter> xiBoundsV0 = mRcV0Map->equal_range(rcV0ofXi);
1930  for (rcV0MapIter v0Iter = xiBoundsV0.first; v0Iter!= xiBoundsV0.second; v0Iter++){
1931  const StMcVertex* mcV0 = (*v0Iter).second;
1932  if (mcV0->parent() != 0 && mcXi == mcV0->parent()->startVertex()) {
1933  // Got a Xi candidate
1934  mRcXiMap->insert(rcXiMapValType (rcXi, mcXi));
1935  mMcXiMap->insert(mcXiMapValType (mcXi, rcXi));
1936 
1937  }
1938  }
1939  }
1940  }
1941  if(Debug()) {
1942  gMessMgr->Info() << "Number of Entries in Xi Maps: " << mRcXiMap->size() << endm;
1943  }
1944 
1945  }
1946  if (doPrintMemoryInfo) {
1947  cout << "End of Make()\n";
1948  StMemoryInfo::instance()->snapshot();
1949  StMemoryInfo::instance()->print();
1950  }
1951  return kStOK;
1952 }
Definition: StHit.h:125
TH2F * mSsdHitResolution
Diff btw global x and z coords of SVT hits.
virtual void Clear(Option_t *option="")
User defined functions.
Definition: StMaker.cxx:634
TH2F * mFtpcHitResolution
Diff btw global x and z coords of SSD hits.
Monte Carlo Track class All information on a simulated track is stored in this class: kinematics...
Definition: StMcTrack.hh:144
Definition: Stypes.h:42
Definition: Stypes.h:40
virtual Int_t Finish()
Definition: StMaker.cxx:776
Event data structure to hold all information from a Monte Carlo simulation. This class is the interfa...
Definition: StMcEvent.hh:169
TH2F * mSvtHitResolution
Diff btw local x and z coords of TPC hits.