24#include "BDSOutputROOTEventTrajectory.hh"
27#include "G4VPhysicalVolume.hh"
29#include "BDSHitEnergyDeposition.hh"
30#include "BDSAuxiliaryNavigator.hh"
31#include "BDSPhysicalVolumeInfoRegistry.hh"
32#include "BDSPhysicalVolumeInfo.hh"
33#include "BDSTrajectory.hh"
34#include "BDSTrajectoryOptions.hh"
41BDSOutputROOTEventTrajectory::BDSOutputROOTEventTrajectory():
42 auxNavigator(nullptr),
48BDSOutputROOTEventTrajectory::~BDSOutputROOTEventTrajectory()
58 if (!traj->GetParent())
61 if (traj->GetParent()->GetTrackID() == 1)
62 {
return traj->GetParentStepIndex();}
64 {
return findPrimaryStepIndex(traj->GetParent());}
69 bool storeStepPointLast,
71 const std::map<G4Material*, short int>& materialToID)
78 G4bool stEK = storageOptions.storeLinks || storageOptions.storeKineticEnergy;
79 G4bool stMo = storageOptions.storeMomentumVector;
80 G4bool stPr = storageOptions.storeProcesses;
81 G4bool stTi = storageOptions.storeTime;
82 G4bool stMa = storageOptions.storeMaterial;
86 for (
auto trajFlag : trajectories->trajectories)
99 for (
auto trajFlag : trajectories->trajectories)
103 if (trajFlag.second && parent)
108 if (parent->GetTrajIndex() != -1)
110 auto trajStartPos = traj->
GetPoint(0)->GetPosition();
114 if(parent->
GetPoint(i)->GetPosition() == trajStartPos)
129 for (
auto trajFlag : trajectories->trajectories)
134 if (!trajFlag.second)
137 partID.push_back((
int) traj->GetPDGEncoding());
138 trackID.push_back((
unsigned int) std::abs(traj->GetTrackID()));
139 parentID.push_back((
unsigned int) std::abs(traj->GetParentID()));
140 parentIndex.push_back((
unsigned int) std::abs(traj->GetParentIndex()));
141 parentStepIndex.push_back((
unsigned int) std::abs(traj->GetParentStepIndex()));
142 depth.push_back((
int) traj->
GetDepth());
146 IndividualTrajectory itj;
147 if (storeStepPointsN > 0)
150 G4int nPoints = std::min(nSteps, storeStepPointsN);
151 for (
int i = 0; i < nPoints; ++i)
154 if (storeStepPointLast && (nPoints < nSteps))
164 filters.push_back(trajectories->filtersMatched.at(traj));
166 XYZ.push_back(itj.XYZ);
167 modelIndicies.push_back(itj.modelIndex);
170 {PXPYPZ.push_back(itj.PXPYPZ);}
176 preProcessTypes.push_back(itj.preProcessType);
177 preProcessSubTypes.push_back(itj.preProcessSubType);
178 postProcessTypes.push_back(itj.postProcessType);
179 postProcessSubTypes.push_back(itj.postProcessSubType);
182 preWeights.push_back(itj.preWeight);
183 postWeights.push_back(itj.postWeight);
184 energyDeposit.push_back(itj.energyDeposit);
187 {T.push_back(itj.T);}
193 {materialID.push_back(itj.materialID);}
195 if (!itj.xyz.empty())
197 xyz.push_back(itj.xyz);
198 pxpypz.push_back(itj.pxpypz);
201 if (!itj.charge.empty())
203 charge.push_back(itj.charge);
205 mass.push_back(itj.mass);
209 if (!itj.isIon.empty())
211 isIon.push_back(itj.isIon);
212 ionA.push_back(itj.ionA);
213 ionZ.push_back(itj.ionZ);
218 primaryStepIndex.push_back(findPrimaryStepIndex(traj));
221 trackID_trackIndex.insert(std::pair<int,int>(traj->GetTrackID(),n));
229 for (
auto iT = trajVec.begin(); iT != trajVec.end(); ++iT)
234 trackID_trackIndex.insert(std::pair<int, int>(traj->GetTrackID(),trackIndex));
236 std::cout << trajVec.size() <<
" " << parentID.size() <<
" " << parentIndex.size() <<
" "
237 << traj->GetTrackID() <<
" " << traj->GetParentID() <<
" " << trackIndex << std::endl;
240 auto processPair = findParentProcess(trackIndex);
241 trackIndex_trackProcess.insert(std::pair<
int,std::pair<int,int>>(trackIndex,processPair));
244 if(processPair.first != -1)
246 int mi = modelIndicies[processPair.first][processPair.second];
247 trackIndex_modelIndex.insert(std::pair<int,int>(trackIndex, mi));
249 {modelIndex_trackIndex.at(mi).push_back(trackIndex);}
250 catch(
const std::exception&)
252 modelIndex_trackIndex.insert(std::pair<
int,std::vector<int>>(mi,std::vector<int>()));
253 modelIndex_trackIndex.at(mi).push_back(trackIndex);
265 const std::map<G4Material*, short int>& materialToID)
const
272 G4ThreeVector pos = point->GetPosition();
273 itj.XYZ.emplace_back(pos.getX() / CLHEP::m, pos.getY() / CLHEP::m, pos.getZ() / CLHEP::m);
280 {itj.modelIndex.push_back(-1);}
292 itj.PXPYPZ.emplace_back(mom.getX(), mom.getY(), mom.getZ());
293 itj.S.push_back(point->
GetPreS() / CLHEP::m);
297 itj.materialID.push_back(materialToID.at(point->
GetMaterial()));
299 if (point->extraLocal)
303 itj.xyz.emplace_back(localPos.getX(), localPos.getY(), localPos.getZ());
304 itj.pxpypz.emplace_back(localMom.getX(), localMom.getY(), localMom.getZ());
307 if (point->extraLink)
309 itj.charge.push_back((
int) (point->
GetCharge() / (G4double)CLHEP::eplus));
311 itj.mass.push_back(point->
GetMass() / CLHEP::GeV);
312 itj.rigidity.push_back(point->
GetRigidity() / (CLHEP::tesla*CLHEP::m));
317 itj.isIon.push_back(point->
GetIsIon());
318 itj.ionA.push_back(point->
GetIonA());
319 itj.ionZ.push_back(point->
GetIonZ());
326 G4cout << phc->GetSize() << G4endl;
344 parentStepIndex.clear();
345 primaryStepIndex.clear();
348 preProcessTypes.clear();
349 preProcessSubTypes.clear();
350 postProcessTypes.clear();
351 postProcessSubTypes.clear();
355 energyDeposit.clear();
377 modelIndicies.clear();
378 trackID_trackIndex.clear();
391 filters = other->filters;
392 partID = other->partID;
393 trackID = other->trackID;
394 parentID = other->parentID;
395 parentIndex = other->parentIndex;
396 parentStepIndex = other->parentStepIndex;
397 primaryStepIndex = other->primaryStepIndex;
398 depth = other->depth;
400 preProcessTypes = other->preProcessTypes;
401 preProcessSubTypes = other->preProcessSubTypes;
402 postProcessTypes = other->postProcessTypes;
403 postProcessSubTypes = other->postProcessSubTypes;
405 preWeights = other->preWeights;
406 postWeights = other->postWeights;
407 energyDeposit = other->energyDeposit;
411 PXPYPZ = other->PXPYPZ;
427 materialID = other->materialID;
428 modelIndicies = other->modelIndicies;
429 trackID_trackIndex = other->trackID_trackIndex;
434std::pair<int,int> BDSOutputROOTEventTrajectory::findParentProcess(
int trackIndex)
436 std::cout <<
"BDSOutputROOTEventTrajectory::findParentProcess> "
437 << trackIndex <<
" " << parentID.size() <<
" " << parentIndex.size() << std::endl;
438 int tid = trackIndex;
439 int pid = parentID.at(tid);
440 std::cout << pid << std::endl;
441 int pin = parentIndex.at(tid);
442 std::cout << pin << std::endl;
445 {
return std::pair<int,int>(-1,-1);}
446 int sin = parentStepIndex.at(tid);
447 std::cout << sin << std::endl;
454 pid = parentID.at(tid);
455 pin = parentIndex.at(tid);
456 sin = parentStepIndex.at(tid);
458 std::cout << tid <<
" " << pid <<
" " << pin <<
" " << sin <<
" " << std::endl;
461 return std::pair<int,int>(pin,sin);
465std::vector<BDSOutputROOTEventTrajectoryPoint> BDSOutputROOTEventTrajectory::trackInteractions(
int trackIDIn)
const
468 if (trackID_trackIndex.find(trackIDIn) == trackID_trackIndex.end())
470 std::cout <<
"No such track ID" << std::endl;
471 return std::vector<BDSOutputROOTEventTrajectoryPoint>();
474 int ti = trackID_trackIndex.at(trackIDIn);
476 std::vector<BDSOutputROOTEventTrajectoryPoint> tpv;
478 int nstep = (int)XYZ[ti].size();
480 {
return std::vector<BDSOutputROOTEventTrajectoryPoint>();}
482 if (postProcessTypes[ti].empty())
484 std::cout <<
"Processes not stored for this file - not possible." << std::endl;
485 return std::vector<BDSOutputROOTEventTrajectoryPoint>();
488 bool usePXPYPZ = !PXPYPZ[ti].empty();
489 bool useT = !T.empty();
490 bool useIon = !
isIon.empty();
491 bool useLocal = !
xyz.empty();
492 bool useLinks = !
charge.empty();
494 bool useMat = !materialID.empty();
496 for (
int i = 0; i < nstep; ++i)
498 int ppt = postProcessTypes[ti][i];
499 int ppst = postProcessSubTypes[ti][i];
505 bool notGeneral = ppt != 7 && ppst != 401;
506 bool changeInEnergy = energyDeposit[ti][i] > 1e-9;
507 if ( (ppt != -1 && ppt != 1 && ppt != 10 && ppt != 0 && notGeneral) || changeInEnergy)
513 postProcessTypes[ti][i],
514 postProcessSubTypes[ti][i],
516 energyDeposit[ti][i],
518 usePXPYPZ ? PXPYPZ[ti][i] : TVector3(),
519 modelIndicies[ti][i],
521 useLocal ?
xyz[ti][i] : TVector3(),
522 useLocal ?
pxpypz[ti][i] : TVector3(),
523 useLinks ?
charge[ti][i] : 0,
527 useLinks ?
mass[ti][i] : 0,
528 useIon ?
isIon[ti][i] : false,
529 useIon ?
ionA[ti][i] : 0,
530 useIon ?
ionZ[ti][i] : 0,
532 useMat ? materialID[ti][i] : -1,
543 if (trackID_trackIndex.find(trackIDIn) == trackID_trackIndex.end())
545 std::cout <<
"No such track ID" << std::endl;
548 int ti = trackID_trackIndex.at(trackIDIn);
549 int pid = (int)parentID[ti];
550 int chosenTrackID = trackIDIn;
553 if (parentID[trackID_trackIndex.at(pid)] > 0)
554 {chosenTrackID = pid;}
555 ti = trackID_trackIndex.at(pid);
556 pid = (int)parentID[ti];
558 return parentProcessPoint(chosenTrackID);
564 if (trackID_trackIndex.find(trackIDIn) == trackID_trackIndex.end())
566 std::cout <<
"No such track ID" << std::endl;
570 int ti = trackID_trackIndex.at(trackIDIn);
571 int pti = (int)parentID[ti];
575 std::cout <<
"Track is a parent" << std::endl;
579 int si = (int)parentStepIndex.at(ti);
582 {pi = trackID_trackIndex.at(pti);}
586 if (si > (
int)XYZ[pi].size())
588 std::cout <<
"Not all step points are stored. Parent step index is outside points stored." << std::endl;
592 bool usePXPYPZ = !PXPYPZ[ti].empty();
593 bool useT = !T.empty();
594 bool useIon = !
isIon.empty();
595 bool useLocal = !
xyz.empty();
596 bool useLinks = !
charge.empty();
598 bool useMat = !materialID.empty();
604 postProcessTypes[pi][si],
605 postProcessSubTypes[pi][si],
607 energyDeposit[pi][si],
609 usePXPYPZ ? PXPYPZ[pi][si] : TVector3(),
610 modelIndicies[pi][si],
611 useT ? T[pi][si] : 0,
612 useLocal ?
xyz[pi][si] : TVector3(),
613 useLocal ?
pxpypz[pi][si] : TVector3(),
614 useLinks ?
charge[pi][si] : 0,
618 useLinks ?
mass[pi][si] : 0,
619 useIon ?
isIon[pi][si] : false,
620 useIon ?
ionA[pi][si] : 0,
621 useIon ?
ionZ[pi][si] : 0,
623 useMat ? materialID[pi][si] : -1,
628std::vector<BDSOutputROOTEventTrajectoryPoint> BDSOutputROOTEventTrajectory::processHistory(
int trackIDIn)
const
631 if (trackID_trackIndex.find(trackIDIn) == trackID_trackIndex.end())
633 std::cout <<
"No such track ID" << std::endl;
634 return std::vector<BDSOutputROOTEventTrajectoryPoint>();
637 if (postProcessTypes.empty())
639 std::cout <<
"Processes not stored for this file - not possible." << std::endl;
640 return std::vector<BDSOutputROOTEventTrajectoryPoint>();
643 int ti = trackID_trackIndex.at(trackIDIn);
645 bool usePXPYPZ = !PXPYPZ.empty();
646 bool useT = !T.empty();
647 bool useIon = !
isIon.empty();
648 bool useLocal = !
xyz.empty();
649 bool useLinks = !
charge.empty();
651 bool useMat = !materialID.empty();
653 std::vector<BDSOutputROOTEventTrajectoryPoint> tpv;
656 unsigned int pi = parentIndex.at(ti);
657 unsigned int psi = parentStepIndex.at(ti);
658 if (psi > (
unsigned int)XYZ[pi].size())
660 std::cout <<
"Not all points stored - defaulting to creation point." << std::endl;
668 postProcessTypes[pi][psi],
669 postProcessSubTypes[pi][psi],
670 postWeights[pi][psi],
671 energyDeposit[pi][psi],
673 usePXPYPZ ? PXPYPZ[ti][psi] : TVector3(),
674 modelIndicies[ti][psi],
675 useT ? T[ti][psi] : 0,
676 useLocal ?
xyz[ti][psi] : TVector3(),
677 useLocal ?
pxpypz[ti][psi] : TVector3(),
678 useLinks ?
charge[ti][psi] : 0,
682 useLinks ?
mass[ti][psi] : 0,
683 useIon ?
isIon[ti][psi] : false,
684 useIon ?
ionA[ti][psi] : 0,
685 useIon ?
ionZ[ti][psi] : 0,
687 useMat ? materialID[ti][psi] : -1,
692 std::reverse(tpv.begin(),tpv.end());
696void BDSOutputROOTEventTrajectory::printTrajectoryInfoByTrackID(
int trackIDIn)
const
699 int storageIndex = 0;
700 auto search = trackID_trackIndex.find(trackIDIn);
701 if (search == trackID_trackIndex.end())
703 std::cout <<
"No such track ID" << std::endl;
707 {storageIndex = search->second;}
708 printTrajectoryInfo(storageIndex);
711void BDSOutputROOTEventTrajectory::printTrajectoryInfo(
int storageIndex)
const
713 int i = storageIndex;
716 if (i > (
int)partID.size() || i < 0)
717 {std::cout <<
"Invalid index" << std::endl;
return;}
720 {std::cout <<
"Index chosen is greater than maximum index of: " << n-1 << std::endl;
return;}
723 std::cout <<
"Storage index " << std::setw(wdt) << i
724 <<
", PDG ID " << std::setw(wdt) << partID[i]
725 <<
", Track ID " << std::setw(wdt) << trackID[i]
726 <<
", Parent ID " << std::setw(wdt) << parentID[i] << std::endl;
727 std::cout <<
"Created by Track ID " << parentID[i] <<
", with storage index " << parentIndex[i] <<
", and at step index " << parentStepIndex[i] << std::endl;
730 std::cout << std::setw(wdt) <<
"step ind" <<
" "
731 << std::setw(wdt) <<
"prePrcT" <<
" " << std::setw(wdt) <<
"prePrcST" <<
" "
732 << std::setw(wdt) <<
"pstPrcT" <<
" " << std::setw(wdt) <<
"pstPrcST" <<
" "
733 << std::setw(wdt) <<
"X" <<
" " << std::setw(wdt) <<
"Y" <<
" "
734 << std::setw(wdt) <<
"Z" <<
" " << std::setw(wdt) <<
"E" <<
" "
735 << std::setw(wdt) <<
"p" <<
" " << std::setw(wdt) <<
"p_x" <<
" "
736 << std::setw(wdt) <<
"p_y" <<
" " << std::setw(wdt) <<
"p_z" <<
" "
737 << std::setw(wdt) <<
"t" << std::endl;
739 for (
size_t j=0; j<XYZ[i].size(); ++j)
741 std::cout << std::setw(wdt) << j <<
" "
742 << std::setw(wdt) << preProcessTypes[i][j] <<
" " << std::setw(wdt) << preProcessSubTypes[i][j] <<
" "
743 << std::setw(wdt) << postProcessTypes[i][j] <<
" " << std::setw(wdt) << postProcessSubTypes[i][j] <<
" "
744 << std::setw(wdt) << XYZ[i][j].X() <<
" " << std::setw(wdt) << XYZ[i][j].Y() <<
" "
745 << std::setw(wdt) << XYZ[i][j].Z() <<
" " << std::setw(wdt) << energyDeposit[i][j] <<
" "
746 << std::setw(wdt) << PXPYPZ[i][j].Mag() <<
" " << std::setw(wdt) << PXPYPZ[i][j].X() <<
" "
747 << std::setw(wdt) << PXPYPZ[i][j].Y() <<
" " << std::setw(wdt) << PXPYPZ[i][j].Z() <<
" "
748 << std::setw(wdt) << T[i][j] << std::endl;
752bool BDSOutputROOTEventTrajectory::parentIsPrimary(
int trackIDIn)
const
755 if (trackID_trackIndex.find(trackIDIn) == trackID_trackIndex.end())
757 std::cout <<
"No such track ID" << std::endl;
761 unsigned int storageIndex = (
unsigned int)trackID_trackIndex.at(trackIDIn);
762 unsigned int parentStorageIndex = parentIndex[storageIndex];
763 return parentID[parentStorageIndex] == 0;
768 for (
int i=0; i< (int)t.preProcessTypes.size();++i)
770 for (
int j=0; j< (int)t.preProcessTypes[i].size(); ++j)
775 <<
" " << t.preProcessTypes[i][j] <<
" " << t.preProcessSubTypes[i][j]
776 <<
" " << t.postProcessTypes[i][j] <<
" " << t.postProcessSubTypes[i][j]
777 <<
" " << t.preWeights[i][j] <<
" " << t.postWeights[i][j]
778 <<
" " << 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.