18#include "TRestGeant4Event.h"
22#include <TRestStringHelper.h>
23#include <TRestTools.h>
26#include "TRestGeant4Metadata.h"
32TRestGeant4Event::TRestGeant4Event() {
39TRestGeant4Event::~TRestGeant4Event() {
46 fPrimaryParticleNames.clear();
51 fXZHitGraph =
nullptr;
52 fYZHitGraph =
nullptr;
53 fXYHitGraph =
nullptr;
55 fXZMultiGraph =
nullptr;
56 fYZMultiGraph =
nullptr;
57 fXYMultiGraph =
nullptr;
73 fTotalDepositedEnergy = 0;
74 fSensitiveVolumeEnergy = 0;
89void TRestGeant4Event::AddActiveVolume(
const string& volumeName) {
91 fVolumeStored.push_back(1);
92 fVolumeStoredNames.push_back(volumeName);
93 fVolumeDepositedEnergy.push_back(0);
96void TRestGeant4Event::ClearVolumes() {
98 fVolumeStored.clear();
99 fVolumeStoredNames.clear();
100 fVolumeDepositedEnergy.clear();
103void TRestGeant4Event::AddEnergyDepositToVolume(Int_t volID, Double_t eDep) {
104 fVolumeDepositedEnergy[volID] += eDep;
107TVector3 TRestGeant4Event::GetMeanPositionInVolume(Int_t volID)
const {
111 for (
unsigned int t = 0; t < GetNumberOfTracks(); t++) {
112 const auto tck = GetTrack(t);
113 if (tck.GetEnergyInVolume(volID) > 0) {
114 pos += tck.GetMeanPositionInVolume(volID) * tck.GetEnergyInVolume(volID);
116 eDep += tck.GetEnergyInVolume(volID);
121 Double_t nan = TMath::QuietNaN();
122 return {nan, nan, nan};
125 pos = (1 / eDep) * pos;
136 TVector3 meanPos = this->GetMeanPositionInVolume(volID);
138 Double_t nan = TMath::QuietNaN();
139 if (meanPos == TVector3(nan, nan, nan))
return TVector3(nan, nan, nan);
141 TRestHits hitsInVolume = GetHitsInVolume(volID);
144 TVector3 deviation = TVector3(0, 0, 0);
146 for (
unsigned int n = 0; n < hitsInVolume.GetNumberOfHits(); n++) {
147 Double_t en = hitsInVolume.GetEnergy(n);
148 TVector3 diff = meanPos - hitsInVolume.
GetPosition(n);
149 diff.SetXYZ(diff.X() * diff.X(), diff.Y() * diff.Y(), diff.Z() * diff.Z());
151 deviation = deviation + en * diff;
155 deviation = (1. / edep) * deviation;
167 for (
unsigned int t = 0; t < GetNumberOfTracks(); t++)
168 if (GetTrack(t).GetEnergyInVolume(volID) > 0)
return GetTrack(t).GetFirstPositionInVolume(volID);
170 Double_t nan = TMath::QuietNaN();
171 return {nan, nan, nan};
184 for (
int t = GetNumberOfTracks() - 1; t >= 0; t--) {
185 if (GetTrack(t).GetEnergyInVolume(volID) > 0) {
186 return GetTrack(t).GetLastPositionInVolume(volID);
189 Double_t nan = TMath::QuietNaN();
190 return {nan, nan, nan};
195 if (fTrackIDToTrackIndex.count(trackID) > 0) {
196 result =
const_cast<TRestGeant4Track*
>(&fTracks[fTrackIDToTrackIndex.at(trackID)]);
197 if (result ==
nullptr || result->GetTrackID() != trackID) {
198 cerr <<
"TRestGeant4Event::GetTrackByID - ERROR: trackIDToTrackIndex map is corrupted" << endl;
211 size_t numberOfHits = 0;
212 for (
const auto& track : fTracks) {
213 numberOfHits += track.GetNumberOfHits(volID);
224 size_t numberOfHits = 0;
225 for (
const auto& track : fTracks) {
226 numberOfHits += track.GetNumberOfPhysicalHits(volID);
238 for (
unsigned int t = 0; t < GetNumberOfTracks(); t++) {
239 const auto& g4Hits = GetTrack(t).GetHits();
240 for (
unsigned int n = 0; n < g4Hits.GetNumberOfHits(); n++) {
241 if (volID != -1 && g4Hits.GetVolumeId(n) != volID)
continue;
243 Double_t x = g4Hits.GetX(n);
244 Double_t y = g4Hits.GetY(n);
245 Double_t z = g4Hits.GetZ(n);
246 Double_t en = g4Hits.GetEnergy(n);
248 hits.
AddHit({x, y, z}, en);
255Int_t TRestGeant4Event::GetNumberOfTracksForParticle(
const TString& particleName)
const {
257 for (
const auto& track : fTracks) {
258 if (particleName.EqualTo(track.GetParticleName())) {
265Double_t TRestGeant4Event::GetEnergyDepositedByParticle(
const TString& particleName)
const {
267 for (
const auto& track : fTracks) {
268 if (particleName.EqualTo(track.GetParticleName())) {
269 energy += track.GetTotalEnergy();
275void TRestGeant4Event::SetBoundaries(Double_t xMin, Double_t xMax, Double_t yMin, Double_t yMax,
276 Double_t zMin, Double_t zMax) {
296 Double_t dX = fMaxX - fMinX;
297 Double_t dY = fMaxY - fMinY;
298 Double_t dZ = fMaxZ - fMinZ;
300 return TMath::Sqrt(dX * dX + dY * dY + dZ * dZ);
303void TRestGeant4Event::SetBoundaries() {
304 Double_t maxX = -1e10, minX = 1e10, maxZ = -1e10, minZ = 1e10, maxY = -1e10, minY = 1e10;
305 Double_t minEnergy = 1e10, maxEnergy = -1e10;
308 for (
unsigned int ntck = 0; ntck < this->GetNumberOfTracks(); ntck++) {
311 const auto& hits = GetTrack(ntck).GetHits();
313 for (
int nhit = 0; nhit < nHits; nhit++) {
314 Double_t x = hits.GetX(nhit);
315 Double_t y = hits.GetY(nhit);
316 Double_t z = hits.GetZ(nhit);
318 Double_t en = hits.GetEnergy(nhit);
320 if (en <= 0)
continue;
322 if (x > maxX) maxX = x;
323 if (x < minX) minX = x;
324 if (y > maxY) maxY = y;
325 if (y < minY) minY = y;
326 if (z > maxZ) maxZ = z;
327 if (z < minZ) minZ = z;
329 if (en > maxEnergy) maxEnergy = en;
330 if (en < minEnergy) minEnergy = en;
343 fMaxEnergy = maxEnergy;
344 fMinEnergy = minEnergy;
350TMultiGraph* TRestGeant4Event::GetXYMultiGraph(Int_t gridElement, vector<TString> pcsList,
351 Double_t minPointSize, Double_t maxPointSize) {
353 delete[] fXYHitGraph;
354 fXYHitGraph =
nullptr;
356 fXYHitGraph =
new TGraph[fTotalHits];
358 fXYMultiGraph =
new TMultiGraph();
362 fLegend_XY =
nullptr;
365 fLegend_XY =
new TLegend(0.75, 0.75, 0.9, 0.85);
368 sprintf(title,
"Event ID %d (XY)", this->GetID());
369 fPad->cd(gridElement)->DrawFrame(fMinX - 10, fMinY - 10, fMaxX + 10, fMaxY + 10, title);
371 Double_t m = 1, n = 0;
372 if (fMaxEnergy - fMinEnergy > 0) {
373 m = (maxPointSize - minPointSize) / (fMaxEnergy - fMinEnergy);
374 n = maxPointSize - m * fMaxEnergy;
377 for (
unsigned int n = 0; n < fXYPcsMarker.size(); n++)
delete fXYPcsMarker[n];
378 fXYPcsMarker.clear();
381 for (
unsigned int p = 0; p < pcsList.size(); p++) legendAdded.push_back(0);
384 for (
unsigned int ntck = 0; ntck < GetNumberOfTracks(); ntck++) {
385 const auto hits = GetTrack(ntck).GetHits();
387 EColor color = GetTrack(ntck).GetParticleColor();
389 for (
unsigned int nhit = 0; nhit < hits.GetNumberOfHits(); nhit++) {
390 Double_t xPos = hits.GetX(nhit);
391 Double_t yPos = hits.GetY(nhit);
392 Double_t energy = hits.GetEnergy(nhit);
394 for (
unsigned int p = 0; p < pcsList.size(); p++) {
395 if (GetTrack(ntck).GetProcessName(hits.GetProcess(nhit)) == pcsList[p]) {
396 TGraph* pcsGraph =
new TGraph(1);
398 pcsGraph->SetPoint(0, xPos, yPos);
399 pcsGraph->SetMarkerColor(kBlack);
400 pcsGraph->SetMarkerSize(3);
401 pcsGraph->SetMarkerStyle(30 + p);
403 fXYPcsMarker.push_back(pcsGraph);
405 if (legendAdded[p] == 0) {
406 fLegend_XY->AddEntry(pcsGraph, GetTrack(ntck).GetProcessName(hits.GetProcess(nhit)),
413 Double_t radius = m * energy + n;
414 if (fMaxEnergy - fMinEnergy <= 0) radius = 2.5;
416 fXYHitGraph[cnt].SetPoint(0, xPos, yPos);
418 fXYHitGraph[cnt].SetMarkerColor(color);
419 fXYHitGraph[cnt].SetMarkerSize(radius);
420 fXYHitGraph[cnt].SetMarkerStyle(20);
422 fXYMultiGraph->Add(&fXYHitGraph[cnt]);
428 fXYMultiGraph->GetXaxis()->SetTitle(
"X-axis (mm)");
429 fXYMultiGraph->GetXaxis()->SetTitleSize(1.25 * fXYMultiGraph->GetXaxis()->GetTitleSize());
430 fXYMultiGraph->GetXaxis()->SetTitleOffset(1.25);
431 fXYMultiGraph->GetXaxis()->SetLabelSize(1.25 * fXYMultiGraph->GetXaxis()->GetLabelSize());
433 fXYMultiGraph->GetYaxis()->SetTitle(
"Y-axis (mm)");
434 fXYMultiGraph->GetYaxis()->SetTitleSize(1.25 * fXYMultiGraph->GetYaxis()->GetTitleSize());
435 fXYMultiGraph->GetYaxis()->SetTitleOffset(1.75);
436 fXYMultiGraph->GetYaxis()->SetLabelSize(1.25 * fXYMultiGraph->GetYaxis()->GetLabelSize());
437 fPad->cd(gridElement);
439 return fXYMultiGraph;
442TMultiGraph* TRestGeant4Event::GetYZMultiGraph(Int_t gridElement, vector<TString> pcsList,
443 Double_t minPointSize, Double_t maxPointSize) {
445 delete[] fYZHitGraph;
446 fYZHitGraph =
nullptr;
448 fYZHitGraph =
new TGraph[fTotalHits];
450 fYZMultiGraph =
new TMultiGraph();
454 fLegend_YZ =
nullptr;
457 fLegend_YZ =
new TLegend(0.75, 0.75, 0.9, 0.85);
460 sprintf(title,
"Event ID %d (YZ)", this->GetID());
461 fPad->cd(gridElement)->DrawFrame(fMinY - 10, fMinZ - 10, fMaxY + 10, fMaxZ + 10, title);
463 for (
unsigned int n = 0; n < fYZPcsMarker.size(); n++)
delete fYZPcsMarker[n];
464 fYZPcsMarker.clear();
466 Double_t m = 1, n = 0;
467 if (fMaxEnergy - fMinEnergy > 0) {
468 m = (maxPointSize - minPointSize) / (fMaxEnergy - fMinEnergy);
469 n = maxPointSize - m * fMaxEnergy;
473 for (
unsigned int p = 0; p < pcsList.size(); p++) legendAdded.push_back(0);
476 for (
unsigned int ntck = 0; ntck < GetNumberOfTracks(); ntck++) {
477 const auto& hits = GetTrack(ntck).GetHits();
479 EColor color = GetTrack(ntck).GetParticleColor();
481 for (
unsigned int nhit = 0; nhit < hits.GetNumberOfHits(); nhit++) {
482 Double_t yPos = hits.GetY(nhit);
483 Double_t zPos = hits.GetZ(nhit);
484 Double_t energy = hits.GetEnergy(nhit);
486 for (
unsigned int p = 0; p < pcsList.size(); p++) {
487 if (GetTrack(ntck).GetProcessName(hits.GetProcess(nhit)) == pcsList[p]) {
488 TGraph* pcsGraph =
new TGraph(1);
490 pcsGraph->SetPoint(0, yPos, zPos);
491 pcsGraph->SetMarkerColor(kBlack);
492 pcsGraph->SetMarkerSize(3);
493 pcsGraph->SetMarkerStyle(30 + p);
495 fYZPcsMarker.push_back(pcsGraph);
497 if (legendAdded[p] == 0) {
498 fLegend_YZ->AddEntry(pcsGraph, GetTrack(ntck).GetProcessName(hits.GetProcess(nhit)),
505 Double_t radius = m * energy + n;
506 if (fMaxEnergy - fMinEnergy <= 0) radius = 2.5;
508 fYZHitGraph[cnt].SetPoint(0, yPos, zPos);
510 fYZHitGraph[cnt].SetMarkerColor(color);
511 fYZHitGraph[cnt].SetMarkerSize(radius);
512 fYZHitGraph[cnt].SetMarkerStyle(20);
514 fYZMultiGraph->Add(&fYZHitGraph[cnt]);
520 fYZMultiGraph->GetXaxis()->SetTitle(
"Y-axis (mm)");
521 fYZMultiGraph->GetXaxis()->SetTitleSize(1.25 * fYZMultiGraph->GetXaxis()->GetTitleSize());
522 fYZMultiGraph->GetXaxis()->SetTitleOffset(1.25);
523 fYZMultiGraph->GetXaxis()->SetLabelSize(1.25 * fYZMultiGraph->GetXaxis()->GetLabelSize());
525 fYZMultiGraph->GetYaxis()->SetTitle(
"Z-axis (mm)");
526 fYZMultiGraph->GetYaxis()->SetTitleSize(1.25 * fYZMultiGraph->GetYaxis()->GetTitleSize());
527 fYZMultiGraph->GetYaxis()->SetTitleOffset(1.75);
528 fYZMultiGraph->GetYaxis()->SetLabelSize(1.25 * fYZMultiGraph->GetYaxis()->GetLabelSize());
529 fPad->cd(gridElement);
531 return fYZMultiGraph;
534TMultiGraph* TRestGeant4Event::GetXZMultiGraph(Int_t gridElement, vector<TString> pcsList,
535 Double_t minPointSize, Double_t maxPointSize) {
537 delete[] fXZHitGraph;
538 fXZHitGraph =
nullptr;
540 fXZHitGraph =
new TGraph[fTotalHits];
542 fXZMultiGraph =
new TMultiGraph();
546 fLegend_XZ =
nullptr;
549 fLegend_XZ =
new TLegend(0.75, 0.75, 0.9, 0.85);
552 sprintf(title,
"Event ID %d (XZ)", this->GetID());
553 fPad->cd(gridElement)->DrawFrame(fMinX - 10, fMinZ - 10, fMaxX + 10, fMaxZ + 10, title);
555 for (
unsigned int n = 0; n < fXZPcsMarker.size(); n++)
delete fXZPcsMarker[n];
556 fXZPcsMarker.clear();
558 Double_t m = 1, n = 0;
559 if (fMaxEnergy - fMinEnergy > 0) {
560 m = (maxPointSize - minPointSize) / (fMaxEnergy - fMinEnergy);
561 n = maxPointSize - m * fMaxEnergy;
565 for (
unsigned int p = 0; p < pcsList.size(); p++) legendAdded.push_back(0);
568 for (
unsigned int ntck = 0; ntck < GetNumberOfTracks(); ntck++) {
569 const auto& hits = GetTrack(ntck).GetHits();
571 EColor color = GetTrack(ntck).GetParticleColor();
573 for (
unsigned int nhit = 0; nhit < hits.GetNumberOfHits(); nhit++) {
574 Double_t xPos = hits.GetX(nhit);
575 Double_t zPos = hits.GetZ(nhit);
576 Double_t energy = hits.GetEnergy(nhit);
578 for (
unsigned int p = 0; p < pcsList.size(); p++) {
579 if (GetTrack(ntck).GetProcessName(hits.GetProcess(nhit)) == pcsList[p]) {
580 TGraph* pcsGraph =
new TGraph(1);
582 pcsGraph->SetPoint(0, xPos, zPos);
583 pcsGraph->SetMarkerColor(kBlack);
584 pcsGraph->SetMarkerSize(3);
585 pcsGraph->SetMarkerStyle(30 + p);
587 fXZPcsMarker.push_back(pcsGraph);
589 if (legendAdded[p] == 0) {
590 fLegend_XZ->AddEntry(pcsGraph, GetTrack(ntck).GetProcessName(hits.GetProcess(nhit)),
597 Double_t radius = m * energy + n;
598 if (fMaxEnergy - fMinEnergy <= 0) radius = 2.5;
600 fXZHitGraph[cnt].SetPoint(0, xPos, zPos);
602 fXZHitGraph[cnt].SetMarkerColor(color);
603 fXZHitGraph[cnt].SetMarkerSize(radius);
604 fXZHitGraph[cnt].SetMarkerStyle(20);
606 fXZMultiGraph->Add(&fXZHitGraph[cnt]);
612 fXZMultiGraph->GetXaxis()->SetTitle(
"X-axis (mm)");
613 fXZMultiGraph->GetXaxis()->SetTitleOffset(1.25);
614 fXZMultiGraph->GetXaxis()->SetTitleSize(1.25 * fXZMultiGraph->GetXaxis()->GetTitleSize());
615 fXZMultiGraph->GetXaxis()->SetLabelSize(1.25 * fXZMultiGraph->GetXaxis()->GetLabelSize());
617 fXZMultiGraph->GetYaxis()->SetTitle(
"Z-axis (mm)");
618 fXZMultiGraph->GetYaxis()->SetTitleOffset(1.75);
619 fXZMultiGraph->GetYaxis()->SetTitleSize(1.25 * fXZMultiGraph->GetYaxis()->GetTitleSize());
620 fXZMultiGraph->GetYaxis()->SetLabelSize(1.25 * fXZMultiGraph->GetYaxis()->GetLabelSize());
621 fPad->cd(gridElement);
623 return fXZMultiGraph;
628TH2F* TRestGeant4Event::GetXYHistogram(Int_t gridElement, vector<TString> optList) {
634 Bool_t stats =
false;
636 for (
unsigned int n = 0; n < optList.size(); n++) {
637 if (optList[n].Contains(
"binSize=")) {
638 TString pitchStr = optList[n].Remove(0, 8);
639 pitch = stod((
string)pitchStr);
642 if (optList[n].Contains(
"stats")) stats =
true;
645 Int_t nBinsX = (fMaxX - fMinX + 20) / pitch;
646 Int_t nBinsY = (fMaxY - fMinY + 20) / pitch;
648 fXYHisto =
new TH2F(
"XY",
"", nBinsX, fMinX - 10, fMinX + pitch * nBinsX, nBinsY, fMinY - 10,
649 fMinY + pitch * nBinsY);
651 for (
unsigned int ntck = 0; ntck < GetNumberOfTracks(); ntck++) {
652 const auto& hits = GetTrack(ntck).GetHits();
654 for (
unsigned int nhit = 0; nhit < hits.GetNumberOfHits(); nhit++) {
655 Double_t xPos = hits.GetX(nhit);
656 Double_t yPos = hits.GetY(nhit);
657 Double_t energy = hits.GetEnergy(nhit);
659 fXYHisto->Fill(xPos, yPos, energy);
665 style.SetOptStat(1001111);
667 fXYHisto->SetStats(stats);
670 sprintf(title,
"Event ID %d (XY)", this->GetID());
671 fXYHisto->SetTitle(title);
673 fXYHisto->GetXaxis()->SetTitle(
"X-axis (mm)");
674 fXYHisto->GetXaxis()->SetTitleOffset(1.25);
675 fXYHisto->GetXaxis()->SetTitleSize(1.25 * fXYHisto->GetXaxis()->GetTitleSize());
676 fXYHisto->GetXaxis()->SetLabelSize(1.25 * fXYHisto->GetXaxis()->GetLabelSize());
678 fXYHisto->GetYaxis()->SetTitle(
"Y-axis (mm)");
679 fXYHisto->GetYaxis()->SetTitleOffset(1.75);
680 fXYHisto->GetYaxis()->SetTitleSize(1.25 * fXYHisto->GetYaxis()->GetTitleSize());
681 fXYHisto->GetYaxis()->SetLabelSize(1.25 * fXYHisto->GetYaxis()->GetLabelSize());
682 fPad->cd(gridElement);
687TH2F* TRestGeant4Event::GetXZHistogram(Int_t gridElement, vector<TString> optList) {
693 Bool_t stats =
false;
695 for (
unsigned int n = 0; n < optList.size(); n++) {
696 if (optList[n].Contains(
"binSize=")) {
697 TString pitchStr = optList[n].Remove(0, 8);
698 pitch = stod((
string)pitchStr);
701 if (optList[n].Contains(
"stats")) stats =
true;
704 Int_t nBinsX = (fMaxX - fMinX + 20) / pitch;
705 Int_t nBinsZ = (fMaxZ - fMinZ + 20) / pitch;
707 fXZHisto =
new TH2F(
"XZ",
"", nBinsX, fMinX - 10, fMinX + pitch * nBinsX, nBinsZ, fMinZ - 10,
708 fMinZ + pitch * nBinsZ);
710 for (
unsigned int ntck = 0; ntck < GetNumberOfTracks(); ntck++) {
711 const auto& hits = GetTrack(ntck).GetHits();
713 for (
unsigned int nhit = 0; nhit < hits.GetNumberOfHits(); nhit++) {
714 Double_t xPos = hits.GetX(nhit);
715 Double_t zPos = hits.GetZ(nhit);
716 Double_t energy = hits.GetEnergy(nhit);
718 fXZHisto->Fill(xPos, zPos, energy);
724 style.SetOptStat(1001111);
726 fXZHisto->SetStats(stats);
729 sprintf(title,
"Event ID %d (XZ)", this->GetID());
730 fXZHisto->SetTitle(title);
732 fXZHisto->GetXaxis()->SetTitle(
"X-axis (mm)");
733 fXZHisto->GetXaxis()->SetTitleOffset(1.25);
734 fXZHisto->GetXaxis()->SetTitleSize(1.25 * fXZHisto->GetXaxis()->GetTitleSize());
735 fXZHisto->GetXaxis()->SetLabelSize(1.25 * fXZHisto->GetXaxis()->GetLabelSize());
737 fXZHisto->GetYaxis()->SetTitle(
"Z-axis (mm)");
738 fXZHisto->GetYaxis()->SetTitleOffset(1.75);
739 fXZHisto->GetYaxis()->SetTitleSize(1.25 * fXZHisto->GetYaxis()->GetTitleSize());
740 fXZHisto->GetYaxis()->SetLabelSize(1.25 * fXZHisto->GetYaxis()->GetLabelSize());
741 fPad->cd(gridElement);
746TH2F* TRestGeant4Event::GetYZHistogram(Int_t gridElement, vector<TString> optList) {
754 for (
unsigned int n = 0; n < optList.size(); n++) {
755 if (optList[n].Contains(
"binSize=")) {
756 TString pitchStr = optList[n].Remove(0, 8);
757 pitch = stod((
string)pitchStr);
760 if (optList[n].Contains(
"stats")) stats =
true;
763 Int_t nBinsY = (fMaxY - fMinY + 20) / pitch;
764 Int_t nBinsZ = (fMaxZ - fMinZ + 20) / pitch;
766 fYZHisto =
new TH2F(
"YZ",
"", nBinsY, fMinY - 10, fMinY + pitch * nBinsY, nBinsZ, fMinZ - 10,
767 fMinZ + pitch * nBinsZ);
769 for (
unsigned int ntck = 0; ntck < GetNumberOfTracks(); ntck++) {
770 const auto& hits = GetTrack(ntck).GetHits();
772 for (
unsigned int nhit = 0; nhit < hits.GetNumberOfHits(); nhit++) {
773 Double_t yPos = hits.GetY(nhit);
774 Double_t zPos = hits.GetZ(nhit);
775 Double_t energy = hits.GetEnergy(nhit);
777 fYZHisto->Fill(yPos, zPos, energy);
783 style.SetOptStat(1001111);
785 fYZHisto->SetStats(stats);
788 sprintf(title,
"Event ID %d (YZ)", this->GetID());
789 fYZHisto->SetTitle(title);
791 fYZHisto->GetXaxis()->SetTitle(
"Y-axis (mm)");
792 fYZHisto->GetXaxis()->SetTitleOffset(1.25);
793 fYZHisto->GetXaxis()->SetTitleSize(1.25 * fYZHisto->GetXaxis()->GetTitleSize());
794 fYZHisto->GetXaxis()->SetLabelSize(1.25 * fYZHisto->GetXaxis()->GetLabelSize());
796 fYZHisto->GetYaxis()->SetTitle(
"Z-axis (mm)");
797 fYZHisto->GetYaxis()->SetTitleOffset(1.75);
798 fYZHisto->GetYaxis()->SetTitleSize(1.25 * fYZHisto->GetYaxis()->GetTitleSize());
799 fYZHisto->GetYaxis()->SetLabelSize(1.25 * fYZHisto->GetYaxis()->GetLabelSize());
800 fPad->cd(gridElement);
806TH1D* TRestGeant4Event::GetXHistogram(Int_t gridElement, vector<TString> optList) {
813 Bool_t stats =
false;
814 for (
unsigned int n = 0; n < optList.size(); n++) {
815 if (optList[n].Contains(
"binSize=")) {
816 TString pitchStr = optList[n].Remove(0, 8);
817 pitch = stod((
string)pitchStr);
820 if (optList[n].Contains(
"stats")) stats =
true;
823 Int_t nBinsX = (fMaxX - fMinX + 20) / pitch;
825 fXHisto =
new TH1D(
"X",
"", nBinsX, fMinX - 10, fMinX + pitch * nBinsX);
827 for (
unsigned int ntck = 0; ntck < GetNumberOfTracks(); ntck++) {
828 const auto& hits = GetTrack(ntck).GetHits();
830 for (
unsigned int nhit = 0; nhit < hits.GetNumberOfHits(); nhit++) {
831 Double_t xPos = hits.GetX(nhit);
832 Double_t energy = hits.GetEnergy(nhit);
834 fXHisto->Fill(xPos, energy);
841 fXHisto->SetStats(stats);
844 sprintf(title,
"Event ID %d (X)", this->GetID());
845 fXHisto->SetTitle(title);
847 fXHisto->GetXaxis()->SetTitle(
"X-axis (mm)");
848 fXHisto->GetXaxis()->SetTitleOffset(1.25);
849 fXHisto->GetXaxis()->SetTitleSize(1.25 * fXHisto->GetXaxis()->GetTitleSize());
850 fXHisto->GetXaxis()->SetLabelSize(1.25 * fXHisto->GetXaxis()->GetLabelSize());
852 fPad->cd(gridElement);
857TH1D* TRestGeant4Event::GetZHistogram(Int_t gridElement, vector<TString> optList) {
864 Bool_t stats =
false;
865 for (
unsigned int n = 0; n < optList.size(); n++) {
866 if (optList[n].Contains(
"binSize=")) {
867 TString pitchStr = optList[n].Remove(0, 8);
868 pitch = stod((
string)pitchStr);
871 if (optList[n].Contains(
"stats")) stats =
true;
874 Int_t nBinsZ = (fMaxZ - fMinZ + 20) / pitch;
876 fZHisto =
new TH1D(
"Z",
"", nBinsZ, fMinZ - 10, fMinZ + pitch * nBinsZ);
878 for (
unsigned int ntck = 0; ntck < GetNumberOfTracks(); ntck++) {
879 const auto& hits = GetTrack(ntck).GetHits();
881 for (
unsigned int nhit = 0; nhit < hits.GetNumberOfHits(); nhit++) {
882 Double_t zPos = hits.GetZ(nhit);
883 Double_t energy = hits.GetEnergy(nhit);
885 fZHisto->Fill(zPos, energy);
892 fZHisto->SetStats(stats);
895 sprintf(title,
"Event ID %d (Z)", this->GetID());
896 fZHisto->SetTitle(title);
898 fZHisto->GetXaxis()->SetTitle(
"Z-axis (mm)");
899 fZHisto->GetXaxis()->SetTitleOffset(1.25);
900 fZHisto->GetXaxis()->SetTitleSize(1.25 * fZHisto->GetXaxis()->GetTitleSize());
901 fZHisto->GetXaxis()->SetLabelSize(1.25 * fZHisto->GetXaxis()->GetLabelSize());
903 fPad->cd(gridElement);
908TH1D* TRestGeant4Event::GetYHistogram(Int_t gridElement, vector<TString> optList) {
915 Bool_t stats =
false;
916 for (
unsigned int n = 0; n < optList.size(); n++) {
917 if (optList[n].Contains(
"binSize=")) {
918 TString pitchStr = optList[n].Remove(0, 8);
919 pitch = stod((
string)pitchStr);
922 if (optList[n].Contains(
"stats")) stats =
true;
925 Int_t nBinsY = (fMaxY - fMinY + 20) / pitch;
927 fYHisto =
new TH1D(
"Y",
"", nBinsY, fMinY - 10, fMinY + pitch * nBinsY);
929 for (
unsigned int ntck = 0; ntck < GetNumberOfTracks(); ntck++) {
930 const auto& hits = GetTrack(ntck).GetHits();
932 for (
unsigned int nhit = 0; nhit < hits.GetNumberOfHits(); nhit++) {
933 Double_t yPos = hits.GetY(nhit);
934 Double_t energy = hits.GetEnergy(nhit);
936 fYHisto->Fill(yPos, energy);
943 fYHisto->SetStats(stats);
946 sprintf(title,
"Event ID %d (Y)", this->GetID());
947 fYHisto->SetTitle(title);
949 fYHisto->GetXaxis()->SetTitle(
"Y-axis (mm)");
950 fYHisto->GetXaxis()->SetTitleOffset(1.25);
951 fYHisto->GetXaxis()->SetTitleSize(1.25 * fYHisto->GetXaxis()->GetTitleSize());
952 fYHisto->GetXaxis()->SetLabelSize(1.25 * fYHisto->GetXaxis()->GetLabelSize());
954 fPad->cd(gridElement);
1025 if (autoBoundaries) SetBoundaries();
1028 if (optList.size() == 0) {
1029 optList.push_back(
"graphXZ");
1030 optList.push_back(
"graphYZ");
1031 optList.push_back(
"histXZ(Cont0,colz)");
1032 optList.push_back(
"histYZ(Cont0,colz)");
1035 for (
unsigned int n = 0; n < optList.size(); n++) {
1036 if (optList[n] ==
"print") this->
PrintEvent();
1039 optList.erase(remove(optList.begin(), optList.end(),
"print"), optList.end());
1041 unsigned int nPlots = optList.size();
1045 for (
unsigned int n = 0; n < nPlots; n++) {
1048 string optionStr = (string)optList[n];
1052 TString drawEventType = optList[n];
1053 size_t startPos = optionStr.find(
"(");
1054 if (startPos == string::npos) startPos = optionStr.find(
"[");
1056 if (startPos != string::npos) drawEventType = optList[n](0, startPos);
1061 string drawOption =
"";
1062 size_t endPos = optionStr.find(
")");
1063 if (endPos != string::npos) {
1064 TString drawOptionTmp = optList[n](startPos + 1, endPos - startPos - 1);
1066 drawOption = (string)drawOptionTmp;
1068 while ((pos = drawOption.find(
",", pos)) != string::npos) {
1069 drawOption.replace(pos, 1,
":");
1077 vector<TString> optList_2;
1079 startPos = optionStr.find(
"[");
1080 endPos = optionStr.find(
"]");
1082 if (endPos != string::npos) {
1083 TString tmpStr = optList[n](startPos + 1, endPos - startPos - 1);
1084 optList_2 = Vector_cast<string, TString>(
Split((
string)tmpStr,
","));
1088 if (drawEventType ==
"graphXZ") {
1089 GetXZMultiGraph(n + 1, optList_2)->Draw(
"P");
1093 if (fXZPcsMarker.size() > 0) fLegend_XZ->Draw(
"same");
1095 for (
unsigned int m = 0; m < fXZPcsMarker.size(); m++) fXZPcsMarker[m]->Draw(
"P");
1096 }
else if (drawEventType ==
"graphYZ") {
1097 GetYZMultiGraph(n + 1, optList_2)->Draw(
"P");
1099 if (fYZPcsMarker.size() > 0) fLegend_YZ->Draw(
"same");
1101 for (
unsigned int m = 0; m < fYZPcsMarker.size(); m++) fYZPcsMarker[m]->Draw(
"P");
1102 }
else if (drawEventType ==
"graphXY") {
1103 GetXYMultiGraph(n + 1, optList_2)->Draw(
"P");
1105 if (fXYPcsMarker.size() > 0) fLegend_XY->Draw(
"same");
1107 for (
unsigned int m = 0; m < fXYPcsMarker.size(); m++) fXYPcsMarker[m]->Draw(
"P");
1108 }
else if (drawEventType ==
"histXY") {
1109 GetXYHistogram(n + 1, optList_2)->Draw((TString)drawOption);
1110 }
else if (drawEventType ==
"histXZ") {
1111 GetXZHistogram(n + 1, optList_2)->Draw((TString)drawOption);
1112 }
else if (drawEventType ==
"histYZ") {
1113 GetYZHistogram(n + 1, optList_2)->Draw((TString)drawOption);
1114 }
else if (drawEventType ==
"histX") {
1115 GetXHistogram(n + 1, optList_2)->Draw((TString)drawOption);
1116 }
else if (drawEventType ==
"histY") {
1117 GetYHistogram(n + 1, optList_2)->Draw((TString)drawOption);
1118 }
else if (drawEventType ==
"histZ") {
1119 GetZHistogram(n + 1, optList_2)->Draw((TString)drawOption);
1126 cout <<
"Number of active volumes : " << GetNumberOfActiveVolumes() << endl;
1127 for (
unsigned int i = 0; i < fVolumeStoredNames.size(); i++) {
1128 if (isVolumeStored(i)) {
1129 cout <<
"Active volume " << i <<
":" << fVolumeStoredNames[i] <<
" has been stored." << endl;
1130 cout <<
"Total energy deposit in volume " << i <<
":" << fVolumeStoredNames[i] <<
" : "
1131 << fVolumeDepositedEnergy[i] <<
" keV" << endl;
1133 cout <<
"Active volume " << i <<
":" << fVolumeStoredNames[i] <<
" has not been stored" << endl;
1140 cout <<
"- Total deposited energy: " << ToEnergyString(fTotalDepositedEnergy) << endl;
1141 cout <<
"- Sensitive detectors total energy: " << ToEnergyString(fSensitiveVolumeEnergy) << endl;
1143 cout <<
"- Primary source position: " << VectorToString(fPrimaryPosition) <<
" mm" << endl;
1145 for (
unsigned int i = 0; i < GetNumberOfPrimaries(); i++) {
1146 const char* sourceNumberString =
1147 GetNumberOfPrimaries() <= 1 ?
""
1148 : TString::Format(
" %d of %zu", i + 1, GetNumberOfPrimaries()).Data();
1149 cout <<
" - Source" << sourceNumberString <<
" primary particle: " << fPrimaryParticleNames[i]
1151 cout <<
" Direction: " << VectorToString(fPrimaryDirections[i]) << endl;
1152 cout <<
" Energy: " << ToEnergyString(fPrimaryEnergies[i]) << endl;
1156 cout <<
"Total number of tracks: " << GetNumberOfTracks() << endl;
1158 int nTracks = GetNumberOfTracks();
1159 if (maxTracks > 0 && (
unsigned int)maxTracks < GetNumberOfTracks()) {
1160 nTracks = min(maxTracks,
int(GetNumberOfTracks()));
1161 cout <<
"Printing only the first " << nTracks <<
" tracks" << endl;
1164 for (
int i = 0; i < nTracks; i++) {
1169void TRestGeant4Event::PrintEventFilterVolumes(
const std::set<std::string>& volumeNames)
const {
1172 cout <<
"- Total deposited energy: " << ToEnergyString(fTotalDepositedEnergy) << endl;
1173 cout <<
"- Sensitive detectors total energy: " << ToEnergyString(fSensitiveVolumeEnergy) << endl;
1175 cout <<
"- Primary source position: " << VectorToString(fPrimaryPosition) <<
" mm" << endl;
1177 for (
unsigned int i = 0; i < GetNumberOfPrimaries(); i++) {
1178 const char* sourceNumberString =
1179 GetNumberOfPrimaries() <= 1 ?
""
1180 : TString::Format(
" %d of %zu", i + 1, GetNumberOfPrimaries()).Data();
1181 cout <<
" - Source" << sourceNumberString <<
" primary particle: " << fPrimaryParticleNames[i]
1183 cout <<
" Direction: " << VectorToString(fPrimaryDirections[i]) << endl;
1184 cout <<
" Energy: " << ToEnergyString(fPrimaryEnergies[i]) << endl;
1188 cout <<
"Total number of tracks: " << GetNumberOfTracks() << endl;
1190 int nTracks = GetNumberOfTracks();
1191 for (
int i = 0; i < nTracks; i++) {
1192 GetTrack(i).PrintTrackFilterVolumes(volumeNames);
1196Bool_t TRestGeant4Event::ContainsProcessInVolume(Int_t processID, Int_t volumeID)
const {
1197 for (
const auto& track : fTracks) {
1198 if (track.ContainsProcessInVolume(processID, volumeID)) {
1205Bool_t TRestGeant4Event::ContainsProcessInVolume(
const TString& processName, Int_t volumeID)
const {
1207 if (metadata ==
nullptr) {
1211 for (
const auto& track : fTracks) {
1212 if (track.ContainsProcessInVolume(processID, volumeID)) {
1219Bool_t TRestGeant4Event::ContainsParticle(
const TString& particleName)
const {
1220 for (
const auto& track : fTracks) {
1221 if (track.GetParticleName() == particleName) {
1228Bool_t TRestGeant4Event::ContainsParticleInVolume(
const TString& particleName, Int_t volumeID)
const {
1229 for (
const auto& track : fTracks) {
1230 if (track.GetParticleName() != particleName) {
1233 if (track.GetHits().GetNumberOfHitsInVolume(volumeID) > 0) {
1241 if (fRun ==
nullptr) {
1242 RESTError <<
"TRestGeant4Event::GetGeant4Metadata: fRun is nullptr" << RESTendl;
1254 for (
auto& track : fTracks) {
1255 track.SetEvent(
this);
1256 track.fHits.SetTrack(&track);
1257 track.fHits.SetEvent(
this);
1261set<string> TRestGeant4Event::GetUniqueParticles()
const {
1263 for (
const auto& track : fTracks) {
1264 result.insert(track.GetParticleName().Data());
1269map<string, map<string, double>> TRestGeant4Event::GetEnergyInVolumePerProcessMap()
const {
1270 map<string, map<string, double>> result;
1271 for (
const auto& [volume, particleProcessMap] : fEnergyInVolumePerParticlePerProcess) {
1272 for (
const auto& [particle, processMap] : particleProcessMap) {
1273 for (
const auto& [process, energy] : processMap) {
1274 result[volume][process] += energy;
1281map<string, map<string, double>> TRestGeant4Event::GetEnergyInVolumePerParticleMap()
const {
1282 map<string, map<string, double>> result;
1283 for (
const auto& [volume, particleProcessMap] : fEnergyInVolumePerParticlePerProcess) {
1284 for (
const auto& [particle, processMap] : particleProcessMap) {
1285 for (
const auto& [process, energy] : processMap) {
1286 result[volume][particle] += energy;
1293map<string, double> TRestGeant4Event::GetEnergyPerProcessMap()
const {
1294 map<string, double> result;
1295 for (
const auto& [volume, particleProcessMap] : fEnergyInVolumePerParticlePerProcess) {
1296 for (
const auto& [particle, processMap] : particleProcessMap) {
1297 for (
const auto& [process, energy] : processMap) {
1298 result[process] += energy;
1305map<string, double> TRestGeant4Event::GetEnergyPerParticleMap()
const {
1306 map<string, double> result;
1307 for (
const auto& [volume, particleProcessMap] : fEnergyInVolumePerParticlePerProcess) {
1308 for (
const auto& [particle, processMap] : particleProcessMap) {
1309 for (
const auto& [process, energy] : processMap) {
1310 result[particle] += energy;
1317map<string, double> TRestGeant4Event::GetEnergyInVolumeMap()
const {
1318 map<string, double> result;
1319 for (
const auto& [volume, particleProcessMap] : fEnergyInVolumePerParticlePerProcess) {
1320 for (
const auto& [particle, processMap] : particleProcessMap) {
1321 for (
const auto& [process, energy] : processMap) {
1322 result[volume] += energy;
1329map<string, map<string, map<string, double>>> TRestGeant4Event::GetEnergyInVolumePerParticlePerProcessMap()
1331 return fEnergyInVolumePerParticlePerProcess;
1334void TRestGeant4Event::AddEnergyInVolumeForParticleForProcess(Double_t energy,
const string& volumeName,
1335 const string& particleName,
1336 const string& processName) {
1340 fEnergyInVolumePerParticlePerProcess[volumeName][particleName][processName] += energy;
1341 fTotalDepositedEnergy += energy;
1344std::pair<double, double> TRestGeant4Event::GetTimeRangeOfIonizationInVolume(
const string& volumeName)
const {
1345 std::pair<double, double> result = {std::numeric_limits<double>::max(),
1346 std::numeric_limits<double>::min()};
1348 for (
const auto& track : fTracks) {
1349 const auto& hits = track.GetHits();
1350 for (
int i = 0; i < int(hits.GetNumberOfHits()); i++) {
1351 if (hits.GetVolumeName(i) == volumeName && hits.GetEnergy(i) > 0) {
1352 const double time = hits.GetTime(i);
1353 result.first = std::min(result.first, time);
1354 result.second = std::max(result.second, time);
virtual void InitializeReferences(TRestRun *run)
Initialize dynamical references when loading the event from a root file.
virtual void PrintEvent() const
virtual void Initialize()=0
An event class to store geant4 generated event information.
TVector3 GetFirstPositionInVolume(Int_t volID) const
Function to get the position (TVector3) of the first track that deposits energy in specified volume....
void InitializeReferences(TRestRun *run) override
Initialize dynamical references when loading the event from a root file.
TPad * DrawEvent(const TString &option="") override
Draw the event.
size_t GetNumberOfHits(Int_t volID=-1) const
Function that returns the total number of hits in the Geant4 event. If a specific volume is given as ...
size_t GetNumberOfPhysicalHits(Int_t volID=-1) const
Function that returns the total number of hits with energy > 0 in the Geant4 event....
Double_t GetBoundingBoxSize()
This method returns the event size as the size of the bounding box enclosing all hits.
TVector3 GetPositionDeviationInVolume(Int_t volID) const
A method that gets the standard deviation from the hits happening at a particular volumeId inside the...
void Initialize() override
void PrintActiveVolumes() const
maxTracks : number of tracks to print, 0 = all
TVector3 GetLastPositionInVolume(Int_t volID) const
Function to get the position (TVector3) of the last track that deposits energy in specified volume....
TRestHits GetHits(Int_t volID=-1) const
Function that returns all the hit depositions in the Geant4 event. If a specific volume is given as a...
void PrintTrack(size_t maxHits=0) const
Prints the track information. N number of hits to print, 0 = all.
size_t GetNumberOfHits(Int_t volID=-1) const
Function that returns the number of hit depositions found inside the TRestGeant4Track....
It saves a 3-coordinate position and an energy for each punctual deposition.
void AddHit(const TVector3 &position, Double_t energy, Double_t time=0, REST_HitType type=XYZ)
Adds a new hit to the list of hits using a TVector3.
TVector3 GetPosition(int n) const
It returns the position of hit number n.
Data provider and manager in REST.
std::vector< std::string > Split(std::string in, std::string separator, bool allowBlankString=false, bool removeWhiteSpaces=false, int startPos=-1)
Split the input string according to the given separator. Returning a vector of fragments.