13 using namespace genie;
14 using namespace genie::hnl;
15 using namespace genie::units;
54 <<
"Getting geometry information from " <<
fGeomFile;
58 TGeoVolume * top_volume =
fGeoManager->GetTopVolume();
60 TGeoShape * ts = top_volume->GetShape();
61 TGeoBBox * box = (TGeoBBox *) ts;
63 this->ImportBoundingBox(box);
70 TVector3 startPoint, momentum, entryPoint, exitPoint;
74 bool didIntersectDet = this->VolumeEntryAndExitPoints( startPoint, momentum, entryPoint, exitPoint,
fGeoManager,
fGeoVolume );
78 std::vector< double > * newProdVtx =
new std::vector< double >();
79 newProdVtx->emplace_back( startPoint.X() );
80 newProdVtx->emplace_back( startPoint.Y() );
81 newProdVtx->emplace_back( startPoint.Z() );
84 if( !didIntersectDet ){
87 TLorentzVector v4dummy( -999.9, -999.9, -999.9, -999.9 );
97 double maxDx = exitPoint.X() - entryPoint.X();
98 double maxDy = exitPoint.Y() - entryPoint.Y();
99 double maxDz = exitPoint.Z() - entryPoint.Z();
101 double maxLength = std::sqrt( std::pow( maxDx , 2.0 ) +
102 std::pow( maxDy , 2.0 ) +
103 std::pow( maxDz , 2.0 ) );
106 double betaMag = p4HNL->P() / p4HNL->E();
107 double gamma = std::sqrt( 1.0 / ( 1.0 - betaMag * betaMag ) );
110 __attribute__((unused))
double ratio_length = elapsed_length / maxLength;
113 double distanceBeforeDet = std::sqrt( std::pow( (entryPoint.X() - startPoint.X()), 2.0 ) +
114 std::pow( (entryPoint.Y() - startPoint.Y()), 2.0 ) +
115 std::pow( (entryPoint.Y() - startPoint.Z()), 2.0 ) );
120 double LabToRestTime = 1.0 / ( gamma );
121 timeBeforeDet *= LabToRestTime;
122 timeInsideDet *= LabToRestTime;
124 double survProb = std::exp( - timeBeforeDet /
fCoMLifetime );
125 weight *= 1.0 / survProb;
126 double decayProb = 1.0 - std::exp( - timeInsideDet /
fCoMLifetime );
127 weight *= 1.0 / decayProb;
138 TVector3 decayPoint = this->
GetDecayPoint( elapsed_length, entryPoint, momentum );
144 event_rec->
Vertex()->T() );
153 TLorentzVector tmpp4( 0.0, 0.0, 0.0, 0.5 );
154 TLorentzVector ex4( 0.0, 0.0, 0.0, 0.0 );
155 ex4.SetXYZT( entryPoint.X(), entryPoint.Y(), entryPoint.Z(), 0.0 );
156 TLorentzVector xx4( 0.0, 0.0, 0.0, 0.0 );
157 xx4.SetXYZT( exitPoint.X(), exitPoint.Y(), exitPoint.Z(), 0.0 );
173 (event_rec->
Particle(1))->SetPosition( entryPoint.X(), entryPoint.Y(), entryPoint.Z(), event_rec->
Particle(1)->
Vt() );
174 (event_rec->
Particle(2))->SetPosition( exitPoint.X(), exitPoint.Y(), exitPoint.Z(), event_rec->
Particle(2)->
Vt() );
182 <<
"Switching units to " << length_units.c_str() <<
" , " << angle_units.c_str() <<
" , " << time_units.c_str();
184 double old_lunits =
lunits;
186 double old_tunits =
tunits;
215 assert( betaMag > 0.0 && betaMag < 1.0 );
217 double gamma = std::sqrt( 1.0 / ( 1.0 - betaMag * betaMag ) );
218 double maxRestTime = maxLabTime / gamma ;
221 double PExit = std::exp( - maxRestTime / CoMLifetime );
227 double ranthrow = rnd->
RndGen().Uniform();
229 double S0 = (1.0 - PExit) * ranthrow + PExit;
230 double rest_time = CoMLifetime * std::log( 1.0 / S0 );
231 double elapsed_time = rest_time * gamma;
247 return elapsed_length;
252 double ex = entryPoint.X();
double ey = entryPoint.Y();
double ez = entryPoint.Z();
253 double px = momentum.X();
double py = momentum.Y();
double pz = momentum.Z();
254 double p2 = px*px + py*py + pz*pz;
double p = std::sqrt(p2);
255 px *= 1./p; py *= 1./p; pz *= 1./p;
257 double dx = ex + travelLength * px;
fDx = dx;
258 double dy = ey + travelLength * py;
fDy = dy;
259 double dz = ez + travelLength * pz;
fDz = dz;
265 TVector3 decayPoint( dx, dy, dz );
271 double ex = entryPoint.X();
double ey = entryPoint.Y();
double ez = entryPoint.Z();
272 double xx = exitPoint.X();
double xy = exitPoint.Y();
double xz = exitPoint.Z();
274 return std::sqrt( (ex-xx)*(ex-xx) + (ey-xy)*(ey-xy) + (ez-xz)*(ez-xz) );
291 <<
"Setting simple decay volume with unit-m side."
292 <<
"\nSetting units to \"mm\", \"rad\", \"ns\"";
299 TVector3 & entryPoint, TVector3 & exitPoint )
const
301 assert(
fOx == 0.0 &&
fOy == 0.0 &&
fOz == 0.0 &&
302 fLx == 1000.0 &&
fLy == 1000.0 &&
fLz == 1000.0 );
303 fSx = startPoint.X();
fSy = startPoint.Y();
fSz = startPoint.Z();
304 fPx = momentum.X();
fPy = momentum.Y();
fPz = momentum.Z();
306 fPx *= 1.0/fP;
fPy *= 1.0/fP; fPz *= 1.0/fP;
313 double tzP = (
fLz -
fSz ) / fPz;
314 double tzM = ( -
fLz -
fSz ) / fPz;
319 double q1t = 0.0, q2t = 0.0;
320 bool pointsOnX =
false, pointsOnY =
false, pointsOnZ =
false;
324 if( std::abs( q1t ) <=
fLy && std::abs( q2t ) <=
fLz ){
328 }
else if(
fSx *
fPx > 0 ){
334 if( std::abs( q1t ) <=
fLy && std::abs( q2t ) <=
fLz ){
338 }
else if(
fSx *
fPx > 0 ){
345 if( std::abs( q1t ) <=
fLz && std::abs( q2t ) <=
fLx ){
349 }
else if(
fSy * fPy > 0 ){
355 if( std::abs( q1t ) <=
fLz && std::abs( q2t ) <=
fLx ){
359 }
else if(
fSy * fPy > 0 ){
366 if( std::abs( q1t ) <=
fLx && std::abs( q2t ) <=
fLy ){
370 }
else if(
fSz * fPz > 0 ){
376 if( std::abs( q1t ) <=
fLx && std::abs( q2t ) <=
fLy ){
380 }
else if(
fSz * fPz > 0 ){
385 bool finalPoints = ( pointsOnX || pointsOnY || pointsOnZ );
396 #ifdef __GENIE_GEOM_DRIVERS_ENABLED__
397 void VertexGenerator::ImportBoundingBox( TGeoBBox * box )
const
410 fOxROOT = (box->GetOrigin())[0];
411 fOyROOT = (box->GetOrigin())[1];
412 fOzROOT = (box->GetOrigin())[2];
427 TVector3 dumori(0.0, 0.0, 0.0);
433 TVector3 xHNL_near = x4HNL->Vect();
435 TLorentzVector * x4HNL_user =
new TLorentzVector();
441 TVector3 startPoint(
xMult * x4HNL_user->X(),
xMult * x4HNL_user->Y(),
xMult * x4HNL_user->Z() );
445 TVector3 momentum( p4HNL->Px(), p4HNL->Py(), p4HNL->Pz() );
448 fSx = startPoint.X();
fSy = startPoint.Y();
fSz = startPoint.Z();
452 fPx = momentum.X();
fPy = momentum.Y();
fPz = momentum.Z();
455 bool VertexGenerator::VolumeEntryAndExitPoints( TVector3 & startPoint, TVector3 & momentum,
456 TVector3 & entryPoint, TVector3 & exitPoint,
457 TGeoManager * , TGeoVolume * )
const
461 double sx = startPoint.X();
double sy = startPoint.Y();
double sz = startPoint.Z();
462 sx *= mmtolunits; sy *= mmtolunits; sz *= mmtolunits;
463 double px = momentum.X();
double py = momentum.Y();
double pz = momentum.Z();
464 double p2 = px*px + py*py + pz*pz;
double p = std::sqrt(p2);
465 px *= 1./p; py *= 1./p; pz *= 1./p;
467 fSx = sx;
fSy = sy;
fSz = sz;
472 double firstZOffset = -0.1;
475 double firstZ =
fOz - (
fLz/2.0 - firstZOffset);
478 double dz = firstZ - sz;
482 double firstX = sx + dx;
483 double firstY = sy + dy;
490 TGeoManager * gm = TGeoManager::Import(
fGeomFile.c_str());
491 gGeoManager->SetCurrentPoint( firstXROOT, firstYROOT, firstZROOT );
492 gGeoManager->SetCurrentDirection( px, py, pz );
503 std::string pathString = this->
CheckGeomPoint( firstXROOT, firstYROOT, firstZROOT );
505 assert( pathString.find(
"/", 1) == string::npos );
507 double stepmax = 1.0e+6;
511 <<
"Starting to search for intersections...";
514 TGeoNode * nextNode = gGeoManager->FindNextBoundaryAndStep( stepmax );
516 if( (gGeoManager->GetCurrentPoint())[0] == firstXROOT &&
517 (gGeoManager->GetCurrentPoint())[1] == firstYROOT &&
518 (gGeoManager->GetCurrentPoint())[2] == firstZROOT )
519 nextNode = gGeoManager->FindNextBoundaryAndStep();
521 pathString = this->
CheckGeomPoint( (gGeoManager->GetCurrentPoint())[0],
522 (gGeoManager->GetCurrentPoint())[1],
523 (gGeoManager->GetCurrentPoint())[2] );
525 if( nextNode == NULL )
528 TVector3 dumori(0.0, 0.0, 0.0);
536 fExROOT = ( gGeoManager->GetCurrentPoint() )[0];
537 fEyROOT = ( gGeoManager->GetCurrentPoint() )[1];
538 fEzROOT = ( gGeoManager->GetCurrentPoint() )[2];
557 const int bdIdxMax = 1
e+4;
559 double sfx = 0.0, sfy = 0.0, sfz = 0.0;
560 double sfxROOT = 0.0, sfyROOT = 0.0, sfzROOT = 0.0;
566 gGeoManager->SetStep( sNextROOT );
571 while( gGeoManager->FindNextBoundaryAndStep() && bdIdx < bdIdxMax ){
572 const Double_t * currPoint = gGeoManager->GetCurrentPoint();
574 sfxROOT = currPoint[0]; sfyROOT = currPoint[1]; sfzROOT = currPoint[2];
576 gGeoManager->SetStep( sNextROOT );
580 if( bdIdx == bdIdxMax ){
582 <<
"Failed to exit this volume. Dropping this trajectory.";
587 if( ( sfxROOT == 0.0 && sfyROOT == 0.0 && sfzROOT == 0.0 ) ||
591 <<
"This section is smaller than 5 cm. Are you sure you want this decay volume? Proceeding anyway.";
593 gGeoManager->SetStep( 5.0 );
595 const Double_t * currPoint = gGeoManager->GetCurrentPoint();
596 sfxROOT = currPoint[0]; sfyROOT = currPoint[1]; sfzROOT = currPoint[2];
625 #endif // #ifdef __GENIE_GEOM_DRIVERS_ENABLED__
644 <<
"Loading geometry parameters from file. . .";
667 double vx = vec.X(), vy = vec.Y(), vz = vec.Z();
669 double Ax2 = ( doBackwards ) ? -
fAx2 :
fAx2;
670 double Az = ( doBackwards ) ? -
fAz :
fAz;
671 double Ax1 = ( doBackwards ) ? -
fAx1 :
fAx1;
674 double x = vx, y = vy, z = vz;
675 vy = y * std::cos( Ax2 ) - z * std::sin( Ax2 );
676 vz = y * std::sin( Ax2 ) + z * std::cos( Ax2 );
679 vx = x * std::cos( Az ) - y * std::sin( Az );
680 vy = x * std::sin( Az ) + y * std::cos( Az );
683 vy = y * std::cos( Ax1 ) - z * std::sin( Ax1 );
684 vz = y * std::sin( Ax1 ) + z * std::cos( Ax1 );
686 TVector3 nvec( vx, vy, vz );
692 double vx = vec.X(), vy = vec.Y(), vz = vec.Z();
693 double ox = oriVec.X(), oy = oriVec.Y(), oz = oriVec.Z();
695 vx -= ox; vy -= oy; vz -= oz;
697 assert( rotVec.size() == 3 );
698 double Ax2 = ( doBackwards ) ? -rotVec.at(2) : rotVec.at(2);
699 double Az = ( doBackwards ) ? -rotVec.at(1) : rotVec.at(1);
700 double Ax1 = ( doBackwards ) ? -rotVec.at(0) : rotVec.at(0);
703 double x = vx, y = vy, z = vz;
704 vy = y * std::cos( Ax2 ) - z * std::sin( Ax2 );
705 vz = y * std::sin( Ax2 ) + z * std::cos( Ax2 );
708 vx = x * std::cos( Az ) - y * std::sin( Az );
709 vy = x * std::sin( Az ) + y * std::cos( Az );
712 vy = y * std::cos( Ax1 ) - z * std::sin( Ax1 );
713 vz = y * std::sin( Ax1 ) + z * std::cos( Ax1 );
716 vx += ox; vy += oy; vz += oz;
717 TVector3 nvec( vx, vy, vz );
733 TGeoVolume *vol = gGeoManager->GetTopVolume();
734 TGeoNode *node = gGeoManager->FindNode(point[0], point[1], point[2]);
735 gGeoManager->MasterToLocal(point, local);
736 return gGeoManager->GetPath();
static constexpr double cm
bool SDVEntryAndExitPoints(TVector3 &startPoint, TVector3 momentum, TVector3 &entryPoint, TVector3 &exitPoint) const
virtual GHepParticle * Particle(int position) const
virtual void SetWeight(double wght)
TLorentzVector * GetX4(void) const
std::vector< double > fDetRotation
static RandomGen * Instance()
Access instance.
int GetParamVect(const std::string &comm_name, std::vector< T > &v, bool is_top_call=true) const
Handle to load vectors of parameters.
static constexpr double s
virtual double Weight(void) const
static constexpr double ns
TGeoManager * fGeoManager
A singleton holding random number generator classes. All random number generation in GENIE should tak...
std::string CheckGeomPoint(Double_t x, Double_t y, Double_t z) const
virtual TLorentzVector * Vertex(void) const
void Configure(const Registry &config)
double Vt(void) const
Get production time.
Expands the EventRecordVisitorI interface to include public interfaces for the HNL VertexGenerator mo...
void SetPosition(const TLorentzVector &v4)
#define LOG(stream, priority)
A macro that returns the requested log4cpp::Category appending a string (using the FILE...
void ProcessEventRecord(GHepRecord *event_rec) const
std::vector< double > fDetTranslation
static constexpr double GeV
TVector3 ApplyUserRotation(TVector3 vec, bool doBackwards) const
TLorentzVector * GetP4(void) const
double UnitFromString(string u)
virtual void Configure(const Registry &config)
double CalcTravelLength(double betaMag, double CoMLifetime, double maxLength) const
virtual double Probability(void) const
void SetStartingParameters(GHepRecord *event_rec) const
double GetMaxLength(TVector3 &entryPoint, TVector3 &exitPoint) const
std::vector< double > fB2URotation
static __attribute__((unused)) double fDecayGammas[]
A registry. Provides the container for algorithm configuration parameters.
std::vector< double > fB2UTranslation
virtual void SetVertex(double x, double y, double z, double t)
TRandom3 & RndGen(void) const
rnd number generator for generic usage
static constexpr double mm
virtual void AddParticle(const GHepParticle &p)
void GetInterestingPoints(TVector3 &entryPoint, TVector3 &exitPoint, TVector3 &decayPoint) const
void EnforceUnits(std::string length_units, std::string angle_units, std::string time_units) const
void SetGeomFile(std::string geomfile) const
static constexpr double kSpeedOfLight
GENIE's GHEP MC event record.
static constexpr double m
STDHEP-like event record entry that can fit a particle or a nucleus.
TVector3 GetDecayPoint(double travelLength, TVector3 &entryPoint, TVector3 &momentum) const