10#include <ecl/geometry/ECLGeometryPar.h>
13#include <ecl/dataobjects/ECLElementNumbers.h>
16#include <framework/logging/Logger.h>
19#include <G4NavigationHistory.hh>
20#include <G4PhysicalVolumeStore.hh>
21#include <G4Point3D.hh>
22#include <G4Transform3D.hh>
23#include <G4Vector3D.hh>
24#include <G4VTouchable.hh>
39 static void Mapping(
int id,
int& ThetaId,
int& PhiId)
41 ThetaId =
m_Theta[((
unsigned int)
id) >> 4];
42 PhiId =
id -
m_dTheta[ThetaId] * 16 - ThetaId * 128;
46 static void Mapping(
int id,
int& ThetaId,
int& PhiId,
int& nrep,
int& indx)
51 int i =
m_tbl[ThetaId];
57 indx = off + (PhiId - nrep * d);
61 static int CellID(
int ThetaId,
int PhiId)
63 return PhiId +
m_dTheta[ThetaId] * 16 + ThetaId * 128;
69 return m_dTheta[ThetaId] + ThetaId * 8;
87 static const unsigned char m_tbl[69];
97 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4,
98 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7,
99 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10,
100 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12,
102 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,
103 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,
104 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,
105 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,
106 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,
107 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,
108 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,
109 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,
110 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,
111 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,
112 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,
113 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,
114 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,
115 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,
116 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,
117 58, 58, 58, 58, 58, 58, 58, 58, 58,
119 59, 59, 59, 59, 59, 59, 59, 59, 59, 60, 60, 60, 60, 60, 60, 60, 60, 60,
120 61, 61, 61, 61, 61, 61, 62, 62, 62, 62, 62, 62,
121 63, 63, 63, 63, 63, 63, 64, 64, 64, 64, 64, 64,
122 65, 65, 65, 65, 65, 65,
123 66, 66, 66, 66, 67, 67, 67, 67, 68, 68, 68, 68
127 0, -5, -10, -14, -18, -22, -24, -26, -28, -30, -32, -34, -33,
129 -32, -31, -30, -29, -28, -27, -26, -25, -24,
130 -23, -22, -21, -20, -19, -18, -17, -16, -15,
131 -14, -13, -12, -11, -10, -9, -8, -7, -6,
132 -5, -4, -3, -2, -1, 0, 1, 2, 3,
133 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
135 14, 15, 16, 14, 12, 10, 8, 6, 2, -2
139 1, 1, 2, 2, 2, 3, 3, 3, 3, 3, 3, 4, 4,
141 0, 0, 0, 0, 0, 0, 0, 0, 0,
142 0, 0, 0, 0, 0, 0, 0, 0, 0,
143 0, 0, 0, 0, 0, 0, 0, 0, 0,
144 0, 0, 0, 0, 0, 0, 0, 0, 0,
145 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
147 4, 4, 3, 3, 3, 3, 3, 2, 2, 2
151 0, 3, 6, 10, 14, 18, 24, 30, 36, 42, 48, 54, 63,
153 132, 134, 136, 138, 140, 142, 144, 146, 148,
154 150, 152, 154, 156, 158, 160, 162, 164, 166,
155 168, 170, 172, 174, 176, 178, 180, 182, 184,
156 186, 188, 190, 192, 194, 196, 198, 200, 202,
157 204, 206, 208, 210, 212, 214, 216, 218, 220, 222,
159 72, 81, 90, 96, 102, 108, 114, 120, 124, 128
162#define pack(x) ((1<<Mapping_t::m_RECIPROCAL_SHIFT)/x+1)
163const unsigned int Mapping_t::m_recip[] = {pack(2), pack(3), pack(4), pack(6), pack(9)};
185 B2DEBUG(150,
"m_B4ECLGeometryParDB deleted ");
203void ParticleGunParameters(
const G4String& comment,
const G4ThreeVector& n,
const G4ThreeVector& r0,
double dphi)
205 cout << comment << endl;
206 cout <<
"Center position = " << r0 <<
", Direction = " << n << endl;
208 double t = -(n.z() * r0.z() - n * r0) / (n.z() * n.z() - n * n);
209 G4ThreeVector r = n * t + r0;
210 cout <<
"Closest point to z-axis = " << r << endl;
211 const double r2d = 180 / M_PI;
212 double th = r2d * n.theta();
213 double phi = r2d * n.phi();
216 cout <<
" 'thetaParams': [" << th <<
", " << th <<
"]," << endl;
217 cout <<
" 'phiParams': [" << phi <<
"+0*" << dphi <<
", " << phi <<
"+0*" << dphi <<
"]," << endl;
218 cout <<
" 'zVertexParams': [" << z <<
", " << z <<
"]" << endl;
221G4Transform3D getT(
const G4VPhysicalVolume& v)
223 return G4Transform3D(v.GetObjectRotationValue(), v.GetObjectTranslation());
226G4Transform3D getT(
const G4String& n)
228 G4PhysicalVolumeStore* store = G4PhysicalVolumeStore::GetInstance();
240 G4VPhysicalVolume* v = store->GetVolume(n);
244void print_trans(
const G4Transform3D& t)
246 for (
int i = 0; i < 4; i++) {
247 for (
int j = 0; j < 3; j++)
248 cout << t(j, i) <<
" ";
263 G4Point3D p0(0, 0, 0); G4Vector3D v0(0, 0, 1);
267 G4Transform3D T = getT(
"ECLForwardCrystalSectorPhysical_1");
268 G4String tnamef(
"ECLForwardWrappedCrystal_Physical_");
269 for (
int i = 0; i < 72; i++) {
270 G4String vname(tnamef); vname += to_string(i);
271 G4Transform3D cT = T * getT(vname);
280 G4Transform3D T = getT(
"ECLBackwardCrystalSectorPhysical_0");
281 G4String tnamef(
"ECLBackwardWrappedCrystal_Physical_");
282 for (
int i = 0; i < 60; i++) {
283 G4String vname(tnamef); vname += to_string(i);
284 G4Transform3D cT = T * getT(vname);
295 m_ECLBarrelGlobalT =
new G4Transform3D(getT(
"ECLBarrelSectorPhysical_0") * G4RotateZ3D(M_PI / 2));
296 G4Transform3D Ts = G4RotateZ3D(-M_PI / 2);
300 G4Transform3D Ts1 = G4RotateZ3D(M_PI / 36) * Ts;
302 G4String tname(
"ECLBarrelWrappedCrystal_Physical_");
303 for (
int i = 0; i < 2 * 46; i++) {
304 G4String vname(tname); vname += to_string(i);
305 G4Transform3D cT = ((i % 2) ? Ts1 : Ts) * getT(vname);
312 B2DEBUG(150,
"ECLGeometryPar::read() initialized with " <<
m_crystals.size() <<
" crystals.");
316void sincos(
const double* ss,
int iphi,
double& s,
double& c)
322 if (iq & 1) {
int t = is; is = ic; ic = t;}
326 if ((((0 << 0) + (0 << 1) + (1 << 2) + (1 << 3)) >> iq) & 1) ls = -ls;
327 if ((((0 << 0) + (1 << 1) + (1 << 2) + (0 << 3)) >> iq) & 1) lc = -lc;
332const double ss72[] = {
333 0.0000000000000000000000,
334 0.0871557427476581735581,
335 0.1736481776669303488517,
336 0.2588190451025207623489,
337 0.3420201433256687330441,
338 0.4226182617406994361870,
339 0.5000000000000000000000,
340 0.5735764363510460961080,
341 0.6427876096865393263226,
342 0.7071067811865475244008,
343 0.7660444431189780352024,
344 0.8191520442889917896845,
345 0.8660254037844386467637,
346 0.9063077870366499632426,
347 0.9396926207859083840541,
348 0.9659258262890682867497,
349 0.9848077530122080593667,
350 0.9961946980917455322950,
351 1.0000000000000000000000
354const double ss16[] = {
355 0.0000000000000000000000,
356 0.3826834323650897717285,
357 0.7071067811865475244008,
358 0.9238795325112867561282,
359 1.0000000000000000000000
365 int thetaid, phiid, nreplica, indx;
371 sincos<72>(ss72, nreplica, s, c);
373 sincos<16>(ss16, nreplica, s, c);
384 double xp = c * t.pos.x() - s * t.pos.y();
385 double yp = s * t.pos.x() + c * t.pos.y();
388 double xv = c * t.dir.x() - s * t.dir.y();
389 double yv = s * t.dir.x() + c * t.dir.y();
420 const G4NavigationHistory* h = touch->GetHistory();
421 int hd = h->GetDepth();
422 int i1 = h->GetReplicaNo(hd - 1);
423 int i2 = h->GetReplicaNo(hd - 2);
429 int ik = i1 - Offset;
432 PhiId = (i2 - (ik % 2)) * NCryst + ik;
433 if (PhiId < 0) PhiId += 144;
435 int i3 = h->GetReplicaNo(hd - 3);
437 PhiId = (i2 + 2 * i3) * NCryst + ik;
444 int i3r = (3 - (i3 % 4)) + 4 * (i3 / 4);
445 PhiId = (2 * i3r + (1 - i2)) * NCryst + ik;
449 int cellID = Offset * 16 + PhiId;
454 G4AffineTransform t = h->GetTopTransform();
455 G4ThreeVector o(0, 0, 0), n(0, 0, 1);
456 G4ThreeVector ro = t.Inverse().TransformPoint(o);
457 G4ThreeVector
rn = t.Inverse().TransformAxis(n);
463 if (dr.mag() > 1e-10 || dn.mag() > 1e-10) {
464 cout <<
"Mismatch " << h->GetVolume(hd - 1)->GetName() <<
" " << cellID <<
" " << ThetaId <<
" " << PhiId <<
" " << NCryst <<
" "
465 << hd <<
" " << i2 <<
" " << i1 <<
" " <<
m_current_crystal.
pos <<
" " << ro <<
" " <<
rn <<
" " << dr <<
" " << dn << endl;
467 for (
int i = 0; i < 144; i++) {
471 if (dr.mag() < 1e-10) cout <<
"best PhiId = " << i << endl;
480 int depth = touch->GetHistoryDepth();
481 if ((depth != 3) && (depth != 5)) {
482 B2WARNING(
"ECLGeometryPar::ECLVolumeToCellID: History depth = " << depth <<
" is out of range: should be 3 or 5.");
485 const G4String& vname = touch->GetVolume()->GetName();
486 std::size_t pos0 = vname.find(
"lv_forward_crystal_");
487 std::size_t pos1 = vname.find(
"lv_barrel_crystal_");
488 std::size_t pos2 = vname.find(
"lv_backward_crystal_");
489 if (pos0 == string::npos && pos1 == string::npos && pos2 == string::npos) {
490 B2WARNING(
"ECLGeometryPar::ECLVolumeToCellID: Volume name does not match pattern. NAME=" << vname);
500 double dt = 6.05 + z * (0.0749 - z * 0.00112);
514 m_nearSize(aNbr.m_nearSize)
522 const std::vector< Identifier >& aNbrs,
523 const std::vector< Identifier >::size_type aNearSize
526 m_nearSize(aNearSize)
529 std::sort(
m_nbrs.begin(),
m_nbrs.begin() + aNearSize, std::less< Identifier >()) ;
530 std::sort(
m_nbrs.begin() + aNearSize,
m_nbrs.end(), std::less< Identifier >()) ;
540 unsigned short i(0) ;
541 for (std::vector< EclNbr::Identifier >::const_iterator
542 iNbr(aNbr.
nbrs().begin()) ;
543 iNbr != aNbr.
nbrs().end() ; ++iNbr) {
545 if (iNbr != aNbr.
nbrs().begin() && i != aNbr.
nearSize() + 1) os <<
"," ;
546 if (i == aNbr.
nearSize() + 1) os <<
"|" ;
547 os << std::setw(4) << (*iNbr) ;
556 unsigned short Nri(0) ;
558 for (std::vector< EclNbr::Identifier >::const_iterator
560 iNbr !=
m_nbrs.end() ; ++iNbr) {
564 cout << std::setw(4) << (*iNbr) ;
593const std::vector< EclNbr::Identifier >&
599const std::vector< EclNbr::Identifier >::const_iterator
605const std::vector< EclNbr::Identifier >::const_iterator
611const std::vector< EclNbr::Identifier >::const_iterator
617const std::vector< EclNbr::Identifier >::const_iterator
623std::vector< EclNbr::Identifier >::size_type
629std::vector< EclNbr::Identifier >::size_type
655 const int cellID = aCellId;
659 std::vector< EclNbr::Identifier >::size_type
nearSize(0);
660 std::vector< EclNbr::Identifier > vNbr;
665 int tm1 = thetaId - 1;
666 int tm2 = thetaId - 2;
667 int tp1 = thetaId + 1;
668 int tp2 = thetaId + 2;
679 int fm1 = (phiId + 143) % 144;
680 int fp1 = (phiId + 1) % 144;
681 int fm2 = (phiId + 142) % 144;
682 int fp2 = (phiId + 2) % 144;
721 const EclIdentifier mPerRingForward[]
722 = { 48, 48, 64, 64, 64, 96, 96, 96, 96, 96, 96, 144, 144, 144, 144 };
723 if (thetaId > 1) nm2 = mPerRingForward[ thetaId - 2 ];
724 if (thetaId > 0) nm1 = mPerRingForward[ thetaId - 1 ];
725 n00 = mPerRingForward[ thetaId ];
726 np1 = mPerRingForward[ thetaId + 1 ];
727 np2 = mPerRingForward[ thetaId + 2 ];
730 const EclIdentifier mPerRingBackward[]
731 = { 64, 64, 64, 96, 96, 96, 96, 96, 144, 144, 144, 144 };
732 if (thetaId < 67) np2 = mPerRingBackward[ 66 - thetaId ];
733 if (thetaId < 68) np1 = mPerRingBackward[ 67 - thetaId ];
734 n00 = mPerRingBackward[ 68 - thetaId ];
735 nm1 = mPerRingBackward[ 69 - thetaId ];
736 nm2 = mPerRingBackward[ 70 - thetaId ];
743 int fp100 = (f0000 * np1 + np1 / 2) / n00;
744 int fp200 = (f0000 * np2 + np2 / 2) / n00;
745 int fm100 = (f0000 * nm1 + nm1 / 2) / n00;
746 int fm200 = (f0000 * nm2 + nm2 / 2) / n00;
748 int f00m1 = (f0000 + n00 - 1) % n00;
749 int f00m2 = (f0000 + n00 - 2) % n00;
750 int f00p1 = (f0000 + 1) % n00;
751 int f00p2 = (f0000 + 2) % n00;
753 int fp1m1 = (fp100 + np1 - 1) % np1;
754 int fp1m2 = (fp100 + np1 - 2) % np1;
755 int fp1p1 = (fp100 + 1) % np1;
756 int fp1p2 = (fp100 + 2) % np1;
758 int fm1m1 = (fm100 + nm1 - 1) % nm1;
759 int fm1m2 = (fm100 + nm1 - 2) % nm1;
760 int fm1p1 = (fm100 + 1) % nm1;
761 int fm1p2 = (fm100 + 2) % nm1;
763 int fp2m1 = (fp200 + np2 - 1) % np2;
764 int fp2m2 = (fp200 + np2 - 2) % np2;
765 int fp2p1 = (fp200 + 1) % np2;
766 int fp2p2 = (fp200 + 2) % np2;
768 int fm2m1 = (fm200 + nm2 - 1) % nm2;
769 int fm2m2 = (fm200 + nm2 - 2) % nm2;
770 int fm2p1 = (fm200 + 1) % nm2;
771 int fm2p2 = (fm200 + 2) % nm2;
772 int delta = n00 / 16;
774 int nth = phiId % delta;
789 if ((nth == 0) || (nth == 1)) {
793 }
else if ((nth == 2) || (nth == 3)) {
800 if ((nth == 0) || (nth == 3)) {
801 fm2p2 = fm2m2 = 1000;
802 }
else if (nth == 1) {
804 }
else if (nth == 2) {
809 if ((nth == 2) || (nth == 5)) {
821 if ((nth == 0) || (nth == 2) || (nth == 3) || (nth == 5)) {
826 if ((nth == 2) || (nth == 5) || (nth == 8)) {
838 if ((nth == 0) || (nth == 2) || (nth == 3)
839 || (nth == 5) || (nth == 6) || (nth == 8))
843 if ((nth == 2) || (nth == 5)) {
855 if ((nth == 0) || (nth == 2) || (nth == 3) || (nth == 5))
859 if ((nth == 2) || (nth == 5) || (nth == 8)) {
871 if ((nth == 0) || (nth == 2) || (nth == 3) || (nth == 5)
872 || (nth == 6) || (nth == 8))
The Class for ECL Geometry Parameters.
int mPar_cellID
The Cell ID information.
virtual ~ECLGeometryPar()
Destructor.
static ECLGeometryPar * Instance()
Static method to get a reference to the ECLGeometryPar instance.
CrystalGeom_t m_current_crystal
the current crystal
G4Transform3D * m_ECLBarrelGlobalT
Global transformations for the barrel part.
ECLGeometryPar()
Constructor.
static ECLGeometryPar * m_B4ECLGeometryParDB
Pointer that saves the instance of this class.
int TouchableToCellID(const G4VTouchable *)
The same as above but without sanity checks.
double time2sensor(int cid, const G4ThreeVector &hit_pos)
function to calculate flight time to diode sensor
void InitCrystal(int cid)
initialise the crystal
void read()
Gets geometry parameters from PhysicalVolumeStore.
void Mapping(int cid)
Mapping theta, phi Id.
std::vector< CrystalGeom_t > m_crystals
the crystals
G4Transform3D * m_ECLBackwardGlobalT
Global transformations for the backward part.
int mPar_thetaID
The Theta ID information.
int mPar_phiID
The Phi ID information.
G4Transform3D * m_ECLForwardGlobalT
Global transformations for the forward part.
int m_ini_cid
initial crystal ID
int GetCellID()
Get Cell Id.
int TouchableDiodeToCellID(const G4VTouchable *)
Mapping from G4VTouchable copyNumbers to Crystal CellID.
int ECLVolumeToCellID(const G4VTouchable *)
Get Cell Id (LEP: new way)
std::vector< Identifier >::size_type nextSize() const
get crystals nextSize
const std::vector< Identifier >::const_iterator nextEnd() const
get crystals nextEnd
EclNbr getNbr(const Identifier aCellId)
get crystals nbr
int GetPhiID()
Get Phi Id.
EclNbr()
Constructors and destructor.
int mNbr_thetaID
The Theta ID information.
virtual ~EclNbr()
destructor
const std::vector< Identifier > & nbrs() const
get crystals nbrs
int mNbr_cellID
data members
const std::vector< Identifier >::const_iterator nearEnd() const
get crystals nearEnd
int mNbr_phiID
The Phi ID information.
void printNbr()
print crystals nbrs
void Mapping(int cid)
Mapping theta, phi Id.
std::vector< Identifier >::size_type m_nearSize
size of near brs
const std::vector< Identifier >::const_iterator nearBegin() const
get crystals nearBegin
const std::vector< Identifier >::const_iterator nextBegin() const
get crystals nextBegin
EclIdentifier Identifier
constants, enums and typedefs
std::vector< Identifier >::size_type nearSize() const
get crystals nearSize
std::vector< Identifier > & m_nbrs
id of m_brs
int GetThetaID()
Get Theta Id.
EclNbr & operator=(const EclNbr &aNbr)
assignment operator(s)
int GetCellID()
Get Cell Id.
static const unsigned char m_RECIPROCAL_SHIFT
reciprocal shift
static void Mapping(int id, int &ThetaId, int &PhiId, int &nrep, int &indx)
Retrieving theta id, phi id, reciprocal shift and index.
static const char m_dTheta[69]
array of theta offsets
static int CellID(int ThetaId, int PhiId)
return cell id as a function of theta id and phi id
static const unsigned int m_denom[5]
array of denominator values
static const unsigned int m_recip[5]
array of reciprocal values
static const unsigned char m_offsets[69]
array of offsets
static int Indx2ThetaId(int indx)
getter for theta
static const unsigned char m_tbl[69]
array of crystals per phi sector
static const unsigned char m_Theta[546]
array of theta
static int Offset(int ThetaId)
return offset based on theta id
static void Mapping(int id, int &ThetaId, int &PhiId)
Retrieving theta and phi id of crystal.
static int ThetaId2NCry(int ThetaId)
getter for number of crystals
std::ostream & operator<<(std::ostream &output, const IntervalOfValidity &iov)
TString rn()
Get random string.
bool isForward(int cellId)
Check whether the crystal is in forward ECL.
bool isBarrel(int cellId)
Check whether the crystal is in barrel ECL.
Abstract base class for different kinds of events.
G4ThreeVector pos
position of crystal
G4ThreeVector dir
direction of crystal