1 #include "ND280AnalysisUtils.hxx" 7 #include "BaseDataClasses.hxx" 8 #include "DetectorDefinition.hxx" 9 #include <ND280BeamBunching.hxx> 10 #include "PionInteractionSystematic.hxx" 11 #include "Parameters.hxx" 20 if ( run<6000)
return 0;
21 else if (run>=6462 && run<7664)
return 1;
22 else if (run>=7665 && run<7754)
return 2;
23 else if (run>=8000 && run<8550)
return 3;
24 else if (run>=8550 && run<8800)
return 4;
25 else if (run>=8983 && run<9414)
return 5;
26 else if (run>=9426 && run<9800)
return 6;
27 else if ((run>=10252 && run<10334)
28 || (run>=10519 && run<10522))
return 7;
29 else if (run>=10334 && run<10518)
return 8;
30 else if (run == 10518){
31 if(subrun < 10)
return 8;
34 else if (run>=10828 && run<10954)
return 13;
35 else if (run == 10954){
36 if(subrun > -1 && subrun < 10)
return 13;
39 else if (run>=10955 && run<11240)
return 9;
40 else if (run>=11305 && run<11443)
return 13;
41 else if (run>=11449 && run<11492)
return 10;
42 else if (run>=11492 && run<11564)
return 11;
43 else if (run>=11619 && run<11687)
return 12;
44 else if (run == 11687){
45 if(subrun < 7)
return 12;
49 else if (run>=90110000 && run<=90119999)
return 0;
50 else if (run>=90210000 && run<=90219999)
return 1;
51 else if (run>=90200000 && run<=90209999)
return 2;
52 else if (run>=90300000 && run<=90300015)
return 3;
53 else if (run>=90300016 && run<=90300110)
return 4;
54 else if (run>=90410000 && run<=90419999)
return 5;
55 else if (run>=90400000 && run<=90409999)
return 6;
56 else if (run>=80510000 && run<=80519999)
return 8;
57 else if (run>=80600000 && run<=80600159)
return 9;
58 else if (run>=80600160 && run<=80600219)
return 10;
59 else if (run>=80600220 && run<=80600299)
return 11;
60 else if (run>=80600300 && run<=80600399)
return 12;
61 else if (run>=80600400 && run<=80609999)
return 12;
63 else if (run>=80307000 && run<=80307999)
return 8;
64 else if (run>=90307000 && run<=90307999)
return 4;
65 else if (run>=92307000 && run<=92307999)
return 4;
68 else if (run>=91110000 && run<=91119999)
return 0;
69 else if (run>=91210000 && run<=91219999)
return 1;
70 else if (run>=91200000 && run<=91209999)
return 2;
71 else if (run>=91300000 && run<=91300015)
return 3;
72 else if (run>=91300016 && run<=91300110)
return 4;
73 else if (run>=91410000 && run<=91419999)
return 5;
74 else if (run>=91400000 && run<=91409999)
return 6;
75 else if (run>=81510000 && run<=81519999)
return 8;
76 else if (run>=81600000 && run<=81600159)
return 9;
77 else if (run>=81600160 && run<=81600219)
return 10;
78 else if (run>=81600220 && run<=81600299)
return 11;
79 else if (run>=81600300 && run<=81600399)
return 12;
80 else if (run>=81600400 && run<=81609999)
return 12;
90 if (run>=80307000 && run<=80307999)
return 0;
91 else if (run>=90307000 && run<=90307999)
return 1;
92 else if (run>=92307000 && run<=92307999)
return 2;
103 Int_t ibunch =
event.Bunch;
106 Float_t numWidthsReqInSorting = 4;
107 Float_t binBunchWidth = 25.;
108 Float_t binTimeOffsetToBunch = -13.;
109 Float_t minRecBinQ = 0.;
110 Int_t minHitsFGD1 = 6;
111 Int_t minHitsFGD2 = 5;
121 selTime += numWidthsReqInSorting*binBunchWidth;
123 for( Int_t i = 0; i <
event.nFgdTimeBins; i++ ){
127 if( det == SubDetId::kFGD1 && FgdTimeBin->NHits[0] == 0 )
continue;
128 if( det == SubDetId::kFGD2 && FgdTimeBin->NHits[1] == 0 )
continue;
129 if( det == SubDetId::kFGD && FgdTimeBin->NHits[0] == 0 && FgdTimeBin->NHits[1] == 0 )
continue;
131 Float_t binTime = FgdTimeBin->MinTime - binTimeOffsetToBunch;
133 bool inBunch =
false;
135 for( UInt_t k = 0 ; k < bunching.
GetNBunches(event); k++ ){
137 if( TMath::Abs( binTime - time ) < numWidthsReqInSorting*binBunchWidth ) inBunch =
true;
140 if( inBunch )
continue;
143 if( binTime >= selTime && FgdTimeBin->RawChargeSum[0] > minRecBinQ && FgdTimeBin->NHits[0] > minHitsFGD1 && (det == SubDetId::kFGD || det == SubDetId::kFGD1) ){
146 if( binTime >= selTime && FgdTimeBin->RawChargeSum[1] > minRecBinQ && FgdTimeBin->NHits[1] > minHitsFGD2 && (det == SubDetId::kFGD || det == SubDetId::kFGD2) ){
152 arr[nSel] =
event.FgdTimeBins[index];
193 double anaUtils::GetNucleonsPerNucleus(massComponentEnum massComponent,
int target_nucleons) {
197 double nNucleonsPerNucleus = 0., nProtonsPerNucleus=0;
205 double carbon[4] = {6, 0, 1.849, 421.0704607 };
206 double oxygen[4] = {8, 0, 0.0794, (12397./6.) };
207 double hydrogen[4] = {1, 0, 0.1579, (1759./6.) };
208 double titanium[4] = {22, 0, 0.0355, 0. };
209 double silicon[4] = {14, 0, 0.0218, 11 };
210 double nitrogen[4] = {7, 0, 0.0031, 0. };
211 double magnesium[4] = {12, 0, 0., 7. };
213 double totArealDensityXY = carbon[2] + oxygen[2] + hydrogen[2] + titanium[2] + silicon[2] + nitrogen[2] + magnesium[2];
214 double totArealDensityWater = carbon[3] + oxygen[3] + hydrogen[3] + titanium[3] + silicon[3] + nitrogen[3] + magnesium[3];
219 carbon[1] = 12 * 0.9893 + 13 * 0.0107;
220 oxygen[1] = 16 * 0.99757 + 17 * 0.00038 + 18 * 0.00205;
221 hydrogen[1] = 1 * 0.999885 + 2 * 0.000115;
222 titanium[1] = 46 * 0.0825 + 47 * 0.0744 + 48 * 0.7372 + 49 * 0.0541 + 50 * 0.0518;
223 silicon[1] = 28 * 0.92223 + 29 * 0.04685 + 30 * 0.03092;
224 nitrogen[1] = 14 * 0.996346 + 15 * 0.00364;
225 magnesium[1] = 24 * 0.7899 + 25 * 0.1000 + 26 * 0.1101;
227 if(massComponent == kFGD1 || massComponent == kFGD2xymodules || massComponent == kFGD2xylike) {
230 nProtonsPerNucleus = carbon[0] * carbon[2] +
231 oxygen[0] * oxygen[2] +
232 hydrogen[0] * hydrogen[2] +
233 titanium[0] * titanium[2] +
234 silicon[0] * silicon[2] +
235 nitrogen[0] * nitrogen[2] +
236 magnesium[0] * magnesium[2] ;
237 nProtonsPerNucleus = nProtonsPerNucleus / totArealDensityXY;
239 nNucleonsPerNucleus = carbon[1] * carbon[2] +
240 oxygen[1] * oxygen[2] +
241 hydrogen[1] * hydrogen[2] +
242 titanium[1] * titanium[2] +
243 silicon[1] * silicon[2] +
244 nitrogen[1] * nitrogen[2] +
245 magnesium[1] * magnesium[2] ;
246 nNucleonsPerNucleus = nNucleonsPerNucleus / totArealDensityXY;
248 else if(massComponent == kFGD2watermodules || massComponent == kFGD2waterlike) {
251 nProtonsPerNucleus = carbon[0] * carbon[3] +
252 oxygen[0] * oxygen[3] +
253 hydrogen[0] * hydrogen[3] +
254 titanium[0] * titanium[3] +
255 silicon[0] * silicon[3] +
256 nitrogen[0] * nitrogen[3] +
257 magnesium[0] * magnesium[3] ;
258 nProtonsPerNucleus = nProtonsPerNucleus / totArealDensityWater;
260 nNucleonsPerNucleus = carbon[1] * carbon[3] +
261 oxygen[1] * oxygen[3] +
262 hydrogen[1] * hydrogen[3] +
263 titanium[1] * titanium[3] +
264 silicon[1] * silicon[3] +
265 nitrogen[1] * nitrogen[3] +
266 magnesium[1] * magnesium[3] ;
267 nNucleonsPerNucleus = nNucleonsPerNucleus / totArealDensityWater;
269 else if (massComponent == kP0Dwater) {
271 nProtonsPerNucleus = (8*1/3. +
274 nNucleonsPerNucleus = ((16*0.99762+17*0.00038+18*0.002)*1/3. +
275 (1*0.99985+2*0.00015)*2/3.);
278 std::cout <<
"Unknown target section selected." << std::endl;
282 if (target_nucleons == 1)
return nProtonsPerNucleus;
283 else if(target_nucleons == 2)
return (nNucleonsPerNucleus - nProtonsPerNucleus);
284 else if(target_nucleons == 3)
return nNucleonsPerNucleus;
286 std::cout <<
"Unknown target nucleons selected." << std::endl;
292 double anaUtils::GetAreaFV(massComponentEnum massComponent) {
294 TVector3 fgd1min = anaUtils::ArrayToTVector3(DetDef::fgd1min);
295 TVector3 fgd2min = anaUtils::ArrayToTVector3(DetDef::fgd2min);
296 TVector3 fgd1max = anaUtils::ArrayToTVector3(DetDef::fgd1max);
297 TVector3 fgd2max = anaUtils::ArrayToTVector3(DetDef::fgd2max);
298 TVector3 FVdefminFGD1 = anaUtils::ArrayToTVector3(FVDef::FVdefminFGD1);
299 TVector3 FVdefminFGD2 = anaUtils::ArrayToTVector3(FVDef::FVdefminFGD2);
300 TVector3 FVdefmaxFGD1 = anaUtils::ArrayToTVector3(FVDef::FVdefmaxFGD1);
301 TVector3 FVdefmaxFGD2 = anaUtils::ArrayToTVector3(FVDef::FVdefmaxFGD2);
303 TVector3 FVfgd1 = (fgd1max - FVdefmaxFGD1)-(fgd1min + FVdefminFGD1);
304 TVector3 FVfgd2 = (fgd2max - FVdefmaxFGD2)-(fgd2min + FVdefminFGD2);
307 if (massComponent == kFGD1) {
308 areaFV = FVfgd1.x() * FVfgd1.y() / 100.;
309 }
else if (massComponent == kFGD2xymodules || massComponent == kFGD2watermodules || massComponent == kFGD2waterlike || massComponent == kFGD2xylike) {
310 areaFV = FVfgd2.x() * FVfgd2.y() / 100.;
313 std::cout <<
"Unknown target section selected." << std::endl;
321 double anaUtils::GetNTargets(massComponentEnum massComponent,
int target_nucleons) {
326 double nXYModulesFGD1FV = 15.;
327 double nXYModulesFGD2FV = 7.;
329 double discardedModulesFGD1 = (FVDef::FVdefminFGD1[2] + FVDef::FVdefmaxFGD1[2]) / DetDef::fgdXYModuleWidth;
330 double discardedModulesFGD2 = (FVDef::FVdefminFGD2[2] + FVDef::FVdefmaxFGD2[2]) / DetDef::fgdXYModuleWidth;
332 int nFGD1 = (int)(discardedModulesFGD1 * 2) ;
333 int nFGD2 = (int)(discardedModulesFGD2 * 2) ;
334 nXYModulesFGD1FV -= (double)(nFGD1/2.);
335 nXYModulesFGD2FV -= (double)(nFGD2/2.);
338 double xyplusair = DetDef::fgdXYModuleWidth + DetDef::fgdXYAirWidth;
339 if (FVDef::FVdefminFGD2[2] > xyplusair || FVDef::FVdefmaxFGD2[2] > xyplusair)
340 std::cout <<
"ERROR: FGD2 FV doesn't include the 6 water modules --> GetNTargets will be wrong for FGD2!" << std::endl;
341 double nWaterModules = 6.;
344 if(massComponent == kFGD1 || massComponent == kFGD2xymodules) {
346 double nXYModulesFV = 0;
347 if (massComponent == kFGD1) {
348 nXYModulesFV = nXYModulesFGD1FV;
349 std::cout <<
"FGD1 (" << nXYModulesFV <<
" modules):" << std::endl;
350 }
else if (massComponent == kFGD2xymodules) {
351 nXYModulesFV = nXYModulesFGD2FV;
352 std::cout <<
"FGD2 XY (" << nXYModulesFV <<
" modules):" << std::endl;
357 massFV = 2.147 * GetAreaFV(massComponent) * nXYModulesFV;
358 double density = 2.147 / (((double)DetDef::fgdXYModuleWidth + (
double)DetDef::fgdXYAirWidth) / 10.);
359 std::cout <<
" density (included air): " << density <<
" g/cm^3" << std::endl;
362 else if(massComponent == kFGD2watermodules) {
366 massFV = 2.79867 * GetAreaFV(massComponent) * nWaterModules;
367 std::cout <<
"FGD2 water modules (" << nWaterModules <<
" modules):" << std::endl;
368 double density = 2.79867 / (((double)DetDef::fgdWaterModuleWidth + (
double)DetDef::fgdWaterAirWidth) / 10.);
369 std::cout <<
" density (included air): " << density <<
" g/cm^3" << std::endl;
372 else if(massComponent == kFGD2waterlike) {
375 massFV = 13.838 * GetAreaFV(massComponent);
376 std::cout <<
"FGD2 water-like (" << nWaterModules <<
" modules):" << std::endl;
379 else if(massComponent == kFGD2xylike) {
382 massFV = 16.887 * GetAreaFV(massComponent);
383 std::cout <<
"FGD2 XY-like (mixed modules):" << std::endl;
386 else if(massComponent == kFGD2) {
387 double Nwater = GetNTargets(kFGD2watermodules,target_nucleons);
388 double Nscint = GetNTargets(kFGD2xymodules,target_nucleons);
389 return (Nwater + Nscint);
392 else if(massComponent == kFGDs) {
393 double Nfgd1 = GetNTargets(kFGD1,target_nucleons);
394 double Nfgd2 = GetNTargets(kFGD2,target_nucleons);
395 return (Nfgd1 + Nfgd2);
398 else if (massComponent == kP0Dwater) {
401 std::cout <<
"P0D:" << std::endl;
405 std::cout <<
"Unknown target section selected." << std::endl;
409 std::cout <<
" mass FV: " << massFV / 1000. <<
" Kg" << std::endl;
412 double nNucleons = massFV * units::Avogadro;
413 if (target_nucleons == 3)
return nNucleons;
414 double nNucleonsPerNucleus = GetNucleonsPerNucleus(massComponent, 3);
415 return nNucleons * GetNucleonsPerNucleus(massComponent, target_nucleons) / nNucleonsPerNucleus;
419 void anaUtils::IncrementPOTBySpill(
const AnaSpillB& spill,
Header& header) {
426 std::cout <<
"WARNING: POT is suspiciously large for run " << info.
Run <<
", subrun " << info.
SubRun <<
", event " << info.
Event <<
": " << beam.
POTSincePreviousSavedSpill <<
". POT will not be counted for this event." << std::endl;
431 std::cout <<
"WARNING: POT is negative for run " << info.
Run <<
", subrun " << info.
SubRun <<
", event " << info.
Event <<
": " << beam.
POTSincePreviousSavedSpill <<
". POT will not be counted for this event." << std::endl;
485 if (p <= 0)
return -999;
499 Float_t anaUtils::ComputeInversePTFlip(
const AnaTrackB& track){
514 if (PTinv==0)
return -999;
515 Float_t pt = 1/PTinv;
517 if (u_t==0)
return -999;
Representation of the beam quality and perhaps other beam information as needed.
int GetFGDMichelElectrons(const AnaEventB &event, const SubDetId::SubDetEnum det, AnaFgdTimeBinB **arr, bool prod5Cut=0)
Get all delayed time bins as Michel Electron candidates.
Float_t DirectionEnd[3]
The reconstructed end direction of the particle.
Float_t GetExitMomentum(const AnaDetCrossingB &cross)
Get the momentum value from AnaDetCrossing.
Int_t SpillsSincePreviousSavedSpill
AnaEventInfoB * EventInfo
Run, sunrun, event, time stamp, etc.
Int_t SubRun
The subrun number.
Float_t MomentumFlip
Momentum for the main PID hypothesis and reverse sense.
Float_t GetEntranceMomentum(const AnaDetCrossingB &cross)
Get the momentum value from AnaDetCrossing.
Float_t ComputeInversePT(const AnaDetCrossingB &cross, bool entrance=true)
Compute inverse PT given an AnaDetCrossing.
AnaBeamB * Beam
The beam quality flags for this spill.
int GetRunPeriod(int run, int subrun=-1)
Returns the run period (sequentially: 0,1,2,3,4,5 ...)
Float_t ComputeMomentumFromInversePTFlip(const AnaParticleB &part, Float_t PTinv)
Compute the total momentum (flip) given the part and the inverse transverse momentum.
Representation of a detector crossing info for a true particle (G4 trajectory).
SubDetEnum
Enumeration of all detector systems and subdetectors.
UInt_t GetNBunches(const AnaEventB &event)
Number of bunches in the run period for the current run.
bool GetIsMC() const
Return whether this spill is from Monte Carlo or not.
Representation of a global track.
Float_t ExitMomentum[3]
for each subdetector tell the exit momentum
Double_t POTSincePreviousSavedSpill
Int_t GoodSpill
Good spill flag, as defined in Beam Summary Data. 0 is bad.
Int_t Event
The ND280 event number.
Float_t GetBunchCentralTime(const AnaEventB &event, Int_t ibunch)
Get the central time for bunch ibunch.
int GetSandMode(int run)
Returns the sans muon modes (sequentially: 0,1,2)
Representation of a reconstructed particle (track or shower).
AnaDataQualityB * DataQuality
The ND280 data quality flags for this spill.
Float_t EntranceMomentum[3]
for each subdetector tell the entrance momentum
Int_t Run
The ND280 run number.