23#include "BDSOutputROOTEventTrajectory.hh"
26#include "G4VPhysicalVolume.hh"
28#include "BDSHitEnergyDeposition.hh"
29#include "BDSAuxiliaryNavigator.hh"
30#include "BDSPhysicalVolumeInfoRegistry.hh"
31#include "BDSPhysicalVolumeInfo.hh"
32#include "BDSTrajectory.hh"
33#include "BDSTrajectoryOptions.hh"
40BDSOutputROOTEventTrajectory::BDSOutputROOTEventTrajectory():
41 auxNavigator(nullptr),
47BDSOutputROOTEventTrajectory::~BDSOutputROOTEventTrajectory()
57 if (!traj->GetParent())
60 if (traj->GetParent()->GetTrackID() == 1)
61 {
return traj->GetParentStepIndex();}
63 {
return findPrimaryStepIndex(traj->GetParent());}
68 bool storeStepPointLast,
70 const std::map<G4Material*, short int>& materialToID)
77 G4bool stEK = storageOptions.storeLinks || storageOptions.storeKineticEnergy;
78 G4bool stMo = storageOptions.storeMomentumVector;
79 G4bool stPr = storageOptions.storeProcesses;
80 G4bool stTi = storageOptions.storeTime;
81 G4bool stMa = storageOptions.storeMaterial;
85 for (
auto trajFlag : trajectories->trajectories)
98 for (
auto trajFlag : trajectories->trajectories)
102 if (trajFlag.second && parent)
107 if (parent->GetTrajIndex() != -1)
109 auto trajStartPos = traj->
GetPoint(0)->GetPosition();
113 if(parent->
GetPoint(i)->GetPosition() == trajStartPos)
128 for (
auto trajFlag : trajectories->trajectories)
133 if (!trajFlag.second)
136 partID.push_back((
int) traj->GetPDGEncoding());
137 trackID.push_back((
unsigned int) std::abs(traj->GetTrackID()));
138 parentID.push_back((
unsigned int) std::abs(traj->GetParentID()));
139 parentIndex.push_back((
unsigned int) std::abs(traj->GetParentIndex()));
140 parentStepIndex.push_back((
unsigned int) std::abs(traj->GetParentStepIndex()));
141 depth.push_back((
int) traj->
GetDepth());
145 IndividualTrajectory itj;
146 if (storeStepPointsN > 0)
149 G4int nPoints = std::min(nSteps, storeStepPointsN);
150 for (
int i = 0; i < nPoints; ++i)
153 if (storeStepPointLast && (nPoints < nSteps))
163 filters.push_back(trajectories->filtersMatched.at(traj));
165 XYZ.push_back(itj.XYZ);
166 modelIndicies.push_back(itj.modelIndex);
169 {PXPYPZ.push_back(itj.PXPYPZ);}
175 preProcessTypes.push_back(itj.preProcessType);
176 preProcessSubTypes.push_back(itj.preProcessSubType);
177 postProcessTypes.push_back(itj.postProcessType);
178 postProcessSubTypes.push_back(itj.postProcessSubType);
181 preWeights.push_back(itj.preWeight);
182 postWeights.push_back(itj.postWeight);
183 energyDeposit.push_back(itj.energyDeposit);
186 {T.push_back(itj.T);}
192 {materialID.push_back(itj.materialID);}
194 if (!itj.xyz.empty())
196 xyz.push_back(itj.xyz);
197 pxpypz.push_back(itj.pxpypz);
200 if (!itj.charge.empty())
202 charge.push_back(itj.charge);
204 mass.push_back(itj.mass);
208 if (!itj.isIon.empty())
210 isIon.push_back(itj.isIon);
211 ionA.push_back(itj.ionA);
212 ionZ.push_back(itj.ionZ);
217 primaryStepIndex.push_back(findPrimaryStepIndex(traj));
220 trackID_trackIndex.insert(std::pair<int,int>(traj->GetTrackID(),n));
228 for (
auto iT = trajVec.begin(); iT != trajVec.end(); ++iT)
233 trackID_trackIndex.insert(std::pair<int, int>(traj->GetTrackID(),trackIndex));
235 std::cout << trajVec.size() <<
" " << parentID.size() <<
" " << parentIndex.size() <<
" "
236 << traj->GetTrackID() <<
" " << traj->GetParentID() <<
" " << trackIndex << std::endl;
239 auto processPair = findParentProcess(trackIndex);
240 trackIndex_trackProcess.insert(std::pair<
int,std::pair<int,int>>(trackIndex,processPair));
243 if(processPair.first != -1)
245 int mi = modelIndicies[processPair.first][processPair.second];
246 trackIndex_modelIndex.insert(std::pair<int,int>(trackIndex, mi));
248 {modelIndex_trackIndex.at(mi).push_back(trackIndex);}
249 catch(
const std::exception&)
251 modelIndex_trackIndex.insert(std::pair<
int,std::vector<int>>(mi,std::vector<int>()));
252 modelIndex_trackIndex.at(mi).push_back(trackIndex);
264 const std::map<G4Material*, short int>& materialToID)
const
271 G4ThreeVector pos = point->GetPosition();
272 itj.XYZ.emplace_back(pos.getX() / CLHEP::m, pos.getY() / CLHEP::m, pos.getZ() / CLHEP::m);
279 {itj.modelIndex.push_back(-1);}
291 itj.PXPYPZ.emplace_back(mom.getX(), mom.getY(), mom.getZ());
292 itj.S.push_back(point->
GetPreS() / CLHEP::m);
296 itj.materialID.push_back(materialToID.at(point->
GetMaterial()));
298 if (point->extraLocal)
302 itj.xyz.emplace_back(localPos.getX(), localPos.getY(), localPos.getZ());
303 itj.pxpypz.emplace_back(localMom.getX(), localMom.getY(), localMom.getZ());
306 if (point->extraLink)
308 itj.charge.push_back((
int) (point->
GetCharge() / (G4double)CLHEP::eplus));
310 itj.mass.push_back(point->
GetMass() / CLHEP::GeV);
311 itj.rigidity.push_back(point->
GetRigidity() / (CLHEP::tesla*CLHEP::m));
316 itj.isIon.push_back(point->
GetIsIon());
317 itj.ionA.push_back(point->
GetIonA());
318 itj.ionZ.push_back(point->
GetIonZ());
325 G4cout << phc->GetSize() << G4endl;
343 parentStepIndex.clear();
344 primaryStepIndex.clear();
347 preProcessTypes.clear();
348 preProcessSubTypes.clear();
349 postProcessTypes.clear();
350 postProcessSubTypes.clear();
354 energyDeposit.clear();
376 modelIndicies.clear();
377 trackID_trackIndex.clear();
390 filters = other->filters;
391 partID = other->partID;
392 trackID = other->trackID;
393 parentID = other->parentID;
394 parentIndex = other->parentIndex;
395 parentStepIndex = other->parentStepIndex;
396 primaryStepIndex = other->primaryStepIndex;
397 depth = other->depth;
399 preProcessTypes = other->preProcessTypes;
400 preProcessSubTypes = other->preProcessSubTypes;
401 postProcessTypes = other->postProcessTypes;
402 postProcessSubTypes = other->postProcessSubTypes;
404 preWeights = other->preWeights;
405 postWeights = other->postWeights;
406 energyDeposit = other->energyDeposit;
410 PXPYPZ = other->PXPYPZ;
426 materialID = other->materialID;
427 modelIndicies = other->modelIndicies;
428 trackID_trackIndex = other->trackID_trackIndex;
433std::pair<int,int> BDSOutputROOTEventTrajectory::findParentProcess(
int trackIndex)
435 std::cout <<
"BDSOutputROOTEventTrajectory::findParentProcess> "
436 << trackIndex <<
" " << parentID.size() <<
" " << parentIndex.size() << std::endl;
437 int tid = trackIndex;
438 int pid = parentID.at(tid);
439 std::cout << pid << std::endl;
440 int pin = parentIndex.at(tid);
441 std::cout << pin << std::endl;
444 {
return std::pair<int,int>(-1,-1);}
445 int sin = parentStepIndex.at(tid);
446 std::cout << sin << std::endl;
453 pid = parentID.at(tid);
454 pin = parentIndex.at(tid);
455 sin = parentStepIndex.at(tid);
457 std::cout << tid <<
" " << pid <<
" " << pin <<
" " << sin <<
" " << std::endl;
460 return std::pair<int,int>(pin,sin);
464std::vector<BDSOutputROOTEventTrajectoryPoint> BDSOutputROOTEventTrajectory::trackInteractions(
int trackIDIn)
const
467 if (trackID_trackIndex.find(trackIDIn) == trackID_trackIndex.end())
469 std::cout <<
"No such track ID" << std::endl;
470 return std::vector<BDSOutputROOTEventTrajectoryPoint>();
473 int ti = trackID_trackIndex.at(trackIDIn);
475 std::vector<BDSOutputROOTEventTrajectoryPoint> tpv;
477 int nstep = (int)XYZ[ti].size();
479 {
return std::vector<BDSOutputROOTEventTrajectoryPoint>();}
481 if (postProcessTypes[ti].empty())
483 std::cout <<
"Processes not stored for this file - not possible." << std::endl;
484 return std::vector<BDSOutputROOTEventTrajectoryPoint>();
487 bool usePXPYPZ = !PXPYPZ[ti].empty();
488 bool useT = !T.empty();
489 bool useIon = !
isIon.empty();
490 bool useLocal = !
xyz.empty();
491 bool useLinks = !
charge.empty();
493 bool useMat = !materialID.empty();
495 for (
int i = 0; i < nstep; ++i)
497 int ppt = postProcessTypes[ti][i];
498 int ppst = postProcessSubTypes[ti][i];
504 bool notGeneral = ppt != 7 && ppst != 401;
505 bool changeInEnergy = energyDeposit[ti][i] > 1e-9;
506 if ( (ppt != -1 && ppt != 1 && ppt != 10 && ppt != 0 && notGeneral) || changeInEnergy)
512 postProcessTypes[ti][i],
513 postProcessSubTypes[ti][i],
515 energyDeposit[ti][i],
517 usePXPYPZ ? PXPYPZ[ti][i] : TVector3(),
518 modelIndicies[ti][i],
520 useLocal ?
xyz[ti][i] : TVector3(),
521 useLocal ?
pxpypz[ti][i] : TVector3(),
522 useLinks ?
charge[ti][i] : 0,
526 useLinks ?
mass[ti][i] : 0,
527 useIon ?
isIon[ti][i] : false,
528 useIon ?
ionA[ti][i] : 0,
529 useIon ?
ionZ[ti][i] : 0,
531 useMat ? materialID[ti][i] : -1,
542 if (trackID_trackIndex.find(trackIDIn) == trackID_trackIndex.end())
544 std::cout <<
"No such track ID" << std::endl;
547 int ti = trackID_trackIndex.at(trackIDIn);
548 int pid = (int)parentID[ti];
549 int chosenTrackID = trackIDIn;
552 if (parentID[trackID_trackIndex.at(pid)] > 0)
553 {chosenTrackID = pid;}
554 ti = trackID_trackIndex.at(pid);
555 pid = (int)parentID[ti];
557 return parentProcessPoint(chosenTrackID);
563 if (trackID_trackIndex.find(trackIDIn) == trackID_trackIndex.end())
565 std::cout <<
"No such track ID" << std::endl;
569 int ti = trackID_trackIndex.at(trackIDIn);
570 int pti = (int)parentID[ti];
574 std::cout <<
"Track is a parent" << std::endl;
578 int si = (int)parentStepIndex.at(ti);
581 {pi = trackID_trackIndex.at(pti);}
585 if (si > (
int)XYZ[pi].size())
587 std::cout <<
"Not all step points are stored. Parent step index is outside points stored." << std::endl;
591 bool usePXPYPZ = !PXPYPZ[ti].empty();
592 bool useT = !T.empty();
593 bool useIon = !
isIon.empty();
594 bool useLocal = !
xyz.empty();
595 bool useLinks = !
charge.empty();
597 bool useMat = !materialID.empty();
603 postProcessTypes[pi][si],
604 postProcessSubTypes[pi][si],
606 energyDeposit[pi][si],
608 usePXPYPZ ? PXPYPZ[pi][si] : TVector3(),
609 modelIndicies[pi][si],
610 useT ? T[pi][si] : 0,
611 useLocal ?
xyz[pi][si] : TVector3(),
612 useLocal ?
pxpypz[pi][si] : TVector3(),
613 useLinks ?
charge[pi][si] : 0,
617 useLinks ?
mass[pi][si] : 0,
618 useIon ?
isIon[pi][si] : false,
619 useIon ?
ionA[pi][si] : 0,
620 useIon ?
ionZ[pi][si] : 0,
622 useMat ? materialID[pi][si] : -1,
627std::vector<BDSOutputROOTEventTrajectoryPoint> BDSOutputROOTEventTrajectory::processHistory(
int trackIDIn)
const
630 if (trackID_trackIndex.find(trackIDIn) == trackID_trackIndex.end())
632 std::cout <<
"No such track ID" << std::endl;
633 return std::vector<BDSOutputROOTEventTrajectoryPoint>();
636 if (postProcessTypes.empty())
638 std::cout <<
"Processes not stored for this file - not possible." << std::endl;
639 return std::vector<BDSOutputROOTEventTrajectoryPoint>();
642 int ti = trackID_trackIndex.at(trackIDIn);
644 bool usePXPYPZ = !PXPYPZ.empty();
645 bool useT = !T.empty();
646 bool useIon = !
isIon.empty();
647 bool useLocal = !
xyz.empty();
648 bool useLinks = !
charge.empty();
650 bool useMat = !materialID.empty();
652 std::vector<BDSOutputROOTEventTrajectoryPoint> tpv;
655 unsigned int pi = parentIndex.at(ti);
656 unsigned int psi = parentStepIndex.at(ti);
657 if (psi > (
unsigned int)XYZ[pi].size())
659 std::cout <<
"Not all points stored - defaulting to creation point." << std::endl;
667 postProcessTypes[pi][psi],
668 postProcessSubTypes[pi][psi],
669 postWeights[pi][psi],
670 energyDeposit[pi][psi],
672 usePXPYPZ ? PXPYPZ[ti][psi] : TVector3(),
673 modelIndicies[ti][psi],
674 useT ? T[ti][psi] : 0,
675 useLocal ?
xyz[ti][psi] : TVector3(),
676 useLocal ?
pxpypz[ti][psi] : TVector3(),
677 useLinks ?
charge[ti][psi] : 0,
681 useLinks ?
mass[ti][psi] : 0,
682 useIon ?
isIon[ti][psi] : false,
683 useIon ?
ionA[ti][psi] : 0,
684 useIon ?
ionZ[ti][psi] : 0,
686 useMat ? materialID[ti][psi] : -1,
691 std::reverse(tpv.begin(),tpv.end());
695void BDSOutputROOTEventTrajectory::printTrajectoryInfoByTrackID(
int trackIDIn)
const
698 int storageIndex = 0;
699 auto search = trackID_trackIndex.find(trackIDIn);
700 if (search == trackID_trackIndex.end())
702 std::cout <<
"No such track ID" << std::endl;
706 {storageIndex = search->second;}
707 printTrajectoryInfo(storageIndex);
710void BDSOutputROOTEventTrajectory::printTrajectoryInfo(
int storageIndex)
const
712 int i = storageIndex;
715 if (i > (
int)partID.size() || i < 0)
716 {std::cout <<
"Invalid index" << std::endl;
return;}
719 {std::cout <<
"Index chosen is greater than maximum index of: " << n-1 << std::endl;
return;}
722 std::cout <<
"Storage index " << std::setw(wdt) << i
723 <<
", PDG ID " << std::setw(wdt) << partID[i]
724 <<
", Track ID " << std::setw(wdt) << trackID[i]
725 <<
", Parent ID " << std::setw(wdt) << parentID[i] << std::endl;
726 std::cout <<
"Created by Track ID " << parentID[i] <<
", with storage index " << parentIndex[i] <<
", and at step index " << parentStepIndex[i] << std::endl;
729 std::cout << std::setw(wdt) <<
"step ind" <<
" "
730 << std::setw(wdt) <<
"prePrcT" <<
" " << std::setw(wdt) <<
"prePrcST" <<
" "
731 << std::setw(wdt) <<
"pstPrcT" <<
" " << std::setw(wdt) <<
"pstPrcST" <<
" "
732 << std::setw(wdt) <<
"X" <<
" " << std::setw(wdt) <<
"Y" <<
" "
733 << std::setw(wdt) <<
"Z" <<
" " << std::setw(wdt) <<
"E" <<
" "
734 << std::setw(wdt) <<
"p" <<
" " << std::setw(wdt) <<
"p_x" <<
" "
735 << std::setw(wdt) <<
"p_y" <<
" " << std::setw(wdt) <<
"p_z" <<
" "
736 << std::setw(wdt) <<
"t" << std::endl;
738 for (
size_t j=0; j<XYZ[i].size(); ++j)
740 std::cout << std::setw(wdt) << j <<
" "
741 << std::setw(wdt) << preProcessTypes[i][j] <<
" " << std::setw(wdt) << preProcessSubTypes[i][j] <<
" "
742 << std::setw(wdt) << postProcessTypes[i][j] <<
" " << std::setw(wdt) << postProcessSubTypes[i][j] <<
" "
743 << std::setw(wdt) << XYZ[i][j].X() <<
" " << std::setw(wdt) << XYZ[i][j].Y() <<
" "
744 << std::setw(wdt) << XYZ[i][j].Z() <<
" " << std::setw(wdt) << energyDeposit[i][j] <<
" "
745 << std::setw(wdt) << PXPYPZ[i][j].Mag() <<
" " << std::setw(wdt) << PXPYPZ[i][j].X() <<
" "
746 << std::setw(wdt) << PXPYPZ[i][j].Y() <<
" " << std::setw(wdt) << PXPYPZ[i][j].Z() <<
" "
747 << std::setw(wdt) << T[i][j] << std::endl;
751bool BDSOutputROOTEventTrajectory::parentIsPrimary(
int trackIDIn)
const
754 if (trackID_trackIndex.find(trackIDIn) == trackID_trackIndex.end())
756 std::cout <<
"No such track ID" << std::endl;
760 unsigned int storageIndex = (
unsigned int)trackID_trackIndex.at(trackIDIn);
761 unsigned int parentStorageIndex = parentIndex[storageIndex];
762 return parentID[parentStorageIndex] == 0;
767 for (
int i=0; i< (int)t.preProcessTypes.size();++i)
769 for (
int j=0; j< (int)t.preProcessTypes[i].size(); ++j)
774 <<
" " << t.preProcessTypes[i][j] <<
" " << t.preProcessSubTypes[i][j]
775 <<
" " << t.postProcessTypes[i][j] <<
" " << t.postProcessSubTypes[i][j]
776 <<
" " << t.preWeights[i][j] <<
" " << t.postWeights[i][j]
777 <<
" " << t.energyDeposit[i][j] <<
" " << t.T[i][j]
Extra G4Navigator to get coordinate transforms.
G4VPhysicalVolume * LocateGlobalPointAndSetup(const G4ThreeVector &point, const G4ThreeVector *direction=nullptr, const G4bool pRelativeSearch=true, const G4bool ignoreDirection=true, G4bool useCurvilinear=true) const
A wrapper for the underlying static navigator instance located within this class.
Structure to record a trajectory point.
Structure to record a trajectory.
std::vector< std::vector< int > > nElectrons
Ion trajectory information.
std::vector< std::vector< int > > charge
Link trajectory information.
std::vector< std::vector< TVector3 > > pxpypz
Local coordinates.
std::vector< std::vector< bool > > isIon
Ion trajectory information.
virtual void Flush()
add comment to avoid warning (no need to make persistent, see issue #191)
void FlushLocal()
Non-virtual version for initialising members.
void FillIndividualTrajectory(IndividualTrajectory &itj, BDSTrajectory *traj, int i, const std::map< G4Material *, short int > &materialToID) const
BDSAuxiliaryNavigator * auxNavigator
Required to find beamline index careful including in streamer.
std::vector< std::vector< double > > mass
Link trajectory information.
std::vector< std::vector< int > > ionZ
Ion trajectory information.
std::vector< std::vector< TVector3 > > xyz
Local coordinates.
std::vector< std::vector< int > > turnsTaken
Link trajectory information.
std::vector< std::vector< double > > rigidity
Link trajectory information.
std::vector< std::vector< int > > ionA
Ion trajectory information.
std::vector< std::vector< double > > kineticEnergy
Link trajectory information.
BDSPhysicalVolumeInfo * GetInfo(G4VPhysicalVolume *logicalVolume, G4bool isTunnel=false)
static BDSPhysicalVolumeInfoRegistry * Instance()
Singleton accessor.
A class holding any information pertaining to a particular physical volume in a BDSIM geant4 model.
G4int GetBeamlineIndex() const
Accessor.
Double map of trajectories to bitset of which filters matched whether to store them.
A Point in a trajectory with extra information.
G4double GetKineticEnergy() const
Accessor for the extra information links.
G4int GetCharge() const
Accessor for the extra information links.
G4double GetPreGlobalTime() const
Accessor.
G4int GetPostProcessType() const
Accessor.
G4ThreeVector GetMomentumLocal() const
Accessor.
G4int GetPreProcessSubType() const
Accessor.
G4bool GetIsIon() const
Accessor for the extra information ions.
G4double GetPreWeight() const
Accessor.
G4double GetRigidity() const
Accessor for the extra information links.
G4int GetTurnsTaken() const
Accessor for the extra information links.
G4double GetEnergyDeposit() const
Accessor.
G4double GetMass() const
Accessor for the extra information links.
G4double GetPreS() const
Accessor.
G4int GetPreProcessType() const
Accessor.
G4int GetIonZ() const
Accessor for the extra information ions.
G4ThreeVector GetPositionLocal() const
Accessor for the extra information local.
G4double GetPostWeight() const
Accessor.
G4int GetPostProcessSubType() const
Accessor.
G4int GetNElectrons() const
Accessor for the extra information ions.
G4int GetIonA() const
Accessor for the extra information ions.
G4Material * GetMaterial() const
Accessor.
G4ThreeVector GetPreMomentum() const
Accessor.
Trajectory information from track including last scatter etc.
virtual int GetPointEntries() const
Get number of trajectory points in this trajectory.
void SetTrajIndex(G4int trajIndexIn)
void SetParentStepIndex(G4int parentStepIndexIn)
The index of the step along the parent trajectory from which this one was created.
virtual G4VTrajectoryPoint * GetPoint(G4int i) const
Access a point - use this class's container.
void SetParentIndex(G4int parentIndexIn)
G4int GetDepth() const
Depth in the tree. Will be filled later once all trajectories are created and sorted.
Temporary structure for an individual trajectory used to convert types.