StRoot  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
StBTofGeometry.cxx
1 /*******************************************************************
2  *
3  * $Id: StBTofGeometry.cxx,v 1.33 2021/04/13 22:35:49 geurts Exp $
4  *
5  * Authors: Shuwei Ye, Xin Dong
6  *******************************************************************
7  *
8  * Description: Collection of geometry classes for the TOF-MRPC
9  * initializes from GEANT geometry
10  *
11  *******************************************************************/
12 #include "Stiostream.h"
13 #include <algorithm>
14 #include <array>
15 #include <math.h>
16 #include <vector>
17 #include <string>
18 #include <stdlib.h>
19 #include <stdio.h>
20 #include "tables/St_tofGeomAlign_Table.h"
21 
22 #include "StBTofGeometry.h"
23 #include "TFile.h"
24 #include "TDataSet.h"
25 #include "TDataSetIter.h"
26 #include "TGeoBBox.h"
27 #include "TGeoManager.h"
28 #include "TGeoMatrix.h"
29 #include "TGeoPhysicalNode.h"
30 
31 #include "StMaker.h"
32 //#include "TMemStat.h"
33 #include "StMessMgr.h"
34 
35 //#include "Debugger.h"
36 
38 //
39 // group of classes for BTof Geometry:
40 //
41 // StBTofGeometry, StBTofNode
42 // StBTofGeomTray, StBTofGeomSensor
43 //
44 // Usage:
45 //
46 // StBTofGeometry* geo = new StBTofGeometry("btof","btof geometry");
47 // geo->Init(TVolume *starHall);
48 //
49 // ---------------------------------------------------------------------------
50 //
51 // StBTofNode
52 // ==============
53 //
55 
56 
57 Bool_t StBTofNode::mDebug = kFALSE;
58 Double_t const StBTofGeomSensor::mSensorDy = 10.35; // Actual module length;
59 const char* StBTofGeometry::sectorPref = "BSEC";
60 const char* StBTofGeometry::trayPref = "BTRA";
61 const char* StBTofGeometry::senPref = "BRMD";
62 
63 //_____________________________________________________________________________
65  : fView(element), pView(new TVolumePosition(*pos)), mMasterNode(top), mTransFlag(kFALSE),
66  mAlign{align.x(), align.y(), align.z()}
67 {
68  SetBit(kIsOwner, false);
69 
70  UpdateMatrix();
71  BuildMembers();
72 }
73 
74 
75 StBTofNode::StBTofNode(const TGeoPhysicalNode& gpNode, const StThreeVectorD& align) :
76  fView(nullptr), pView(nullptr), mMasterNode(nullptr), mTransFlag(false),
77  mAlign{align.x(), align.y(), align.z()}
78 {
79  SetBit(kIsOwner, true);
80 
81  TGeoBBox* bbox = static_cast<TGeoBBox*>( gpNode.GetShape() );
82 
83  mTShape = new TBRIK( gpNode.GetVolume()->GetName(), "BTOF shape", "unknown", bbox->GetDX(), bbox->GetDY(), bbox->GetDZ() );
84  mTVolume = new TVolume( gpNode.GetVolume()->GetName(), "BTOF volume", mTShape );
85 
86  TGeoHMatrix* ghMatrix = static_cast<TGeoHMatrix*>( gpNode.GetMatrix() );
87 
88  double* rotationM = ghMatrix->GetRotationMatrix();
89 
90  double rotationF[9] = {
91  rotationM[0], rotationM[3], rotationM[6],
92  rotationM[1], rotationM[4], rotationM[7],
93  rotationM[2], rotationM[5], rotationM[8]
94  };
95 
96  // The rotation matrix is owned by pView
97  TRotMatrix* rotMatrix = new TRotMatrix("rotMatrix", "BTOF rotation matrix", rotationF);
98 
99  double* trans = ghMatrix->GetTranslation();
100 
101  pView = new TVolumePosition(mTVolume, trans[0], trans[1], trans[2], rotMatrix);
102  pView->SetMatrixOwner(true);
103 
104  fView = new TVolumeView( static_cast<TVolume*>(nullptr), pView);
105 
106  TVolumePosition* masterPosition = new TVolumePosition(nullptr, 0, 0, 0, TVolume::GetIdentity());
107 
108  // By default masterPosition is owned by mMasterNode
109  mMasterNode = new TVolumeView( static_cast<TVolume*>(nullptr), masterPosition);
110 
111  UpdateMatrix();
112  BuildMembers();
113 }
114 
115 
116 //_____________________________________________________________________________
117 void StBTofNode::UpdateMatrix()
118 {
119  //
120  //Update the Translation and RotateMatrix between local and master
121  // and store them as members: mTransMRS, mRotMRS
122  //while TNode stores them locally to share among all TNode objects,
123  // thus they may be changed afterward !
124  //
125 
126  mTransFlag = kFALSE;
127  CalcMatrix(this, mAlign, mTransMRS, mRotMRS);
128  mTransFlag = kTRUE;
129 
130 }
131 
132 //_____________________________________________________________________________
133 void StBTofNode::CalcMatrix(StBTofNode* son, Double_t* align,
134  Double_t* trans, Double_t* rot, StBTofNode* mother)
135 {
136  //
137  //Translation vector and Rotation matrix from TNode "mother" to "son"
138  //
139  // 1. Transformation: mother(x,y,z) ==> son(x',y',z')
140  //
141  // [x'] [ m[0] m[1] m[2] ] [ [x] [dx] ]
142  // [y'] = [ m[3] m[4] m[5] ] . [ [y] - [dy] ]
143  // [z'] [ m[6] m[7] m[8] ] [ [z] [dz] ]
144  //
145  // Transpose([x',y',z']) = M . Transpose([x-dx,y-dy,z-dz])
146  // and
147  // Transpose([x-dx,y-dy,z-dz]) = inverse(M) . Transpose([x',y',z'])
148  //
149  // where transpose(M) = inverse(M)
150  //
151  // 2. In the representation of vector:
152  //
153  // Vectors: V' = x' I' + y' J' + z' K'
154  // V = x I + y J + z K = V' + dV
155  // dV = dx I + dy J + dz K
156  //
157  // V' . I' = x' = (V-dV) . I'
158  // = (x-dx) (I.I') + (y-dy) (J.I') + (z-dz) (K.I')
159  // = (x-dx) m[0] + (y-dy) m[1] + (z-dz) m[2]
160  //
161  // so, the projections of unit vector I' on I, J, K
162  // yield m[0], m[1], m[2]
163  //
164  //********************************************************************
165 
166 
167  Double_t xl[3], xm[3];
168 
169  // son->TNode::UpdateMatrix();
170  // son->GetpView()->UpdateMatrix();
171  // LOG_INFO << "StBTofNode::CalcMatrix" << endm;
172 
173  xl[0] = 0; xl[1] = 0; xl[2] = 0;
174  ConvertPos(son,xl, mother,xm);
175  trans[0] = xm[0];
176  trans[1] = xm[1];
177  trans[2] = xm[2];
178 
179  xl[0] = 1; xl[1] = 0; xl[2] = 0;
180  ConvertPos(son,xl, mother,xm);
181  rot[0] = xm[0]-trans[0];
182  rot[1] = xm[1]-trans[1];
183  rot[2] = xm[2]-trans[2];
184 
185  xl[0] = 0; xl[1] = 1; xl[2] = 0;
186  ConvertPos(son,xl, mother,xm);
187  rot[3] = xm[0]-trans[0];
188  rot[4] = xm[1]-trans[1];
189  rot[5] = xm[2]-trans[2];
190 
191  xl[0] = 0; xl[1] = 0; xl[2] = 1;
192  ConvertPos(son,xl, mother,xm);
193  rot[6] = xm[0]-trans[0];
194  rot[7] = xm[1]-trans[1];
195  rot[8] = xm[2]-trans[2];
196 
197  // Alignment parameters;
198  trans[0] += align[0];
199  trans[1] += align[1];
200  trans[2] += align[2];
201 
202  return;
203 }
204 
205 //_____________________________________________________________________________
206 void StBTofNode::ConvertPos(
207  StBTofNode* from, const Double_t* pos_from,
208  StBTofNode* to, Double_t* pos_to)
209 {
210  if (to==0) from->Local2Master(pos_from,pos_to);
211  else {
212  Double_t xg[3];
213  from->Local2Master(pos_from,xg);
214  to->Master2Local(xg,pos_to);
215  }
216 
217  return;
218 }
219 
220 //_____________________________________________________________________________
221 void StBTofNode::BuildMembers()
222 {
223  //
224  //Build date members: mCenter{Rxy,Eta,Phi}, m{Eta,Phi}{Min,Max}
225  //
226 
227  Double_t xl[3];
228  Double_t xg[3];
229  TBRIK *brik = dynamic_cast<TBRIK*>(GetShape());
230  // LOG_INFO << " Get shape ready" << endm;
231  if(!brik) { LOG_INFO << " no brik " << endm; return; }
232  // Double_t dx = brik->GetDx();
233  Double_t dy = brik->GetDy();
234  Double_t dz = brik->GetDz();
235 
236  // LOG_INFO << " size = " <<dx << " " << dy << " " << dz << endm;
237 /*
238  //center point
239  Double_t xc[3];
240  xc[0] = 0; xc[1] = 0; xc[2] = 0;
241  Local2Master(xc, xg);
242  StThreeVectorD center(xg[0], xg[1], xg[2]);
243  mCenterRxy = center.perp();
244  mCenterEta = center.pseudoRapidity();
245  mCenterPhi = center.phi();
246 */
247 
248  // -dz
249  xl[0] = 0; xl[1] = 0; xl[2] = -dz;
250  Local2Master(xl, xg);
251  mEtaMin = StThreeVectorD(xg[0],xg[1],xg[2]).pseudoRapidity();
252 
253  // +dz
254  xl[0] = 0; xl[1] = 0; xl[2] = dz;
255  Local2Master(xl, xg);
256  mEtaMax = StThreeVectorD(xg[0],xg[1],xg[2]).pseudoRapidity();
257 
258  // -dy
259  xl[0] = 0; xl[1] = -dy; xl[2] = 0;
260  Local2Master(xl, xg);
261  mPhiMin = StThreeVectorD(xg[0],xg[1],xg[2]).phi();
262 
263  // +dy
264  xl[0] = 0; xl[1] = dy; xl[2] = 0;
265  Local2Master(xl, xg);
266  mPhiMax = StThreeVectorD(xg[0],xg[1],xg[2]).phi();
267 
268  if (mEtaMin>mEtaMax) {
269  Double_t tmp = mEtaMin;
270  mEtaMin = mEtaMax;
271  mEtaMax = tmp;
272  }
273 
274  if (mPhiMin>mPhiMax) {
275  Double_t tmp = mPhiMin;
276  mPhiMin = mPhiMax;
277  mPhiMax = tmp;
278  }
279 
280  return;
281 }
282 
283 //_____________________________________________________________________________
284 void StBTofNode::Local2Master(const Double_t* local, Double_t* master)
285 {
286  //
287  //Transform local coordinate into global coordinate
288  //
289  // pView->UpdateMatrix();
290  if (!mTransFlag) {
291  if (!mMasterNode) { LOG_INFO << " no Master! " << endm; return;}
292  if (pView) {
293  pView->Local2Master(local, master);
294  } else {
295  TVolumeView *son = GetfView();
296  TVolumeView *mrs = GetTopNode();
297 
298  TVolumePosition *pos = 0;
299  pos = son->Local2Master(son, mrs);
300  pos->Local2Master(local, master);
301  delete pos;
302  }
303  return;
304  }
305 
306  //mTransFlag==kTRUE, i.e. StBTofGeomNode::UpdateMatrix() invoked already
307  Double_t x, y, z;
308  x = local[0];
309  y = local[1];
310  z = local[2];
311 
312  master[0] = mTransMRS[0] + mRotMRS[0]*x + mRotMRS[3]*y + mRotMRS[6]*z;
313  master[1] = mTransMRS[1] + mRotMRS[1]*x + mRotMRS[4]*y + mRotMRS[7]*z;
314  master[2] = mTransMRS[2] + mRotMRS[2]*x + mRotMRS[5]*y + mRotMRS[8]*z;
315 
316 }
317 
318 //_____________________________________________________________________________
319 void StBTofNode::Master2Local(const Double_t* master, Double_t* local)
320 {
321  //
322  //Transform global coordinate into local coordinate
323  //
324  // pView->UpdateMatrix();
325  // pView->Master2Local(master, local);
326  if (!mTransFlag) {
327  LOG_INFO << " and No TVolumePosition::Master2Local is wrong, so do nothing" << endm;
328  return;
329  }
330 
331  //mTransFlag==kTRUE, i.e. StBTofGeomNode::UpdateMatrix() invoked already
332  Double_t x, y, z;
333  x = master[0] - mTransMRS[0];
334  y = master[1] - mTransMRS[1];
335  z = master[2] - mTransMRS[2];
336 
337  local[0] = mRotMRS[0]*x + mRotMRS[1]*y + mRotMRS[2]*z;
338  local[1] = mRotMRS[3]*x + mRotMRS[4]*y + mRotMRS[5]*z;
339  local[2] = mRotMRS[6]*x + mRotMRS[7]*y + mRotMRS[8]*z;
340 }
341 
342 //_____________________________________________________________________________
343 StThreeVectorD StBTofNode::YZPlaneNormal()
344 {
345  //
346  //Calculate the vector unit of normal to YZ-plane
347  // i.e. the global representation of local unit vector (1,0,0)
348  //
349 
350  Double_t ux[3], nx[3];
351 
352  ux[0] = 1; ux[1] = 0; ux[2] = 0;
353  Local2Master(ux,nx);
354 
355  nx[0] -= mTransMRS[0];
356  nx[1] -= mTransMRS[1];
357  nx[2] -= mTransMRS[2];
358 
359  return StThreeVectorD(nx[0],nx[1],nx[2]);
360 }
361 
362 //_____________________________________________________________________________
363 StThreeVectorD StBTofNode::GetCenterPosition()
364 const
365 {
366  //
367  //Return the global representation of this node(TBRIk-shape) center
368  //
369 
370  Double_t xg[3];
371  xg[0] = mTransMRS[0];
372  xg[1] = mTransMRS[1];
373  xg[2] = mTransMRS[2];
374 
375  return StThreeVectorD(xg[0],xg[1],xg[2]);
376 }
377 
378 //_____________________________________________________________________________
379 Bool_t StBTofNode::IsLocalPointIn(const Double_t x, const Double_t y,
380  const Double_t z)
381 {
382  TBRIK *brik = dynamic_cast<TBRIK*> (GetShape());
383  Double_t dx = brik->GetDx();
384  Double_t dy = brik->GetDy();
385  Double_t dz = brik->GetDz();
386  Bool_t ret = -dx<x && x<dx && -dy<y && y<dy && -dz<z && z<dz;
387 
388  return ret;
389 }
390 
391 //_____________________________________________________________________________
392 Bool_t StBTofNode::IsGlobalPointIn(const StThreeVectorD &global)
393 {
394  Double_t xl[3], xg[3];
395  xg[0] = global.x();
396  xg[1] = global.y();
397  xg[2] = global.z();
398  Master2Local(xg, xl);
399  Bool_t ret = IsLocalPointIn(xl[0], xl[1], xl[2]);
400 
401  return ret;
402 }
403 
404 //_____________________________________________________________________________
405 Bool_t StBTofNode::HelixCross(const StHelixD &helix, Double_t &pathLen,
406  StThreeVectorD &cross)
407 {
408  //
409  // check if helix go through this node(TBRIK)
410  // and return the path length of helix before crossing this node
411  //
412  // static const Float_t MaxPathLength = 1000.; //Maximum path length
413  Float_t MaxPathLength = 1000.;
414 
415  Bool_t ret = kFALSE;
416  pathLen = 0;
417 
418  //
419  // Get the normal to the YZ-plane
420  //
421  StThreeVectorD planeNormal = YZPlaneNormal();
422 
423  //
424  // Get the center position
425  //
426  StThreeVectorD centerPos = GetCenterPosition();
427 
428  //
429  // Find the intersection point between the helix and the cell plane
430  //
431  pathLen = helix.pathLength(centerPos,planeNormal);
432  if ( pathLen>0 && pathLen<MaxPathLength ) {
433  cross = helix.at(pathLen);
434  //
435  // Check if the intersected point is really in the cell
436  //
437  ret = IsGlobalPointIn(cross);
438  }
439  return ret;
440 }
441 
442 //_____________________________________________________________________________
443 Bool_t StBTofNode::HelixCross(const StHelixD &helix, Double_t &pathLen,
444  StThreeVectorD &cross, Double_t &theta)
445 {
446  //
447  // check if helix go through this node(TBRIK)
448  // and return the path length of helix before crossing this node
449  //
450  // static const Float_t MaxPathLength = 1000.; //Maximum path length
451  Float_t MaxPathLength = 1000.;
452 
453  Bool_t ret = kFALSE;
454  pathLen = 0;
455 
456  //
457  // Get the normal to the YZ-plane
458  //
459  StThreeVectorD planeNormal = YZPlaneNormal();
460 
461  //
462  // Get the center position
463  //
464  StThreeVectorD centerPos = GetCenterPosition();
465 
466  //
467  // Find the intersection point between the helix and the cell plane
468  //
469  pathLen = helix.pathLength(centerPos,planeNormal);
470  if ( pathLen>0 && pathLen<MaxPathLength ) {
471  cross = helix.at(pathLen);
472  theta = planeNormal.angle(helix.cat(pathLen));
473  //
474  // Check if the intersected point is really in the cell
475  //
476  ret = IsGlobalPointIn(cross);
477  }
478  return ret;
479 }
480 
481 //_____________________________________________________________________________
482 void StBTofNode::Print(Option_t *opt) const
483 {
484  TBRIK *brik = dynamic_cast<TBRIK*> (GetShape());
485  LOG_INFO << "Name=" << GetName() << "\t TBRIK-dimension=" << brik->GetDx()
486  << " : " << brik->GetDy() << " : " << brik->GetDz()
487  // << "\n Center Rxy:Eta:Phi=" << mCenterRxy << " : "
488  // << mCenterEta << " : " << mCenterPhi
489  << "\n EtaRange=" << mEtaMin << " : " << mEtaMax
490  << "\t PhiRange=" << mPhiMin << " : " << mPhiMax
491  << endm;
492  LOG_INFO <<"trans[0-2]=" << mTransMRS[0] <<" " <<mTransMRS[1]
493  <<" " <<mTransMRS[2]
494  <<"\nmRotMRS[0-2]=" <<mRotMRS[0] <<" " <<mRotMRS[1] <<" " <<mRotMRS[2]
495  <<"\nmRotMRS[3-5]=" <<mRotMRS[3] <<" " <<mRotMRS[4] <<" " <<mRotMRS[5]
496  <<"\nmRotMRS[6-8]=" <<mRotMRS[6] <<" " <<mRotMRS[7] <<" " <<mRotMRS[8]
497  <<endm;
498 }
499 
501 //
502 // StBTofGeomTray
503 // ==============
504 //
506 
507 
508 Bool_t StBTofGeomTray::mDebug = kFALSE;
509 
510 //_____________________________________________________________________________
511 StBTofGeomTray::StBTofGeomTray(const Int_t ibtoh, TVolumeView *sector, TVolumeView *top, const StThreeVectorD& align, TVolumePosition *pos)
512  : StBTofNode((TVolumeView *)sector->First(), top, align, pos)
513 {
514  mSectorsInBTOH = top->GetListSize()/2;
515  mBTOHIndex = ibtoh + 1;
516  mTrayIndex = ibtoh * mSectorsInBTOH + sector->GetPosition()->GetId();
517 }
518 
519 
520 StBTofGeomTray::StBTofGeomTray(const int trayId, const TGeoPhysicalNode& node, const StThreeVectorD& align)
521  : StBTofNode(node, align)
522 {
523  int mBTOHId = ( trayId <= 60 ? 1 : 2 );
524  int sectorId = ( trayId <= 60 ? trayId : trayId - 60 );
525 
526  mSectorsInBTOH = StBTofGeometry::mNTrays/2;
527  mBTOHIndex = mBTOHId;
528  mTrayIndex = (mBTOHId - 1) * mSectorsInBTOH + sectorId;
529 }
530 
531 
532 //_____________________________________________________________________________
533 void StBTofGeomTray::Print(const Option_t *opt) const
534 {
535  LOG_INFO << "StBTofGeomTray, tray#=" << mTrayIndex << endm;
536  StBTofNode::Print(opt);
537 }
538 
539 
541 //
542 // StBTofGeomSensor
543 // ================
544 //
546 
547 
548 Bool_t StBTofGeomSensor::mDebug = kFALSE;
549 
550 //_____________________________________________________________________________
551 StBTofGeomSensor::StBTofGeomSensor(TVolumeView *element, TVolumeView *top, const StThreeVectorD& align, TVolumePosition *pos)
552  : StBTofNode(element, top, align, pos)
553 {
554  mModuleIndex = element->GetPosition()->GetId();
555  CreateGeomCells();
556 }
557 
558 
559 StBTofGeomSensor::StBTofGeomSensor(const int moduleId, const TGeoPhysicalNode& node, const StThreeVectorD& align)
560  : StBTofNode(node, align)
561 {
562  mModuleIndex = moduleId;
563  CreateGeomCells();
564 }
565 
566 
567 //_____________________________________________________________________________
569 {
570  //
571  //Divide this sensor to creat cells
572  //
573 
574  //
575  // change the size according to the real cells
576  // mSensorDy -- defined by myself
577  //
578  Double_t sensor_dy = mSensorDy;
579  Double_t cell_width = 2*sensor_dy/mCells;
580 
581  for (int i=0; i<=mCells; i++) mCellY[i] = cell_width*i - sensor_dy;
582 
583 }
584 
585 //_____________________________________________________________________________
586 Double_t StBTofGeomSensor::GetCellYMin(const Int_t icell)
587 const
588 {
589  Double_t ret = 0;
590  if (icell<=0 || icell>mCells) {
591  LOG_INFO << "cell#=" << icell <<" is out range=[0," << mCells << "]"
592  << endm;
593  } else ret = mCellY[icell-1];
594 
595  return ret;
596 }
597 
598 //_____________________________________________________________________________
599 Double_t StBTofGeomSensor::GetCellYMax(const Int_t icell)
600 const
601 {
602  Double_t ret = 0;
603  if (icell<=0 || icell>mCells) {
604  LOG_INFO << "cell#=" << icell <<" is out range=[0," << mCells << "]"
605  << endm;
606  } else ret = mCellY[icell];
607 
608  return ret;
609 }
610 
611 //_____________________________________________________________________________
612 StThreeVectorD StBTofGeomSensor::GetCellPosition(const Int_t icell)
613 {
614  //
615  // Get the center position of cell in this sensor
616  //
617 
618  static const char* where = "StBTofGeomSensor::GetCellPosition";
619  /*
620  TBRIK *thisBrik = dynamic_cast<TBRIK*> (GetShape());
621  Double_t sensor_dy = thisBrik->GetDy();
622  */
623 
624  // change the size according to the real cells
625  Double_t sensor_dy = mSensorDy;
626  Double_t cell_dy = 2*sensor_dy/mCells;
627 
628  Double_t xl[3], xg[3];
629  if (icell>=1 && icell<=mCells) {
630  xl[0] = 0;
631  xl[1] = (icell*2-1)*cell_dy - sensor_dy;
632  xl[2] = 0;
633  Local2Master(xl,xg);
634  } else { //invalid cell, return (0.,0.,0.)
635  LOG_INFO << "Warning in " << where <<" Invalid cell# =" << icell << endm;
636  xg[0] = 0.;
637  xg[1] = 0.;
638  xg[2] = 0.;
639  }
640 
641  return StThreeVectorD(xg[0],xg[1],xg[2]);
642 }
643 
644 
645 //_____________________________________________________________________________
646 Int_t StBTofGeomSensor::FindCellIndex(const Double_t* local)
647 {
648  //
649  //Look up the cell the local point in
650  //
651 
652  Int_t icell=-1;
653  if ( IsLocalPointIn(local[0],local[1],local[2]) ) {
654 
655  for (Int_t i=0; i<mCells; i++) {
656  if (mCellY[i]<= local[1] && local[1]<=mCellY[i+1]) {
657  icell = i+1;
658  break;
659 
660  }
661  }
662  }
663 
664  return icell;
665 }
666 
667 //_____________________________________________________________________________
668 void StBTofGeomSensor::Print(const Option_t *opt) const
669 {
670  LOG_INFO << "StBTofGeomSensor, module#=" << mModuleIndex << endm;
671  StBTofNode::Print(opt);
672 
673  LOG_INFO << " Cells=" << mCells << "\t Y range for cells=\n";
674  for (Int_t i=0; i<=mCells; i++) LOG_INFO << " : " << mCellY[i];
675  LOG_INFO << endm;
676 }
677 
678 
680 //
681 // StBTofGeometry
682 // ==============
683 //
685 
686 StBTofGeometry *gBTofGeometry = 0;
687 static const Int_t CELLSINMODULE = 6;
688 
689 
690 Bool_t StBTofGeometry::mDebug = kFALSE;
691 bool StBTofGeometry::mGemTofGeom = true; // Consider this default: GEMtof trays are in all Runs13+
692 
693 
694 //_____________________________________________________________________________
695 StBTofGeometry::StBTofGeometry(const char* name, const char* title)
696  : TNamed(name,title)
697 {
698  mCellsInModule = StBTofGeomSensor::GetCells();
699  mModulesInTray = 0;
700  mNValidTrays = 0;
701  mRootFile = 0;
702  mInitFlag = kFALSE;
703  mTopNode = 0;
704  mIsMC = kFALSE;
705  SetAlignFile("");
706 
707  std::fill( mBTofTray, mBTofTray + mNTrays, nullptr );
708  std::fill( &mBTofSensor[0][0], &mBTofSensor[mNTrays][0], nullptr );
709 
710  //
711  //We only need one instance of StBTofGeometry
712  //
713  if (gBTofGeometry) {
714  LOG_INFO << "Warning !! There is already StBTofGeometry at pointer="
715  << (void*)gBTofGeometry << ", so it is deleted"
716  << endm;
717  delete gBTofGeometry;
718  }
719  gBTofGeometry = this;
720 }
721 
722 //_____________________________________________________________________________
723 StBTofGeometry::~StBTofGeometry()
724 {
725  LOG_INFO << "Warning !! StBTofGeometry at pointer =" << (void*)gBTofGeometry
726  << " is deleted" << endm;
727  gBTofGeometry = 0;
728 
729  for(int i=0;i<mNTrays;i++) {
730  if(mBTofTray[i]) delete mBTofTray[i];
731  mBTofTray[i] = 0;
732  for(int j=0;j<mNModules;j++) {
733  if(mBTofSensor[i][j]) delete mBTofSensor[i][j];
734  mBTofSensor[i][j] = 0;
735  }
736  }
737 
738 }
739 
740 //_____________________________________________________________________________
741 void StBTofGeometry::Init(StMaker *maker, TVolume *starHall, TGeoManager* geoManager )
742 {
743  //
744  //Define geometry parameters and establish the geometry
745  //
746  if(maker->Debug()) DebugOn();
747 
748  // Zero out internal alignment arrays
749  std::fill_n(mTrayX0, mNTrays, 0);
750  std::fill_n(mTrayY0, mNTrays, 0);
751  std::fill_n(mTrayZ0, mNTrays, 0);
752 
753  // retrieve align parameters -- need to use db
754 
755  std::array<double, mNTrays> phi0{}, x0{}, z0{};
756 
757  // If not MC input, load the alignment parameters from the database; otherwise ignore.
758  if (mIsMC) {
759  LOG_INFO << "[StBTofGeometry] detected MC-mode: ignore alignment corrections" << endm;
760  } else if (strcmp(mAlignFile.c_str(),"")!=0) {
761  LOG_INFO << "[StBTofGeometry] receiving alignment parameters from input files" << endm;
762  ifstream inData;
763  inData.open(mAlignFile.c_str());
764  if(inData.good()) {
765  for(int i=0;i<mNTrays;i++) {
766  inData >> phi0[i] >> z0[i] >> x0[i];
767  }
768  } else {
769  LOG_WARN << " Bad input file ! Use ideal geometry! " << endm;
770  }
771  inData.close();
772  } else {
773  LOG_INFO << "[StBTofGeometry] retrieving geometry alignment parameters from database" << endm;
774  TDataSet *mDbTOFDataSet = maker->GetDataBase("Calibrations/tof/tofGeomAlign");
775  if (!mDbTOFDataSet) {
776  LOG_WARN << "[StBTofGeometry] unable to find Calibrations/tof/tofGeomAlign! Use ideal geometry!" << endm;
777  } else {
778  St_tofGeomAlign* tofGeomAlign = static_cast<St_tofGeomAlign*>(mDbTOFDataSet->Find("tofGeomAlign"));
779  if(!tofGeomAlign) {
780  LOG_WARN << "Unable to get tof geometry align parameter! Use ideal geometry!" << endm;
781  } else {
782  tofGeomAlign_st* geomAlign = static_cast<tofGeomAlign_st*>(tofGeomAlign->GetArray());
783 
784  for (Int_t i=0;i<mNTrays;i++) {
785  phi0[i] = geomAlign[i].phi0;
786  x0[i] = geomAlign[i].x0;
787  z0[i] = geomAlign[i].z0;
788  }
789  }
790  }
791  }
792 
793  for(int i=0;i<mNTrays;i++) {
794  double phi;
795  if(i<60) {
796  phi = 72 - i*6; // phi angle of tray Id = i+1, west
797  double cs = TMath::Cos(phi*TMath::Pi()/180.);
798  double ss = TMath::Sin(phi*TMath::Pi()/180.);
799  mTrayX0[i] = phi0[i]*ss + x0[i]*cs;
800  mTrayY0[i] = -phi0[i]*cs + x0[i]*ss;
801  mTrayZ0[i] = z0[i];
802  } else {
803  phi = 108 + (i-60)*6; // phi angle of tray Id = i+1, east
804  double cs = TMath::Cos(phi*TMath::Pi()/180.);
805  double ss = TMath::Sin(phi*TMath::Pi()/180.);
806  mTrayX0[i] = -phi0[i]*ss + x0[i]*cs;
807  mTrayY0[i] = phi0[i]*cs + x0[i]*ss;
808  mTrayZ0[i] = -z0[i]; // thus z0 will be the distance between the tray end to the TPC central membrane
809  }
810 
811  if(maker->Debug()) {
812  LOG_DEBUG << " Tray # = " << i+1 << " Align parameters " << mTrayX0[i] << " " << mTrayY0[i] << " " << mTrayZ0[i] << endm;
813  }
814  }
815 
816 /* GEM trays appear in Runs13+
817  * Be certain that you select the correct geometry tag when using this. Y2012 tag and Y2013+ data will generate a bug!
818 */
819 
820  mGemTofGeom = (maker->GetDateTime().GetYear() >=2013);
821 
822  if ( geoManager )
823  InitFrom( *geoManager );
824  else if ( starHall )
825  InitFrom( *starHall );
826  else
827  LOG_ERROR << "StBTofGeometry::Init - Cannot build BTOF geometry without Geant or TGeo input\n";
828 
829 
830 /* Starting with geometry tags in Y2013, GMT units were installed into tof trays 8,23,93, & 108.
831  * This caused a shift in the module index for geant[1-24] instead of daqs [5-28].
832  * This is a correction to shift the geant modules such that they can match with daq info
833  *
834  */
835  if(mGemTofGeom){
836  LOG_INFO << "StBTofGeometry::Init -- GEMTOF-tray module indexes will be corrected for year " << maker->GetDateTime().GetYear() << endm;
837  for(Int_t j=0;j<mModulesInTray;j++){
838  Int_t imod(0);
839  if(mBTofSensor[7][j]){
840  imod = mBTofSensor[7][j]->Index();
841  mBTofSensor[7][j]->SetIndex(imod+4); //The shift is 4
842  }
843  if(mBTofSensor[22][j]){
844  imod = mBTofSensor[22][j]->Index();
845  mBTofSensor[22][j]->SetIndex(imod+4);
846  }
847  if(mBTofSensor[92][j]){
848  imod = mBTofSensor[92][j]->Index();
849  mBTofSensor[92][j]->SetIndex(imod+4);
850  }
851  if(mBTofSensor[107][j]){
852  imod = mBTofSensor[107][j]->Index();
853  mBTofSensor[107][j]->SetIndex(imod+4);
854  }
855  }//for j
856  }//if Year
857 
858  mInitFlag = true;
859 }
860 
861 //_____________________________________________________________________________
862 bool StBTofGeometry::TrayHasGmtModules(int trayId)
863 {
864  // only tag GEM trays 8, 23, 93, and 108 for Runs 13+
865  if (mGemTofGeom) // mGemTofGeom is determined in StBTofGeometry::Init()
866  return trayId == 8 || trayId == 23 || trayId == 93 || trayId == 108;
867  else
868  return false;
869 }
870 
871 //_____________________________________________________________________________
872 void StBTofGeometry::InitFrom(TVolume &starHall)
873 {
874  // Initialize TOFr geometry from STAR geometry
875  // BTofConf -- 0 tray_BTof (default)
876  // 1 full_BTof
877 
878  // Loop over the STAR geometry and mark the volume needed
879  TDataSetIter volume(&starHall,0);
880 
881  TVolume *starDetectorElement = 0;
882  while ( (starDetectorElement = ( TVolume *)volume()) )
883  {
884  // const char *elementName = starDetectorElement->GetName();
885  // Bool_t found = ! ( strcmp(elementName,tofElements[0]) && strcmp(elementName,tofElements[1]) && strcmp(elementName,tofElements[2]) );
886  Bool_t found = ( IsBSEC(starDetectorElement) || IsBTRA(starDetectorElement) || IsBRMD(starDetectorElement) );
887  if (found) {
888 
889  starDetectorElement->SetVisibility(TVolume::kBothVisible);
890  starDetectorElement->Mark();
891  if (starDetectorElement->GetLineColor()==1 || starDetectorElement->GetLineColor()==7)
892  starDetectorElement->SetLineColor(14);
893 
894  } else {
895 
896  starDetectorElement->UnMark();
897  starDetectorElement->SetVisibility(TVolume::kThisUnvisible);
898 
899  }
900  }
901 
902  starHall.SetVisibility(TVolume::kBothVisible);
903  mTopNode = new TVolumeView(starHall,10);
904 
905  mSectorsInBTOH = mTopNode->GetListSize()/2; // # of sectors in one half
906 
908  // save the sensors and trays
910  if(!mTopNode) {
911  LOG_WARN << " No Top Node for Tof Geometry! " << endm;
912  return;
913  }
914  LOG_INFO << "[StBTofGeometry] # of sectors = " << mTopNode->GetListSize() << endm;
915 
916  TVolumePosition *transPos = 0;
917 
918 // TDataSetIter nextDet(mTopNode, 0);
919  TVolumeViewIter nextDet((TVolumeView *)mTopNode, 0);
920  TVolumeView *secVolume = 0;
921  TVolumeView *detVolume = 0;
922  Int_t ibtoh = 0;
923  Int_t isec = 0;
924  Int_t isensor = 0;
925  mNValidTrays = 0;
926  mModulesInTray = 0;
927  StThreeVectorD align{};
928  while ( (detVolume = (TVolumeView *)nextDet()) ) {
929 
930  if(strcmp(detVolume->GetName(), sectorPref)==0) { // sector volume
931  isec++;
932  secVolume = (TVolumeView *)detVolume;
933  continue; // sector continue;
934  }
935  if(strcmp(detVolume->GetName(), trayPref)==0) { // tray volume
936  if ( isec>60 ) ibtoh = 1;
937  int sectorsInBTOH = mTopNode->GetListSize()/2;
938  int trayIndex = ibtoh * sectorsInBTOH + secVolume->GetPosition()->GetId(); // secVolume
939  LOG_DEBUG << " Tray # " << trayIndex << " has # of modules = " << detVolume->GetListSize() << endm;
940  isensor = 0; // clear for this tray
941  if(detVolume->GetListSize()) { // valid tray
942 
943  int itray = trayIndex - 1;
944 
945  align.set(mTrayX0[itray], mTrayY0[itray], mTrayZ0[itray]);
946  transPos = nextDet[0];
947 
948  mNValidTrays++;
949 
950  mBTofTray[mNValidTrays-1] = new StBTofGeomTray(ibtoh, secVolume, mTopNode, align, transPos);
951  delete transPos; transPos = 0;
952 
953  if(mDebug) {
954  LOG_DEBUG << " Initialize and save tray # " << mBTofTray[mNValidTrays-1]->Index() << " with " << detVolume->GetListSize() << " modules" << endm;
955  LOG_DEBUG << " alignment parameters \t" << mTrayX0[itray] << " " << mTrayY0[itray] << " " << mTrayZ0[itray] << endm;
956  mBTofTray[mNValidTrays-1]->Print();
957  }
958 
959  }
960  }
961  if(strcmp(detVolume->GetName(), senPref)==0) { // module volume
962 
963  transPos = nextDet[0];
964 
965  mBTofSensor[mNValidTrays-1][isensor] = new StBTofGeomSensor(detVolume, mTopNode, align, transPos);
966  delete transPos; transPos = 0;
967 
968  if(mDebug) mBTofSensor[mNValidTrays-1][isensor]->Print();
969 
970  isensor++;
971  if(isensor>mModulesInTray) mModulesInTray = isensor;
972  }
973  }
974 
975  mBTofConf = 0;
976  if (mNValidTrays==120) mBTofConf = 1;
977 
978  LOG_INFO << "[StBTofGeometry] Done. NValidTrays = " << mNValidTrays << " NModulesInTray = " << mModulesInTray << endm;
979 
980  if(mDebug) Print();
981 
982  return;
983 
984 }
985 
990 void StBTofGeometry::InitFrom(TGeoManager &geoManager)
991 {
992  mNValidTrays = 0;
993 
994  for (int trayId = 1; trayId <= mNTrays; trayId++)
995  {
996  bool hasGmt = StBTofGeometry::TrayHasGmtModules(trayId);
997 
998  std::string geoPath( FormTGeoPath(geoManager, trayId, hasGmt) );
999 
1000  if ( geoPath.empty() ) {
1001  LOG_WARN << "StBTofGeometry::InitFrom(...) - Cannot find path to BTOF tray "
1002  "(id " << trayId << "). Skipping...\n";
1003  continue;
1004  }
1005 
1006  mNValidTrays++;
1007 
1008  const TGeoPhysicalNode* gpNode = geoManager.MakePhysicalNode( geoPath.c_str() );
1009 
1010  StThreeVectorD align(mTrayX0[trayId-1], mTrayY0[trayId-1], mTrayZ0[trayId-1]);
1011 
1012  mBTofTray[mNValidTrays-1] = new StBTofGeomTray(trayId, *gpNode, align);
1013 
1014  // Loop over the max number of modules (mNModules) that can be present in a tray
1015  int maxModuleId = hasGmt ? 24 : mNModules;
1016 
1017  for(int moduleId = 1; moduleId <= maxModuleId; moduleId++)
1018  {
1019  std::string geoPath( FormTGeoPath(geoManager, trayId, hasGmt, moduleId) );
1020 
1021  if ( geoPath.empty() ) {
1022  LOG_WARN << "StBTofGeometry::InitFrom(...) - Cannot find path to BTOF module "
1023  "(id " << moduleId << "). Skipping...\n";
1024  continue;
1025  }
1026 
1027  const TGeoPhysicalNode* gpNode = geoManager.MakePhysicalNode( geoPath.c_str() );
1028 
1029  mBTofSensor[mNValidTrays-1][moduleId-1] = new StBTofGeomSensor(moduleId, *gpNode, align);
1030  }
1031  }
1032 
1033  mBTofConf = ( mNValidTrays == 120 ? 1 : 0 );
1034 
1035  mModulesInTray = mNModules;
1036 
1037  LOG_INFO << "[StBTofGeometry] Done. NValidTrays = " << mNValidTrays << " NModulesInTray = " << mModulesInTray << endm;
1038 }
1039 
1040 
1046 std::string StBTofGeometry::FormTGeoPath(TGeoManager &geoManager,
1047  int trayId, bool hasGmt, int moduleId)
1048 {
1049  // BTOH_1/BTO1_2 - east/west
1050  // TOF trayId map: west=1-60, east=61-120
1051  int halfId = ( trayId <= 60 ? 1 : 2 );
1052  int sectorId = ( trayId <= 60 ? trayId : trayId - 60 );
1053 
1054  std::ostringstream geoPath;
1055 
1056  // Node paths depend on using TpcRefSys
1057  bool trs = geoManager.FindVolumeFast("TpcRefSys");
1058  geoPath << "/HALL_1/CAVE_1/" << ((trs) ? "TpcRefSys_1/" : "") << "BTOF_1"
1059  << (halfId == 1 ? "/BTOH_" : "/BTO1_") << halfId;
1060 
1061  // Node names depend on whether this sector contains GMT modules
1062  geoPath << ( hasGmt ? "/BSE1_" : "/BSEC_" ) << sectorId
1063  << ( hasGmt ? "/BTR1_1" : "/BTRA_1");
1064 
1065  // Go deeper only when module is requested
1066  if ( moduleId >= 1 )
1067  {
1068  geoPath << ( hasGmt ? "/BXT1_1/BRT1_1/BGM1_1/BRM1_" :
1069  "/BXTR_1/BRTC_1/BGMT_1/BRMD_" )
1070  << moduleId;
1071  }
1072 
1073  bool found = geoManager.CheckPath( geoPath.str().c_str() );
1074 
1075  return found ? geoPath.str() : "";
1076 }
1077 
1078 
1079 //_____________________________________________________________________________
1080 Bool_t StBTofGeometry::ContainOthers(TVolume *element)
1081 {
1082  TVolumeView *elementView = new TVolumeView(*element,1);
1083  TList *list = elementView->GetListOfShapes();
1084  if ( list ) {
1085  LOG_INFO << " yes list in " << element->GetName() << endm;
1086  return kTRUE;
1087  } else {
1088  LOG_INFO << " no list in " << element->GetName() << endm;
1089  return kFALSE;
1090  }
1091 }
1092 
1093 //_____________________________________________________________________________
1094 Bool_t StBTofGeometry::LackThis(const char* fromWhere)
1095 {
1096  if (gBTofGeometry == 0) {
1097  LOG_INFO << " !! Warning from " << fromWhere
1098  << "\n no StBTofGeometry existing, create one instance first"
1099  << endm;
1100  return kTRUE;
1101  } else return kFALSE;
1102 }
1103 
1104 //_____________________________________________________________________________
1105 Int_t StBTofGeometry::CalcCellId(const Int_t volumeId, const Float_t* local)
1106 const
1107 {
1108  Double_t dlocal[3];
1109  dlocal[0] = local[0];
1110  dlocal[1] = local[1];
1111  dlocal[2] = local[2];
1112  return CalcCellId(volumeId,dlocal);
1113 }
1114 
1115 //_____________________________________________________________________________
1116 Int_t StBTofGeometry::CalcCellId(const Int_t volumeId, const Double_t* local)
1117 const
1118 {
1119  //
1120  // Calculate cellID based on volumeId and local position in a sensor
1121  //
1122 
1123  Int_t icell, imodule, itray;
1124  DecodeVolumeId(volumeId, imodule, itray);
1125  StBTofGeomSensor *sensor = GetGeomSensor(imodule, itray);
1126  if (!sensor) return -1;
1127  icell = sensor->FindCellIndex(local);
1128  Int_t ret = CalcCellId(icell, imodule, itray);
1129 
1130  return ret;
1131 }
1132 
1133 //_____________________________________________________________________________
1134 Bool_t StBTofGeometry::IsCellValid(const Int_t icell)
1135 const
1136 {
1137  //
1138  //Check the validity of cell# = [1,mCellsInModule]
1139  //
1140  return (icell>=1 && icell<=mCellsInModule);
1141 }
1142 
1143 //_____________________________________________________________________________
1144 Bool_t StBTofGeometry::IsSensorValid(const Int_t imodule)
1145 const
1146 {
1147  //
1148  //Check the validity of module# = [1,mModulesInTray]
1149  //
1150  return (imodule>=1 && imodule<=mModulesInTray);
1151 }
1152 
1153 //_____________________________________________________________________________
1154 Bool_t StBTofGeometry::IsTrayValid(const Int_t itray)
1155 const
1156 {
1157  //
1158  //Check the validity of tray#
1159  // return kTRUE if found in the tray list
1160  //
1161 
1162  Bool_t ret = kFALSE;
1163  for(int i=0;i<mNValidTrays;i++) {
1164  if(!mBTofTray[i]) continue;
1165  if(mBTofTray[i]->Index() == itray) {
1166  ret = kTRUE;
1167  break;
1168  }
1169  }
1170 
1171  return ret;
1172 }
1173 
1174 //_____________________________________________________________________________
1175 Int_t StBTofGeometry::CalcSensorId(const Int_t imodule, const Int_t itray)
1176 const
1177 {
1178  //
1179  //Encode imodule and itray into SensorId
1180  //
1181 
1182  Int_t sensorId = -1;
1183  if (!IsSensorValid(imodule)) return sensorId;
1184 
1185  Int_t idx = GetAtOfTray(itray);
1186 
1187  if (idx<0) return sensorId;
1188 
1189  sensorId = imodule-1 + mModulesInTray*idx;
1190 
1191  return sensorId;
1192 }
1193 
1194 //_____________________________________________________________________________
1195 Int_t StBTofGeometry::PrevCellId(const Int_t cellId)
1196 const
1197 {
1198  //
1199  //Look up the cell prior to cellId in the same module
1200  // and return the cellId of cell found
1201  //
1202 
1203  Int_t found = -1;
1204  Int_t icell, imodule, itray;
1205  DecodeCellId(cellId,icell,imodule,itray);
1206  StBTofGeomSensor* sensor = GetGeomSensor(imodule,itray);
1207  Int_t icell_p = sensor->PrevCellIndex(icell);
1208 
1209  found = CalcCellId(icell_p,imodule,itray);
1210 
1211  return found;
1212 }
1213 
1214 //_____________________________________________________________________________
1215 Int_t StBTofGeometry::NextCellId(const Int_t cellId)
1216 const
1217 {
1218  //
1219  //Look up the cell prior to cellId in the same module
1220  // and return the cellId of cell found
1221  //
1222 
1223  Int_t found = -1;
1224  Int_t icell, imodule, itray;
1225  DecodeCellId(cellId,icell,imodule,itray);
1226  StBTofGeomSensor* sensor = GetGeomSensor(imodule,itray);
1227  Int_t icell_p = sensor->NextCellIndex(icell);
1228 
1229  found = CalcCellId(icell_p,imodule,itray);
1230 
1231  return found;
1232 }
1233 
1234 //_____________________________________________________________________________
1235 Int_t StBTofGeometry::CalcCellId(const Int_t icell, const Int_t imodule,
1236  const Int_t itray)
1237 const
1238 {
1239  //
1240  //Encode icell, imodule and itray into CellId
1241  //
1242 
1243  Int_t cellId = -1;
1244  if (!IsCellValid(icell)) return cellId;
1245 
1246  Int_t sensorId = CalcSensorId(imodule,itray);
1247  if (sensorId<0) return cellId; //Invalid sensorId
1248 
1249  cellId = icell-1 + mCellsInModule*sensorId;
1250 
1251  return cellId;
1252 }
1253 
1254 //_____________________________________________________________________________
1255 Bool_t StBTofGeometry::DecodeSensorId(const Int_t sensorId,
1256  Int_t &imodule, Int_t &itray)
1257 const
1258 {
1259  //
1260  //decode sensorId into tray#, module# in itray, imodule
1261  //
1262 
1263  imodule = sensorId%mModulesInTray + 1;
1264  if (!IsSensorValid(imodule)) return kFALSE;
1265 
1266  Int_t idx = sensorId/mModulesInTray;
1267 
1268  itray = GetTrayIndexAt(idx);
1269 
1270  StBTofGeomTray *tray = GetGeomTrayAt(idx);
1271  if (!tray) return kFALSE;
1272  itray = tray->Index();
1273 // delete tray;
1274  return kTRUE;
1275 }
1276 
1277 //_____________________________________________________________________________
1278 Bool_t StBTofGeometry::DecodeCellId(const Int_t cellId, Int_t &icell,
1279  Int_t &imodule, Int_t &itray)
1280 const
1281 {
1282  //
1283  //decode cellId into tray#, module#, cell# in itray, imodule, icell
1284  //
1285 
1286  Int_t sensorId = cellId/mCellsInModule;
1287  if (!DecodeSensorId(sensorId,imodule,itray)) return kFALSE;
1288 
1289  icell = cellId%mCellsInModule + 1;
1290 
1291  return IsCellValid(icell);
1292 }
1293 
1294 //_____________________________________________________________________________
1295 Int_t StBTofGeometry::GetCellIndex(const Int_t cellId)
1296 const
1297 {
1298  //
1299  //decode cellId and return cell#
1300  //
1301 
1302  Int_t icell = cellId%mCellsInModule + 1;
1303 
1304  return icell;
1305 }
1306 
1307 //_____________________________________________________________________________
1308 void StBTofGeometry::DecodeVolumeId(const Int_t volumeId,
1309  Int_t &imodule, Int_t &itray)
1310 const
1311 {
1312  //
1313  //decode the volumeId into tray# and module# in itray, imodule
1314  // see the definition of TOFr's volumeId in "pams/sim/g2t/g2t_volume_id.g"
1315  //
1316 
1317  Int_t ires = volumeId;
1318 
1319  Int_t rileft = int(ires/10/100/100);
1320  ires = ires-rileft*100*100*10;
1321 
1322  itray = int(ires/10/100);
1323  ires = ires-itray*100*10;
1324 
1325  imodule = int(ires/10);
1326  // Int_t icell = ires%10; //always 0 since not defined in geant geometry
1327 
1328  itray = itray + (rileft-1)*mSectorsInBTOH;
1329 
1330  return;
1331 }
1332 
1333 //_____________________________________________________________________________
1334 StBTofGeomSensor* StBTofGeometry::GetGeomCell(const Int_t cellId)
1335 const
1336 {
1337  //
1338  //Return StBTofGeomSensor* where the cell of cellId is in
1339  //
1340 
1341  Int_t icell, imodule, itray;
1342  DecodeCellId(cellId, icell, imodule, itray);
1343  StBTofGeomSensor* sensor = GetGeomSensor(imodule, itray);
1344 
1345  return sensor;
1346 }
1347 
1348 //_____________________________________________________________________________
1349 StBTofGeomSensor* StBTofGeometry::GetGeomSensor(const Int_t imodule,
1350  const Int_t itray)
1351 const
1352 {
1353  //
1354  //itray is dummy if itray==0 and it is the current single tray
1355  //
1356 
1357  for(int i=0;i<mNValidTrays;i++) {
1358  if(!mBTofTray[i]) continue;
1359  if(mBTofTray[i]->Index()==itray) {
1360  for(int j=0;j<mModulesInTray;j++) {
1361  if(!mBTofSensor[i][j]) continue;
1362  if(mBTofSensor[i][j]->Index()==imodule) return mBTofSensor[i][j];
1363  }
1364  }
1365  }
1366 
1367  return 0;
1368 }
1369 
1370 //_____________________________________________________________________________
1371 StBTofGeomTray* StBTofGeometry::GetGeomTray(const Int_t itray)
1372 const
1373 {
1374  //
1375  //itray is dummy if itray==0 and it is the current single tray
1376  //
1377 
1378  for(int i=0;i<mNValidTrays;i++) {
1379  if(!mBTofTray[i]) continue;
1380  if(mBTofTray[i]->Index()==itray) return mBTofTray[i];
1381  }
1382  return 0;
1383 }
1384 
1385 //_____________________________________________________________________________
1386 Int_t StBTofGeometry::GetTrayIndexAt(const Int_t idx)
1387 const
1388 {
1389  if (!mTopNode) {
1390  return idx + 1;
1391  }
1392 
1393  //
1394  //Get the tray index at index of the list
1395  //
1396 
1397  TDataSetIter nextSector(mTopNode);
1398  TVolumeView *sectorVolume = 0;
1399  Int_t ibtoh = 0, i = 0;
1400  Int_t itray = -1;
1401  while ( (sectorVolume = (TVolumeView *)nextSector()) ) {
1402  i++;
1403  if ( i>mSectorsInBTOH ) ibtoh = 1;
1404  int trayIndex = ibtoh * mSectorsInBTOH + sectorVolume->GetPosition()->GetId();
1405  if (i==idx) {
1406  itray = trayIndex;
1407  break;
1408  }
1409  }
1410 
1411  return itray;
1412 }
1413 
1414 //_____________________________________________________________________________
1415 StBTofGeomTray* StBTofGeometry::GetGeomTrayAt(const Int_t idx)
1416 const
1417 {
1418  //
1419  //Get the StBTofGeomTray at index of the list
1420  //
1421 
1422  Int_t itray = GetTrayIndexAt(idx);
1423  if(itray<=0||itray>mNTrays) return 0;
1424 
1425  for(int i=0;i<mNValidTrays; i++) {
1426  if(mBTofTray[i] && mBTofTray[i]->Index()==itray) return mBTofTray[i];
1427  }
1428 
1429  return 0;
1430 }
1431 
1432 //_____________________________________________________________________________
1433 Int_t StBTofGeometry::GetAtOfTray(const Int_t itray)
1434 const
1435 {
1436  if (!mTopNode) {
1437  return itray - 1;
1438  }
1439 
1440  //
1441  //Find out the list-index of StBTofGeomTray with TrayIndex=itray
1442  // itray is dummy if itray==0 and it is the current single tray
1443  //
1444 
1445  Int_t at = -1;
1446 
1447  TDataSetIter nextSector(mTopNode);
1448  TVolumeView *sectorVolume = 0;
1449  Int_t ibtoh = 0, i = 0;
1450  while ( (sectorVolume = (TVolumeView *)nextSector()) ) {
1451  i++;
1452  if ( i>mSectorsInBTOH ) ibtoh = 1;
1453  int trayIndex = ibtoh * mSectorsInBTOH + sectorVolume->GetPosition()->GetId();
1454  if (trayIndex == itray) {
1455  at = i;
1456  break;
1457  }
1458  }
1459 
1460  return at;
1461 }
1462 
1463 //_____________________________________________________________________________
1464 void StBTofGeometry::Print(Option_t *opt) const
1465 {
1466  LOG_INFO << "Trays=" << mNValidTrays <<"\t ModulesInTray=" << mModulesInTray
1467  << "\t CellsInModule=" << mCellsInModule << endm;
1468 }
1469 
1470 //_____________________________________________________________________________
1471 Int_t StBTofGeometry::CellIdPointIn(const StThreeVectorD& point)
1472 const
1473 {
1474  //
1475  //Return the ID of cell which containing the global point
1476  //
1477 
1478  Int_t cellId = -1;
1479  Double_t xl[3], xg[3];
1480  xg[0] = point.x();
1481  xg[1] = point.y();
1482  xg[2] = point.z();
1483 
1484  //Loop over trays
1485  //
1486 
1487  Int_t itray = -1, imodule = -1, icell = -1;
1488  for(int i=0;i<mNValidTrays;i++) {
1489  if(!mBTofTray[i]) continue;
1490  if ( mBTofTray[i]->IsGlobalPointIn(point) ) {
1491  itray = mBTofTray[i]->Index();
1492  if ( !(mBTofTray[i]->GetfView()->GetListSize()) ) {
1493  LOG_INFO << " No sensors in tray " << itray << endm;
1494  return cellId;
1495  }
1496 
1497  for( int j=0;j<mModulesInTray;j++) {
1498  if(!mBTofSensor[i][j]) continue;
1499  if ( mBTofSensor[i][j]->IsGlobalPointIn(point) ) {
1500  imodule = mBTofSensor[i][j]->Index();
1501  mBTofSensor[i][j]->Master2Local(xg,xl);
1502  icell = mBTofSensor[i][j]->FindCellIndex(xl);
1503  }
1504  } // end for (j)
1505  } // end if
1506  } // end for (i)
1507 
1508  if ( itray <= 0 || imodule <= 0 ) return cellId;
1509  cellId = CalcCellId(icell, imodule, itray);
1510  return cellId;
1511 }
1512 
1513 //_____________________________________________________________________________
1514 Bool_t StBTofGeometry::HelixCross(const StHelixD &helix)
1515 const
1516 {
1517  //
1518  // return "kTRUE" if any cell is crossed by this helix
1519  //
1520 
1521  IntVec idVec;
1522  DoubleVec pathVec;
1523  PointVec crossVec;
1524 
1525  Bool_t crossed = HelixCrossCellIds(helix,idVec,pathVec,crossVec);
1526 
1527  return crossed;
1528 }
1529 
1530 //_____________________________________________________________________________
1532  IntVec &idVec, DoubleVec &pathVec, PointVec &crossVec)
1533 const
1534 {
1535  //
1536  // return "kTRUE" if any cell is crossed by this helix
1537  // and also fill the cellIds which are crossed by the helix
1538  // and the path length of the helix before crossing the cell
1539  //
1540 
1541  IntVec projTrayVec;
1542  if( !projTrayVector(helix, projTrayVec) ) return kFALSE;
1543 
1544  Double_t pathLen;
1545  Int_t cellId;
1546  StThreeVectorD cross;
1547  idVec.clear();
1548  pathVec.clear();
1549  crossVec.clear();
1550 
1551  for(int i=0;i<mNValidTrays;i++) {
1552  if(!mBTofTray[i]) continue;
1553  int trayId = mBTofTray[i]->Index();
1554 
1556 
1557  bool itrayFind = kFALSE;
1558  for(size_t it=0;it<projTrayVec.size();it++) {
1559  int validtrayId = projTrayVec[it];
1560  if(validtrayId==trayId) {
1561  itrayFind = kTRUE;
1562  break;
1563  }
1564  }
1565  if(!itrayFind) continue;
1566 
1567  for(int j=0;j<mModulesInTray;j++) {
1568  if(!mBTofSensor[i][j]) continue;
1569  int moduleId = mBTofSensor[i][j]->Index();
1570  if ( mBTofSensor[i][j]->HelixCross(helix,pathLen,cross) ) {
1571  Double_t global[3], local[3];
1572  global[0] = cross.x();
1573  global[1] = cross.y();
1574  global[2] = cross.z();
1575  mBTofSensor[i][j]->Master2Local(global,local);
1576  Int_t icell = mBTofSensor[i][j]->FindCellIndex(local);
1577  cellId = CalcCellId(icell, moduleId, trayId);
1578  if (cellId>=0) { // a bug before // reject hit in the edge of module;
1579  pathVec.push_back(pathLen);
1580  idVec.push_back(cellId);
1581  crossVec.push_back(cross);
1582  }
1583  }
1584  } // end for (j)
1585  } // end for (i)
1586 
1587  if (idVec.size()>0) {
1588  // mleak1.PrintMem(" normal return true");
1589  return kTRUE;
1590  }
1591  else {
1592  // mleak1.PrintMem(" normal return false");
1593  return kFALSE;
1594  }
1595 }
1596 
1597 //_____________________________________________________________________________
1599  IntVec &idVec, DoubleVec &pathVec, PointVec &crossVec, DoubleVec &thetaVec)
1600 const
1601 {
1602  //
1603  // return "kTRUE" if any cell is crossed by this helix
1604  // and also fill the cellIds which are crossed by the helix
1605  // and the path length of the helix before crossing the cell
1606  //
1607 
1608  IntVec projTrayVec;
1609  if( !projTrayVector(helix, projTrayVec) ) return kFALSE;
1610 
1611  Double_t pathLen,theta;
1612  Int_t cellId;
1613  StThreeVectorD cross;
1614  idVec.clear();
1615  pathVec.clear();
1616  crossVec.clear();
1617 
1618  for(int i=0;i<mNValidTrays;i++) {
1619  if(!mBTofTray[i]) continue;
1620  int trayId = mBTofTray[i]->Index();
1621 
1623 
1624  bool itrayFind = kFALSE;
1625  for(size_t it=0;it<projTrayVec.size();it++) {
1626  int validtrayId = projTrayVec[it];
1627  if(validtrayId==trayId) {
1628  itrayFind = kTRUE;
1629  break;
1630  }
1631  }
1632  if(!itrayFind) continue;
1633 
1634  for(int j=0;j<mModulesInTray;j++) {
1635  if(!mBTofSensor[i][j]) continue;
1636  int moduleId = mBTofSensor[i][j]->Index();
1637  if ( mBTofSensor[i][j]->HelixCross(helix,pathLen,cross,theta) ) {
1638  Double_t global[3], local[3];
1639  global[0] = cross.x();
1640  global[1] = cross.y();
1641  global[2] = cross.z();
1642  mBTofSensor[i][j]->Master2Local(global,local);
1643  Int_t icell = mBTofSensor[i][j]->FindCellIndex(local);
1644  cellId = CalcCellId(icell, moduleId, trayId);
1645  if (cellId>=0) { // a bug before // reject hit in the edge of module;
1646  pathVec.push_back(pathLen);
1647  idVec.push_back(cellId);
1648  crossVec.push_back(cross);
1649  thetaVec.push_back(theta);
1650 
1651  }
1652  }
1653  } // end for (j)
1654  } // end for (i)
1655 
1656  if (idVec.size()>0) {
1657  // mleak1.PrintMem(" normal return true");
1658  return kTRUE;
1659  }
1660  else {
1661  // mleak1.PrintMem(" normal return false");
1662  return kFALSE;
1663  }
1664 }
1665 
1666 //_____________________________________________________________________________
1667 Bool_t StBTofGeometry::HelixCross(const StHelixD &helix, IntVec validModuleVec, IntVec projTrayVec)
1668 const
1669 {
1670  //
1671  // return "kTRUE" if any cell is crossed by this helix
1672  //
1673 
1674  IntVec idVec;
1675  DoubleVec pathVec;
1676  PointVec crossVec;
1677 
1678  Bool_t crossed = HelixCrossCellIds(helix,validModuleVec, projTrayVec, idVec,pathVec,crossVec);
1679 
1680  return crossed;
1681 }
1682 
1683 
1684 //_____________________________________________________________________________
1685 Bool_t StBTofGeometry::HelixCrossCellIds(const StHelixD &helix, IntVec validModuleVec, IntVec projTrayVec, IntVec &idVec, DoubleVec &pathVec, PointVec &crossVec)
1686 const
1687 {
1689  // optimized :
1690  // input : helix, validModuleVec from DAQ,
1691  // projTrayVec possible hit tray from this helix
1692  // Xin Dong
1694  //
1695  // return "kTRUE" if any cell is crossed by this helix
1696  // and also fill the cellIds which are crossed by the helix
1697  // and the path length of the helix before crossing the cell
1698  //
1699 
1700  if(validModuleVec.size()==0) return kFALSE;
1701  if(projTrayVec.size()==0) return kFALSE;
1702 
1703  Double_t pathLen;
1704  Int_t cellId;
1705  StThreeVectorD cross;
1706  idVec.clear();
1707  pathVec.clear();
1708  crossVec.clear();
1709 
1710  for(int i=0;i<mNValidTrays;i++) {
1711  if(!mBTofTray[i]) continue;
1712  int trayId = mBTofTray[i]->Index();
1713  bool itrayFind = kFALSE;
1714 
1715  for(size_t it=0;it<projTrayVec.size();it++) {
1716  int validtrayId = projTrayVec[it];
1717  if(validtrayId==trayId) {
1718  itrayFind = kTRUE;
1719  break;
1720  }
1721  }
1722  if(!itrayFind) continue;
1723 
1724  // LOG_INFO << " Helix cross sensitive tray " << trayId << endm;
1725 
1726  for(int j=0;j<mModulesInTray;j++) {
1727  if(!mBTofSensor[i][j]) continue;
1728  int moduleId = mBTofSensor[i][j]->Index();
1729  for(size_t iv=0;iv<validModuleVec.size();iv++) {
1730  int validtrayId = validModuleVec[iv]/100;
1731  int validmoduleId = validModuleVec[iv]%100;
1732  if(validtrayId==trayId&&validmoduleId==moduleId) {
1733  if ( mBTofSensor[i][j]->HelixCross(helix,pathLen,cross) ) {
1734  Double_t global[3], local[3];
1735  global[0] = cross.x();
1736  global[1] = cross.y();
1737  global[2] = cross.z();
1738  mBTofSensor[i][j]->Master2Local(global,local);
1739  Int_t icell = mBTofSensor[i][j]->FindCellIndex(local);
1740  cellId = CalcCellId(icell, moduleId, trayId);
1741  if (cellId>=0) { // a bug before // reject hit in the edge of module;
1742  pathVec.push_back(pathLen);
1743  idVec.push_back(cellId);
1744  crossVec.push_back(cross);
1745  }
1746  }
1747  } // endif (tray && module)
1748  } // end for (iv)
1749  } // end for (j)
1750  } // end for (i)
1751 
1752  if (idVec.size()>0) {
1753  // mleak1.PrintMem(" normal return true");
1754  return kTRUE;
1755  }
1756  else {
1757  // mleak1.PrintMem(" normal return false");
1758  return kFALSE;
1759  }
1760 }
1761 
1762 //---------------------------------------------------------------------------
1763 // estimate the possible projection on the TOF tray
1764 Bool_t StBTofGeometry::projTrayVector(const StHelixD &helix, IntVec &trayVec) const {
1765 
1766  trayVec.clear();
1767  double R_tof[2]= {210., 216.}; // inner and outer surfaces
1768 // double res = 5.0;
1769 // second choice - choose 2 neighbouring trays
1770 
1771  for(int i=0;i<2;i++) {
1772 
1773  double s = helix.pathLength(R_tof[i]).first;
1774  if(s<0.) s = helix.pathLength(R_tof[i]).second;
1775  StThreeVectorD point = helix.at(s);
1776  double phi = point.phi()*180/3.14159;
1777  double z = point.z();
1778 
1779  int itray[3] = {0,0,0};
1780  if(z<0) {
1781  // east ring, start from 108 deg (id=61) , clock-wise from east facing west
1782  itray[0] = (255+(int)phi)%360/6+61;
1783  itray[1] = itray[0] - 1;
1784  if(itray[1]<=60) itray[1] += 60;
1785  itray[2] = itray[0] + 1;
1786  if(itray[2]>120) itray[2] -= 60;
1787 // itray[1] = (255+(int)(phi+res))%360/6+61;
1788 // itray[2] = (255+(int)(phi-res))%360/6+61;
1789  } else {
1790  // west ring, start from 72 deg (id=1) , clock-wise from west facing east
1791  itray[0] = (435-(int)phi)%360/6+1;
1792  itray[1] = itray[0] - 1;
1793  if(itray[1]<=0) itray[1] += 60;
1794  itray[2] = itray[0] + 1;
1795  if(itray[2]>60) itray[2] -= 60;
1796 // itray[1] = (435-(int)(phi+res))%360/6+1;
1797 // itray[2] = (435-(int)(phi-res))%360/6+1;
1798  }
1799 
1800  for(int k=0;k<3;k++) {
1801  if(itray[k]<=0 || itray[k]>120) continue;
1802 
1803  bool found = kFALSE;
1804  for(size_t j=0;j<trayVec.size();j++) {
1805  if(trayVec[j]==itray[k]) {
1806  found = kTRUE;
1807  break;
1808  }
1809  }
1810 
1811  if(found) continue;
1812 
1813  trayVec.push_back(itray[k]);
1814  } // end loop k
1815  } // end loop i
1816 
1817 /*
1818  cout << " proj tray id = ";
1819  for(size_t it=0;it<trayVec.size();it++) {
1820  cout << trayVec[it] << " ";
1821  }
1822  cout << endl;
1823 */
1824 
1825  if(trayVec.size()>0) return kTRUE;
1826  else return kFALSE;
1827 }
1828 
1829 /*******************************************************************
1830  * $Log: StBTofGeometry.cxx,v $
1831  * Revision 1.33 2021/04/13 22:35:49 geurts
1832  * Fixed geomtry serious bug in accounting of valid trays and in the handling of GEM-trays pre-Run13 (introduced with v1.14.2.13)
1833  * h/t to Leszek Kosarzewski.
1834  *
1835  * Revision 1.32 2019/08/07 15:56:52 geurts
1836  * Fix node paths when using TpcRefSys (affects runs before 2013)
1837  *
1838  * Revision 1.31 2018/02/26 23:29:12 smirnovd
1839  * StBTofGeometry: Missing flag set to initialize geometry once
1840  *
1841  * I believe this flag should be set but have been overlooked.
1842  * Otherwise why call IsInitDone() in StBTofMatchMaker?
1843  *
1844  * Revision 1.30 2018/02/26 23:29:05 smirnovd
1845  * StBTofGeometry: Simple relation between tray index and id
1846  *
1847  * Revision 1.29 2018/02/26 23:29:00 smirnovd
1848  * StBTofGeometry: Introduced alternative initialization using TGeo geometry
1849  *
1850  * Revision 1.28 2018/02/26 23:28:53 smirnovd
1851  * StBTofGeometry: Added private InitFrom(TGeoManager)
1852  *
1853  * Revision 1.27 2018/02/26 23:28:45 smirnovd
1854  * StBTofGeometry: InitFrom(TVolume*) to InitFrom(TVolume&)
1855  *
1856  * Revision 1.26 2018/02/26 23:28:38 smirnovd
1857  * StBTofGeometry: s/InitFromStar/InitFrom/ and make it private
1858  *
1859  * Revision 1.25 2018/02/26 23:28:22 smirnovd
1860  * StBTofGeometry: New method to form TGeo paths for trays and modules
1861  *
1862  * Revision 1.24 2018/02/26 23:28:14 smirnovd
1863  * StBTofGeomSensor: New constructor accepting TGeo
1864  *
1865  * Revision 1.23 2018/02/26 23:28:07 smirnovd
1866  * StBTofGeoTray: New constructor accepting TGeo
1867  *
1868  * Revision 1.22 2018/02/26 23:28:00 smirnovd
1869  * StBTofNode: New constructor accepting TGeo volume
1870  *
1871  * The new TGeo constructor creates transient TVolume objects to provide
1872  * functionality compatible with the existing TVolume-base geometry
1873  * transformations. Unlike previously, the TVolume objects are owned by this class
1874  * and so have to be deleted.
1875  *
1876  * Revision 1.21 2018/02/26 23:27:53 smirnovd
1877  * Accept reference instead of pointer to xyz alignment
1878  *
1879  * Revision 1.20 2018/02/26 23:27:45 smirnovd
1880  * StBTofGeometry: Senseless assignments in destructors
1881  *
1882  * Revision 1.19 2018/02/26 23:27:38 smirnovd
1883  * StBTofGeometry: Set correct z component for tray alignment
1884  *
1885  * It makes more sense to set the right sign for the z component depending on the
1886  * BTOF half instead of accounting for that sign later.
1887  *
1888  * Revision 1.18 2018/02/26 23:27:30 smirnovd
1889  * StBTofGeometry: C++ style to zero out arrays
1890  *
1891  * Revision 1.17 2018/02/26 23:27:23 smirnovd
1892  * StBTofGeometry: Use std::array in place of plain C arrays
1893  *
1894  * Revision 1.16 2018/02/26 23:27:15 smirnovd
1895  * StBTofGeometry: Removed unused member pointer to non-TGeo ROOT geometry
1896  *
1897  * Revision 1.15 2018/02/26 23:13:19 smirnovd
1898  * Move embedded CVS log messages to the end of file
1899  *
1900  * Revision 1.14 2017/10/20 17:50:33 smirnovd
1901  * Squashed commit of the following:
1902  *
1903  * StBTof: Remove outdated ClassImp macro
1904  *
1905  * Prefer explicit namespace for std:: names in header files
1906  *
1907  * Removed unnecessary specification of default std::allocator
1908  *
1909  * Frank signed-off
1910  *
1911  * Revision 1.13 2014/02/06 21:21:13 geurts
1912  * Fix Index() of modules in GEMTOF trays, only applies to Run 13+ geometries [Joey Butterworth]
1913  *
1914  * Revision 1.12 2011/07/27 16:15:12 geurts
1915  * Alignment calibration modifications [Patrick Huck]:
1916  * - added mAlignFile and SetAlignFile for use in StBTofMatchMaker
1917  * - phi0, x0, z0 made mNTrays dependent
1918  *
1919  * Revision 1.11 2010/09/17 20:40:09 geurts
1920  * Protect Init() and InitFromStar() against non-initialized database/geant.
1921  * No immediate crash, but a LOG_ERROR instead.
1922  *
1923  * Revision 1.10 2010/08/09 18:45:36 geurts
1924  * Include methods in StBTofNode and StBTofGeometry that calculate local theta [Masa]
1925  *
1926  * Revision 1.9 2010/07/14 20:35:28 geurts
1927  * introduce switch to enable ideal MC geometry, without alignment updates. Default: disabled
1928  *
1929  * Revision 1.8 2010/05/25 22:09:44 geurts
1930  * improved database handling and reduced log output
1931  *
1932  * Revision 1.7 2010/04/03 02:00:53 dongx
1933  * X0 (radial offset) included in the tray alignment
1934  *
1935  * Revision 1.6 2009/09/15 00:17:27 dongx
1936  * Corrected the calculation for tray alignment parameters in X-Y
1937  *
1938  * Revision 1.5 2009/08/25 15:41:29 fine
1939  * fix the compilation issues under SL5_64_bits gcc 4.3.2
1940  *
1941  * Revision 1.4 2009/03/18 14:18:18 dongx
1942  * - Optimized the geometry initialization function, reduced the CPU time use
1943  * - Optimized the HelixCrossCellIds() function, now doing the tray fast projection to reduce the loop
1944  *
1945  * Revision 1.3 2009/02/13 00:00:56 dongx
1946  * Tray geometry alignment implemented.
1947  *
1948  * Revision 1.2 2009/02/12 01:45:57 dongx
1949  * Clean up
1950  *
1951  * Revision 1.1 2009/02/02 21:56:54 dongx
1952  * first release - Barrel geometry
1953  */
static const char * sectorPref
filename for alignment input
StBTofGeomTray(const Int_t ibtoh, TVolumeView *sector, TVolumeView *top, const StThreeVectorD &align, TVolumePosition *pos=0)
Control message printing of this class.
Bool_t HelixCrossCellIds(const StHelixD &helix, IntVec &idVec, DoubleVec &pathVec, PointVec &crossVec) const
Double_t mTrayX0[mNTrays]
Alignment parameters.
StBTofNode(TVolumeView *element, TVolumeView *top, const StThreeVectorD &align, TVolumePosition *pos=0)
Control message printing of this class.
void CreateGeomCells()
Control message printing of this class.
static Bool_t mDebug
Alignment parameters.
virtual void SetVisibility(ENodeSEEN vis=TVolume::kBothVisible)
Definition: TVolume.cxx:753
virtual TVolumePosition * Local2Master(const TVolumeView *localNode, const TVolumeView *masterNode=0)
to be documented
virtual Double_t * Local2Master(const Double_t *local, Double_t *master, Int_t nPoints=1) const
static TRotMatrix * GetIdentity()
Return a pointer the &quot;identity&quot; matrix.
Definition: TVolume.cxx:507
pair< double, double > pathLength(double r) const
path length at given r (cylindrical r)
Definition: StHelix.cc:351
string mAlignFile
Control message printing of this class.
static Bool_t mDebug
Control MC input (ignore alignment corrections)
Int_t mSectorsInBTOH
the root file of geometry
virtual TDataSet * Find(const char *path) const
Definition: TDataSet.cxx:362