@@ -743,7 +743,7 @@ int MCReplayEngine::getMediumId(int volId) const
743743Bool_t MCReplayEngine::SetProcess (const char * flagName, Int_t flagValue)
744744{
745745 if (mUpdateProcessesCutsBlocked ) {
746- ::Info (" MCReplayEngine::Gstpar " , " Parameter setting closed, nothing is changed." );
746+ ::Info (" MCReplayEngine::SetProcess " , " Parameter setting closed, nothing is changed." );
747747 return false ;
748748 }
749749 return insertProcessOrCut (mProcessesGlobal , physics::namesCuts, flagName, flagValue);
@@ -752,10 +752,18 @@ Bool_t MCReplayEngine::SetProcess(const char* flagName, Int_t flagValue)
752752Bool_t MCReplayEngine::SetCut (const char * cutName, Double_t cutValue)
753753{
754754 if (mUpdateProcessesCutsBlocked ) {
755- ::Info (" MCReplayEngine::Gstpar " , " Parameter setting closed, nothing is changed." );
755+ ::Info (" MCReplayEngine::SetCut " , " Parameter setting closed, nothing is changed." );
756756 return false ;
757757 }
758- return insertProcessOrCut (mCutsGlobal , physics::namesCuts, cutName, cutValue);
758+ auto setGlobal = insertProcessOrCut (mCutsGlobal , physics::namesCuts, cutName, cutValue);
759+ return setGlobal;
760+ for (auto & mediumCuts : mCuts ) {
761+ if (!mediumCuts) {
762+ continue ;
763+ }
764+ insertProcessOrCut (*mediumCuts, physics::namesCuts, cutName, cutValue);
765+ }
766+ return setGlobal;
759767}
760768
761769Int_t MCReplayEngine::CurrentVolID (Int_t& copyNo) const
@@ -893,14 +901,15 @@ void MCReplayEngine::Gstpar(Int_t itmed, const char* param, Double_t parval)
893901 ::Info (" MCReplayEngine::Gstpar" , " Parameter setting closed, nothing is changed." );
894902 return ;
895903 }
896- if (insertProcessOrCut (mProcesses , physics::namesProcesses, mProcessesGlobal , itmed, param, (int )parval)) {
904+ if (insertProcessOrCut (mProcesses , physics::namesProcesses, mProcessesGlobal , itmed, param, (int )parval, true )) {
897905 return ;
898906 }
899- if (!insertProcessOrCut (mCuts , physics::namesCuts, mCutsGlobal , itmed, param, parval)) {
907+ if (!insertProcessOrCut (mCuts , physics::namesCuts, mCutsGlobal , itmed, param, parval, true )) {
900908 ::Warning (" MCReplayEngine::Gstpar" , " Could not set parameter %s, unknown and therefore skipped" , param);
901909 }
902910}
903911
912+
904913void MCReplayEngine::loadCurrentCutsAndProcesses (int volId)
905914{
906915 mCurrentProcesses = &mProcessesGlobal ;
@@ -985,36 +994,97 @@ bool MCReplayEngine::initRun()
985994
986995void MCReplayEngine::transportUserHitSecondary ()
987996{
988- // For now we just start and finish this secondary. This is only done to pretend the transport for the user stack
997+ // secondaries that are somehow produced by the framework (e.g. during hit creation) cannot be taken into accoun.
998+ // Since we rely on pre-recorded steps, we can only pretend to account for them.
989999 fApplication ->PreTrack ();
9901000 fApplication ->PostTrack ();
9911001}
9921002
1003+ bool MCReplayEngine::startTrack (const o2::StepInfo& step)
1004+ {
1005+ mStack ->SetCurrentTrack (mUserTrackId [step.trackID ]);
1006+ mCurrentTrackLength = 0 .;
1007+
1008+ if (isPrimary (step.trackID )) {
1009+ mCurrentPrimaryId = step.trackID ;
1010+ fApplication ->BeginPrimary ();
1011+ }
1012+ mCurrentTrackId = step.trackID ;
1013+ fApplication ->PreTrack ();
1014+ gRandom ->SetSeed (makeHash (step));
1015+
1016+ if (!keepStep (step)) {
1017+ mSkipTrack [step.trackID ] = step.t ;
1018+ return false ;
1019+ }
1020+ return true ;
1021+ }
1022+
1023+ void MCReplayEngine::finishTrack (const o2::StepInfo& nextStep)
1024+ {
1025+ if (mCurrentTrackId > -1 ) {
1026+ fApplication ->PostTrack ();
1027+ }
1028+ if (isPrimary (nextStep.trackID ) && mCurrentPrimaryId >= 0 ) {
1029+ fApplication ->FinishPrimary ();
1030+ }
1031+ }
1032+
1033+ void MCReplayEngine::finishTrack ()
1034+ {
1035+ if (mCurrentTrackId >= 0 ) {
1036+ fApplication ->PostTrack ();
1037+ mCurrentTrackId = -1 ;
1038+ }
1039+ if (mCurrentPrimaryId > -1 ) {
1040+ fApplication ->FinishPrimary ();
1041+ mCurrentPrimaryId = -1 ;
1042+ }
1043+ }
1044+
1045+ bool MCReplayEngine::stepping ()
1046+ {
1047+ fApplication ->Stepping ();
1048+ // now let's see if the track was stopped for some reason
1049+ if (mIsTrackStopped ) {
1050+ // reset the flag for the next track to come
1051+ mIsTrackStopped = false ;
1052+ if (mAllowStopTrack ) {
1053+ mSkipTrack [mCurrentStep ->trackID ] = mCurrentStep ->t ;
1054+ return false ;
1055+ }
1056+ }
1057+ return true ;
1058+ }
1059+
9931060void MCReplayEngine::ProcessEvent (Int_t eventId)
9941061{
995- // prepare
996- std::vector<o2::StepInfo>* steps = nullptr ;
1062+ // at this point, we do not allow any process or cut settings anymore from the outside
1063+ blockSetProcessesCuts ();
1064+ std::vector<o2::StepInfo>* steps{};
9971065 mCurrentLookups = nullptr ;
9981066 mStepBranch ->SetAddress (&steps);
9991067 mLookupBranch ->SetAddress (&mCurrentLookups );
10001068 mStepBranch ->GetEvent (eventId);
10011069 mLookupBranch ->GetEvent (eventId);
10021070
10031071 // whether or not to skip certain tracks
1004- mSkipTrack .resize (mCurrentLookups ->tracktopdg .size (), false );
1072+ mSkipTrack .resize (mCurrentLookups ->tracktopdg .size (), - 1 . );
10051073 // 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.
10061074 mUserTrackId .resize (mCurrentLookups ->tracktopdg .size (), -1 );
1007- // some caching to be able to run pre- and post-hooks at the right time
1008- int currentTrackId = -1 ;
1075+ std::cout << " Number of PDGs: " << mUserTrackId .size () << std::endl;
1076+ // cache track and primary IDs during stepping
1077+ mCurrentTrackId = -1 ;
1078+ mCurrentPrimaryId = -1 ;
10091079
1080+ // preparation done, start replay
10101081 fApplication ->BeginEvent ();
10111082 fApplication ->GeneratePrimaries ();
10121083
10131084 // Remember how many primaries are expected to be transported
10141085 auto expectedNPrimaries = mStack ->GetNprimary ();
10151086
1016- /* SOME REMARKS
1017-
1087+ /*
10181088 1. Steps are expected to be grouped together track-by-track (that comes from the MCStepLogger and will only work properly for the serial simulation run)
10191089 2. Therefore, if a step with a different track ID is reached, it is assumed that the previous track is finished
10201090 3. Since in the original reference run, some secondaries might have been pushed to the user stack but not transported, we comply with the track ID assignement of the user stack in a replay run
@@ -1029,59 +1099,44 @@ void MCReplayEngine::ProcessEvent(Int_t eventId)
10291099 TStopwatch stopwatch{};
10301100
10311101 for (auto & step : *steps) {
1032-
1033- // TODO This should not happen. (see comment in header file for these flags)
10341102 if (mIsEventStopped ) {
10351103 mIsEventStopped = false ;
10361104 ::Warning (" MCReplayEngine::ProcessEvent" , " Event %d was stopped. That should usually not happen" , mCurrentEvent );
10371105 break ;
10381106 }
10391107
1040- mSkipTrack [step.trackID ] = !step.newtrack && mSkipTrack [step.trackID ];
1108+ mSkipTrack [step.trackID ] = !step.newtrack && mSkipTrack [step.trackID ] >= 0 . ? mSkipTrack [step. trackID ] : - 1 . ;
10411109
10421110 // skip if flagged and increment
1043- if (mSkipTrack [step.trackID ]) {
1111+ if (mSkipTrack [step.trackID ] >= 0 . ) {
10441112 continue ;
10451113 }
1046- if (mCurrentLookups ->tracktoparent [step.trackID ] > -1 && mSkipTrack [mCurrentLookups ->tracktoparent [step.trackID ]]) {
1047- // skip recursively in case parent was skipped, only affects secondaries of course
1048- mSkipTrack [step.trackID ] = true ;
1049- continue ;
1114+ if (mCurrentLookups ->tracktoparent [step.trackID ] > -1 ) {
1115+ auto parentTime = mSkipTrack [mCurrentLookups ->tracktoparent [step.trackID ]];
1116+ if (parentTime >= 0 && parentTime <= step.t ) {
1117+ // skip recursively in case parent was skipped, only affects secondaries of course
1118+ mSkipTrack [step.trackID ] = step.t ;
1119+ continue ;
1120+ }
10501121 }
1051-
10521122 if (step.entered || step.newtrack ) {
10531123 // find the correct set of cuts and processes for this volume
10541124 loadCurrentCutsAndProcesses (step.volId );
10551125 mGeoManager ->cd (step.geopath ->c_str ());
10561126 }
10571127
10581128 // NOW PERFORM EVERYTHIN NECESSARY TO START / FINISH A TRACK
1129+ if (mCurrentTrackId != step.trackID ) {
10591130
1060- if (currentTrackId == step.trackID && mIsTrackStopped ) {
1061- // track can be told to be stopped in replay run due to different states of RNGs of reference and replay run, will be ignored
1062- nStopTrack++;
1063- mIsTrackStopped = false ;
1064- }
1065-
1066- if (currentTrackId != step.trackID ) {
1067- // Found a new track
1068-
1069- auto prim = isPrimary (step.trackID );
1131+ // Finish potential last track
1132+ finishTrack (step);
10701133
1071- if (currentTrackId > -1 ) {
1072- // only invoke if there has been at least 1 track before
1073- fApplication ->PostTrack ();
1074- if (prim) {
1075- // finish previous primary only in case all its secondary tracks have been transported and a new primary is about to be transported
1076- fApplication ->FinishPrimary ();
1077- }
1078- }
1079-
1080- if (!prim) {
1134+ if (!isPrimary (step.trackID )) {
10811135 // decide to skip this secondary immediately, primaries must be popped first since otherwise we might run into inconsitencies with the user stack
10821136 // therefore, it looks as if this secondary never appeared
10831137 if (!keepStep (step)) {
1084- mSkipTrack [step.trackID ] = true ;
1138+ mSkipTrack [step.trackID ] = step.t ;
1139+ mCurrentTrackId = -1 ;
10851140 continue ;
10861141 }
10871142
@@ -1105,35 +1160,22 @@ void MCReplayEngine::ProcessEvent(Int_t eventId)
11051160 mUserTrackId [step.trackID ] = popTrackId;
11061161 }
11071162
1108- currentTrackId = step.trackID ;
1109- mStack ->SetCurrentTrack (mUserTrackId [step.trackID ]);
1110- mCurrentTrackLength = 0 .;
1111-
1112- if (prim) {
1113- fApplication ->BeginPrimary ();
1114- }
1115- fApplication ->PreTrack ();
1116-
1117- if (!keepStep (step)) {
1118- // This is for primaries since secondaries would have been skipped already above
1119- mSkipTrack [step.trackID ] = true ;
1163+ if (!startTrack (step)) {
11201164 continue ;
11211165 }
1122-
1123- // We fix the RNG so in case the hits are somehow based on that, the hits among different Replay runs are exactly reproduced
1124- gRandom ->SetSeed (makeHash (step));
11251166 }
11261167
11271168 mCurrentTrackLength += step.step ;
11281169 mCurrentStep = &step;
11291170
1171+ if (!stepping ()) {
1172+ continue ;
1173+ }
11301174 nStepsKept++;
1131- fApplication ->Stepping ();
11321175 }
11331176
11341177 // Finish last track and the entire event
1135- fApplication ->PostTrack ();
1136- fApplication ->FinishPrimary ();
1178+ finishTrack ();
11371179
11381180 fApplication ->FinishEvent ();
11391181
@@ -1142,7 +1184,9 @@ void MCReplayEngine::ProcessEvent(Int_t eventId)
11421184 auto nStepsSkipped = steps->size () - nStepsKept;
11431185 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 >(nStepsKept) / steps->size () << " \n " ;
11441186 std::cout << " In addition, " << nUserTracks << " tracks produced during hit creation were ignored\n " ;
1145- std::cout << " TVirtualMC::StopTrack was ignored " << nStopTrack << " times\n " ;
1187+ if (!mAllowStopTrack ) {
1188+ std::cout << " TVirtualMC::StopTrack was ignored " << nStopTrack << " times\n " ;
1189+ }
11461190 std::cout << " Real time: " << stopwatch.RealTime () << " , CPU time: " << stopwatch.CpuTime () << " \n " ;
11471191
11481192 delete steps;
0 commit comments