Hi,
for our Analysis of data and Monte Carlo files we are trying to implement a way to to a particle identification (corresponding to different entries in the trees in the files) and saving the result into entry lists e.g. one for each particle type.
It is important for us to have in the end one list for each particle type and each file of the chain. It is likely that for the further parts of the analysis only a subset of files is chosen to be used, so the code would have to connect these files and load all lists from a file that are requested, so if we want electrons only the lists for those should be loaded and a global entrylist for the chain should be created.
The problem we are encountering for the following piece of code is that in the entry lists there are wrong numbers of particles. There should be 10000 entries for electron and pion each but it is 20000 each somehow. We were trying to build a global entry list for each particle first which should then be divided by TEntryList::GetLists(). For the Monte Carlo Files below we already know that all entries in a tree is a certain particle, so we just (try to…) add all of them to the entrylist:
[code]void CTB_AnalysisV3::CreateEntryLists() {
cout << “INFO: CreateEntryLists is creating your entry lists…” << endl;
TFile *EntryLists_file=new TFile(“EntryLists.root”,“recreate”);
if (!EntryLists_file) {
cerr << “ERROR: EntryLists.root not found!” << endl;
return;
}
TEntryList *EntryList_u=new TEntryList(“EntryList_u”,“EntryList_u”);
TEntryList *EntryList_p=new TEntryList(“EntryList_p”,“EntryList_p”);
TEntryList *EntryList_e=new TEntryList(“EntryList_e”,“EntryList_e”);
TEntryList *EntryList_m=new TEntryList(“EntryList_m”,“EntryList_m”);
char filename_old[200], filename_new[200];
int pid=0; // set initial PID to unknown
Long64_t N_events=fChain->GetEntries();
for (Long64_t Event=0; Event<N_events;Event++) {
fChain->SetBranchStatus("*",0);
fChain->GetEntry(Event);
TFile *file=fChain->GetFile();
sprintf(filename_new,"%s",file->GetName());
string filename_str=filename_new;
if (strcmp(filename_old,filename_new)!=0) { // check whether new file has been connected
cout << “New file connected: " << filename_new << endl;
sprintf(filename_old,”%s",filename_new);
string filename_str=filename_new;
string run_str;
if (filename_str.find(".mc.root")!=string::npos) { // do MC PID
string pid_str=filename_str.substr(filename_str.find("_10k")+4,1);
TFile *currFile=new TFile(filename_str.c_str());
TTree *tmpTree=(TTree*)currFile->Get("tree");
Long64_t currEntries=tmpTree->GetEntries();
cout << "…it’s a MC file with " << currEntries << " entries of type " << pid_str << endl;
for(Long64_t entries=0; entries<currEntries; ++entries) {
if (pid_str==“p”) EntryList_p->Enter(entries,fChain);
else if (pid_str==“e”) EntryList_e->Enter(entries,fChain);
else if (pid_str==“m”) EntryList_m->Enter(entries,fChain);
else EntryList_u->Enter(entries,fChain);
/* if (pid_str==“p”) EntryList_p->Enter(Event+entries);
else if (pid_str==“e”) EntryList_e->Enter(Event+entries);
else if (pid_str==“m”) EntryList_m->Enter(Event+entries);
else EntryList_u->Enter(Event+entries);*/
}
Event+=currEntries-1;
continue;
}
run_str=filename_str.substr(filename_str.find(“2102”)+3,4);
cout << "…it’s run number " << run_str << endl;
cout << “…it’s a data file… I’ll go on and do tedious NonTrtPid work ;-)” << endl;
}
// put pid cuts
switch (pid) {
case 1: EntryList_p->Enter(Event,fChain); break;
case 2: EntryList_e->Enter(Event,fChain); break;
case 3: EntryList_m->Enter(Event,fChain); break;
default: EntryList_u->Enter(Event,fChain);
}
}
EntryLists_file->cd();
fChain->SetBranchStatus("*",1);
TString particle_labels[4]={“u”,“p”,“e”,“m”};
for (int p=0;p<4;p++) {
TString EventListName;
EventListName=“EntryList_”+particle_labels[p];
cout << EventListName << endl;
TEntryList EntryList=(TEntryList)EntryLists_file->Get(EventListName);
// if (!EntryList) cout << “EntryList” << endl;
TList *LEntryList=EntryList->GetLists();
// if (!LEntryList) cout << “LEntryList” << endl;
TIter next(LEntryList);
Int_t count=0;
while (TObject *obj=next()) {
TEntryList SubEntryList=(TEntryList)obj;
TString title=(TString)SubEntryList->GetFileName();
string filename_str=title.Data();
// string filename_str=(string)title;
cout << filename_str << endl;
if (filename_str.find(".mc.root")!=string::npos) { // do MC PID
title=“EntryList-”+title(title.Length()-11,6)+"-"+particle_labels[p];
} else {
title=“EntryListMC-”+title(title.Length()-11,6)+"-"+particle_labels[p];
}
SubEntryList->SetName(title.Data());
SubEntryList->Write();
cout << SubEntryList->GetN() << endl;
++count;
}
}
EntryLists_file->cd();
EntryList_u->Write();
EntryList_p->Write();
EntryList_e->Write();
EntryList_m->Write();
// EntryLists_file->Write();
EntryLists_file->Close();
cout << “INFO: CreateEntryLists is done!” << endl;
}
[/code]
And this code is the one that is supposed to take each file in a chain (at the moment the same that was used to create the lists) and load the lists for each file and build the global one.
[code]void CTB_AnalysisV3::GetEntryList(int pid_loop) {
TString particle_labels[4]={“u”,“p”,“e”,“m”};
cout << “INFO: GetEntryList is reading your entry list for " << particle_labels[pid_loop] << " …” << endl;
TFile *EntryLists_file=new TFile(“EntryLists.root”,“read”);
if (!EntryLists_file) {
cout << “ERROR: EntryLists.root not found!” << endl;
return;
}
TEntryList *EntryList=new TEntryList();
TObjArray *ListOfFiles=fChain->GetListOfFiles();
TIter next(ListOfFiles);
Int_t count=0;
while (TObject *obj=next()) {
TString title;
title=(TString)obj->GetTitle();
title=“EntryList-”+title(title.Length()-11,6)+"-"+particle_labels[pid_loop];
TEntryList SubEntryList=(TEntryList)EntryLists_file->Get(title.Data());
if (SubEntryList) {
EntryList->Add(SubEntryList);
}
++count;
}
if (!EntryList) {
cout << “ERROR: EntryList for " << particle_labels[pid_loop] << " not found!” << endl;
return;
}
fChain->SetEntryList(EntryList);
EntryLists_file->Close();
cout << “INFO: GetEntryList is done!” << endl;
}
[/code]
currently the latter code is not yet called because the creation of the lists already has an error (as discribed above).
Is there any obvious mistake in CreateEntryLists() or is the way of using the lists not correct? We are not sure about the way of converting global to local lists and the other way around. The Reference Guide seems to be not so detailed in that part. Thank you for having a look into it, I hope I pointed out everything important.
Cheers,
Daniel