make_fc_mass_and_oct_nersc_2019.C
Go to the documentation of this file.
2 #include "CAFAna/Core/Spectrum.h"
4 
5 #include "CAFAna/Fit/Fit.h"
7 
10 
11 #include "CAFAna/Vars/FitVars.h"
12 
13 #include "CAFAna/FC/FCPoint.h"
14 #include "CAFAna/FC/FCCollection.h"
15 #include "CAFAna/FC/FCSurface.h"
16 
20 
21 //#include "3FlavorAna/Ana2018/nue/joint_fit_2018_tools.h"
23 
24 #include "CAFAna/Analysis/Calcs.h"
25 #include "OscLib/IOscCalc.h"
26 
27 #include "TRandom3.h"
28 #include "TH1.h"
29 #include "TGraph.h"
30 
31 using namespace ana;
32 
33 
34 void make_fc_mass_and_oct_nersc_2019(TString options, int NPts, int N, int jid, int npts_flush = 0)
35 {
36 
37  // specify octant and hierarchy as the option arg
38  assert(options == "LOIH" || options == "LONH" ||
39  options == "UOIH" || options == "UONH");
40  bool lo = options.Contains("LO");
41  bool nh = options.Contains("NH");
42 
43  std::string fcout = TString::Format("FCCol_%s_number_v%d_%d.root", options.Data(), N, jid).Data();
44 // std::string fcout = "FCCol_" + options.Data() + "_number_v"
45 // + number
46 // + "_"
47 // + std::to_string(jid)
48 // +".root";
49 
50  FCCollection fccol;
52 
53  double thisPOT;
54  double thisLivetime;
55 
56  // Grab the systs
57  // bools to make the function calls a little more readable
58  bool nueOnly = true;
59  bool numuOnly= true;
60  bool isFHC = true;
61  bool isRHC = true;
62 
63  // joint
64  std::vector<const ISyst*> systs = GetJointFitSystematicList(true, !nueOnly, !numuOnly, true, true, true);
65 
66  // nue fhc
67  std::vector<const ISyst*> snue_fhc = getAllAna2018Systs(kNueAna2018, true, kFHC);
68 
69  // nue rhc
70  std::vector<const ISyst*> snue_rhc = getAllAna2018Systs(kNueAna2018, true, kRHC);
71 
72  // numu
73  std::vector<const ISyst*> snumu = GetJointFitSystematicList(true, !nueOnly, numuOnly, isFHC, isRHC, true);
74 
75  // We're setting up the requisite inputs to the nue experiment
76  // nue prediction
77  std::vector <const IPrediction*> nue_preds;
78  std::vector <std::pair <TH1D*, double > > nue_cosmics;
79  std::vector <Spectrum> nue_cosmics_spectra;
80  bool minimizeMemory = true;
81 
82  // Grab the nue predictions for fhc and rhc
83  nue_preds.push_back(GetNuePrediction2019("combo", calc, true, "fhc", false, false, minimizeMemory, true));
84  nue_preds.push_back(GetNuePrediction2019("prop", calc, true, "rhc", false, false, minimizeMemory, true));
85 
86  nue_cosmics.push_back(GetNueCosmics2019("fhc", false, true));
87  nue_cosmics.push_back(GetNueCosmics2019("rhc", false, true));
88 
89  // We need to store cosmic hists as spectra to add into our fake data
90  // FHC and RHC have different POT and Livetimes
91  for(int i = 0; i < 2; i++) {
92  if(i==0) {
93  thisPOT = kAna2019FHCPOT;
94  thisLivetime = kAna2019FHCLivetime;
95  }
96  else {
97  thisPOT = kAna2019RHCPOT;
98  thisLivetime = kAna2019RHCLivetime;
99  }
100  nue_cosmics_spectra.push_back(Spectrum(nue_cosmics[i].first,
101  thisPOT, thisLivetime));
102  }
103 
104 
105  //////////////////////////////////////////////////////////////////////
106  // Numu Prediction
107  //////////////////////////////////////////////////////////////////////
108  std::vector<const IPrediction*> numu_preds;
109  std::vector< std::pair<TH1D*, double> > numu_cosmics;
110  std::vector<Spectrum> numu_cosmics_spectra;
111 
112  std::vector<const IPrediction*> this_numu_preds;
113  std::vector< std::pair<TH1D*, double> > this_numu_cosmics;
114 
115  // Construct numu inputs
116  for(std::string beam : {"fhc", "rhc"}){
117  this_numu_preds = GetNumuPredictions2019(4,true, beam, false, kNuMu, minimizeMemory, true);
118  this_numu_cosmics = GetNumuCosmics2019(4, beam, false, true);
119  numu_preds.insert(numu_preds.end(),
120  this_numu_preds.begin(),
121  this_numu_preds.end());
122  numu_cosmics.insert(numu_cosmics.end(),
123  this_numu_cosmics.begin(),
124  this_numu_cosmics.end());
125 
126  for(std::pair<TH1D*, double> h : this_numu_cosmics){
127  thisPOT = kAna2019FHCPOT;
128  thisLivetime = kAna2019FHCLivetime;
129  if(beam == "rhc") {
130  thisPOT = kAna2019RHCPOT;
131  thisLivetime = kAna2019RHCLivetime;
132  }
133  numu_cosmics_spectra.push_back(Spectrum(h.first, thisPOT, thisLivetime));
134  }
135 
136  }
137 
138  // Grab analysis slices to find the bin centers and the best
139  // fit point
140  std::string helperupsname = std::string(getenv("FCHELPERANA2019_LIB_PATH"));
141  std::string anaslicename = helperupsname +
142  "/Surfaces/hist_slices_2019_joint_realData_both_systs_dmsq.root";
143 
144  // find the best fit point in the parameter space of interest
145  TFile* anaslicefile = TFile::Open(anaslicename.c_str());
146 
147  std::string options_reversed = nh? "NH" : "IH";
148  options_reversed += lo? "LO" : "UO";
149 
150  std::string slice_shortname = "slice_dmsq_" + options_reversed;
151 
152  TH1* anaslice = (TH1F*) anaslicefile->Get(slice_shortname.c_str());
153  int best_bin = anaslice->GetMinimumBin();
154  double true_dmsq = anaslice->GetBinCenter(best_bin);
155 
156  std::string helpername =
157  helperupsname
158  + "/FCInputs/"
159  + "slices_FCInput_2019_joint_realData_both_systs_dmsq.root";
160 
161  TFile* fchelp = TFile::Open(helpername.c_str());
162 
163  // Get profiled parameters at best fit
164  TGraph* hssth23 = (TGraph*)fchelp->Get((options_reversed + "_SinSqTheta23").c_str());
165  TGraph *hdelta = (TGraph*)fchelp->Get((options_reversed + "_DeltaCPpi").c_str());
166  TGraph *hss2th13 = (TGraph*)fchelp->Get((options_reversed + "_SinSq2Theta13").c_str());
167 
168  //// double seeddmsq32 = hdmsq32->Eval(0.);
169  double seeddelta = hdelta->Eval(true_dmsq);
170  double seedssth23 = hssth23->Eval(true_dmsq);
171  double seedss2th13 = hss2th13->Eval(true_dmsq);
172 
173 
174  delete hssth23;
175  delete hdelta;
176  delete hss2th13;
177 
178  // Now, look for all the systematics
179  std::map<std::string,double> seedsyst;
180  for(const ISyst* syst :systs) {
181  TGraph* h = (TGraph*) fchelp->Get((options_reversed +"_"+syst->ShortName()).c_str());
182  if(!h){
183  std::cout << "Don't see a prof hist for " << options+"_"+syst->ShortName() << ". Continuing, but check your ups version." << std::endl;
184  continue;
185  }
186  double seedval = h->Eval(true_dmsq);
187 
188  seedsyst.insert(std::pair<std::string,double>(syst->ShortName(),seedval));
189  }
190 
191 
192  // Now everything is set up, we can start throwing FC mock experiments
193 
194  for(int i = 0; i < NPts; i++){
195  ResetOscCalcToDefault(calc);
196 
197 
198  // The variable you're plotting isn't a nuisance parameter, should
199  // be set to the trueX that you threw for this experiment.
200  // Other oscillation parameters are nuisance parameters and
201  // should be seeded at their best fit
202  kFitDeltaInPiUnits.SetValue(calc, seeddelta);
203  kFitSinSq2Theta13.SetValue(calc, seedss2th13);
204  kFitDmSq32.SetValue(calc, true_dmsq);
205  kFitSinSqTheta23LowerOctant->SetValue(calc, seedssth23);
206 
207  // Set syst shift - they're nuisance parameters, so set them
208  // to the best fit. Nue and Numu predictions are taught about
209  // slightly different sets of systematics, so we need to throw
210  // the predictions with different seeds
211  SystShifts seednue_fhc;
212  for(const ISyst *syst : snue_fhc){
213  if(seedsyst.find(syst->ShortName()) == seedsyst.end()) continue;
214  seednue_fhc.SetShift(syst, seedsyst[syst->ShortName()]);
215  }
216  SystShifts seednue_rhc;
217  for(const ISyst *syst : snue_rhc){
218  if(seedsyst.find(syst->ShortName()) ==seedsyst.end()) continue;
219  seednue_rhc.SetShift(syst, seedsyst[syst->ShortName()]);
220  }
221  SystShifts seednumu;
222  for(const ISyst *syst : snumu){
223  if(seedsyst.find(syst->ShortName()) ==seedsyst.end()) continue;
224  seednumu.SetShift(syst, seedsyst[syst->ShortName()]);
225  }
226 
227  // Make a mock data spectrum for nue
228  // use mock data + cosmic as predictions
229  double mock_integral_fhc = 0;
230  double mock_integral_rhc = 0;
231  assert(nue_preds.size()==2 && "Something is wrong with nue preds. Size !=2");
232  std::vector<Spectrum> mocknue;
233  SystShifts this_seednue;
234  for (int j = 0; j < (int) nue_preds.size(); j++){
235 
236  double thisPOT = j == 0? kAna2019FHCPOT : kAna2019RHCPOT;
237 
238  if(j==0) this_seednue = seednue_fhc;
239  else this_seednue = seednue_rhc;
240  Spectrum fakenue = nue_preds[j]->PredictSyst(calc,this_seednue);
241 
242  // Add in cosmic prediction here, make sure it gets Poisson fluctuated
243  fakenue += nue_cosmics_spectra[j];
244  mocknue.push_back(fakenue.MockData(thisPOT));
245  // Save this, for posterity's sake
246  if(j==0) mock_integral_fhc += mocknue[j].Integral(thisPOT);
247  if(j==1) mock_integral_rhc += mocknue[j].Integral(thisPOT);
248  }
249 
250  std::vector<Spectrum> mocknumu;
251  // Make a mock data spectrum for numu
252  assert(numu_cosmics_spectra.size()==8 && "Issue with N quantiles in cosmics");
253  assert(numu_preds.size()==8 && "Issue with N quantiles in predictions");
254  for (int j = 0; j < 8; j++){
255  double thisPOT = kAna2019FHCPOT;
256  if(j > 3) thisPOT = kAna2019RHCPOT;
257  Spectrum fakenm = numu_preds[j]->PredictSyst(calc,seednumu);
258  fakenm += numu_cosmics_spectra[j]; // Again, add cosmic spectra pre-fluctuation
259  mocknumu.push_back(fakenm.MockData(thisPOT)); // Fluctuate
260  }
261 
262 
263  // Set up experiment, nova nue + nova numu (4 quantiles) + PDG reactor
264  std::vector<const IExperiment*> expts;
265  std::vector<const IExperiment*> numu_expts;
266  // Nue experiments
267  for(int j = 0; j < 2; j++) {
268  expts.push_back(new SingleSampleExperiment(nue_preds[j], mocknue[j],
269  nue_cosmics[j].first,
270  nue_cosmics[j].second)); // Nue
271  }
272  for (int j = 0; j < 8; j++) {
273  expts.push_back(new SingleSampleExperiment(numu_preds[j], mocknumu[j],
274  numu_cosmics[j].first,
275  numu_cosmics[j].second));
276  numu_expts.push_back(new SingleSampleExperiment(numu_preds[j], mocknumu[j],
277  numu_cosmics[j].first,
278  numu_cosmics[j].second));
279 
280  }
281 
282  // Add reactor
283  expts.push_back( WorldReactorConstraint2017() );
284  numu_expts.push_back(WorldReactorConstraint2017());
285  MultiExperiment expt(expts);
286  MultiExperiment numu_expt(numu_expts);
287 
288  // Correlate your systs
289  // A bit tricky since nue and numu predictions know about a
290  // different list of systs, but there are functions to do this
291  // in joint_fit_2018_tools.h
292  expt.SetSystCorrelations(0, GetCorrelations(true,true));
293  expt.SetSystCorrelations(1, GetCorrelations(true, false));
294 
295  auto notfornumu = GetCorrelations(false, false);
296 
297  for(int j = 0; j < 8; j++) {
298  expt.SetSystCorrelations(j+2, notfornumu);
299  }
300 
301  // Finally, we get to do some FC
302  //////////////////////////////////////////////////////////////////
303  // Use numu only fit to find th23 and dmsq seeds for the joint fit
304  //////////////////////////////////////////////////////////////////
305 
307  SystShifts auxShifts = SystShifts::Nominal();
308  double maxmixing = 0.514;
309  Fitter fitnumu_only(&numu_expt, {kFitSinSqTheta23LowerOctant, &kFitDmSq32});
310 
311  std::cout << "\nFinding the seeds from numu only fit" << endl;
312  double minchi_numu = fitnumu_only.Fit(numu_calc, auxShifts,
313  {{&kFitDmSq32, {-2.35e-3}},
314  {kFitSinSqTheta23LowerOctant, {0.4}}},
315  {},
316  Fitter::kQuiet);
317  double pre_seed_th23 = kFitSinSqTheta23LowerOctant->GetValue(numu_calc);
318  double pre_seed_dmsq = kFitDmSq32.GetValue(numu_calc);
319 
320  double pre_seed_th23_LO = ( pre_seed_th23 > maxmixing ) ?
321  (2*maxmixing - pre_seed_th23) : pre_seed_th23;
322  double pre_seed_th23_UO = ( pre_seed_th23 > maxmixing ) ?
323  pre_seed_th23 : (2*maxmixing-pre_seed_th23);
324  if(pre_seed_th23_LO > 0.5) pre_seed_th23_LO = 0.45;
325 
326  // done getting pre seeds
327  //-----------------------------------------------------------------
328 
329  // Set up fitter for chi best
330  // make a vector of oscillation parameters that are our
331  // nuisance parameters
332  const IFitVar* th23_fit_var;
333  const IFitVar* dmsq_fit_var;
334  if(nh) dmsq_fit_var = &kFitDmSq32NormalHierarchy;
335  else dmsq_fit_var = &kFitDmSq32InvertedHierarchy;
336  if(lo) th23_fit_var = kFitSinSqTheta23LowerOctant;
337  else th23_fit_var = kFitSinSqTheta23UpperOctant;
338  std::vector<const IFitVar*> constrained_fitVars = {&kFitDeltaInPiUnits,
339  th23_fit_var,
341  dmsq_fit_var};
342 
343  Fitter constrained_fit(&expt, constrained_fitVars, systs);
344  SystShifts seedShifts = {};
345 
346  double bestdelta = 0;
347  double bestssth23 = 0;
348  double bestth13 = 0;
349  double bestdmsq = 0;
350  double bestchi = 1e10;
351  double cf_dmsq = 0;
352  double cf_delta = 0;
353  double cf_ssth23 = 0;
354  double cf_th13 = 0;
355 
356  std::vector <double> cf_delta_seeds = {0., 0.5, 1.0, 1.5};
357  std::vector <double> th23_seeds = {lo? pre_seed_th23_LO : pre_seed_th23_UO};
358  std::vector <double> dmsq_seeds = {nh? abs(pre_seed_dmsq) : -1 * abs(pre_seed_dmsq)};
359  std::map <const IFitVar*, std::vector<double>> cf_seedPts =
360  {{th23_fit_var, th23_seeds},
361  {&kFitDeltaInPiUnits, cf_delta_seeds},
362  {dmsq_fit_var, dmsq_seeds}};
363  std::cout << "Starting " << options << " fit ----->" << endl;
364  auxShifts.ResetToNominal();
365  double chi_cf = constrained_fit.Fit(calc,
366  auxShifts,
367  cf_seedPts,
368  {},
369  Fitter::kQuiet);
370  cf_dmsq = kFitDmSq32.GetValue(calc);
371  cf_delta = kFitDeltaInPiUnits.GetValue(calc);
372  cf_ssth23 = kFitSinSqTheta23LowerOctant->GetValue(calc);
373  cf_th13 = kFitSinSq2Theta13.GetValue(calc);
374 
375  std::vector <double> bf_delta_seeds = {0., 0.5, 1.0, 1.5};
376  std::vector <double> bf_ssth23_seeds = {pre_seed_th23_LO, pre_seed_th23_UO, maxmixing};
377  std::map <const IFitVar*, std::vector<double>> bf_seedPts =
378  {{&kFitSinSqTheta23, bf_ssth23_seeds},
379  {&kFitDeltaInPiUnits, bf_delta_seeds},
380  {&kFitDmSq32, {fabs(pre_seed_dmsq), -1*fabs(pre_seed_dmsq)}},
381  {&kFitSinSq2Theta13, {0.082}}};
382 
383  std::vector <const IFitVar*> bestVars =
385  Fitter bestfit(&expt, bestVars, systs);
386 
387  std::cout << "Starting the best fit ----->" << endl;
388  auxShifts.ResetToNominal();
389  double chi_bf = bestfit.Fit(calc,
390  auxShifts,
391  bf_seedPts,
392  {},
393  Fitter::kQuiet);
394  bestdmsq = kFitDmSq32.GetValue(calc);
395  bestssth23 = kFitSinSqTheta23.GetValue(calc);
396  bestdelta = kFitDeltaInPiUnits.GetValue(calc);
397  bestth13 = kFitSinSq2Theta13.GetValue(calc);
398 
399 
400  FCPoint pt(seeddelta, seedssth23, seedss2th13, true_dmsq,
401  pre_seed_th23, pre_seed_dmsq,
402  cf_delta, cf_ssth23, cf_th13, cf_dmsq,
403  chi_cf,
404  bestdelta, bestssth23, bestth13, bestdmsq,
405  chi_bf);
406 
407  fccol.AddPoint(pt);
408  unsigned int nfc_pts = fccol.NPoints();
409 
410  if(npts_flush != 0){
411  if(nfc_pts % npts_flush == 0){
412  std::cout << "Saving " + std::to_string(nfc_pts) +
413  " points to " << fcout << endl;
414  fccol.SaveToFile(fcout);
415  }
416  }
417  } // end loop over N points
418  fccol.SaveToFile(fcout);
419 }
420 
TSpline3 lo("lo", xlo, ylo, 12,"0")
Cuts and Vars for the 2020 FD DiF Study.
Definition: vars.h:6
void ResetOscCalcToDefault(osc::IOscCalcAdjustable *calc)
Reset calculator to default assumptions for all parameters.
Definition: Calcs.cxx:23
std::vector< SystGroupDef > systs
Definition: syst_header.h:385
fvar< T > fabs(const fvar< T > &x)
Definition: fabs.hpp:15
double GetValue(const osc::IOscCalcAdjustable *osc) const override
Definition: FitVars.cxx:141
double GetValue(const osc::IOscCalcAdjustable *osc) const override
const double kAna2019RHCLivetime
Definition: Exposures.h:227
double GetValue(const osc::IOscCalcAdjustable *osc) const override
Forward to wrapped Var&#39;s GetValue()
const FitDmSq32 kFitDmSq32
Definition: FitVars.cxx:18
Simple record of shifts applied to systematic parameters.
Definition: SystShifts.h:20
std::vector< const IPrediction * > GetNumuPredictions2019(const int nq=4, bool useSysts=true, std::string beam="fhc", bool GetFromUPS=false, ENu2018ExtrapType numuExtrap=kNuMu, bool minimizeMemory=false, bool NERSC=false)
void SetValue(osc::IOscCalcAdjustable *osc, double val) const override
Definition: FitVars.cxx:177
double GetValue(const osc::IOscCalcAdjustable *osc) const override
Definition: FitVars.cxx:171
const FitSinSqTheta23UpperOctant kFitSinSqTheta23UpperOctant
Definition: FitVars.cxx:16
void make_fc_mass_and_oct_nersc_2019(TString options, int NPts, int N, int jid, int npts_flush=0)
void AddPoint(const FCPoint &p)
Definition: FCCollection.h:17
void abs(TH1 *hist)
void SetValue(osc::IOscCalcAdjustable *osc, double val) const override
Forward to wrapped Var&#39;s SetValue()
double Integral(double exposure, double *err=0, EExposureType expotype=kPOT) const
Return total number of events scaled to pot.
Definition: Spectrum.cxx:333
void SetValue(osc::IOscCalcAdjustable *osc, double val) const override
Definition: FitVars.cxx:48
static SystShifts Nominal()
Definition: SystShifts.h:34
double GetValue(const osc::IOscCalcAdjustable *osc) const override
Definition: FitVars.cxx:42
osc::OscCalcDumb calc
osc::IOscCalcAdjustable * DefaultOscCalc()
Create a new calculator with default assumptions for all parameters.
Definition: Calcs.cxx:49
Encapsulate code to systematically shift a caf::SRProxy.
Definition: ISyst.h:14
const IPrediction * GetNuePrediction2019(std::string decomp, osc::IOscCalc *calc, bool corrSysts, std::string beam, bool isFakeData, bool GetFromUPS=false, bool minimizeMemory=false, bool NERSC=false)
Representation of a spectrum in any variable, with associated POT.
Definition: Spectrum.h:33
unsigned int NPoints() const
Definition: FCCollection.h:26
Represents the results of a single Feldman-Cousins pseudo-experiment.
Definition: FCPoint.h:8
std::vector< const ISyst * > getAllAna2018Systs(const EAnaType2018 ana, const bool smallgenie, const BeamType2018 beam, bool isFit)
expt
Definition: demo5.py:34
std::string getenv(std::string const &name)
const ReactorExperiment * WorldReactorConstraint2017()
Reactor constraint from PDG 2017.
const double j
Definition: BetheBloch.cxx:29
const double kAna2019FHCLivetime
Definition: Exposures.h:226
void SetValue(osc::IOscCalcAdjustable *osc, double val) const override
Definition: FitVars.cxx:147
std::vector< float > Spectrum
Definition: Constants.h:527
static bool isFHC
OStream cout
Definition: OStream.cxx:6
const double kAna2019RHCPOT
Definition: Exposures.h:224
Combine multiple component experiments.
::xsd::cxx::tree::string< char, simple_type > string
Definition: Database.h:154
Spectrum MockData(double pot, int idx=0) const
Mock data is FakeData with Poisson fluctuations applied.
Definition: Spectrum.cxx:384
std::vector< std::pair< TH1D *, double > > GetNumuCosmics2019(const int nq=4, std::string beam="fhc", bool GetFromUPS=false, bool NERSC=false)
const FitSinSqTheta23LowerOctant kFitSinSqTheta23LowerOctant
Definition: FitVars.cxx:17
void ResetToNominal()
Definition: SystShifts.cxx:141
const ConstrainedFitVarWithPrior fitSsqTh23_UniformPriorSsqTh23 & kFitSinSqTheta23
assert(nhit_max >=nhit_nbins)
const double kAna2019FHCPOT
Definition: Exposures.h:223
Interface definition for fittable variables.
Definition: IFitVar.h:16
std::vector< std::pair< const ISyst *, const ISyst * > > GetCorrelations(bool isNue, bool isFHC, bool ptExtrap)
void Format(TGraph *gr, int lcol, int lsty, int lwid, int mcol, int msty, double msiz)
Definition: Style.cxx:154
const FitSinSq2Theta13 kFitSinSq2Theta13
Definition: FitVars.cxx:13
std::string to_string(ModuleType mt)
Definition: ModuleType.h:32
void SaveToFile(const std::string &fname) const
const FitDmSq32InvertedHierarchy kFitDmSq32InvertedHierarchy
Definition: FitVars.cxx:23
const FitVarWithPrior fitDeltaInPiUnits_UniformPriordCP & kFitDeltaInPiUnits
const FitDmSq32NormalHierarchy kFitDmSq32NormalHierarchy
Definition: FitVars.cxx:20
std::vector< const ISyst * > GetJointFitSystematicList(bool corrSysts, bool nueExclusive=false, bool numuExclusive=false, bool isFHC=true, bool isRHC=true, bool intersection=true, bool ptExtrap=true)
void SetShift(const ISyst *syst, double shift, bool force=false)
Definition: SystShifts.cxx:78
void SetSystCorrelations(int idx, const std::vector< std::pair< const ISyst *, const ISyst * >> &corrs)
std::pair< TH1D *, double > GetNueCosmics2019(std::string beam, bool GetFromUPS=false, bool NERSC=false)
Compare a single data spectrum to the MC + cosmics expectation.
Collection of FCPoint. Serializable to/from a file.
Definition: FCCollection.h:12