11 #include <ecl/geometry/ECLGeometryPar.h>
12 #include <framework/logging/Logger.h>
14 #include <G4VTouchable.hh>
15 #include <G4PhysicalVolumeStore.hh>
16 #include <G4NavigationHistory.hh>
17 #include <G4Transform3D.hh>
18 #include <G4Point3D.hh>
19 #include <G4Vector3D.hh>
30 static void Mapping(
int id,
int& ThetaId,
int& PhiId)
32 ThetaId = m_Theta[((
unsigned int)
id) >> 4];
33 PhiId =
id - m_dTheta[ThetaId] * 16 - ThetaId * 128;
36 static void Mapping(
int id,
int& ThetaId,
int& PhiId,
int& nrep,
int& indx)
38 Mapping(
id, ThetaId, PhiId);
40 int off = m_offsets[ThetaId];
41 int i = m_tbl[ThetaId];
46 nrep = (PhiId * r) >> m_RECIPROCAL_SHIFT;
47 indx = off + (PhiId - nrep * d);
50 static int CellID(
int ThetaId,
int PhiId)
52 return PhiId + m_dTheta[ThetaId] * 16 + ThetaId * 128;
55 static int Offset(
int ThetaId)
57 return m_dTheta[ThetaId] + ThetaId * 8;
60 static int Indx2ThetaId(
int indx)
65 static int ThetaId2NCry(
int ThetaId)
67 return m_denom[m_tbl[ThetaId]];
71 static const char m_dTheta[69];
72 static const unsigned char m_Theta[546], m_tbl[69], m_offsets[69];
74 static const unsigned char m_RECIPROCAL_SHIFT = 16;
75 static const unsigned int m_recip[5], m_denom[5];
78 const unsigned char Mapping_t::m_Theta[546] = {
80 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4,
81 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7,
82 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10,
83 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12,
85 13, 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15,
86 16, 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 18,
87 19, 19, 19, 19, 19, 19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 21, 21, 21, 21, 21, 21, 21, 21, 21,
88 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24,
89 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27,
90 28, 28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 30, 30, 30, 30, 30, 30, 30, 30, 30,
91 31, 31, 31, 31, 31, 31, 31, 31, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 33, 33, 33, 33, 33, 33, 33, 33, 33,
92 34, 34, 34, 34, 34, 34, 34, 34, 34, 35, 35, 35, 35, 35, 35, 35, 35, 35, 36, 36, 36, 36, 36, 36, 36, 36, 36,
93 37, 37, 37, 37, 37, 37, 37, 37, 37, 38, 38, 38, 38, 38, 38, 38, 38, 38, 39, 39, 39, 39, 39, 39, 39, 39, 39,
94 40, 40, 40, 40, 40, 40, 40, 40, 40, 41, 41, 41, 41, 41, 41, 41, 41, 41, 42, 42, 42, 42, 42, 42, 42, 42, 42,
95 43, 43, 43, 43, 43, 43, 43, 43, 43, 44, 44, 44, 44, 44, 44, 44, 44, 44, 45, 45, 45, 45, 45, 45, 45, 45, 45,
96 46, 46, 46, 46, 46, 46, 46, 46, 46, 47, 47, 47, 47, 47, 47, 47, 47, 47, 48, 48, 48, 48, 48, 48, 48, 48, 48,
97 49, 49, 49, 49, 49, 49, 49, 49, 49, 50, 50, 50, 50, 50, 50, 50, 50, 50, 51, 51, 51, 51, 51, 51, 51, 51, 51,
98 52, 52, 52, 52, 52, 52, 52, 52, 52, 53, 53, 53, 53, 53, 53, 53, 53, 53, 54, 54, 54, 54, 54, 54, 54, 54, 54,
99 55, 55, 55, 55, 55, 55, 55, 55, 55, 56, 56, 56, 56, 56, 56, 56, 56, 56, 57, 57, 57, 57, 57, 57, 57, 57, 57,
100 58, 58, 58, 58, 58, 58, 58, 58, 58,
102 59, 59, 59, 59, 59, 59, 59, 59, 59, 60, 60, 60, 60, 60, 60, 60, 60, 60,
103 61, 61, 61, 61, 61, 61, 62, 62, 62, 62, 62, 62,
104 63, 63, 63, 63, 63, 63, 64, 64, 64, 64, 64, 64,
105 65, 65, 65, 65, 65, 65,
106 66, 66, 66, 66, 67, 67, 67, 67, 68, 68, 68, 68
109 const char Mapping_t::m_dTheta[69] = {
110 0, -5, -10, -14, -18, -22, -24, -26, -28, -30, -32, -34, -33,
112 -32, -31, -30, -29, -28, -27, -26, -25, -24,
113 -23, -22, -21, -20, -19, -18, -17, -16, -15,
114 -14, -13, -12, -11, -10, -9, -8, -7, -6,
115 -5, -4, -3, -2, -1, 0, 1, 2, 3,
116 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
118 14, 15, 16, 14, 12, 10, 8, 6, 2, -2
121 const unsigned char Mapping_t::m_tbl[69] = {
122 1, 1, 2, 2, 2, 3, 3, 3, 3, 3, 3, 4, 4,
124 0, 0, 0, 0, 0, 0, 0, 0, 0,
125 0, 0, 0, 0, 0, 0, 0, 0, 0,
126 0, 0, 0, 0, 0, 0, 0, 0, 0,
127 0, 0, 0, 0, 0, 0, 0, 0, 0,
128 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
130 4, 4, 3, 3, 3, 3, 3, 2, 2, 2
133 const unsigned char Mapping_t::m_offsets[69] = {
134 0, 3, 6, 10, 14, 18, 24, 30, 36, 42, 48, 54, 63,
136 132, 134, 136, 138, 140, 142, 144, 146, 148,
137 150, 152, 154, 156, 158, 160, 162, 164, 166,
138 168, 170, 172, 174, 176, 178, 180, 182, 184,
139 186, 188, 190, 192, 194, 196, 198, 200, 202,
140 204, 206, 208, 210, 212, 214, 216, 218, 220, 222,
142 72, 81, 90, 96, 102, 108, 114, 120, 124, 128
145 #define pack(x) ((1<<Mapping_t::m_RECIPROCAL_SHIFT)/x+1)
146 const unsigned int Mapping_t::m_recip[] = {pack(2), pack(3), pack(4), pack(6), pack(9)};
147 const unsigned int Mapping_t::m_denom[] = { (2), (3), (4), (6), (9)};
153 if (!m_B4ECLGeometryParDB) m_B4ECLGeometryParDB =
new ECLGeometryPar();
154 return m_B4ECLGeometryParDB;
157 ECLGeometryPar::ECLGeometryPar()
164 ECLGeometryPar::~ECLGeometryPar()
166 if (m_B4ECLGeometryParDB) {
167 delete m_B4ECLGeometryParDB;
168 B2DEBUG(150,
"m_B4ECLGeometryParDB deleted ");
170 if (m_ECLForwardGlobalT)
delete m_ECLForwardGlobalT;
171 if (m_ECLBarrelGlobalT)
delete m_ECLBarrelGlobalT;
172 if (m_ECLBackwardGlobalT)
delete m_ECLBackwardGlobalT;
175 void ECLGeometryPar::clear()
186 void ParticleGunParameters(
const G4String& comment,
const G4ThreeVector& n,
const G4ThreeVector& r0,
double dphi)
188 cout << comment << endl;
189 cout <<
"Center position = " << r0 <<
", Direction = " << n << endl;
191 double t = -(n.z() * r0.z() - n * r0) / (n.z() * n.z() - n * n);
192 G4ThreeVector r = n * t + r0;
193 cout <<
"Closest point to z-axis = " << r << endl;
194 const double r2d = 180 / M_PI;
195 double th = r2d * n.theta();
196 double phi = r2d * n.phi();
199 cout <<
" 'thetaParams': [" << th <<
", " << th <<
"]," << endl;
200 cout <<
" 'phiParams': [" << phi <<
"+0*" << dphi <<
", " << phi <<
"+0*" << dphi <<
"]," << endl;
201 cout <<
" 'zVertexParams': [" << z <<
", " << z <<
"]" << endl;
204 G4Transform3D getT(
const G4VPhysicalVolume& v)
206 return G4Transform3D(v.GetObjectRotationValue(), v.GetObjectTranslation());
209 G4Transform3D getT(
const G4String& n)
211 G4PhysicalVolumeStore* store = G4PhysicalVolumeStore::GetInstance();
223 G4VPhysicalVolume* v = store->GetVolume(n);
227 void print_trans(
const G4Transform3D& t)
229 for (
int i = 0; i < 4; i++) {
230 for (
int j = 0; j < 3; j++)
231 cout << t(j, i) <<
" ";
236 void ECLGeometryPar::read()
239 m_crystals.reserve(46 * 2 + 132);
246 G4Point3D p0(0, 0, 0); G4Vector3D v0(0, 0, 1);
249 m_ECLForwardGlobalT =
new G4Transform3D(getT(
"ECLForwardPhysical"));
250 G4Transform3D T = getT(
"ECLForwardCrystalSectorPhysical_1");
251 G4String tnamef(
"ECLForwardWrappedCrystal_Physical_");
252 for (
int i = 0; i < 72; i++) {
253 G4String vname(tnamef); vname += to_string(i);
254 G4Transform3D cT = T * getT(vname);
256 m_crystals.push_back(c);
262 m_ECLBackwardGlobalT =
new G4Transform3D(getT(
"ECLBackwardPhysical"));
263 G4Transform3D T = getT(
"ECLBackwardCrystalSectorPhysical_0");
264 G4String tnamef(
"ECLBackwardWrappedCrystal_Physical_");
265 for (
int i = 0; i < 60; i++) {
266 G4String vname(tnamef); vname += to_string(i);
267 G4Transform3D cT = T * getT(vname);
269 m_crystals.push_back(c);
278 m_ECLBarrelGlobalT =
new G4Transform3D(getT(
"ECLBarrelSectorPhysical_0") * G4RotateZ3D(M_PI / 2));
279 G4Transform3D Ts = G4RotateZ3D(-M_PI / 2);
283 G4Transform3D Ts1 = G4RotateZ3D(M_PI / 36) * Ts;
285 G4String tname(
"ECLBarrelWrappedCrystal_Physical_");
286 for (
int i = 0; i < 2 * 46; i++) {
287 G4String vname(tname); vname += to_string(i);
288 G4Transform3D cT = ((i % 2) ? Ts1 : Ts) * getT(vname);
290 m_crystals.push_back(c);
295 B2DEBUG(150,
"ECLGeometryPar::read() initialized with " << m_crystals.size() <<
" crystals.");
299 void sincos(
const double* ss,
int iphi,
double& s,
double& c)
305 if (iq & 1) {
int t = is; is = ic; ic = t;}
309 if ((((0 << 0) + (0 << 1) + (1 << 2) + (1 << 3)) >> iq) & 1) ls = -ls;
310 if ((((0 << 0) + (1 << 1) + (1 << 2) + (0 << 3)) >> iq) & 1) lc = -lc;
315 const double ss72[] = {
316 0.0000000000000000000000,
317 0.0871557427476581735581,
318 0.1736481776669303488517,
319 0.2588190451025207623489,
320 0.3420201433256687330441,
321 0.4226182617406994361870,
322 0.5000000000000000000000,
323 0.5735764363510460961080,
324 0.6427876096865393263226,
325 0.7071067811865475244008,
326 0.7660444431189780352024,
327 0.8191520442889917896845,
328 0.8660254037844386467637,
329 0.9063077870366499632426,
330 0.9396926207859083840541,
331 0.9659258262890682867497,
332 0.9848077530122080593667,
333 0.9961946980917455322950,
334 1.0000000000000000000000
337 const double ss16[] = {
338 0.0000000000000000000000,
339 0.3826834323650897717285,
340 0.7071067811865475244008,
341 0.9238795325112867561282,
342 1.0000000000000000000000
345 void ECLGeometryPar::InitCrystal(
int cid)
347 if (m_crystals.size() == 0) read();
348 int thetaid, phiid, nreplica, indx;
349 Mapping_t::Mapping(cid, thetaid, phiid, nreplica, indx);
354 sincos<72>(ss72, nreplica, s, c);
356 sincos<16>(ss16, nreplica, s, c);
360 T = m_ECLForwardGlobalT;
361 }
else if (cid < 7776) {
362 T = m_ECLBarrelGlobalT;
364 T = m_ECLBackwardGlobalT;
367 double xp = c * t.pos.x() - s * t.pos.y();
368 double yp = s * t.pos.x() + c * t.pos.y();
371 double xv = c * t.dir.x() - s * t.dir.y();
372 double yv = s * t.dir.x() + c * t.dir.y();
375 m_current_crystal.pos = (1 / CLHEP::cm) * (*T * G4Point3D(xp, yp, t.pos.z()));
376 m_current_crystal.dir = *T * G4Vector3D(xv, yv, t.dir.z());
382 int ECLGeometryPar::GetCellID(
int ThetaId,
int PhiId)
384 return Mapping_t::CellID(ThetaId, PhiId);
387 void ECLGeometryPar::Mapping(
int cid)
390 Mapping_t::Mapping(mPar_cellID, mPar_thetaID, mPar_phiID);
393 int ECLGeometryPar::TouchableDiodeToCellID(
const G4VTouchable* touch)
395 return TouchableToCellID(touch);
398 int ECLGeometryPar::TouchableToCellID(
const G4VTouchable* touch)
403 const G4NavigationHistory* h = touch->GetHistory();
404 int hd = h->GetDepth();
405 int i1 = h->GetReplicaNo(hd - 1);
406 int i2 = h->GetReplicaNo(hd - 2);
408 int ThetaId = Mapping_t::Indx2ThetaId(i1);
409 int NCryst = Mapping_t::ThetaId2NCry(ThetaId);
410 int Offset = Mapping_t::Offset(ThetaId);
412 int ik = i1 - Offset;
415 PhiId = (i2 - (ik % 2)) * NCryst + ik;
416 if (PhiId < 0) PhiId += 144;
418 int i3 = h->GetReplicaNo(hd - 3);
420 PhiId = (i2 + 2 * i3) * NCryst + ik;
427 int i3r = (3 - (i3 % 4)) + 4 * (i3 / 4);
428 PhiId = (2 * i3r + (1 - i2)) * NCryst + ik;
432 int cellID = Offset * 16 + PhiId;
437 G4AffineTransform t = h->GetTopTransform();
438 G4ThreeVector o(0, 0, 0), n(0, 0, 1);
439 G4ThreeVector ro = t.Inverse().TransformPoint(o);
440 G4ThreeVector
rn = t.Inverse().TransformAxis(n);
445 G4ThreeVector dr = m_current_crystal.pos - ro, dn = m_current_crystal.dir -
rn;
446 if (dr.mag() > 1e-10 || dn.mag() > 1e-10) {
447 cout <<
"Missmatch " << h->GetVolume(hd - 1)->GetName() <<
" " << cellID <<
" " << ThetaId <<
" " << PhiId <<
" " << NCryst <<
" "
448 << hd <<
" " << i2 <<
" " << i1 <<
" " << m_current_crystal.pos <<
" " << ro <<
" " <<
rn <<
" " << dr <<
" " << dn << endl;
450 for (
int i = 0; i < 144; i++) {
451 int ci = Mapping_t::CellID(ThetaId, i);
453 dr = m_current_crystal.pos - ro;
454 if (dr.mag() < 1e-10) cout <<
"best PhiId = " << i << endl;
461 int ECLGeometryPar::ECLVolumeToCellID(
const G4VTouchable* touch)
463 int depth = touch->GetHistoryDepth();
464 if ((depth != 3) && (depth != 5)) {
465 B2WARNING(
"ECLGeometryPar::ECLVolumeToCellID: History depth = " << depth <<
" is out of range: should be 3 or 5.");
468 const G4String& vname = touch->GetVolume()->GetName();
469 std::size_t pos0 = vname.find(
"lv_forward_crystal_");
470 std::size_t pos1 = vname.find(
"lv_barrel_crystal_");
471 std::size_t pos2 = vname.find(
"lv_backward_crystal_");
472 if (pos0 == string::npos && pos1 == string::npos && pos2 == string::npos) {
473 B2WARNING(
"ECLGeometryPar::ECLVolumeToCellID: Volume name does not match pattern. NAME=" << vname);
476 return TouchableToCellID(touch);
479 double ECLGeometryPar::time2sensor(
int cid,
const G4ThreeVector& hit_pos)
481 if (cid != m_ini_cid) InitCrystal(cid);
482 double z = 15. - (hit_pos - m_current_crystal.pos) * m_current_crystal.dir;
483 double dt = 6.05 + z * (0.0749 - z * 0.00112);
496 m_nbrs(*new std::vector<
Identifier > (aNbr.m_nbrs)) ,
497 m_nearSize(aNbr.m_nearSize)
505 const std::vector< Identifier >& aNbrs ,
506 const std::vector< Identifier >::size_type aNearSize
508 m_nbrs(*new std::vector<
Identifier > (aNbrs)) ,
509 m_nearSize(aNearSize)
512 std::sort(
m_nbrs.begin() ,
m_nbrs.begin() + aNearSize , std::less< Identifier >()) ;
513 std::sort(
m_nbrs.begin() + aNearSize ,
m_nbrs.end() , std::less< Identifier >()) ;
523 unsigned short i(0) ;
524 for (std::vector< EclNbr::Identifier >::const_iterator
525 iNbr(aNbr.
nbrs().begin()) ;
526 iNbr != aNbr.
nbrs().end() ; ++iNbr) {
528 if (iNbr != aNbr.
nbrs().begin() && i != aNbr.
nearSize() + 1) os <<
"," ;
529 if (i == aNbr.
nearSize() + 1) os <<
"|" ;
530 os << std::setw(4) << (*iNbr) ;
539 unsigned short Nri(0) ;
541 for (std::vector< EclNbr::Identifier >::const_iterator
543 iNbr !=
m_nbrs.end() ; ++iNbr) {
547 cout << std::setw(4) << (*iNbr) ;
576 const std::vector< EclNbr::Identifier >&
582 const std::vector< EclNbr::Identifier >::const_iterator
588 const std::vector< EclNbr::Identifier >::const_iterator
594 const std::vector< EclNbr::Identifier >::const_iterator
600 const std::vector< EclNbr::Identifier >::const_iterator
606 std::vector< EclNbr::Identifier >::size_type
612 std::vector< EclNbr::Identifier >::size_type
619 int EclNbr::GetCellID(
int ThetaId,
int PhiId)
638 const int cellID = aCellId;
642 std::vector< EclNbr::Identifier >::size_type
nearSize(0);
643 std::vector< EclNbr::Identifier > vNbr;
648 int tm1 = thetaId - 1;
649 int tm2 = thetaId - 2;
650 int tp1 = thetaId + 1;
651 int tp2 = thetaId + 2;
653 if (aCellId > 1151 && aCellId < 7776) {
662 int fm1 = (phiId + 143) % 144;
663 int fp1 = (phiId + 1) % 144;
664 int fm2 = (phiId + 142) % 144;
665 int fp2 = (phiId + 2) % 144;
702 if (aCellId < 1153) {
703 const EclIdentifier mPerRingForward[]
704 = { 48, 48, 64, 64, 64, 96, 96, 96, 96, 96, 96, 144, 144, 144, 144 };
705 if (thetaId > 1) nm2 = mPerRingForward[ thetaId - 2 ];
706 if (thetaId > 0) nm1 = mPerRingForward[ thetaId - 1 ];
707 n00 = mPerRingForward[ thetaId ];
708 np1 = mPerRingForward[ thetaId + 1 ];
709 np2 = mPerRingForward[ thetaId + 2 ];
711 const EclIdentifier mPerRingBackward[]
712 = { 64, 64, 64, 96, 96, 96, 96, 96, 144, 144, 144, 144 };
713 if (thetaId < 67) np2 = mPerRingBackward[ 66 - thetaId ];
714 if (thetaId < 68) np1 = mPerRingBackward[ 67 - thetaId ];
715 n00 = mPerRingBackward[ 68 - thetaId ];
716 nm1 = mPerRingBackward[ 69 - thetaId ];
717 nm2 = mPerRingBackward[ 70 - thetaId ];
724 int fp100 = (f0000 * np1 + np1 / 2) / n00;
725 int fp200 = (f0000 * np2 + np2 / 2) / n00;
726 int fm100 = (f0000 * nm1 + nm1 / 2) / n00;
727 int fm200 = (f0000 * nm2 + nm2 / 2) / n00;
729 int f00m1 = (f0000 + n00 - 1) % n00;
730 int f00m2 = (f0000 + n00 - 2) % n00;
731 int f00p1 = (f0000 + 1) % n00;
732 int f00p2 = (f0000 + 2) % n00;
734 int fp1m1 = (fp100 + np1 - 1) % np1;
735 int fp1m2 = (fp100 + np1 - 2) % np1;
736 int fp1p1 = (fp100 + 1) % np1;
737 int fp1p2 = (fp100 + 2) % np1;
739 int fm1m1 = (fm100 + nm1 - 1) % nm1;
740 int fm1m2 = (fm100 + nm1 - 2) % nm1;
741 int fm1p1 = (fm100 + 1) % nm1;
742 int fm1p2 = (fm100 + 2) % nm1;
744 int fp2m1 = (fp200 + np2 - 1) % np2;
745 int fp2m2 = (fp200 + np2 - 2) % np2;
746 int fp2p1 = (fp200 + 1) % np2;
747 int fp2p2 = (fp200 + 2) % np2;
749 int fm2m1 = (fm200 + nm2 - 1) % nm2;
750 int fm2m2 = (fm200 + nm2 - 2) % nm2;
751 int fm2p1 = (fm200 + 1) % nm2;
752 int fm2p2 = (fm200 + 2) % nm2;
753 int delta = n00 / 16;
755 int nth = phiId % delta;
770 if ((nth == 0) || (nth == 1)) {
774 }
else if ((nth == 2) || (nth == 3)) {
781 if ((nth == 0) || (nth == 3)) {
782 fm2p2 = fm2m2 = 1000;
783 }
else if (nth == 1) {
785 }
else if (nth == 2) {
790 if ((nth == 2) || (nth == 5)) {
802 if ((nth == 0) || (nth == 2) || (nth == 3) || (nth == 5)) {
807 if ((nth == 2) || (nth == 5) || (nth == 8)) {
819 if ((nth == 0) || (nth == 2) || (nth == 3)
820 || (nth == 5) || (nth == 6) || (nth == 8))
824 if ((nth == 2) || (nth == 5)) {
836 if ((nth == 0) || (nth == 2) || (nth == 3) || (nth == 5))
840 if ((nth == 2) || (nth == 5) || (nth == 8)) {
852 if ((nth == 0) || (nth == 2) || (nth == 3) || (nth == 5)
853 || (nth == 6) || (nth == 8))