Dear experts on RDataFrame,
I have a question concerning using Random number generators inside lambda functions for column-definition.
My workflow is the following :
TRandom3 rnd; //random number generator to align 30% of events passing on MC the HLT1_TOS requirement (AllTrackL0Decision_TOS)
struct TrackHLT1Info{
double p;
double pt;
bool hlt1_tos;
TrackHLT1Info() = default;
TrackHLT1Info( double _p, double _pt, bool _hlt1_tos){
p = _p;
pt = _pt;
hlt1_tos = _hlt1_tos;
};
};
//Set of helper Lambda functions to eval Alignment of HLT1AllTrackL0Decision
auto makeTrackInfo = [](double p, double pt, bool isTOS){ return TrackHLT1Info( p, pt, isTOS); };
auto evalTOSUpdate = [&rnd]( const TrackHLT1Info & finalStateParticle , const uint & runNumber, const unsigned long long & evtNumber , const bool & Bp_Hlt1TrackAllL0Decision_TOS ){
if( Bp_Hlt1TrackAllL0Decision_TOS == false){ return false; } //If the global OR is already false, it keeps to be false ( we only tight up the cut, not loosen it)
if(finalStateParticle.hlt1_tos == false){ return false; } //If the particle TOS is already false, it keeps to be false ( we only tight up the cut, not loosen it)
//We reach this only if the particle is TOS
rnd.SetSeed( runNumber * evtNumber);
bool rndvalue = rnd.Uniform( 0,1); //throw random number between 0,1 uniformely ( the seet set is needed to have not random behaviour)
bool updatedStatus = finalStateParticle.hlt1_tos;
if ( rndvalue < 0.3){
//For 30% of events tight up the P, PT cut [ assuming IPCHI2 is already aligned ! [ there are other cuts done by the HLT1AllTrackL0 [ IP are the same for all TCKs ]]]
//Track Chi2 and number of hits cut is dropped for alignment since the info available in MC is "post-HLT2" reconstruction and NOT at HLT1 level
updatedStatus = finalStateParticle.p > 10000.f && finalStateParticle.pt > 1700 && finalStateParticle.hlt1_tos;
}
return updatedStatus;
};
auto dd = df.Define("E1_HLTTRACK_PT", "TMath::Sqrt(E1_TRACK_PX*E1_TRACK_PX + E1_TRACK_PY*E1_TRACK_PY)")
.Define("E2_HLTTRACK_PT", "TMath::Sqrt(E2_TRACK_PX*E2_TRACK_PX + E2_TRACK_PY*E2_TRACK_PY)")
.Define("E1_HLTTRACK_P", "TMath::Sqrt(E1_TRACK_PX*E1_TRACK_PX + E1_TRACK_PY*E1_TRACK_PY + E1_TRACK_PZ*E1_TRACK_PZ)")
.Define("E2_HLTTRACK_P", "TMath::Sqrt(E2_TRACK_PX*E2_TRACK_PX + E2_TRACK_PY*E2_TRACK_PY + E2_TRACK_PZ*E2_TRACK_PZ)")
.Define("E1_TrackHLT1Info", makeTrackInfo, {"E1_HLTTRACK_P", "E1_HLTTRACK_PT", "E1_Hlt1TrackAllL0Decision_TOS"})
.Define("E2_TrackHLT1Info", makeTrackInfo, {"E2_HLTTRACK_P", "E2_HLTTRACK_PT", "E2_Hlt1TrackAllL0Decision_TOS"})
.Define("K_TrackHLT1Info", makeTrackInfo, {"K_P", "K_PT", "K_Hlt1TrackAllL0Decision_TOS"})
.Define("E1_Hlt1TrackAllL0Decision_TOS_update", evalTOSUpdate , { "E1_TrackHLT1Info", "runNumber", "eventNumber","Bp_Hlt1TrackAllL0Decision_TOS"})
.Define("E2_Hlt1TrackAllL0Decision_TOS_update", evalTOSUpdate , { "E2_TrackHLT1Info", "runNumber", "eventNumber","Bp_Hlt1TrackAllL0Decision_TOS"})
.Define("K_Hlt1TrackAllL0Decision_TOS_update", evalTOSUpdate , { "K_TrackHLT1Info" , "runNumber", "eventNumber","Bp_Hlt1TrackAllL0Decision_TOS"})
.Define("Bp_Hlt1TrackAllL0Decision_TOS_update", "E1_Hlt1TrackAllL0Decision_TOS_update || E2_Hlt1TrackAllL0Decision_TOS_update || K_Hlt1TrackAllL0Decision_TOS_update");
dd.Snapshot(_newTreeName.Data(), _newTFileName.Data() , DropColumns(dd.GetColumnNames(),dd.GetDefinedColumnNames(), blacklist ) );
My question is the following : given the lambda defined capturing the [&rnd]
, can i assume that “event-by-event” the random number generated will be the same everywhere?
Also, would this code work also MT ? I have disabled implicit MT since i am not 100% that the external capture of the TRandom3 number would work if the lambda function and the Define are called with MT enabled.
Thanks in advance
Renato