Skip to content

Commit 5a7a825

Browse files
Benedikt Volkelbenedikt-voelkel
authored andcommitted
Small fixes and updates
* ignore TVirtualMC::StopTrack() due to different RNG (settings) during the reference and replay run, tracks might be stopped during hit production making the replay slightly inconsistent (this is analugous to swallowing all secondaries produced during hit production which is done as well) * print number of skipped and kept steps at the end of a replay * change energy cut to an energy PRODUCTION cut. The previous implementation - killing a track at a certain point of its lifetime - was inconsistent as in that case ALL secondaries were killed (also those produced BEFORE the track was killed) * the previous point needs a revision since it is desirable to consistently remove tracks at any point during their lifetime.
1 parent 9a6ccfd commit 5a7a825

File tree

1 file changed

+41
-20
lines changed

1 file changed

+41
-20
lines changed

MCReplay/src/MCReplayEngine.cxx

Lines changed: 41 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -908,13 +908,13 @@ void MCReplayEngine::ProcessEvent(Int_t eventId)
908908

909909
// whether or not to skip certain tracks
910910
std::vector<bool> skipTrack(mCurrentLookups->tracktopdg.size(), false);
911+
// we need to make sure we follow the indexing of the user stack. During the original simulation, there might have been more tracks pushed than transported. In the replay case, we only have the tracks that have been originally transported. Hence, the indexing this time might be different.
912+
std::vector<int> userTrackId(mCurrentLookups->tracktopdg.size(), -1);
911913
// some caching to be able to run pre- and post-hooks at the right time
912914
int currentTrackId = -1;
913915
// some caching to be able to update the TGeoManager state
914916
int previousVolId = -1;
915917
int previousCopyNo = -1;
916-
// we need to make sure we follow the indexing of the user stack. During the original simulation, there might have been more tracks pushed than transported. In the replay case, we only have the tracks that have been originally transported. Hence, the indexing this time might be different.
917-
std::vector<int> userTrackId(mCurrentLookups->tracktopdg.size(), -1);
918918

919919
fApplication->BeginEvent();
920920
fApplication->GeneratePrimaries();
@@ -939,18 +939,25 @@ void MCReplayEngine::ProcessEvent(Int_t eventId)
939939
2. hits are exactly reproduced for each replay run
940940
*/
941941

942+
unsigned int nStepsKept{0};
943+
942944
for (const auto& step : *steps) {
943945

944946
// TODO This should not happen. (see comment in header file for these flags)
945947
if (mIsEventStopped) {
946948
mIsEventStopped = false;
949+
::Warning("MCReplayEngine::ProcessEvent", "Event %d was stopped. That should usually not happen", mCurrentEvent);
950+
delete steps;
951+
delete mCurrentLookups;
947952
return;
948953
}
949954

950-
// check whether track itself or parent was flagged.
951-
// Flag this track to be skipped in case the parent has been flagged.
952-
// NOTE We are not checking mIsTrackStopped, that is done after each step separately
953-
if (skipTrack[step.trackID] || (mCurrentLookups->tracktoparent[step.trackID] > -1 && skipTrack[mCurrentLookups->tracktoparent[step.trackID]])) {
955+
// skip if flagged and increment
956+
if (skipTrack[step.trackID]) {
957+
continue;
958+
}
959+
if (mCurrentLookups->tracktoparent[step.trackID] > -1 && skipTrack[mCurrentLookups->tracktoparent[step.trackID]]) {
960+
// skip recursively in case parent was skipped, only affects secondaries of course
954961
skipTrack[step.trackID] = true;
955962
continue;
956963
}
@@ -968,17 +975,20 @@ void MCReplayEngine::ProcessEvent(Int_t eventId)
968975
mGeoManager->FindNode(step.x, step.y, step.z);
969976
}
970977

971-
if (!keepStep(step)) {
972-
// We can only do it now after the current volume and hence medium have been found including the loading of current cuts and processes
973-
skipTrack[step.trackID] = true;
974-
continue;
975-
}
976-
977978
// NOW PERFORM EVERYTHIN NECESSARY TO START / FINISH A TRACK
978979

980+
if (currentTrackId == step.trackID && mIsTrackStopped) {
981+
// as the warning says, it should not happen but could (e.g. due to double vs. float precision)
982+
// but mainly due to the fact that the RNG (TRandom) in the reference run and in this replay do not have the same seeding
983+
::Warning("MCReplayEngine::ProcessEvent", "Track %d was stopped (PDG %d). That should usually not happen", userTrackId[step.trackID], mCurrentLookups->tracktopdg[step.trackID]);
984+
mIsTrackStopped = false;
985+
}
986+
979987
if (currentTrackId != step.trackID) {
980988
// Found a new track
989+
981990
auto prim = isPrimary(step.trackID);
991+
982992
if (currentTrackId > -1) {
983993
// only invoke if there has been at least 1 track before
984994
fApplication->PostTrack();
@@ -989,7 +999,14 @@ void MCReplayEngine::ProcessEvent(Int_t eventId)
989999
}
9901000

9911001
if (!prim) {
992-
// only push track is a secondary
1002+
// decide to skip this secondary immediately, primaries must be popped first since otherwise we might run into inconsitencies with the user stack
1003+
// therefore, it looks as if this secondary never appeared
1004+
if (!keepStep(step)) {
1005+
skipTrack[step.trackID] = true;
1006+
continue;
1007+
}
1008+
1009+
// only push track if it is a secondary
9931010
// by default just assign the MCStepLogger track ID, but the user stack might then decide to do something else
9941011
userTrackId[step.trackID] = step.trackID;
9951012
mStack->PushTrack(1, userTrackId[mCurrentLookups->tracktoparent[step.trackID]], mCurrentLookups->tracktopdg[step.trackID], step.px, step.py, step.pz, step.E, step.x, step.y, step.z, step.t, 1., 1., 1., TMCProcess(step.prodprocess), userTrackId[step.trackID], 1., 0);
@@ -1016,21 +1033,22 @@ void MCReplayEngine::ProcessEvent(Int_t eventId)
10161033
fApplication->BeginPrimary();
10171034
}
10181035
fApplication->PreTrack();
1036+
1037+
if (!keepStep(step)) {
1038+
// This is for primaries since secondaries would have been skipped already above
1039+
skipTrack[step.trackID] = true;
1040+
continue;
1041+
}
1042+
10191043
// We fix the RNG so in case the hits are somehow based on that, the hits among different Replay runs are exactly reproduced
10201044
gRandom->SetSeed(makeHash(step));
10211045
}
10221046

10231047
mCurrentTrackLength += step.step;
10241048
mCurrentStep = const_cast<o2::StepInfo*>(&step);
10251049

1050+
nStepsKept++;
10261051
fApplication->Stepping();
1027-
1028-
if (mIsTrackStopped) {
1029-
::Warning("MCReplayEngine::ProcessEvent", "Track %d was stopped. That should usually not happen", userTrackId[step.trackID]);
1030-
skipTrack[step.trackID] = true;
1031-
mIsTrackStopped = false;
1032-
continue;
1033-
}
10341052
}
10351053

10361054
// Finish last track and the entire event
@@ -1039,6 +1057,9 @@ void MCReplayEngine::ProcessEvent(Int_t eventId)
10391057

10401058
fApplication->FinishEvent();
10411059

1060+
auto nStepsSkipped = steps->size() - nStepsKept;
1061+
std::cout << "Original number, skipped, kept, skipped fraction and kept fraction of steps: " << steps->size() << " " << nStepsSkipped << " " << nStepsKept << " " << static_cast<float>(nStepsSkipped) / steps->size() << " " << static_cast<float>(nStepsSkipped) / steps->size() << "\n";
1062+
10421063
delete steps;
10431064
delete mCurrentLookups;
10441065

0 commit comments

Comments
 (0)