StRoot  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
StTofGeometry.cxx
1 /*******************************************************************
2  *
3  * $Id: StTofGeometry.cxx,v 1.13 2018/01/03 21:07:14 smirnovd Exp $
4  *
5  * Author: Frank Geurts
6  *****************************************************************
7  *
8  * Description: Geometry definitions and utility class for TOFp
9  *
10  *****************************************************************
11  *
12  * $Log: StTofGeometry.cxx,v $
13  * Revision 1.13 2018/01/03 21:07:14 smirnovd
14  * StTofGeometry: Get rid of unsupported xdf and outdated ctf tables
15  *
16  * Revision 1.12 2007/04/17 23:01:51 dongx
17  * replaced with standard STAR Loggers
18  *
19  * Revision 1.11 2005/05/13 19:37:36 perev
20  * Defence agains 1/0 added
21  *
22  * Revision 1.10 2004/06/10 15:53:50 dongx
23  * -head file "StHelixD.hh" included
24  * -simplify the macro definition
25  *
26  * Revision 1.9 2004/06/09 21:26:32 dongx
27  * add function projTrayVector(..) to increase the matching speed
28  *
29  * Revision 1.8 2004/04/28 18:58:16 dongx
30  * fix a bug on the mis-matching by the opposite direction tracks
31  *
32  * Revision 1.7 2003/09/13 00:42:32 perev
33  * XDF obsolete + small fixes
34  *
35  * Revision 1.6 2003/09/02 17:59:10 perev
36  * gcc 3.2 updates + WarnOff
37  *
38  * Revision 1.5 2003/08/06 23:45:36 geurts
39  * refer to tofPathLength.hh for function definitions
40  *
41  * Revision 1.4 2003/04/15 03:24:17 geurts
42  * many, many changes:
43  * . updated and extended StructSlatHit, introduced tofSlatHitVector and Iterator
44  * . generalize (2+1)-D slat model from 3 layers to n layers, default n=5
45  * . introduced new member functions which identify 3x3 and 5x5 neighbours
46  * . introduced SetDebug() option.
47  * . minor updates in mTofParam parameters
48  *
49  * Revision 1.3 2002/01/23 17:30:45 geurts
50  * removed const
51  *
52  * Revision 1.2 2002/01/22 01:55:05 geurts
53  * STAR dBase access routine, bugfixes and doxygenized
54  *
55  * Revision 1.1 2001/09/28 19:09:40 llope
56  * first version
57  *
58  *******************************************************************/
60 
79 //VP#include "St_XDFFile.h"
80 #include "StMessMgr.h"
81 #include "St_DataSetIter.h"
82 #include "PhysicalConstants.h"
83 #include "tables/St_tofSlatGeom_Table.h"
84 #include "StThreeVectorD.hh"
85 #include "StPhysicalHelixD.hh"
86 #include "StMaker.h"
87 #include "StTofUtil/StTofGeometry.h"
88 #include "StTofUtil/tofPathLength.hh"
89 
90 #include <utility>
91 using std::pair;
92 
93 
96  mDebug = false;
97 }
98 
101 
102 
103 
106  initGeomFromXdf();
107  initDaqMap();
108 }
109 
110 
111 
114  initGeomFromDbase(maker);
115  initDaqMap();
116 }
117 
118 
119 
121 void StTofGeometry::initGeomFromXdf(const Char_t* InputXdfFile){
122 }
123 
124 
125 
128  if (!maker){
129  LOG_INFO << "StTofGeometry: unable to initialize without maker" << endm;
130  return;
131  }
132  LOG_INFO << "StTofGeometry: eventtime = ";
133  maker->GetDateTime().Print();
134 
135  TDataSet* mDbDataSet;
136  mDbDataSet= maker->GetDataBase("Geometry/tof");
137 
138  assert(mDbDataSet);
139  St_tofSlatGeom* mSlatGeom = static_cast<St_tofSlatGeom*>(mDbDataSet->Find("tofSlatGeom"));
140  assert(mSlatGeom);
141  tofSlatGeom_st *mslats= static_cast<tofSlatGeom_st*>(mSlatGeom->GetArray());
142  int numRows=mSlatGeom->GetNRows(); // should be 41 rows...
143  LOG_INFO << "StTofGeometry: numRows = " << numRows << endm;
144  for (int i=0;i<numRows;i++) mTofSlatVec.push_back(mslats[i]);
145 
146 
147  mTofParam.i_eta_max = 10;
148  mTofParam.i_eta_min = 1;
149  mTofParam.i_phi_max = 5;
150  mTofParam.i_phi_min = 1;
151  mTofParam.n_counter_eta = 10;
152  mTofParam.n_counter_phi = 5;
153  mTofParam.n_tray_eta = 1;
154  mTofParam.n_tray_phi = 1;
155  mTofParam.counter_thickness = 2;
156  mTofParam.counter_width = 4;
157  mTofParam.r = 213.95;
158  mTofParam.tray_height = 4.7;
159  mTofParam.tray_width = 10.795;
160  mTofParam.tray_length = 120.81;
161  mTofParam.tray_phi_zero = 0;
162 
163 }
164 
165 
166 
168 int StTofGeometry::calcSlatId(const int iphi, const int ieta) const {
169  return ((ieta - 1) * 4 + iphi);
170 }
171 
172 
173 
175 tofSlatGeom_st StTofGeometry::tofSlat(const Int_t slatId) const {
176  tofSlatGeom_st thisSlat;
177  if(slatId > 0)
178  thisSlat = mTofSlatVec[slatId-1];
179  else
180  LOG_INFO << "StTofGeometry: Warning: slatId ("<< slatId <<") seriously out of range" << endm;
181  return thisSlat;
182 }
183 
184 
185 
188  LOG_INFO << "StTofGeometry: Initializing default DAQ and SlatId mappings" << endm;
189 
190  // tray...
191  mTofDaqMap[ 0]=37; mTofDaqMap[ 1]=38; mTofDaqMap[ 2]=39; mTofDaqMap[ 3]=40; mTofDaqMap[ 4]=41;
192  mTofDaqMap[ 5]=33; mTofDaqMap[ 6]=34; mTofDaqMap[ 7]=35; mTofDaqMap[ 8]=36;
193  mTofDaqMap[ 9]=29; mTofDaqMap[10]=30; mTofDaqMap[11]=31; mTofDaqMap[12]=32;
194  mTofDaqMap[13]=25; mTofDaqMap[14]=26; mTofDaqMap[15]=27; mTofDaqMap[16]=28;
195  mTofDaqMap[17]=21; mTofDaqMap[18]=22; mTofDaqMap[19]=23; mTofDaqMap[20]=24;
196  mTofDaqMap[21]=17; mTofDaqMap[22]=18; mTofDaqMap[23]=19; mTofDaqMap[24]=20;
197  mTofDaqMap[25]=13; mTofDaqMap[26]=14; mTofDaqMap[27]=15; mTofDaqMap[28]=16;
198  mTofDaqMap[29]= 9; mTofDaqMap[30]=10; mTofDaqMap[31]=11; mTofDaqMap[32]=12;
199  mTofDaqMap[33]= 5; mTofDaqMap[34]= 6; mTofDaqMap[35]= 7; mTofDaqMap[36]= 8;
200  mTofDaqMap[37]= 1; mTofDaqMap[38]= 2; mTofDaqMap[39]= 3; mTofDaqMap[40]= 4;
201 
202  // ramp and pvpd....
203  mTofDaqMap[41]=99;
204  mTofDaqMap[42]=51;
205  mTofDaqMap[43]=52;
206  mTofDaqMap[44]=53;
207  mTofDaqMap[45]=54;
208  mTofDaqMap[46]=55;
209  mTofDaqMap[47]=56;
210 
211  // determine Slat-to-DaqId
212  for (int i=0;i<41;i++) mTofSlatMap[mTofDaqMap[i]]=i+1;
213  mTofSlatMap[0]=99;
214 }
215 
216 
217 
220  tofSlatGeom_st thisSlat = tofSlat(slatId);
221  double cosAng = thisSlat.cosang;
222  double sinAng = ::sqrt(1.0 - cosAng*cosAng);
223  double tanAng = fabs(sinAng/cosAng);
224  double r = (fabs(thisSlat.z) + thisSlat.r/tanAng) * sinAng;
225  double x = r * fabs(cosAng) * cos(thisSlat.phi);
226  double y = r * fabs(cosAng) * sin(thisSlat.phi);
227  double z = r * sinAng * cosAng/fabs(cosAng)*(-1.0);
228  StThreeVectorD slatNormPoint = StThreeVectorD(x,y,z);
229  return slatNormPoint;
230 }
231 
232 
233 
235 
240  StThreeVectorD planeNormPoint(0.0, 0.0, 0.0);
241  tofSlatGeom_st thisSlat = tofSlat(slatId);
242  int iEta = thisSlat.ieta;
243  int iPhi, centerSlatId;
244  if (iEta==10){ // for 5w rows take the centre (iphi=3)
245  iPhi=3;
246  centerSlatId=calcSlatId(iPhi,iEta);
247  planeNormPoint = tofSlatNormPoint(centerSlatId);
248  }
249  else { // in case of 4w rows average over slats iphi=2,4
250  for (iPhi=2;iPhi<4;iPhi++){
251  centerSlatId=calcSlatId(iPhi,iEta);
252  planeNormPoint += tofSlatNormPoint(centerSlatId)/2;
253  }
254 
255  }
256  return planeNormPoint;
257 }
258 
259 
260 
262 void StTofGeometry::printGeo(ostream& os) const {
263  os << "------StTofGeometry::printGeo()------" << endm;
264  os << "eta id max & min = " << mTofParam.i_eta_max << " "
265  << mTofParam.i_eta_min << endm;
266  os << "phi id max & min = " << mTofParam.i_phi_max << " "
267  << mTofParam.i_phi_min << endm;
268  os << "counters/trays/eta(phi) = " << mTofParam.n_counter_eta << " "
269  << mTofParam.n_counter_phi << endm;
270  os << "trays in eta & phi = " << mTofParam.n_tray_eta << " "
271  << mTofParam.n_tray_phi << endm;
272  os << "slat thickness & width = " << mTofParam.counter_thickness << " "
273  << mTofParam.counter_width << endm;
274  os << "mean counter radius = " << mTofParam.r << endm;
275  os << "tray height & width = " << mTofParam.tray_height << " "
276  << mTofParam.tray_width << endm;
277  os << "tray length & phi0 = " << mTofParam.tray_length << " "
278  << mTofParam.tray_phi_zero << endm;
279  LOG_INFO << "---------------------------------------" << endm;
280 }
281 
282 
283 
285 void StTofGeometry::printSlat(const Int_t slatId, ostream& os) const {
286  os << "------StTofGeometry::printSlat()------" << endm;
287  os << "Slat: id, tray, eta, phi = " << " " << slatId << " "
288  << tofSlat(slatId).trayId << " " << tofSlat(slatId).ieta
289  << " " << tofSlat(slatId).iphi << endm;
290  os << "ieta, cosang = "<< tofSlat(slatId).ieta<< " "
291  << tofSlat(slatId).cosang<< endm;
292  os << "eta, eta_max, etamin = " << tofSlat(slatId).eta<< " "
293  << tofSlat(slatId).eta_max<< " "
294  << tofSlat(slatId).eta_min<< endm;
295  os << "r, z, z_max, z_min = " << tofSlat(slatId).r<< " "
296  << tofSlat(slatId).z<< " "
297  << tofSlat(slatId).z_max<< " "
298  << tofSlat(slatId).z_min<< endm;
299  os << "iphi, phi, phi_max, phi_min = "<< tofSlat(slatId).iphi<< " "
300  << tofSlat(slatId).phi<< " "
301  << tofSlat(slatId).phi_max << " "
302  << tofSlat(slatId).phi_min<< endm;
303  LOG_INFO << "------------------------------------" << endm;
304 }
305 
306 
307 
309 int StTofGeometry::tofSlatCross(const StThreeVectorD& point, const tofSlatGeom_st tofSlat) const {
310  int slatCross=0;
311  float phi = point.phi();
312 
313  // swap eta min and max in STAF database for slats with eta > 0.
314  float etaMin, etaMax;
315  if(tofSlat.eta < 0) {
316  etaMin = tofSlat.eta_min;
317  etaMax = tofSlat.eta_max;
318  }
319  else {
320  etaMin = tofSlat.eta_max;
321  etaMax = tofSlat.eta_min;
322  }
323 
324  // start to check
325  if(point.pseudoRapidity() >= etaMin &&
326  point.pseudoRapidity() <= etaMax) {
327 
328  if (phi >= tofSlat.phi_min && phi <= tofSlat.phi_max)
329  slatCross = 1;
330  }
331  return slatCross;
332 }
333 
334 
335 
337 int StTofGeometry::tofSlatCrossId(const int volumeId) const {
338  int phiId = -1;
339  int etaId = -1;
340 
341  int trayEta = volumeId/100000;
342  int trayPhi = static_cast<int>(fmod(volumeId,100000.)/1000) ;
343  int counterPhi = static_cast<int>(fmod(volumeId,1000.)/100) ;
344  int counterEta = static_cast<int>(fmod(volumeId,100.)) ;
345 
346  if (trayEta==1) {
347  phiId = 14 - trayPhi ;
348  if (phiId<1) phiId = phiId + 60 ;
349  if (counterEta==1)
350  phiId = phiId * 5 - counterPhi + 1; // 5w row
351  else
352  phiId = phiId * 4 - counterPhi + 1; // 4w rows
353  etaId = counterEta + 10 ;
354  LOG_INFO << "StTofGeometry: WARNING TOFp tray not in EAST barrel" << endm;
355  }
356  else if (trayEta==2) {
357  phiId = trayPhi - 42 ;
358  if (phiId<1) phiId = phiId + 60 ;
359  if (counterEta==1)
360  phiId = phiId * 5 + counterPhi - 5; // 5w row
361  else
362  phiId = phiId * 4 + counterPhi - 4; // 4w rows
363  etaId = 11 - counterEta ;
364  }
365  else
366  LOG_INFO<<" StTofGeometry::tofSlatCrossId unknown trayId "<<trayEta<<endm ;
367 
368  int slatId = calcSlatId(counterPhi,etaId);
369  return slatId;
370 }
371 
372 
373 
376  int etaId = -1;
377  int phiId = -1;
378 
379  for (unsigned int i=0;i<mTofSlatVec.size();i++){
380  if(point.z() >= mTofSlatVec[i].z_min &&
381  point.z() <= mTofSlatVec[i].z_max &&
382  point.phi() >= mTofSlatVec[i].phi_min &&
383  point.phi() <= mTofSlatVec[i].phi_max) {
384  etaId = mTofSlatVec[i].ieta;
385  phiId = mTofSlatVec[i].iphi;
386  break;
387  }
388  if (etaId!=-1 && phiId!=-1) break;
389  }
390 
391  // calculate slat index (negative index indicates that the point is out of all slats)
392  int slatId;
393  if(etaId > 0 && phiId > 0) slatId = calcSlatId(phiId,etaId);
394  else slatId = -1;
395 
396  return slatId;
397 }
398 
399 
400 
402 tofSlatHitVector StTofGeometry::tofHelixToArray(const StPhysicalHelixD& helix,
403  idVector slatIdVec) {
404  idVector idErasedVec = slatIdVec;
405  idVectorIter slatIdIter, idErasedIter;
406 
407  double pathLength;
408 
409  StructSlatHit slatHit;
410  tofSlatHitVector slatHitVec;
411  slatHitVec.clear();
412 
413  // determine which stats in cluster are crossed by the track-helix.
414  while (slatIdVec.size() != 0) {
415 
416  // the first slat in the cluster
417  slatIdIter = slatIdVec.begin();
418 
419  int trayId = this->tofSlat(*slatIdIter).trayId;
420  float cosang = this->tofSlat(*slatIdIter).cosang;
421  int iEta = this->tofSlat(*slatIdIter).ieta;
422 
423  // layer[mMax-1] closest to STAR center, layer[0] farthest.
424  // typically hitprof [msb|...|lsb] = [innermost| ... | outermost]
425  unsigned int idMiddleLayer = (mMaxSlatLayers-1)/2;
426  float layerSeperation = mTofParam.counter_thickness/(mMaxSlatLayers-1);
427  StThreeVectorD slatNormLayer[mMaxSlatLayers];
428  slatNormLayer[idMiddleLayer] = this->tofPlaneNormPoint(*slatIdIter);
429  StThreeVectorD slatNormalVec = slatNormLayer[idMiddleLayer]/slatNormLayer[idMiddleLayer].mag();
430  for (unsigned int ll=1;ll<(idMiddleLayer+1);ll++){
431  slatNormLayer[idMiddleLayer+ll] = slatNormLayer[idMiddleLayer]
432  *((slatNormLayer[idMiddleLayer].mag() - ll*layerSeperation )
433  /slatNormLayer[idMiddleLayer].mag());
434  slatNormLayer[idMiddleLayer-ll] = slatNormLayer[idMiddleLayer]
435  *((slatNormLayer[idMiddleLayer].mag() + ll*layerSeperation )
436  /slatNormLayer[idMiddleLayer].mag());
437  }
438  StThreeVectorD hitAtLayer[mMaxSlatLayers];
439  for (unsigned int ll=0;ll<mMaxSlatLayers;ll++){
440  pathLength = helix.pathLength(slatNormLayer[ll], slatNormalVec);
441  pathLength = (pathLength>0) ? pathLength : 1.0e+33;
442  hitAtLayer[ll] = helix.at(pathLength);
443  }
444 
445  // loop over all slats in idErasedVec (=slatIdVec at the begining of while)
446  idErasedIter = idErasedVec.begin();
447  while (idErasedIter != idErasedVec.end()) {
448 
449  // check if any slat in the plane where the first slat lies
450  if(this->tofSlat(*idErasedIter).cosang == cosang &&
451  this->tofSlat(*idErasedIter).ieta == iEta &&
452  this->tofSlat(*idErasedIter).trayId == trayId) {
453 
454  bool layer[mMaxSlatLayers];
455  int numberOfHitLayers(0);
456  for (unsigned int ll=0;ll<mMaxSlatLayers;ll++){
457  layer[ll] = tofSlatCross(hitAtLayer[ll], this->tofSlat(*idErasedIter));
458  if (layer[ll]) numberOfHitLayers++;
459  }
460 
461  // save fired slat in slatHitVec which will be returned at the end
462  if (numberOfHitLayers>0) {
463  slatHit.hitProfile = 0;
464  if (Debug()) LOG_INFO << "L(0-"<<mMaxSlatLayers-1<<"): ";
465  for (unsigned int ll=0;ll<mMaxSlatLayers;ll++){
466  slatHit.hitProfile = 2*slatHit.hitProfile + layer[ll]*1;
467  if (Debug()) LOG_INFO <<layer[ll];
468  }
469  if (Debug()) LOG_INFO << endm;
470 
471  unsigned int innerLayer(0), outerLayer(mMaxSlatLayers-1);
472  // boundary control not really necessary since anyLayer guarantees at least one layer
473  while (!layer[innerLayer] && (innerLayer<=mMaxSlatLayers)) innerLayer++;
474  while (!layer[outerLayer] && (outerLayer>= 0 )) outerLayer--;
475  if (Debug()) LOG_INFO << "Li="<<innerLayer<< " Lo="<<outerLayer<<" nLx="<<numberOfHitLayers<<endm;
476 
477 
478  float s(0);
479  StThreeVectorD distance(0,0,0);
480 
481  if (innerLayer!=outerLayer){
482  s = tofPathLength(&hitAtLayer[innerLayer],&hitAtLayer[outerLayer],helix.curvature());
483  distance = hitAtLayer[outerLayer] - hitAtLayer[innerLayer];
484  }
485 
486  float theta_xy = atan2(distance.x(),distance.y());
487  float theta_zr = atan2(distance.z(),distance.perp());
488 
489  // make angles local to the slat
490  theta_zr -= acos(this->tofSlat(*idErasedIter).cosang);
491  theta_xy += pi/2 + this->tofSlat(*idErasedIter).phi;
492 
493  slatHit.s = s;
494  slatHit.theta_xy = theta_xy;
495  slatHit.theta_zr = theta_zr;
496 
497  slatHit.slatIndex = *idErasedIter;
498 
499  // calculate average hit position, based on all hit layers
500  StThreeVectorD averageHitPos(0,0,0);
501  for (unsigned int i=0;i<mMaxSlatLayers;i++)
502  if (layer[i]){
503  averageHitPos += hitAtLayer[i]/numberOfHitLayers;
504  slatHit.layerHitPositions.push_back(hitAtLayer[i]);
505  }
506  slatHit.hitPosition = averageHitPos;
507 
508  slatHitVec.push_back(slatHit);
509  slatHit.layerHitPositions.clear();
510  }
511  //erase the slat entry which has been checked (preparing for the next round)
512  idErasedVec.erase(idErasedIter);
513  idErasedIter--;
514  }
515  idErasedIter++;
516  }
517  slatIdVec = idErasedVec;
518  }
519  return slatHitVec;
520 }
521 
522 
525  int slatId = this->tofSlatCrossId(*hitPoint);
526  if (slatId>0){
527  float zmin = this->tofSlat(slatId).z_min;
528  float zmax = this->tofSlat(slatId).z_max;
529  float cosang = this->tofSlat(slatId).cosang;
530 
531  // pmt is on the zmax side.
532  float length = (zmax-hitPoint->z())/cosang ;
533  float max_distance = (zmax-zmin)/cosang ;
534 
535  if (length>max_distance || length<0){
536  LOG_INFO << "HitPositionCorrection: length="<<length<<" max="<<max_distance
537  << " zmin="<<zmin<<" zmax="<<zmax<<" cosang="<<cosang<<endm;
538  this->printSlat(slatId);
539  }
540 
541  return length;
542  }
543 
544  // return very negative value to indicate bad slatId.
545  LOG_INFO << "slatHitPosition: hit point out of range;"
546  << " phi=" << hitPoint->phi() << " z=" << hitPoint->z() << endm;
547  return -100.;
548 }
549 
550 
552 idVector StTofGeometry::slatNeighbours(int slatId){
553  tofSlatGeom_st middleSlat = this->tofSlat(slatId);
554  int slatPhi = middleSlat.iphi;
555  int slatEta = middleSlat.ieta;
556 
557  idVector neighbours;
558  neighbours.clear();
559  int thisSlatId, ieta, iphi;
560 
561  // for all the 4w rows life is simple ...
562  if (slatEta<9){
563  for (ieta= slatEta-1;ieta<=slatEta+1;ieta++)
564  for (iphi= slatPhi-1;iphi<=slatPhi+1;iphi++){
565  if ((ieta==slatEta) && (iphi==slatPhi)) continue;
566  if ((ieta <1) || (iphi<1) || (iphi>4)) continue;
567  thisSlatId = calcSlatId(iphi,ieta);
568  neighbours.push_back(thisSlatId);
569  }
570  }
571  // the 4w row next to the 5w row needs a little bit attention ...
572  else if (slatEta==9){
573  for (ieta= slatEta-1;ieta<=slatEta;ieta++)
574  for (iphi= slatPhi-1;iphi<=slatPhi+1;iphi++){
575  if ((ieta==slatEta) && (iphi==slatPhi)) continue;
576  if ((iphi<1) || (iphi>4)) continue;
577  thisSlatId = calcSlatId(iphi,ieta);
578  neighbours.push_back(thisSlatId);
579  }
580  ieta = slatEta+1; iphi = slatPhi;
581  thisSlatId = calcSlatId(iphi,ieta);
582  neighbours.push_back(thisSlatId);
583  iphi = slatPhi+1;
584  thisSlatId = calcSlatId(iphi,ieta);
585  neighbours.push_back(thisSlatId);
586  }
587  // the 5w row needs special treatment ...
588  else if (slatEta==10){
589  for (iphi= slatPhi-1;iphi<=slatPhi+1;iphi++){
590  if (iphi==slatPhi) continue;
591  if ((iphi<1) || (iphi>5)) continue;
592  ieta = slatEta;
593  thisSlatId = calcSlatId(iphi,ieta);
594  neighbours.push_back(thisSlatId);
595  }
596  ieta=slatEta-1;
597  for (iphi=slatPhi-1;iphi<=slatPhi;iphi++){
598  if ((iphi<1) || (iphi>4)) continue;
599  thisSlatId = calcSlatId(iphi,ieta);
600  neighbours.push_back(thisSlatId);
601  }
602  }
603 
604  return neighbours;
605 }
606 
607 
610  // consider a wider range around this slatId (5x5)
611  tofSlatGeom_st middleSlat = this->tofSlat(slatId);
612  int slatPhi = middleSlat.iphi;
613  int slatEta = middleSlat.ieta;
614 
615  idVector neighbours;
616  neighbours.clear();
617  int thisSlatId, ieta, iphi;
618 
619  for (ieta=slatEta-2;ieta<=slatEta+2;ieta++){
620  if ((ieta<1) || (ieta>10)) continue;
621  int iphiMax = (ieta==10)?5:4;
622  for (iphi = 1; iphi<=iphiMax; iphi++){
623  if ((ieta==slatEta) && (iphi==slatPhi)) continue;
624  thisSlatId = calcSlatId(iphi,ieta);
625  neighbours.push_back(thisSlatId);
626  }
627  }
628 
629  return neighbours;
630 }
631 
632 
635  int slatId = this->tofSlatCrossId(*hitPoint);
636  if (slatId>0){
637  float phimin = this->tofSlat(slatId).phi_min;
638  float phimax = this->tofSlat(slatId).phi_max;
639 
640  float philoc = hitPoint->phi() - phimin;
641  float max_deltaphi = (phimax-phimin);
642 
643  if (philoc>max_deltaphi || philoc<0){
644  LOG_INFO << "slatHitPhiPosition: phi="<<philoc<<" max="<<max_deltaphi
645  << " phimin="<<phimin<<" phimax="<<phimax<<endm;
646  this->printSlat(slatId);
647  }
648 
649  return philoc;
650  }
651 
652  // return very negative value to indicate bad slatId.
653  LOG_INFO << "slatHitPhiPosition: hit point out of range;"
654  << " phi=" << hitPoint->phi() << " z=" << hitPoint->z() << endm;
655  return -100.;
656 }
657 
658 //---------------------------------------------------------------------------
659 // estimate the possible projection on the TOF tray
660 Bool_t StTofGeometry::projTrayVector(const StHelixD &helix, idVector &trayVec) const {
661 
662  trayVec.clear();
663  double R_tof = 220.;
664  double res = 5.0;
665  double s1 = helix.pathLength(R_tof).first;
666  if(s1<0.) s1 = helix.pathLength(R_tof).second;
667  StThreeVectorD point = helix.at(s1);
668  double phi = point.phi()*180/3.14159;
669 
670  // east ring, start from 108 deg (id=61) , clock-wise from east facing west
671  int itray_east = (255+(int)phi)%360/6+61;
672  trayVec.push_back(itray_east);
673 
674  int itray_east1 = (255+(int)(phi+res))%360/6+61;
675  int itray_east2 = (255+(int)(phi-res))%360/6+61;
676  if(itray_east1!=itray_east) {
677  trayVec.push_back(itray_east1);
678  }
679  if(itray_east2!=itray_east&&itray_east2!=itray_east1) {
680  trayVec.push_back(itray_east2);
681  }
682 
683  // west ring, start from 72 deg (id=1) , clock-wise from west facing east
684  int itray_west = (435-(int)phi)%360/6+1;
685  trayVec.push_back(itray_west);
686 
687  int itray_west1 = (435-(int)(phi+res))%360/6+1;
688  int itray_west2 = (435-(int)(phi-res))%360/6+1;
689  if(itray_west1!=itray_west) {
690  trayVec.push_back(itray_west1);
691  }
692  if(itray_west2!=itray_west&&itray_west2!=itray_west1) {
693  trayVec.push_back(itray_west2);
694  }
695 
696 // LOG_INFO << " proj tray id = ";
697 // for(size_t it=0;it<trayVec.size();it++) {
698 // LOG_INFO << trayVec[it] << " ";
699 // }
700 // LOG_INFO << endm;
701 
702  if(trayVec.size()>0) return kTRUE;
703  else return kFALSE;
704 }
tofSlatGeom_st tofSlat(const Int_t slatId) const
return slat geometry structure for slatId
idVector slatNeighbours(const int)
returns idVector of 3x3 (max) neighbouring slatIds
void printGeo(ostream &os=cout) const
print global geometry parameters
idVector slatNeighboursWide(const int)
returns idVector of 5x5 (max) neighbouring slatIds
void initDaqMap()
set-up the default Daq-to-SlatId and Slat-to-DaqId mappings
void initGeomFromXdf(const Char_t *="/afs/rhic.bnl.gov/star/users/geurts/public/dbase/ctg_pars.xdf")
initialize TOF Slat parameters from XDF file
tofSlatHitVector tofHelixToArray(const StPhysicalHelixD &helix, idVector slatIdVec)
finds slats in an array of trays which are crossed by a track-helix.
pair< double, double > pathLength(double r) const
path length at given r (cylindrical r)
Definition: StHelix.cc:351
float slatPhiPosition(StThreeVectorD *)
returns the local Phi angle of a track inside a slat
float slatHitPosition(StThreeVectorD *)
returns 1-D hit position on the TOFp slat (Zhit)
StThreeVectorD tofSlatNormPoint(const Int_t slatId) const
calculate the normal vector &lt;r&gt; to a slat
~StTofGeometry()
default empty destructor
StThreeVectorD tofPlaneNormPoint(const Int_t slatId) const
calculate the normal vector to a slats-plane
int tofSlatCross(const StThreeVectorD &point, const tofSlatGeom_st tofSlat) const
check if a point is in a slat
void printSlat(const Int_t slatId, ostream &os=cout) const
print slat-specific geometry parameters
int tofSlatCrossId(const StThreeVectorD &point) const
return the index of a slat if the point is in the slat
void initGeomFromDbase(StMaker *)
initialize TOF Slat parameters from STAR dBase
StTofGeometry()
defaulty constructor
virtual TDataSet * Find(const char *path) const
Definition: TDataSet.cxx:362
void init()
initialize geometry class from XDF file and set-up DAQ/Slat mappings