20 #include "TObjArray.h"
22 #include "TTreeReader.h"
23 #include "TTreeReaderValue.h"
24 #include "TTreeReaderArray.h"
27 using namespace chrono;
31 vector<const char*> locVector;
33 TObjArray *arr = tree->GetListOfBranches();
35 for (
int i = 0; i < arr->GetEntries(); ++i)
37 TBranch *b = (TBranch*)arr->At(i);
38 const char* b_name = b->GetName();
41 if ( strstr( b_name,
"__ChargedIndex" ) != NULL ||
42 strstr( b_name,
"__NeutralIndex" ) != NULL )
44 locVector.push_back( b_name );
53 bool searchMap( map<string, Int_t> p_map,
string substring )
57 for (
auto const &p_iter : p_map )
59 if ( p_iter.first.find(substring) != string::npos )
66 bool compareMaps( map<string, Int_t> p_map, map<string, Int_t> s_map )
70 int totalParticles = 0;
71 int matchedParticles = 0;
74 if ( p_map.size() != s_map.size() )
78 for (
auto const &p_iter : p_map )
83 for (
auto const &s_iter : s_map )
86 if ( p_iter.second == s_iter.second )
91 isMatch = ( totalParticles == matchedParticles ) ?
true :
false;
97 void mergeTrees(
const char* primaryFile,
const char* primaryTree,
const char* secondaryFile,
const char* secondaryTree)
100 high_resolution_clock::time_point
t1 = high_resolution_clock::now();
102 TFile f_secondary(secondaryFile);
103 TTree *t_secondary = (TTree*)f_secondary.Get(secondaryTree);
105 TFile f_orig(primaryFile);
106 TTree *t_orig = (TTree*)f_orig.Get(primaryTree);
108 TFile f_primary(
"newtree.root",
"recreate");
109 TTree *t_primary = (TTree*)t_orig->CloneTree();
112 vector<const char*> branches_primary =
getBranches(t_primary);
113 vector<const char*> branches_secondary =
getBranches(t_secondary);
116 UInt_t initArraySize = 100;
117 Float_t new_chisq[initArraySize];
118 UInt_t new_ndf[initArraySize];
119 string p(primaryTree);
120 string primaryReactionName = p.substr(0, p.find(
"_"));
121 cout <<
"Primary reaction: " << primaryReactionName << endl;
122 string s(secondaryTree);
123 string secondaryReactionName = s.substr(0, s.find(
"_"));
124 cout <<
"Secondary reaction: " << secondaryReactionName << endl;
127 TTreeReader primaryReader(t_primary);
128 cout <<
"added primary tree" << endl;
129 TTreeReaderArray<Float_t> chisq(primaryReader,
"ChiSq_KinFit");
130 TTreeReaderArray<UInt_t> ndf(primaryReader,
"NDF_KinFit");
131 TTreeReaderValue<UInt_t>
run(primaryReader,
"RunNumber");
132 TTreeReaderValue<ULong64_t> event(primaryReader,
"EventNumber");
133 TTreeReaderArray<Int_t> ChargedHypoID(primaryReader,
"ChargedHypo__TrackID");
134 TTreeReaderArray<Int_t> ChargedHypo__PID(primaryReader,
"ChargedHypo__PID");
135 TTreeReaderArray<Int_t> NeutralHypoID(primaryReader,
"NeutralHypo__NeutralID");
136 TTreeReaderArray<Int_t> beam_ID(primaryReader,
"ComboBeam__BeamIndex");
138 TTreeReader secondaryReader(t_secondary);
139 cout <<
"added secondary tree" << endl;
140 TTreeReaderArray<Float_t> secondary_chisq(secondaryReader,
"ChiSq_KinFit");
141 TTreeReaderArray<UInt_t> secondary_ndf(secondaryReader,
"NDF_KinFit");
142 TTreeReaderValue<UInt_t> secondary_run(secondaryReader,
"RunNumber");
143 TTreeReaderValue<ULong64_t> secondary_event(secondaryReader,
"EventNumber");
144 TTreeReaderArray<Int_t> secondary_ChargedHypoID(secondaryReader,
"ChargedHypo__TrackID");
145 TTreeReaderArray<Int_t> secondary_ChargedHypo__PID(secondaryReader,
"ChargedHypo__PID");
146 TTreeReaderArray<Int_t> secondary_NeutralHypoID(primaryReader,
"NeutralHypo__NeutralID");
147 TTreeReaderArray<Int_t> secondary_beam_ID(secondaryReader,
"ComboBeam__BeamIndex");
151 map< const char*, TTreeReaderArray<Int_t> > primary_ReaderArray__Int;
152 map< const char*, TTreeReaderArray<Int_t> > secondary_ReaderArray__Int;
155 for (
auto const& p_iter : branches_primary )
157 TTreeReaderArray<Int_t> a(primaryReader, p_iter);
158 auto P = make_pair( p_iter, a );
159 primary_ReaderArray__Int.insert(P);
161 for (
auto const& s_iter : branches_secondary )
163 TTreeReaderArray<Int_t> a(secondaryReader, s_iter);
164 auto P = make_pair( s_iter, a );
165 secondary_ReaderArray__Int.insert(P);
167 cout <<
"Added to maps" << endl;
170 const int size_primary = (int)primary_ReaderArray__Int.size();
171 const int size_secondary = (int)secondary_ReaderArray__Int.size();
173 const char* keys_primary[ size_primary ];
174 const char* keys_secondary[ size_secondary ];
177 for (
auto const& p_iter : primary_ReaderArray__Int )
179 keys_primary[count] = p_iter.first;
183 for (
auto const& s_iter : secondary_ReaderArray__Int )
185 keys_secondary[count] = s_iter.first;
190 string branchName(
"ChiSq_KinFit_");
191 branchName += secondaryReactionName;
192 TBranch *new_b_chisq = t_primary->Branch(branchName.c_str(), &new_chisq, (branchName +
"[NumCombos]/F").c_str() );
193 branchName =
"NDF_KinFit_";
194 branchName += secondaryReactionName;
195 TBranch *new_b_ndf = t_primary->Branch(branchName.c_str(), &new_ndf, (branchName +
"[NumCombos]/i").c_str() );
198 map< ULong64_t, Long64_t > map_event_secondary;
199 while (secondaryReader.Next() )
201 ULong64_t thisEvent = *secondary_event;
202 Long64_t thisEntry = secondaryReader.GetCurrentEntry();
203 map_event_secondary.insert( pair< ULong64_t, Long64_t >(thisEvent, thisEntry ) );
207 while (primaryReader.Next() )
209 Long64_t pentry = primaryReader.GetCurrentEntry();
210 if ( pentry / 1000000 * 1000000 == pentry )
211 cout << pentry / 1000000 + 1 <<
" million events analyzed" << endl;
214 secondaryReader.Restart();
217 for (UInt_t i = 0; i < initArraySize; ++i)
223 UInt_t p_numCombos = primary_ReaderArray__Int.begin()->second.GetSize();
226 if (map_event_secondary.find( *event ) == map_event_secondary.end() )
234 Long64_t entry = map_event_secondary.at( *event );
235 secondaryReader.SetEntry( entry );
239 UInt_t s_numCombos = secondary_ReaderArray__Int.begin()->second.GetSize();
242 for (UInt_t i = 0; i < p_numCombos; ++i)
244 bool isMatched =
false;
247 map<string, Int_t> primary_trackIDs;
248 map<string, Int_t> primary_neutralIDs;
249 for (
int i_keys = 0; i_keys < size_primary; ++i_keys )
253 const char* b_name = keys_primary[ i_keys ];
255 if ( strstr( b_name,
"__ChargedIndex" ) != NULL )
257 track = ChargedHypoID[ primary_ReaderArray__Int.at( b_name )[i] ];
258 auto track_pair = make_pair( s, track );
259 primary_trackIDs.insert( track_pair );
261 else if ( strstr( b_name,
"__NeutralIndex" ) != NULL )
263 neutral = NeutralHypoID[ primary_ReaderArray__Int.at( b_name )[i] ];
264 auto neutral_pair = make_pair( s, neutral );
265 primary_neutralIDs.insert( neutral_pair );
269 Int_t beam = beam_ID[i];
272 for (UInt_t j = 0; j < s_numCombos; ++j)
274 map<string, Int_t> secondary_trackIDs;
275 map<string, Int_t> secondary_neutralIDs;
276 for (
int j_keys = 0; j_keys < size_secondary; ++j_keys )
280 const char* b_name = keys_secondary[ j_keys ];
282 if ( strstr( b_name,
"__ChargedIndex" ) != NULL )
284 track = secondary_ChargedHypoID[ secondary_ReaderArray__Int.at( b_name )[j] ];
285 auto track_pair = make_pair( s, track );
286 secondary_trackIDs.insert(track_pair);
288 else if ( strstr( b_name,
"__NeutralIndex" ) != NULL )
290 neutral = secondary_NeutralHypoID[ secondary_ReaderArray__Int.at( b_name )[j] ];
291 auto neutral_pair = make_pair( s, neutral );
292 secondary_neutralIDs.insert( neutral_pair );
296 Int_t secondary_beam = secondary_beam_ID[j];
299 bool hasPlus =
searchMap( primary_trackIDs,
"Plus" );
300 bool hasMinus =
searchMap( primary_trackIDs,
"Minus" );
301 bool hasProton =
searchMap( primary_trackIDs,
"Proton" );
302 bool hasPhoton =
searchMap( primary_neutralIDs,
"Photon" );
306 bool chargedMatch = (hasPlus || hasMinus || hasProton) ?
compareMaps( primary_trackIDs, secondary_trackIDs ) :
true;
307 bool neutralMatch = hasPhoton ?
compareMaps( primary_neutralIDs, secondary_neutralIDs ) :
true;
310 if ( !(chargedMatch && neutralMatch) )
313 if (beam != secondary_beam)
317 new_chisq[i] = secondary_chisq[j];
318 new_ndf[i] = secondary_ndf[j];
327 t_primary->Write(
"", TObject::kOverwrite);
330 high_resolution_clock::time_point t2 = high_resolution_clock::now();
332 auto duration = duration_cast<microseconds>( t2 -
t1 ).count();
333 cout <<
"The process took: " << duration <<
" microseconds" << endl;
334 cout <<
"The process took: " << duration*1E-6 <<
" seconds" << endl;
335 cout <<
"The process took: " << duration*1E-6/60. <<
" minutes" << endl;
bool searchMap(map< string, Int_t > p_map, string substring)
bool compareMaps(map< string, Int_t > p_map, map< string, Int_t > s_map)
vector< const char * > getBranches(TTree *tree)
void mergeTrees(const char *primaryFile, const char *primaryTree, const char *secondaryFile, const char *secondaryTree)