Spectrum.hh

Deil Christoph, 05/02/2013 04:37 PM

Download (12.7 KB)

 
1
#ifndef FLUX_SPECTRUM_HH
2
#define FLUX_SPECTRUM_HH
3

    
4
#include <TH1D.h>
5
#include <TH2D.h>
6
#include <TString.h>
7

    
8
#include <sash/MonitorBase.hh>
9
#if defined(__CINT__) || defined(CINTOBJECT)
10
#include <sash/EnvelopeEntry.hh>
11
#include <sash/HESSArray.hh>
12
#endif
13

    
14
#include "SpectrumConstants.hh"
15
#include "SpectrumStats.hh"
16
#include "EnergyAxis.hh"
17

    
18
namespace Flux {
19

    
20
  typedef std::pair<int, int> BinRange;
21

    
22
  class FitFunction;
23

    
24
  /*! \class Flux::Spectrum
25
    \brief Stores count and exposure information in energy bins.
26
    \ingroup Flux
27
    \author Heidelberg team
28
    \todo Bkg -> Off in documentation
29

30
    Filled by SpectrumMaker, read by SpectrumFitter.
31

32
    use this to loop over bins:
33
    \code
34
    for(int bin=1; bin<=GetNbins(); bin++){ 
35
    ... 
36
    }
37
    \endcode
38

39
  */
40
  class Spectrum : public Sash::MonitorBase {
41
  public:
42

    
43
    //
44
    // Constructors and destructors
45
    //
46
    Spectrum(Sash::HESSArray&
47
#if defined(__CINT__) || defined(CINTOBJECT)
48
             = hessdummy
49
#endif
50
             , const char * name ="");
51
    
52
    Spectrum(const char *handleFunc,
53
             Sash::HESSArray&
54
#if defined(__CINT__) || defined(CINTOBJECT)
55
             = hessdummy
56
#endif
57
             , const char * name="");
58

    
59
    Spectrum(const Spectrum& other);
60
    Spectrum(const Spectrum& other, const char* newname);
61
    /** Clone this object.
62
        \todo Why doesn't the Sash::MonitorBase:Clone method actually clone an object?
63
    */
64
    virtual TObject* clone(const char* /*newname*/) const
65
    { return new Spectrum(*this/*,newname*/); }
66

    
67
    inline virtual ~Spectrum() {}
68
    virtual void Clear(Option_t *option="R");
69

    
70
    void Init();
71
    void InitBinning(double Emin = DEFAULT_EMIN,
72
                     double Emax = DEFAULT_EMAX, 
73
                     int nbinspdec = DEFAULT_BINS_PER_DEC, 
74
                     bool reinitialise = true);
75

    
76
    //
77
    // Operators
78
    //
79
    bool operator==(const Spectrum& rhs) const;
80
    bool operator!=(const Spectrum& rhs) const;
81
    void Add(const Spectrum& rhs);
82
    void operator+=(const Spectrum& rhs);
83
    Spectrum operator+(const Spectrum& rhs) const;
84

    
85
    //
86
    // GETMEMBERs
87
    //
88
    GETMEMBER(Moniker, TString);
89
    GETMEMBER(EnergyAxis, Flux::EnergyAxis);
90
    GETMEMBER(SafeBinRange, BinRange);
91
    GETMEMBER(Cells, std::vector<Flux::SpectrumStats>);
92
    GETMEMBER(EnergyResolution, TH2D);
93
    GETMEMBER(EnergyResolution2, TH2D);
94
    GETMEMBER(AreaTimeEnergyResolution, TH2D);
95
    GETMEMBER(AreaTimeEnergyResolution2, TH2D);
96

    
97
    //
98
    // Moniker ("title": Using Title conflicts with MonitorBase!)
99
    //
100
    void SetMoniker(TString title){ GetMoniker() = title; }
101
    void SetMoniker(const char* title){ GetMoniker() = TString(title); }
102

    
103
    //! Number of bins of axis.    
104
    int GetNbins() const {return GetEnergyAxis().GetNbins(); } 
105

    
106
    //
107
    // bin finders & helpers
108
    //
109
    void FindFineBinRange(const int bin, 
110
                          int& fine_bmin, int& fine_bmax);
111

    
112
    //
113
    // data finders & helpers
114
    //
115
    bool HasContentLess(const std::string field, const int bin, 
116
                        const double value = 0) const;
117
    bool AllHasContentLess(const std::string field, 
118
                           const double value = 0) const;
119
    void GetContentLessBinRange(const std::string field, const double value,
120
                                int &minbin, int &maxbin) const;
121
    void GetContentLessEnergyRange(const std::string field, const double value, 
122
                                   double &emin, double &emax) const;
123

    
124
    bool HasNoCounts(const int bin) const;
125
    bool AllHasNoCounts() const;
126
    void GetCountsBinRange(int &minbin, int &maxbin) const;
127
    void GetCountsEnergyRange(double &emin, double &emax) const;
128

    
129
    void GetMinLivetimeBinRange(double minLivetimeFraction, 
130
                                int &minbin, int &maxbin) const;
131
    void GetMinLivetimeEnergyRange(double minLivetimeFraction, 
132
                                   double &emin, double &emax) const;
133

    
134
    bool HasNoData(const int bin) const;
135
    bool AllHasNoData() const;
136
    void GetDataBinRange(int &minbin, int &maxbin) const;
137
    void GetDataEnergyRange(double &emin, double &emax) const;
138

    
139
    bool IsSafe(const double energy) const;
140
    void GetSafeEnergyRange(double &emin, double &emax) const;
141
    void SetSafeEnergyRange(const double emin, const double emax);
142

    
143
    // Clear methods
144
    void ClearBinsOutsideBinRange(const int bmin, const int bmax);
145
    void ClearBinsOutsideEnergyRange(const double emin, const double emax);
146
    void ClearBinsOutsideSafeRange();
147

    
148
    // Get range & clear methods
149
    void ClearAndGetDataEnergyRange(double &emin, double &emax);
150
    void ClearAndGetCountsEnergyRange(double &emin, double &emax);
151
    void ClearAndGetMinLivetimeEnergyRange(double minLivetimeFraction, 
152
                                           double &emin, double &emax);
153

    
154
    //
155
    // filling
156
    //
157
    void Fill(double energy, double recoarea, bool isOn = true);
158

    
159
    //
160
    // setting / getting
161
    //
162
    void SetBinContent(int bin, Flux::SpectrumStats stats);
163
    void SetBinContent(std::string field, int bin, double value);
164
    void SetBinContents(std::vector<Flux::SpectrumStats> points);
165
    void SetBinContents(std::string field, double value);
166
    void SetBinContents(std::string field, std::vector<double> values);
167
    void ClearBin(int bin);
168
    //! Reference to a bin that let's you get and set without making 
169
    //! local copies and two calls (get, set).
170
    Flux::SpectrumStats& GetCell(int bin) { return GetCells()[bin]; }
171
    std::vector<Flux::SpectrumStats> GetBinContents() const;
172
    Flux::SpectrumStats GetBinContent(int bin) const;
173
    std::vector<double> GetBinContents(const std::string field,
174
                                       const int bmin = 1, const int bmax = N_BINS) const;
175
    double GetBinContent(std::string field, int bin) const;
176
    int GetNDataBins() const;
177
    std::vector<double> GetEmptyVector() const;
178

    
179
    //
180
    // integration tools
181
    //
182
    Flux::SpectrumStats Integral() const;
183
    Flux::SpectrumStats Integral(int bmin, int bmax) const;
184
    //! Return integral (sum total) of all bin contents. 
185
    Flux::SpectrumStats GetTotalStats() const { return Integral(); }
186
    Flux::SpectrumStats GetTotalStats(int bmin, int bmax) const;
187
    Flux::SpectrumStats GetTotalStats(double emin, double emax) const;
188
    double Integral(std::string field) const;
189
    double Integral(std::string field, int bmax, int bmin) const;
190
    //! Return integral (sum total) of all bin contents of a field. 
191
    double GetStatTotal(std::string field) const { return Integral(field); }
192
    double GetStatTotal(std::string field, 
193
                        int bmin, int bmax) const;
194
    double GetStatTotal(std::string field, 
195
                        double emin, double emax) const;
196

    
197
    //
198
    // Expected Counts
199
    //
200
    double ExpectedCounts(int bin, 
201
                          FitFunction* model, bool integrate = DEFAULT_INTEGRATE) const;
202
    double ExpectedCounts(int bmin, int bmax,
203
                          FitFunction* model, bool integrate = DEFAULT_INTEGRATE) const;
204
    double ExpectedCounts(double emin, double emax, 
205
                          FitFunction* model, bool integrate = DEFAULT_INTEGRATE) const;
206
    double ExpectedCountsPL(int bin,
207
                            double gamma = DEFAULT_GAMMA, 
208
                            double norm = DEFAULT_NORM, 
209
                            double eref = DEFAULT_EREF, 
210
                            bool integrate = DEFAULT_INTEGRATE) const;
211
    double ExpectedCountsPL(int bmin, int bmax,
212
                            double gamma = DEFAULT_GAMMA, 
213
                            double norm = DEFAULT_NORM, 
214
                            double eref = DEFAULT_EREF, 
215
                            bool integrate = DEFAULT_INTEGRATE) const;
216
    double ExpectedCountsPL(double emin, double emax,
217
                            double gamma = DEFAULT_GAMMA, 
218
                            double norm = DEFAULT_NORM, 
219
                            double eref = DEFAULT_EREF, 
220
                            bool integrate = DEFAULT_INTEGRATE) const;
221

    
222
    //
223
    // Expected Hadrons
224
    //
225
    static double ExpectedHadron(int nOn, int nOff,
226
                                 double alpha, double expGamma);
227
    double ExpectedHadron(int bin, double expCounts=-1.) const;
228

    
229
    //
230
    // Flux, limits and sensitivity
231
    //
232
    void FluxAndLimits(double& flux, double& flux_down, double& flux_up,
233
                        double energy, const double emin, const double emax, FitFunction* model,
234
                        double cl = DEFAULT_CL, bool integrate = DEFAULT_INTEGRATE) const;
235
    void FluxAndLimitsPL(double& flux, double& flux_down, double& flux_up,
236
                        double energy, double emin, double emax, double gamma = DEFAULT_GAMMA,
237
                        double cl = DEFAULT_CL, bool integrate = DEFAULT_INTEGRATE) const;
238
    double Sensitivity(double energy, double emin, double emax,
239
                        FitFunction* model, double cl = DEFAULT_CL, bool integrate =
240
                                        DEFAULT_INTEGRATE) const;
241
    double SensitivityPL(double energy, double emin, double emax, double gamma =
242
                        DEFAULT_GAMMA, double cl = DEFAULT_CL,
243
                        bool integrate = DEFAULT_INTEGRATE) const;
244

    
245
    //
246
    // weighted quantities
247
    //
248
    // \todo Make weighting more flexible, e.g. via string argument.
249
    double WeightedMean(const std::vector<double> values, const int bmin = 0,
250
                        const int bmax = N_BINS, FitFunction* model = 0,
251
                        const bool weighted = true) const;
252
    double WeightedMean(const std::string field, const int bmin = 0,
253
                        const int bmax = N_BINS, FitFunction* model = 0,
254
                        const bool weighted = true) const;
255
    double WeightedMeanEnergy(int bmin = 0, int bmax = N_BINS,
256
                              FitFunction* model = 0, bool weighted = true) const;
257

    
258
    //
259
    // rebinning 
260
    //
261
    static void ListRebinAlgos();
262
    Spectrum * Rebin(const char* algorithm = DEFAULT_REBIN_ALGO.c_str(),
263
                     double parameter = DEFAULT_REBIN_PARAM,
264
                     const char* newname = "");
265
    Spectrum * PairBinsInRange(int bmin, int bmax, const char* newname = "");
266
    Spectrum * RegroupBins(int Ngroup = 1, const char* newname = "");
267

    
268
    //
269
    // Fitting
270
    //
271
    int FitFlux(FitFunction* f1,  
272
                Option_t* algorithm, Option_t* option);
273

    
274
    //
275
    // histograms
276
    //
277
    TH1D * MakeEmptyHist(std::string name, std::string title = "") const;
278
    TH1D * MakeHist(std::string field, std::string name, 
279
                    std::string title = "") const;
280

    
281
    //
282
    // plotting
283
    //
284
    void DiagnosticsPlots();
285
    TCanvas * StatisticsPlots();
286
    TCanvas * EnergyResolutionPlots();
287
    void Draw(Option_t* opt = "");
288

    
289
    //
290
    // printing
291
    //
292
    void DoPrint(std::ostream& os, Option_t* opt = "") const;
293
    void Print(Option_t* opt = "") const; // *MENU*
294
    void print(std::ostream&) const;
295
    void print_TotalStatsForBins(std::ostream& os, int bmin = NONE,
296
                                 int bmax = NONE, bool verbose = true) const;
297
    void print_TotalStats(std::ostream& os, double Emin = DEFAULT_EMIN,
298
                          double Emax = DEFAULT_EMAX, bool verbose = true) const;
299
    void print_Table(std::ostream& os, Option_t* opt = "") const;
300
    void print_CSV_columns(std::ostream& os) const;
301
    void print_CSV(std::ostream& os) const;
302
    void print_SafeRange(std::ostream& os) const;
303

    
304
    //
305
    // Convenience static functions
306
    //
307
    static Spectrum* GetEmptySpectrum(const char* name = "");
308
    static Spectrum* GetSpectrumFromFile(const char* filename,
309
                                         bool filelist = false,
310
                                         std::string specname = "");
311
    static Spectrum* FindSpectrum(std::string specname = "");
312
    static Spectrum* GetSpectrumNoHAP(const char* filename = "spectrum.root",
313
                                      const char* specname = "Spectrum");
314

    
315
  private : 
316
    // \todo Why do we need a moniker? Can't we simply use GetName()?
317
    TString fMoniker;              //< A moniker ("title")
318
    Flux::EnergyAxis fEnergyAxis;  //< The energy axis of this spectrum object
319
    BinRange fSafeBinRange;        //< Bin range within the safe energy thresholds.
320

    
321
    std::vector<Flux::SpectrumStats> fCells;  //< vector of statistics (counts and exposure) for each energy bin
322

    
323
    // Q: Why four resolutions and not one?
324
    // A: Because we are investigating / debugging this at the moment.
325
    //    EnergyResolution is only meaningful for each run, it is only used for debugging
326
    //    AreaTimeEnergyResolution is meaningful for each run and total, it is used for spectral fitting
327
    //    Version 1 or 2 are different formats to do the same thing.
328
    //    Both have advantages and disadvantages.
329
    //    You should get consistent results if you use either one.
330
    TH2D fEnergyResolution;  //< Energy resolution format 1 with y = (E_reco - E) / E
331
    TH2D fEnergyResolution2;  //< Energy resolution format 2 with y = log(E_reco)
332
    TH2D fAreaTimeEnergyResolution;  //< Area x Time x Energy resolution format 1 with y = (E_reco - E) / E
333
    TH2D fAreaTimeEnergyResolution2;  //< Area x Time x Energy resolution format 2 with y = log(E_reco)
334

    
335
    // Helper functions
336
    static bool getFromFile(const char* filename, Spectrum **spec, std::string specname = "");
337
    static bool getFromFiles(const char* filename, Spectrum **spec);
338

    
339
    ClassDef(Flux::Spectrum, 9);
340
    // 2 -> 3: new flux module
341
    // 3 -> 4: add fSafeEnergyRange and remove
342
    // fUBEnergyOn, fUBEffAreaOn, fUBEnergyOff, fUBEffAreaOff
343
    // 4 -> 5: add TTree* fEvents
344
    // 5 -> 6: change fSafeEnergyRange to fSafeBinRange to avoid off by one errors
345
    // 6 -> 7: replace TTree with vector and make the code simpler.
346
    // 7 -> 8: major clean-up
347
    // 8 -> 9: finally, more energy resolution histos!
348
  };
349

    
350

    
351
}// end namespace flux
352

    
353
std::ostream& operator<<(std::ostream& os, const Flux::Spectrum& spectrum);
354

    
355
#endif