StRoot  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
StTrackTopologyMap.cxx
1 /***************************************************************************
2  *
3  * $Id: StTrackTopologyMap.cxx,v 2.22 2019/03/04 17:02:16 ullrich Exp $
4  *
5  * Author: Thomas Ullrich, Aug 1999
6  ***************************************************************************
7  *
8  * Description:
9  *
10  * The topo map is stored in two 32 bit words.
11  * Cases: Depending on the context the bits have slightly
12  * different meaning. For FTPC tracks bit 1-20 describe
13  * the FTPC. There's no confusion with the TPC since
14  * there are only tracks in either one. Starting 2007
15  * the 6 layers of the SVT are re-used for the HFT.
16  *
17  * With the introduction of the iTPC things get a bit
18  * more complex, especially for 2018 where the old inner
19  * TPC has to coexist with one iTPC sector. A new 64
20  * bit word has been added to keep this additional info
21  * (if present). The iTPC is treated as a separate detector
22  * with one exceptions:
23  * trackTpcOnly(): does take kTpcId and kiTpcId into account.
24  * Note also, that largestGap() is not valid when called for
25  * kTpcId when the iTPC has hits. In 2018 tracks can have hits
26  * in old inner TPC and iTPC.
27  *
28  * bit Case 1 Case 2 Case 3 Addendum
29  *--------------------------------------------------------------------------
30  * 0 primary-vertex-used
31  * 1 SVT layer=1 FTPC-West row=1 PXL layer=1 iTPC row=1
32  * 2 SVT layer=2 FTPC-West row=2 PXL layer=2 iTPC row=2
33  * 3 SVT layer=3 FTPC-West row=3 PXL layer=3 iTPC row=3
34  * 4 SVT layer=4 FTPC-West row=4 IST layer=1 iTPC row=4
35  * 5 SVT layer=5 FTPC-West row=5 IST layer=2 iTPC row=5
36  * 6 SVT layer=6 FTPC-West row=6 SSD layer=1 iTPC row=6
37  * 7 SSD FTPC-West row=7 SSD layer=2 iTPC row=7
38  * 8 TPC row=1 FTPC-West row=8 iTPC row=8
39  * 9 TPC row=2 FTPC-West row=9 iTPC row=9
40  * 10 TPC row=3 FTPC-West row=10 iTPC row=10
41  * 11 TPC row=4 FTPC-East row=1 iTPC row=11
42  * 12 TPC row=5 FTPC-East row=2 iTPC row=12
43  * 13 TPC row=6 FTPC-East row=3 iTPC row=13
44  * 14 TPC row=7 FTPC-East row=4 iTPC row=14
45  * 15 TPC row=8 FTPC-East row=5 iTPC row=15
46  * 16 TPC row=9 FTPC-East row=6 iTPC row=16
47  * 17 TPC row=10 FTPC-East row=7 iTPC row=17
48  * 18 TPC row=11 FTPC-East row=8 iTPC row=18
49  * 19 TPC row=12 FTPC-East row=9 iTPC row=19
50  * 20 TPC row=13 FTPC-East row=10 iTPC row=20
51  * --------> inner/outer TPC
52  * 21 TPC row=14 iTPC row=21
53  * 22 TPC row=15 iTPC row=22
54  * 23 TPC row=16 iTPC row=23
55  * 24 TPC row=17 iTPC row=24
56  * 25 TPC row=18 iTPC row=25
57  * 26 TPC row=19 iTPC row=26
58  * 27 TPC row=20 iTPC row=27
59  * 28 TPC row=21 iTPC row=28
60  * 29 TPC row=22 iTPC row=29
61  * 30 TPC row=23 iTPC row=30
62  * 31 TPC row=24 iTPC row=31
63  * -------------------------- word boundary
64  * 32 0 TPC row=25 iTPC row=32
65  * 33 1 TPC row=26 iTPC row=33
66  * 34 2 TPC row=27 iTPC row=34
67  * 35 3 TPC row=28 iTPC row=35
68  * 36 4 TPC row=29 iTPC row=36
69  * 37 5 TPC row=30 iTPC row=37
70  * 38 6 TPC row=31 iTPC row=38
71  * 39 7 TPC row=32 iTPC row=39
72  * 40 8 TPC row=33 iTPC row=40
73  * 41 9 TPC row=34
74  * 42 10 TPC row=35
75  * 43 11 TPC row=36
76  * 44 12 TPC row=37
77  * 45 13 TPC row=38
78  * 46 14 TPC row=39
79  * 47 15 TPC row=40
80  * 48 16 TPC row=41
81  * 49 17 TPC row=42
82  * 50 18 TPC row=43
83  * 51 19 TPC row=44
84  * 52 20 TPC row=45
85  * 53 21 Mwpc
86  * 54 22 CTB
87  * 55 23 ToF
88  * 56 24 RICH
89  * 57 25 Barrel EMC/SMD
90  * 58 26 Endcap EMC/SMD
91  * 59 27
92  * 60 28
93  * 61 29 HFT Format (case 3) - TPC tracks
94  * 62 30 turn around flag (flags that track spirals back)
95  * 63 31 FTPC Format (flags TOC or FTPC)
96  *
97  ***************************************************************************
98  *
99  * $Log: StTrackTopologyMap.cxx,v $
100  * Revision 2.22 2019/03/04 17:02:16 ullrich
101  * Modified iTpcBit() to simplify querying the topology map for hits in the outer sectors
102  *
103  * Revision 2.21 2018/03/27 02:41:00 genevb
104  * iTPC modifications, plus proper use of booleans
105  *
106  * Revision 2.20 2016/02/24 18:51:09 ullrich
107  * Made kSsd and kSst equivalent in numberOfHits()
108  *
109  * Revision 2.19 2014/03/18 13:23:04 fisyak
110  * Xin\'s fix for Ssd numberOfHits with hftFormat
111  *
112  * Revision 2.18 2014/03/16 16:06:24 fisyak
113  * Xin\'s fix for HFT
114  *
115  * Revision 2.17 2007/11/07 00:54:54 ullrich
116  * Added PXL and IST.
117  *
118  * Revision 2.16 2005/06/23 19:04:24 ullrich
119  * Added overloaded version of hasHitInDetector() taking up to 6 args.
120  *
121  * Revision 2.15 2004/08/11 05:21:22 genevb
122  * tpcOnly excludes SSD
123  *
124  * Revision 2.14 2002/03/18 17:11:31 jeromel
125  * Typo found by Jamie while testing P02gd. Corrected.
126  *
127  * Revision 2.13 2001/05/10 19:12:15 genevb
128  * Switch FTPC definitions
129  *
130  * Revision 2.12 2001/04/24 21:32:07 genevb
131  * Additional helper functions
132  *
133  * Revision 2.11 2001/04/05 04:00:58 ullrich
134  * Replaced all (U)Long_t by (U)Int_t and all redundant ROOT typedefs.
135  *
136  * Revision 2.10 2000/12/08 20:21:08 genevb
137  * Changed kTofPatchId -> kTofId
138  *
139  * Revision 2.9 2000/07/28 19:49:28 akio
140  * Change in Detector Id for Endcap SMD
141  *
142  * Revision 2.8 2000/05/17 17:21:34 ullrich
143  * New method largestGap() and new output operator.
144  *
145  * Revision 2.7 2000/04/12 19:44:03 genevb
146  * Reimplement mMap data members as individual unsigned ints
147  *
148  * Revision 2.6 2000/04/10 19:59:33 genevb
149  * StRoot/StEvent/doc/tex/
150  *
151  * Revision 2.5 2000/03/29 00:16:30 ullrich
152  * Fixed off-by-one error.
153  *
154  * Revision 2.4 2000/01/07 18:20:34 ullrich
155  * Buf fixed. Wrong indices for mMap in bit().
156  *
157  * Revision 2.3 1999/12/13 20:16:36 ullrich
158  * Changed numbering scheme for hw_position unpack methods (STAR conventions).
159  *
160  * Revision 2.2 1999/10/28 22:27:55 ullrich
161  * Adapted new StArray version. First version to compile on Linux and Sun.
162  *
163  * Revision 2.1 1999/10/13 19:45:46 ullrich
164  * Initial Revision
165  *
166  **************************************************************************/
167 #include "StTrackTopologyMap.h"
168 #include "StMessMgr.h"
169 #include <vector>
170 #include <algorithm>
171 #include <numeric>
172 
173 #if !defined(ST_NO_NAMESPACES)
174 using std::vector;
175 using std::adjacent_difference;
176 using std::max_element;
177 #endif
178 
179 static const char rcsid[] = "$Id: StTrackTopologyMap.cxx,v 2.22 2019/03/04 17:02:16 ullrich Exp $";
180 
181 ClassImp(StTrackTopologyMap)
182 
184 {
185  mMap0 = mMap1 = 0;
186  mMap_iTpc = 0;
187 }
188 
189 StTrackTopologyMap::StTrackTopologyMap(unsigned int m1,
190  unsigned int m2,
191  unsigned long long m3)
192 : mMap0(m1), mMap1(m2), mMap_iTpc(m3)
193 { /* noop */ }
194 
195 StTrackTopologyMap::StTrackTopologyMap(const unsigned int* m,
196  unsigned long long k)
197 : mMap0(m[0]), mMap1(m[1]), mMap_iTpc(k)
198 { /* noop */ }
199 
200 StTrackTopologyMap::StTrackTopologyMap(const unsigned long* m,
201  unsigned long long k)
202 : mMap0(m[0]), mMap1(m[1]), mMap_iTpc(k)
203 { /* noop */ }
204 
205 StTrackTopologyMap::~StTrackTopologyMap() { /* noop */ }
206 
207 bool
208 StTrackTopologyMap::bit(int i) const
209 {
210  return i>31 ? (mMap1>>(i-32) & 1U) : (mMap0>>i & 1U);
211 }
212 
213 bool
214 StTrackTopologyMap::iTpcBit(int i) const
215 {
216  return (i < 41 ? (mMap_iTpc>>i & 1ULL) : bit(i-20));
217 }
218 
219 bool
220 StTrackTopologyMap::ftpcFormat() const
221 {
222  return bit(63);
223 }
224 
225 bool
226 StTrackTopologyMap::hftFormat() const
227 {
228  return bit(61);
229 }
230 
231 unsigned long long
232 StTrackTopologyMap::data(unsigned int i) const
233 {
234  unsigned long long theData = 0;
235  switch (i) {
236  case 0:
237  theData = static_cast<unsigned long long>(mMap0);
238  break;
239  case 1:
240  theData = static_cast<unsigned long long>(mMap1);
241  break;
242  case 2:
243  theData = mMap_iTpc;
244  break;
245  default:
246  break;
247  }
248  return theData;
249 }
250 
251 bool
252 StTrackTopologyMap::primaryVertexUsed() const { return bit(0); }
253 
254 bool
255 StTrackTopologyMap::turnAroundFlag() const { return bit(62); }
256 
257 bool
258 StTrackTopologyMap::hasHitInDetector(StDetectorId id) const
259 {
260  return ((numberOfHits(id)) ? true : false);
261 }
262 
263 
264 bool
265 StTrackTopologyMap::hasHitInDetector(StDetectorId d1, StDetectorId d2,
266  StDetectorId d3, StDetectorId d4,
267  StDetectorId d5, StDetectorId d6) const
268 {
269  //
270  // Note d3 - d6 are optional, if not given they will have
271  // the value kUnknownId and shouldn't be used.
272  //
273  return (hasHitInDetector(d1) && hasHitInDetector(d2) &&
274  (d3 == kUnknownId ? true : hasHitInDetector(d3)) &&
275  (d4 == kUnknownId ? true : hasHitInDetector(d4)) &&
276  (d5 == kUnknownId ? true : hasHitInDetector(d5)) &&
277  (d6 == kUnknownId ? true : hasHitInDetector(d6)));
278 }
279 
280 bool
281 StTrackTopologyMap::hasHitInSvtLayer(unsigned int layer) const
282 {
283  if (ftpcFormat())
284  return false;
285  else
286  return bit(layer);
287 }
288 
289 bool
290 StTrackTopologyMap::hasHitInPxlLayer(unsigned int layer) const
291 {
292  if(ftpcFormat())
293  return false;
294  else
295  return bit(layer);
296 }
297 
298 bool
299 StTrackTopologyMap::hasHitInIstLayer(unsigned int layer) const
300 {
301  if(ftpcFormat())
302  return false;
303  else
304 // return bit(layer+2);
305  return bit(layer+3);
306 }
307 
308 bool
309 StTrackTopologyMap::hasHitInSsdLayer(unsigned int layer) const
310 {
311  if(ftpcFormat())
312  return false;
313  else {
314  if(hftFormat())
315  return bit(layer+5);
316  else
317  return bit(layer+6);
318  }
319 }
320 
321 bool
322 StTrackTopologyMap::hasHitInRow(StDetectorId id, unsigned int row) const
323 {
324  switch (id) {
325  case kTpcId:
326  return !ftpcFormat() && bit(row+7);
327  break;
328  case kFtpcWestId:
329  return ftpcFormat() && bit(row);
330  break;
331  case kFtpcEastId:
332  return ftpcFormat() && bit(row+10);
333  break;
334  case kiTpcId:
335  return !ftpcFormat() && iTpcBit(row);
336  break;
337  default:
338  return false;
339  break;
340  }
341 }
342 
343 unsigned int
344 StTrackTopologyMap::numberOfHits(StDetectorId id) const
345 {
346  if (ftpcFormat() &&
347  !(id == kFtpcWestId || id == kFtpcEastId))
348  return 0;
349 
350  int i;
351  int n = 0;
352 
353  switch (id) {
354  case kSvtId:
355  for (i=1; i<7; i++)
356  if (hasHitInSvtLayer(i)) n++;
357  break;
358  case kSstId:
359  case kSsdId:
360  if(! hftFormat()) {
361  if (bit(7)) n++;
362  } else {
363  for(int i=1;i<=2;i++) {
364  if (hasHitInSsdLayer(i)) n++;
365  }
366  }
367  break;
368  case kPxlId:
369  for(i=1;i<=3;i++)
370  if(hasHitInPxlLayer(i)) n++;
371  break;
372  case kIstId:
373  // for(i=1;i<4;i++)
374  for(i=1;i<=2;i++)
375  if(hasHitInIstLayer(i)) n++;
376  break;
377  case kFtpcWestId:
378  case kFtpcEastId:
379  for (i=1; i<11; i++)
380  if (hasHitInRow(id, i)) n++;
381  break;
382  case kTpcId:
383  for (i=1; i<46; i++)
384  if (hasHitInRow(id, i)) n++;
385  break;
386  case kiTpcId:
387  for (i=1; i<41; i++)
388  if (hasHitInRow(id, i)) n++;
389  break;
390  case kMwpcWestId:
391  case kMwpcEastId:
392  if (bit(53)) n++;
393  break;
394  case kCtbId:
395  if (bit(54)) n++;
396  break;
397  case kTofId:
398  if (bit(55)) n++;
399  break;
400  case kRichId:
401  if (bit(56)) n++;
402  break;
403  case kBarrelEmcTowerId:
404  case kBarrelEmcPreShowerId:
405  case kBarrelSmdEtaStripId:
406  case kBarrelSmdPhiStripId:
407  if (bit(57)) n++;
408  break;
409  case kEndcapEmcTowerId:
410  case kEndcapEmcPreShowerId:
411  case kEndcapSmdUStripId:
412  case kEndcapSmdVStripId:
413  if (bit(58)) n++;
414  break;
415  default:
416  n = 0;
417  break;
418  }
419  return n;
420 }
421 
422 bool
423 StTrackTopologyMap::trackTpcOnly() const
424 {
425  if(hftFormat()) {
426  return ((hasHitInDetector(kTpcId) || hasHitInDetector(kiTpcId)) &&
427  !(hasHitInDetector(kPxlId) || hasHitInDetector(kIstId) || hasHitInDetector(kSsdId)));
428  }
429  else
430  return ((hasHitInDetector(kTpcId) || hasHitInDetector(kiTpcId)) &&
431  !(hasHitInDetector(kSvtId) || hasHitInDetector(kSsdId)));
432 }
433 
434 bool
435 StTrackTopologyMap::trackSvtOnly() const
436 {
437  return (hasHitInDetector(kSvtId) && !(hasHitInDetector(kTpcId) || hasHitInDetector(kiTpcId)));
438 }
439 
440 bool
441 StTrackTopologyMap::trackTpcSvt() const
442 {
443  return ((hasHitInDetector(kTpcId) || hasHitInDetector(kiTpcId)) && hasHitInDetector(kSvtId));
444 }
445 
446 bool
447 StTrackTopologyMap::trackFtpcEast() const
448 {
449  return hasHitInDetector(kFtpcEastId);
450 }
451 
452 bool
453 StTrackTopologyMap::trackFtpcWest() const
454 {
455  return hasHitInDetector(kFtpcWestId);
456 }
457 
458 bool
459 StTrackTopologyMap::trackFtpc() const
460 {
461  return (hasHitInDetector(kFtpcWestId) || hasHitInDetector(kFtpcEastId));
462 }
463 
464 int
465 StTrackTopologyMap::largestGap(StDetectorId id) const
466 {
467  if (id == kTpcId && hasHitInDetector(kiTpcId)) {
468  gMessMgr->Warning() << "StTrackTopologyMap::largestGap():\n"
469  << "\tWas called for detector id=kTpcId but there\n"
470  << "\tare also hits in the iTPC present. The largest\n"
471  << "\tgap in the TPC cannot be derived reliably at\n"
472  << "\t this point. Results are unreliable.\n"
473  << endm;
474  }
475 
476  if (ftpcFormat() && !(id == kFtpcWestId || id == kFtpcEastId))
477  return -1;
478 
479  vector<int> rows;
480  int i;
481 
482  switch (id) {
483  case kSvtId:
484  for (i=1; i<7; i++)
485  if (hasHitInSvtLayer(i)) rows.push_back(i);
486  break;
487  case kFtpcWestId:
488  case kFtpcEastId:
489  for (i=1; i<11; i++)
490  if (hasHitInRow(id, i)) rows.push_back(i);
491  break;
492  case kTpcId:
493  for (i=1; i<46; i++)
494  if (hasHitInRow(id, i)) rows.push_back(i);
495  break;
496  case kiTpcId:
497  for (i=1; i<41; i++)
498  if (hasHitInRow(id, i)) rows.push_back(i);
499  break;
500  default:
501  return -1;
502  }
503 
504  if (rows.size() < 2) return -1;
505 
506  vector<int> diffs(rows.size());
507  adjacent_difference(rows.begin(), rows.end(), diffs.begin());
508  return *max_element(diffs.begin()+1, diffs.end()) - 1; // skip first
509 }
510 
511 ostream& operator<< (ostream& os, const StTrackTopologyMap& m)
512 {
513  auto word0 = m.data(0);
514  auto word1 = m.data(1);
515  auto word2 = m.data(2); // iTPC
516 
517  for (int i=0; i<64; i++) {
518  if (i>31)
519  os << ((word1>>(i-32) & 1U) ? 1 : 0);
520  else
521  os << ((word0>>i & 1U) ? 1 : 0);
522  }
523 
524  os << 't' << endl;
525 
526  for (int i=0; i<64; i++) {
527  os << ((word2>>i & 1U) ? 1 : 0);
528  }
529 
530  return os;
531 }
532