hpstr
The Heavy Photon Search Toolkit for Reconstruction (hpstr) provides an interface to physics data from the HPS experiment saved in the LCIO format and converts it into an ROOT based format.
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
BlFitHistos.cxx
Go to the documentation of this file.
1#include "BlFitHistos.h"
2#include <sstream>
3
4//Globally used fit window
5double fitmin;
6double fitmax;
7
9 //ModuleMapper used to translate between hw and sw names
10 mmapper_ = new ModuleMapper(year);
11
12 //Global svtIDMap built in ModuleMapper. Required to output baselines in database format
14}
15
18
19void BlFitHistos::getHistosFromFile(TFile* inFile, std::string layer){
20
21 for (auto hist: _h_configs.items()) {
22 std::string h_name = hist.key();
23 std::cout << "h_name: " << h_name << std::endl;
24
25 //Check for substring "L<layer>" in input histograms
26 std::size_t found = (h_name).find_first_of("_");
27 std::string h_layer = h_name.substr(0,found);
28 if (h_layer.find(layer) == std::string::npos)
29 continue;
30 if(debug_)
31 std::cout << "found layer " << layer << " in " << h_name << std::endl;
32
33 found = (h_name).find_last_of("_");
34 std::string sample = h_name.substr(found+1);
35 if(debug_)
36 std::cout << "time sample is " << sample << std::endl;
37
38 TIter next(inFile->GetListOfKeys());
39 TKey *key;
40 bool got = false;
41 std::string histoname;
42 while ((key = (TKey*)next())) {
43 std::string name(key->GetName());
44 if(debug_)
45 std::cout << "Checking if histokey " << name << " matches " << h_name << std::endl;
46 if (name.find(h_name) != std::string::npos){
47 TH2F *hh = (TH2F*) inFile-> Get(key->GetName());
48 histos2d[key->GetName()] = hh;
49 std::cout << "Adding histo " << key->GetName() << " to list of histos to fit" << std::endl;
50 }
51 }
52 }
53}
54
55void BlFitHistos::backwardsIterChi2Fit(TH1D* hist, double xmin, double xmax){
56
57
58 TF1 *fit = new TF1("fit", "gaus", xmin, xmax);
59 hist->Fit("fit","ORQN","");
60 double fitMean = fit->GetParameter(1);
61 double fitSig = fit->GetParameter(2);
62 double fitnorm = fit->GetParameter(0);
63 double fitchi2 = fit->GetChisquare();
64 double fitndf = fit->GetNDF();
65
66 double iterChi2 = fitchi2/fitndf;
67 double newChi2 = 0;
68 double stepx = hist->GetBinWidth(0);
69 double iterxmax = xmax;
70 int i = 0;
71
72 if(debug_){
73 std::cout << "Initial xmin and xmax " << xmin << " | " << xmax << std::endl;
74 std::cout << "Initial mean and sigma " << fitMean << " | " << fitSig << std::endl;
75 std::cout << "Initial Chi2: " << iterChi2 << std::endl;
76 }
77 while((iterxmax > xmin + 10*stepx) && (newChi2 < iterChi2*0.98)){
78
79 xmax = iterxmax;
80 iterxmax = iterxmax - stepx;
81 if(debug_)
82 std::cout << "Iterating xmax to: " << iterxmax << std::endl;
83
84 if(i > 0){
85 iterChi2 = newChi2;
86 }
87
88 fit->SetRange(xmin,iterxmax);
89 hist->Fit("fit","ORQN","");
90 fitMean = fit->GetParameter(1);
91 fitSig = fit->GetParameter(2);
92 fitnorm = fit->GetParameter(0);
93 fitchi2 = fit->GetChisquare();
94 fitndf = fit->GetNDF();
95
96 if(fitMean > iterxmax){
97 break;
98 }
99
100 if(fitndf > 0){
101 newChi2 = fitchi2/fitndf;
102 if(debug_){
103 std::cout << "iter" << i << " newChi2 = " << newChi2 << std::endl;
104 }
105 }
106 else{
107 continue;
108 }
109 i++;
110 }
111
112 fitmax = xmax;
113}
114
115void BlFitHistos::iterativeGausFit(TH1D* hist, double min, double max, double sigmaRange, double hardminimum, double hardmaximum) {
116
117 double minthresh = hardminimum;
118 double threshold = hardmaximum;
119 //perform single Gaus fit across full range of histo
120 if (min < 0.0 )
121 min = hist->GetBinLowEdge(hist->FindFirstBinAbove(0.0,1));
122
123 if (max < 0.0 )
124 max = hist->GetBinLowEdge(hist->FindLastBinAbove(0.0,1));
125
126 //Initial fit to establish rough mean and sigma
127 if (debug_)
128 std::cout << "initial min: " << min << " | initial max: " << max << std::endl;
129
130 TF1 *fitA = new TF1("fitA", "gaus", min, max);
131 hist->Fit("fitA","ORQN","");
132 double fitAMean = fitA->GetParameter(1);
133 double fitASig = fitA->GetParameter(2);
134
135 delete fitA;
136
137 if(fitAMean + fitASig*sigmaRange < threshold)
138 max = fitAMean + fitASig*sigmaRange;
139 if(fitAMean - fitASig*sigmaRange > minthresh)
140 min = fitAMean - fitASig*sigmaRange;
141
142 if (debug_){
143 std::cout << "meanA " << fitAMean << " | sigmaA: " << fitASig << std::endl;
144 std::cout << "minA: " << min << " | maxA: " << max << std::endl;
145 }
146
147 //Fit second time using updated min and max
148 TF1 *fitB = new TF1("fitB", "gaus", min, max);
149 hist->Fit("fitB","ORQN","");
150 double fitMean = fitB->GetParameter(1);
151 double fitSig = fitB->GetParameter(2);
152 if (debug_)
153 std::cout << "meanB " << fitMean << " | sigmaB: " << fitSig << std::endl;
154
155 if(fitMean + fitSig*sigmaRange < threshold)
156 max = fitMean + fitSig*sigmaRange;
157 if(fitMean - fitSig*sigmaRange > minthresh)
158 min = fitMean - fitSig*sigmaRange;
159
160 if (debug_)
161 std::cout << "minB: " << min << " | maxB: " << max << std::endl;
162
163 TF1 *fit = new TF1("fit", "gaus", min, max);
164 hist->Fit("fit","ORQN","");
165
166 double newFitSig = 99999;
167 double newFitMean = 99999;
168 int i = 0;
169 while (std::abs(fitSig - newFitSig) > 0.0005 || std::abs(fitMean - newFitMean) > 0.0005) {
170 double itermax = max;
171 double itermin = min;
172
173 if(i > 0){
174 fitMean = newFitMean;
175 fitSig = newFitSig;
176 }
177
178 if(fitMean + fitSig*sigmaRange < threshold)
179 max = fitMean + fitSig*sigmaRange;
180 if(fitMean - fitSig*sigmaRange > minthresh)
181 min = fitMean - fitSig*sigmaRange;
182 fit->SetRange(min,max);
183 hist->Fit("fit","ORQN","");
184
185 newFitMean = fit->GetParameter(1);
186 newFitSig = fit->GetParameter(2);
187
188 if(i > 20)
189 break;
190 i = i + 1;
191 }
192
193 fitmin = min;
194 fitmax = max;
195}
196
197void BlFitHistos::fit2DHistoChannelBaselines(std::map<std::string,TH2F*> histos2d, int rebin_, int minStats_, int deadRMS_, std::string thresholdsFileIn_, FlatTupleMaker* flat_tuple_) {
198
199 //Get half module string names
200 std::vector<std::string> halfmodule_strings;
201 mmapper_->getStrings(halfmodule_strings);
202
203 //Build FebHybAPV thresholds map in modulemapper
205 //Read apv channel thresholds from file for closest run
206 mmapper_->ReadThresholdsFile(thresholdsFileIn_);
207
208 //Loop over rawsvthit 2D histograms, one for each selected halfmodule
209 for(std::map<std::string, TH2F*>::iterator it = histos2d.begin(); it != histos2d.end(); ++it)
210 {
211 gDirectory->cd("/");
212 TH2F* halfmodule_hh = it->second;
213 halfmodule_hh->RebinY(rebin_);
214 halfmodule_hh->Write();
215 std::string hh_name = it->first;
216
217 //get the hardware tag for this F<n>H<M>. Required for svtid mapping
218 std::string hwTag;
219
220 for(std::vector<std::string>::iterator it = halfmodule_strings.begin(); it != halfmodule_strings.end(); ++it){
221 if(hh_name.find(*it) != std::string::npos){
222 hwTag = mmapper_->getHwFromString(*it);
223 if(debug_)
224 std::cout << "hwTag for " << hh_name << " is " << hwTag << std::endl;
225 break;
226 }
227 }
228
229 //Feb and Hybrid numbers
230 std::string feb = (hwTag.substr(1,1));
231 std::string hyb = (hwTag.substr(3,1));
232 gDirectory->mkdir(("F"+feb+"H"+hyb).c_str())->cd();
233 //Perform fitting procedure over all channels on a sensor
234 for(int cc=0; cc < 640 ; ++cc)
235 {
236 if(debug_){
237 std::cout << hh_name << " " << cc << std::endl;
238 std::cout << "CHANNEL " << cc << std::endl;
239 }
240 if (cc%100 == 0)
241 std::cout << "CHANNEL " << cc << std::endl;
242
243 //get the global svt_id for channel
244 int svt_id = mmapper_->getSvtIDFromHWChannel(cc, hwTag, svtIDMap);
245 if(debug_)
246 std::cout << "Global SVT ID: " << svt_id << std::endl;
247
248 //Feb 0-1 have max_channel = 512.
249 //svt_id = 99999 means max_channel reached. Skip cc > 512
250 if(svt_id == 99999)
251 continue;
252
253 //load apv channel readout threshold value from run_thresholds.dat file
254 double threshold = (double) mmapper_->getThresholdValue(feb, hyb, cc);
255 if(debug_)
256 std::cout << "THRESHOLD F" <<feb << "H" <<hyb << "channel " << cc << ": " << threshold << std::endl;
257
258 //Set Channel and Hybrid information and paramaters in the flat tuple
259 flat_tuple_->setVariableValue("halfmodule_hh", hh_name);
260 flat_tuple_->setVariableValue("channel", cc);
261 flat_tuple_->setVariableValue("svt_id", svt_id);
262 flat_tuple_->setVariableValue("minStats", (double)minStats_);
263 flat_tuple_->setVariableValue("rebin", (double)rebin_);
264
265 //Get YProjection (1D Channel Histo) from 2D Histogram
266 TH1D* projy_h = halfmodule_hh->ProjectionY(Form("%s_proY_ch%i",hh_name.c_str(),cc),
267 cc+1,cc+1,"e");
268 projy_h->Smooth(1);
269 projy_h->SetTitle(Form("%s_proY_ch%i",hh_name.c_str(),cc));
270
271 //Check number of entries and RMS of channel
272 flat_tuple_->setVariableValue("n_entries", projy_h->GetEntries());
273 double chRMS = projy_h->GetRMS();
274 flat_tuple_->setVariableValue("rms", chRMS);
275
276 //If the channel RMS is under some threshold, flag it as "dead"
277 if(chRMS < deadRMS_ || projy_h->GetEntries() == 0)
278 flat_tuple_->setVariableValue("dead",1.0);
279
280 //Fit window max set by threshold value loaded from file
281 //Minum value of x set to first bin with fraction of maximum value
282 double maxbin = projy_h->GetBinContent(projy_h->GetMaximumBin());
283 //double frac = 0.15;
284 double frac = 0.2;
285 int minbin = projy_h->FindFirstBinAbove((double)frac*maxbin,1);
286 double minx = projy_h->GetBinLowEdge(minbin);
287 flat_tuple_->setVariableValue("minthreshold",minx);
288 double binwidth = projy_h->GetBinWidth(minbin);
289 double minxVal = projy_h->GetBinContent(minbin);
290
291 double maxx = threshold - binwidth*1;
292 flat_tuple_->setVariableValue("threshold",maxx);
293
294 //If channel does not have the minimum statistics required, set all variables to -9999.9
295 //and skip the fit procedure on this channel
296 if (minbin == -1 || projy_h->GetEntries() < minStats_ )
297 {
298 flat_tuple_->setVariableValue("BlFitMean", -9999.9);
299 flat_tuple_->setVariableValue("BlFitSigma", -9999.9);
300 flat_tuple_->setVariableValue("BlFitNorm", -9999.9);
301 flat_tuple_->setVariableValue("BlFitRangeLower", -9999.9);
302 flat_tuple_->setVariableValue("BlFitRangeUpper", -9999.9);
303 flat_tuple_->setVariableValue("BlFitChi2", -9999.9);
304 flat_tuple_->setVariableValue("BlFitNdf", -9999.9);
305 flat_tuple_->setVariableValue("lowdaq", 0.0);
306 flat_tuple_->setVariableValue("suplowDaq", 0.0);
307 flat_tuple_->setVariableValue("lowStats",1.0);
308 flat_tuple_->setVariableValue("badfit",0.0);
309 flat_tuple_->fill();
310 continue;
311 }
312 flat_tuple_->setVariableValue("lowStats",0.0);
313
314 fitmin = minx;
315 fitmax = maxx;
316 iterativeGausFit(projy_h, fitmin, fitmax, 1, minx, threshold);
318
319 TF1 *fit = new TF1("fit", "gaus", fitmin, fitmax);
320 projy_h->Fit("fit","ORQ","");
321 double fitmean = fit->GetParameter(1);
322 double fitsigma = fit->GetParameter(2);
323 double fitnorm = fit->GetParameter(0);
324 double fitchi2 = fit->GetChisquare();
325 double fitndf = fit->GetNDF();
326
327 if(debug_){
328 std::cout << "Fit Mean: " << fitmean << std::endl;
329 std::cout << "Fit sigma: " << fitsigma << std::endl;
330 std::cout << "Fit norm: " << fitnorm << std::endl;
331 std::cout << "Fit min: " << fitmin << std::endl;
332 std::cout << "Fit max: " << fitmax << std::endl;
333 }
334 projy_h->Draw();
335 projy_h->Write();
336 delete fit;
337
338 //If fit mean is less than fitmax, channel does not have full gaussian shape.
339 //Mark channel as super_low_Daq
340 bool badfit = false;
341 bool suplowDaq = false;
342 if(fitmean <= fitmin || fitmin > fitmax){
343 badfit = true;
344 if(debug_)
345 std::cout << "bad fit!" << std::endl;
346 }
347
348 if(!badfit && fitmean >= fitmax){
349 suplowDaq = true;
350 if(debug_)
351 std::cout << "Super low Daq threshold" << std::endl;
352 }
353
354 bool lowdaq = false;
355 if(!badfit && !suplowDaq){
356 //Check channel to see if it has a low DAQ threshold, where landau shape interferes with baseline
357 //If maxbin occurs outside of fit mean by NSigma...flag
358 double maxbinx = projy_h->GetBinLowEdge(projy_h->GetMaximumBin());
359 if ((std::abs(maxbinx - fitmean) > fitsigma)){
360 lowdaq = true;
361 }
362 //If fitmean > fitmax or fitmean < fitmin...flag
363 if(fitmean > fitmax || fitmean < fitmin)
364 lowdaq = true;
365
366 //If bins after fitmax averaged to the right are greater than the fitmean...flag
367 double maxavg = 0;
368 int fitmaxbin = projy_h->FindBin(fitmax);
369 for (int i = 1; i < 6; i++){
370 maxavg = maxavg + projy_h->GetBinContent(fitmaxbin + i);
371 }
372 maxavg = maxavg/5;
373 if(maxavg > fitnorm)
374 lowdaq = true;
375 }
376
377 if(debug_)
378 if(lowdaq)
379 std::cout << "Low daq threshold" << std::endl;
380
381 flat_tuple_->setVariableValue("lowdaq", lowdaq);
382 flat_tuple_->setVariableValue("suplowDaq", suplowDaq);
383 flat_tuple_->setVariableValue("badfit", badfit);
384 flat_tuple_->setVariableValue("BlFitMean", fitmean);
385 flat_tuple_->setVariableValue("BlFitSigma", fitsigma);
386 flat_tuple_->setVariableValue("BlFitNorm", fitnorm);
387 flat_tuple_->setVariableValue("BlFitChi2", fitchi2);
388 flat_tuple_->setVariableValue("BlFitNdf", fitndf);
389 flat_tuple_->setVariableValue("BlFitRangeLower", fitmin);
390 flat_tuple_->setVariableValue("BlFitRangeUpper", fitmax);
391
392 flat_tuple_->fill();
393
394 delete projy_h;
395 continue;
396
397 }
398 }
399}
double fitmin
double fitmax
std::map< std::string, TH2F * > histos2d
description
void getHistosFromFile(TFile *inFile, std::string layer="")
Get the Histos From File object.
BlFitHistos(int year)
std::map< std::string, std::map< int, int > > svtIDMap
description
ModuleMapper * mmapper_
description
void fit2DHistoChannelBaselines(std::map< std::string, TH2F * > histos2d, int rebin_, int minStats_, int deadRMS_, std::string thresholdsFileIn_, FlatTupleMaker *flat_tuple_)
description
bool debug_
description
void backwardsIterChi2Fit(TH1D *hist, double xmin, double xmax)
description
void iterativeGausFit(TH1D *hist, double min, double max, double sigmaRange, double hardminimum, double hardmaximum)
description
description
void setVariableValue(std::string variable_name, double value)
description
void fill()
description
json _h_configs
description
void getStrings(std::vector< std::string > &strings)
Get list of string modules.
std::string getHwFromString(const std::string &key)
Get the Hw From String.
void ReadThresholdsFile(std::string filename)
Used to read svt channel DAQ threshold values from daq thresholds file.
int getSvtIDFromHWChannel(int channel, std::string hwTag, std::map< std::string, std::map< int, int > > svtid_map)
Return global svt id for channel by providing local channel number and F<n>H<m> of channel.
int getThresholdValue(std::string feb, std::string hybrid, int channel)
Get channel DAQ threshold.
std::map< std::string, std::map< int, int > > buildChannelSvtIDMap()
Build global svt id map for all FebHybrid combinations.
void buildApvChannelMap()
Used to generate apv channel map and read in thresholds from database.