SND@LHC Software
Loading...
Searching...
No Matches
neutrinoFilterGoldenSample.cxx File Reference
#include <iostream>
#include <vector>
#include "TObject.h"
#include "TFile.h"
#include "TTree.h"
#include "TChain.h"
#include "TClonesArray.h"
#include "TH1D.h"
#include "ShipMCTrack.h"
#include "sndBaseCut.h"
#include "sndMinSciFiHitsCut.h"
#include "sndSciFiStationCut.h"
#include "sndVetoCut.h"
#include "sndMinSciFiConsecutivePlanes.h"
#include "sndDSActivityCut.h"
#include "sndUSQDCCut.h"
#include "sndEventDeltat.h"
#include "sndAvgSciFiFiducialCut.h"
#include "sndAvgDSFiducialCut.h"
#include "sndDSVetoCut.h"
Include dependency graph for neutrinoFilterGoldenSample.cxx:

Go to the source code of this file.

Enumerations

enum  Cutset {
  stage1cuts , novetocuts , FVsideband , allowWalls2and5 ,
  stage1cutsVetoFirst , nueFilter
}
 

Functions

int main (int argc, char **argv)
 

Enumeration Type Documentation

◆ Cutset

enum Cutset
Enumerator
stage1cuts 
novetocuts 
FVsideband 
allowWalls2and5 
stage1cutsVetoFirst 
nueFilter 

Definition at line 27 of file neutrinoFilterGoldenSample.cxx.

Function Documentation

◆ main()

int main ( int  argc,
char **  argv 
)

Definition at line 29 of file neutrinoFilterGoldenSample.cxx.

29 {
30
31 std::cout << "Starting neutrino filter" << std::endl;
32
33 if (argc != 4) {
34 std::cout << "Two arguments required: input file name (or reg exp), output file name, cut set (0: stage 1 selection, 1: no veto or scifi 1st layer, 2: FV sideband, 3: include walls 2 and 5, 4: nue filter (no DS selection, allow walls 1 to 4." << std::endl;
35 exit(-1);
36 }
37
38 // Input files
39 bool isMC = false;
40 TChain * ch = new TChain("rawConv");
41 ch->Add(argv[1]);
42 if (ch->GetEntries() == 0){
43 delete ch;
44 ch = new TChain("cbmsim");
45 ch->Add(argv[1]);
46 if (ch->GetEntries() > 0) {
47 isMC = true;
48 ch->SetBranchStatus("EventHeader", 0); // To be able to run on old MC.
49 ch->SetBranchStatus("EventHeader.", 0); // To be able to run on old MC. Bizarre....?
50 } else {
51 std::cout << "Didn't find rawConv or cbmsim in input file" << std::endl;
52 exit(-1);
53 }
54 }
55 std::cout << "Got input tree" << std::endl;
56
57 // MC truth
58 TClonesArray * MCTracks = new TClonesArray("ShipMCTrack", 5000);
59 if (isMC) ch->SetBranchAddress("MCTrack", &MCTracks);
60
61 // Output file
62 TFile * outFile = new TFile(argv[2], "RECREATE");
63 std::cout << "Got output file" << std::endl;
64
65 ch->GetEntry(0);
66 ch->GetFile()->Get("BranchList")->Write("BranchList", TObject::kSingleKey);
67 ch->GetFile()->Get("TimeBasedBranchList")->Write("TimeBasedBranchList", TObject::kSingleKey);
68 if (ch->GetFile()->Get("FileHeader")) ch->GetFile()->Get("FileHeader")->Write();
69 if (ch->GetFile()->Get("FileHeaderHeader")) ch->GetFile()->Get("FileHeaderHeader")->Write();
70
71 // Set up all branches to copy to output TTree.
72 TTree * outTree = ch->CloneTree(0);
73 std::cout << "Got output tree" << std::endl;
74
75 // Set up cuts
76 std::cout << "Starting cut set up" << std::endl;
77
78 std::vector< snd::analysis_cuts::baseCut * > cutFlow;
79
80 int selected_cutset = std::atoi(argv[3]);
81
82 if (selected_cutset == stage1cuts){ // Stage 1 cuts
83 cutFlow.push_back( new snd::analysis_cuts::avgSciFiFiducialCut(200, 1200, 300, 128*12-200, ch)); // E. Average SciFi hit channel number must be within [200, 1200] (ver) and [300, max-200] (hor)
84 cutFlow.push_back( new snd::analysis_cuts::avgDSFiducialCut(70, 105, 10, 50, ch)); // F. Average DS hit bar number must be within [70, 105] (ver) and [10, 50] (hor)
85 cutFlow.push_back( new snd::analysis_cuts::vetoCut(ch)); // B. No veto hits
86 cutFlow.push_back( new snd::analysis_cuts::sciFiStationCut(0., std::vector<int>(1, 1), ch)); // C. No hits in first SciFi plane
87 cutFlow.push_back( new snd::analysis_cuts::sciFiStationCut(0., std::vector<int>(1, 2), ch)); // C. No hits in second SciFi plane
88 cutFlow.push_back( new snd::analysis_cuts::sciFiStationCut(0.05, std::vector<int>(1, 5), ch)); // D. Vertex not in 5th wall
89 cutFlow.push_back( new snd::analysis_cuts::minSciFiConsecutivePlanes(ch)); // G. At least two consecutive SciFi planes hit
90 cutFlow.push_back( new snd::analysis_cuts::DSActivityCut(ch)); // H. If there is a downstream hit, require hits in all upstream stations.
91 if (not isMC) cutFlow.push_back( new snd::analysis_cuts::eventDeltatCut(-1, 100, ch)); // J. Previous event more than 100 clock cycles away. To avoid deadtime issues.
92
93 } else if (selected_cutset == stage1cutsVetoFirst){ // Stage 1 cuts but with Veto cut upfront. For neutral hadron background estimation
94 cutFlow.push_back( new snd::analysis_cuts::vetoCut(ch)); // B. No veto hits
95 cutFlow.push_back( new snd::analysis_cuts::avgSciFiFiducialCut(200, 1200, 300, 128*12-200, ch)); // E. Average SciFi hit channel number must be within [200, 1200] (ver) and [300, max-200] (hor)
96 cutFlow.push_back( new snd::analysis_cuts::avgDSFiducialCut(70, 105, 10, 50, ch)); // F. Average DS hit bar number must be within [70, 105] (ver) and [10, 50] (hor)
97 cutFlow.push_back( new snd::analysis_cuts::sciFiStationCut(0., std::vector<int>(1, 1), ch)); // C. No hits in first SciFi plane
98 cutFlow.push_back( new snd::analysis_cuts::sciFiStationCut(0., std::vector<int>(1, 2), ch)); // C. No hits in second SciFi plane
99 cutFlow.push_back( new snd::analysis_cuts::sciFiStationCut(0.05, std::vector<int>(1, 5), ch)); // D. Vertex not in 5th wall
100 cutFlow.push_back( new snd::analysis_cuts::minSciFiConsecutivePlanes(ch)); // G. At least two consecutive SciFi planes hit
101 cutFlow.push_back( new snd::analysis_cuts::DSActivityCut(ch)); // H. If there is a downstream hit, require hits in all upstream stations.
102 if (not isMC) cutFlow.push_back( new snd::analysis_cuts::eventDeltatCut(-1, 100, ch)); // J. Previous event more than 100 clock cycles away. To avoid deadtime issues.
103
104 } else if (selected_cutset == novetocuts) {
105 cutFlow.push_back( new snd::analysis_cuts::sciFiStationCut(0.05, std::vector<int>(1, 5), ch)); // D. Vertex not in 5th wall
106 cutFlow.push_back( new snd::analysis_cuts::avgSciFiFiducialCut(200, 1200, 300, 128*12-200, ch)); // E. Average SciFi hit channel number must be within [200, 1200] (ver) and [300, max-200] (hor)
107 cutFlow.push_back( new snd::analysis_cuts::avgDSFiducialCut(70, 105, 10, 50, ch)); // F. Average DS hit bar number must be within [70, 105] (ver) and [10, 50] (hor)
108 cutFlow.push_back( new snd::analysis_cuts::minSciFiConsecutivePlanes(ch)); // G. At least two consecutive SciFi planes hit
109 cutFlow.push_back( new snd::analysis_cuts::DSActivityCut(ch)); // H. If there is a downstream hit, require hits in all upstream stations.
110 if (not isMC) cutFlow.push_back( new snd::analysis_cuts::eventDeltatCut(-1, 100, ch)); // J. Previous event more than 100 clock cycles away. To avoid deadtime issues.
111
112 } else if (selected_cutset == FVsideband){
113 cutFlow.push_back( new snd::analysis_cuts::vetoCut(ch)); // B. No veto hits
114 cutFlow.push_back( new snd::analysis_cuts::sciFiStationCut(0., std::vector<int>(1, 1), ch)); // C. No hits in first SciFi plane
115 cutFlow.push_back( new snd::analysis_cuts::sciFiStationCut(0., std::vector<int>(1, 2), ch)); // D. Vertex not in 5th wall
116 cutFlow.push_back( new snd::analysis_cuts::sciFiStationCut(0.05, std::vector<int>(1, 5), ch)); // D. Vertex not in 5th wall
117 cutFlow.push_back( new snd::analysis_cuts::avgSciFiFiducialCut(200, 1200, 300, 128*12-200, ch, true)); // E. Average SciFi hit channel number must be within [200, 1200] (ver) and [300, max-200] (hor)
118 cutFlow.push_back( new snd::analysis_cuts::minSciFiConsecutivePlanes(ch)); // G. At least two consecutive SciFi planes hit
119 cutFlow.push_back( new snd::analysis_cuts::DSActivityCut(ch)); // H. If there is a downstream hit, require hits in all upstream stations.
120 if (not isMC) cutFlow.push_back( new snd::analysis_cuts::eventDeltatCut(-1, 100, ch)); // J. Previous event more than 100 clock cycles away. To avoid deadtime issues.
121
122 } else if (selected_cutset == allowWalls2and5) {
123 cutFlow.push_back( new snd::analysis_cuts::avgSciFiFiducialCut(200, 1200, 300, 128*12-200, ch)); // E. Average SciFi hit channel number must be within [200, 1200] (ver) and [300, max-200] (hor)
124 cutFlow.push_back( new snd::analysis_cuts::avgDSFiducialCut(70, 105, 10, 50, ch)); // F. Average DS hit bar number must be within [70, 105] (ver) and [10, 50] (hor)
125 cutFlow.push_back( new snd::analysis_cuts::vetoCut(ch)); // B. No veto hits
126 cutFlow.push_back( new snd::analysis_cuts::sciFiStationCut(0., std::vector<int>(1, 1), ch)); // C. No hits in first SciFi plane
127 cutFlow.push_back( new snd::analysis_cuts::DSActivityCut(ch)); // H. If there is a downstream hit, require hits in all upstream stations.
128 if (not isMC) cutFlow.push_back( new snd::analysis_cuts::eventDeltatCut(-1, 100, ch)); // J. Previous event more than 100 clock cycles away. To avoid deadtime issues.
129
130 } else if (selected_cutset == nueFilter) {
131 cutFlow.push_back( new snd::analysis_cuts::avgSciFiFiducialCut(200, 1200, 300, 128*12-200, ch)); // E. Average SciFi hit channel number must be within [200, 1200] (ver) and [300, max-200] (hor)
132 cutFlow.push_back( new snd::analysis_cuts::vetoCut(ch)); // B. No veto hits
133 cutFlow.push_back( new snd::analysis_cuts::sciFiStationCut(0.05, std::vector<int>(1, 5), ch)); // D. Vertex not in 5th wall
134 cutFlow.push_back( new snd::analysis_cuts::DSVetoCut(ch)); // D. Veto events with hits in last DS planes
135 if (not isMC) cutFlow.push_back( new snd::analysis_cuts::eventDeltatCut(-1, 100, ch)); // J. Previous event more than 100 clock cycles away. To avoid deadtime issues.
136 } else {
137 std::cout << "Unrecognized cutset. Exitting" << std::endl;
138 exit(-1);
139 }
140 std::cout << "Done initializing cuts" << std::endl;
141
142 int n_cuts = (int) cutFlow.size();
143
144 // Book histograms
145 // Cut-by-cut
146 // All cut variables
147 std::vector<std::vector<TH1D*> > cut_by_cut_var_histos = std::vector<std::vector<TH1D*> >();
148 for (int i_cut = -1; i_cut < n_cuts; i_cut++){
149 std::vector<TH1D*> this_cut_by_cut_var_histos = std::vector<TH1D*>();
150 for (snd::analysis_cuts::baseCut * cut : cutFlow) {
151 for(int i_dim = 0; i_dim < cut->getNbins().size(); i_dim++){
152 this_cut_by_cut_var_histos.push_back(new TH1D((std::to_string(i_cut)+"_"+cut->getShortName()+"_"+std::to_string(i_dim)).c_str(),
153 cut->getShortName().c_str(),
154 cut->getNbins()[i_dim], cut->getRangeStart()[i_dim], cut->getRangeEnd()[i_dim]));
155 }
156 }
157 cut_by_cut_var_histos.push_back(this_cut_by_cut_var_histos);
158 }
159
160 std::vector<std::vector<std::vector<TH1D*> > > cut_by_cut_truth_histos = std::vector<std::vector<std::vector<TH1D*> > >();
161 if (isMC) {
162 for (int i_species = 0; i_species < 5; i_species++){ // e, mu, tau, NC
163 std::vector<std::vector<TH1D*> > this_species_histos = std::vector<std::vector<TH1D*> >();
164 std::string species_suffix;
165 switch (i_species) {
166 case 0:
167 species_suffix = "nueCC";
168 break;
169 case 1:
170 species_suffix = "numuCC";
171 break;
172 case 2:
173 species_suffix = "nutauCC";
174 break;
175 case 3:
176 species_suffix = "NC";
177 break;
178 case 4:
179 species_suffix = "Other"; // For PG sim
180 break;
181 default :
182 std::cerr << "MC truth histograms initialization error! Unknown species" << std::endl;
183 exit(-1);
184 }
185
186 for (int i_cut = -1; i_cut < n_cuts; i_cut++){
187
188 std::vector<TH1D*> this_cut_by_cut_truth_histos = std::vector<TH1D*>();
189 this_cut_by_cut_truth_histos.push_back(new TH1D((species_suffix+"_"+std::to_string(i_cut)+"_Enu").c_str(), "Enu", 300, 0, 3000));
190 this_cut_by_cut_truth_histos.push_back(new TH1D((species_suffix+"_"+std::to_string(i_cut)+"_EEM").c_str(), "ELep", 300, 0, 3000));
191 this_cut_by_cut_truth_histos.push_back(new TH1D((species_suffix+"_"+std::to_string(i_cut)+"_EHad").c_str(), "EHad", 300, 0, 3000));
192 this_cut_by_cut_truth_histos.push_back(new TH1D((species_suffix+"_"+std::to_string(i_cut)+"_vtxX").c_str(), "vtxX", 200, -100, 0));
193 this_cut_by_cut_truth_histos.push_back(new TH1D((species_suffix+"_"+std::to_string(i_cut)+"_vtxY").c_str(), "vtxY", 200, 0, 100));
194 this_cut_by_cut_truth_histos.push_back(new TH1D((species_suffix+"_"+std::to_string(i_cut)+"_vtxZ").c_str(), "vtxZ", 200, 280, 380));
195
196 this_species_histos.push_back(this_cut_by_cut_truth_histos);
197 }
198 cut_by_cut_truth_histos.push_back(this_species_histos);
199 }
200 }
201 // N-1
202 std::vector<TH1D*> n_minus_1_var_histos = std::vector<TH1D*>();
203 for (snd::analysis_cuts::baseCut * cut : cutFlow) {
204 for(int i_dim = 0; i_dim < cut->getNbins().size(); i_dim++){
205 n_minus_1_var_histos.push_back(new TH1D(("n_minus_1_"+cut->getShortName()+"_"+std::to_string(i_dim)).c_str(),
206 cut->getShortName().c_str(),
207 cut->getNbins()[i_dim], cut->getRangeStart()[i_dim], cut->getRangeEnd()[i_dim]));
208 }
209 }
210
211 std::cout << "Done initializing histograms" << std::endl;
212
213 // Cut flow
214 TH1D * cutFlowHistogram = new TH1D("cutFlow", "Cut flow;;Number of events passing cut", n_cuts+1, 0, n_cuts+1);
215 for (int i = 2; i <= cutFlowHistogram->GetNbinsX(); i++){
216 cutFlowHistogram->GetXaxis()->SetBinLabel(i, cutFlow.at(i-2)->getName().c_str());
217 }
218
219 std::cout << "Done initializing cut flow histogram" << std::endl;
220
221 // Get number of entries
222 unsigned long int n_entries = ch->GetEntries();
223
224 // Holder for cut results
225 std::vector<bool> passes_cut = std::vector<bool>(n_cuts, false);
226
227 std::cout << "Starting event loop" << std::endl;
228 for (unsigned long int i_entry = 0; i_entry < n_entries; i_entry++){
229 ch->GetEntry(i_entry);
230 if (i_entry%10000 == 0) std::cout << "Reading entry " << i_entry << std::endl;
231
232 cutFlowHistogram->Fill(0);
233
234 // Apply cuts
235 int n_cuts_passed = 0;
236 bool accept_event = true;
237 int i_cut = 0;
238 for (snd::analysis_cuts::baseCut * cut : cutFlow){
239 if (cut->passCut()){
240 if (accept_event) cutFlowHistogram->Fill(1 + i_cut);
241 passes_cut[i_cut] = true;
243 } else {
244 accept_event = false;
245 passes_cut[i_cut] = false;
246 }
247 i_cut++;
248 }
249 if (accept_event) outTree->Fill();
250
251
252 // Fill histograms
253 std::vector<TH1D*>::iterator hist_it;
254 // Sequential
255 for (int seq_cut = -1; seq_cut < ((int) passes_cut.size()); seq_cut++){
256 if (seq_cut >= 0){
257 if (not passes_cut[seq_cut]) break;
258 }
259 hist_it = cut_by_cut_var_histos[seq_cut+1].begin();
260 for (snd::analysis_cuts::baseCut * cut : cutFlow) {
261 for (int i_dim = 0; i_dim < cut->getPlotVar().size(); i_dim++){
262 (*hist_it)->Fill(cut->getPlotVar()[i_dim]);
263 hist_it++;
264 }
265 }
266 if (isMC) {
267
268 int this_species = -1;
269 if (MCTracks->GetEntries() < 2) {
270 this_species = 4;
271 } else {
272
273 int pdgIn = abs(((ShipMCTrack*)MCTracks->At(0))->GetPdgCode());
274 int pdgOut = abs(((ShipMCTrack*)MCTracks->At(1))->GetPdgCode());
275
276 if (pdgIn == (pdgOut+1)){
277 //CC
278 if (pdgIn == 12) this_species = 0; // nueCC
279 if (pdgIn == 14) this_species = 1; // numuCC
280 if (pdgIn == 16) this_species = 2; // nutauCC
281 } else if (pdgIn == pdgOut) {
282 //NC
283 this_species = 3;
284 } else {
285 // Other
286 this_species = 4;
287 }
288 }
289 cut_by_cut_truth_histos[this_species][seq_cut+1][0]->Fill(((ShipMCTrack*) MCTracks->At(0))->GetEnergy()); // Enu
290 if (this_species < 4) {
291 cut_by_cut_truth_histos[this_species][seq_cut+1][1]->Fill(((ShipMCTrack*) MCTracks->At(1))->GetEnergy()); // ELep
292 cut_by_cut_truth_histos[this_species][seq_cut+1][2]->Fill(((ShipMCTrack*) MCTracks->At(0))->GetEnergy()-((ShipMCTrack*) MCTracks->At(1))->GetEnergy()); // EHad
293 }
294 cut_by_cut_truth_histos[this_species][seq_cut+1][3]->Fill(((ShipMCTrack*) MCTracks->At(0))->GetStartX()); // X
295 cut_by_cut_truth_histos[this_species][seq_cut+1][4]->Fill(((ShipMCTrack*) MCTracks->At(0))->GetStartY()); // Y
296 cut_by_cut_truth_histos[this_species][seq_cut+1][5]->Fill(((ShipMCTrack*) MCTracks->At(0))->GetStartZ()); // Z
297 }
298 }
299
300 // N-1
301 int current_cut = 0;
302 hist_it = n_minus_1_var_histos.begin();
303 for (snd::analysis_cuts::baseCut * cut : cutFlow) {
304 for (int i_dim = 0; i_dim < cut->getPlotVar().size(); i_dim++){
305 if (((not passes_cut[current_cut]) and (n_cuts_passed == (cutFlow.size()-1)))
306 or (n_cuts_passed == cutFlow.size()) ) (*hist_it)->Fill(cut->getPlotVar()[i_dim]);
307 hist_it++;
308 }
309 current_cut++;
310 }
311 }
312
313 outFile->Write();
314
315 return 0;
316}
int i
Definition ShipAna.py:86