ATLAS Offline Software
Loading...
Searching...
No Matches
CaloHadDMCoeffMinim.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
5//-----------------------------------------------------------------------
6// File and Version Information:
7//
8// Description: see CaloHadDMCoeffMinim.h
9//
10// Environment:
11// Software developed for the ATLAS Detector at CERN LHC
12//
13// Author List:
14// Gennady Pospelov
15//
16//-----------------------------------------------------------------------
18#include "AthenaKernel/Units.h"
26#include <cmath>
27#include <format>
28#include <iostream>
29
30#include <CLHEP/Vector/LorentzVector.h>
31
32#include "TROOT.h"
33#include "TStyle.h"
34#include "TError.h"
35#include "TFile.h"
36#include "TChain.h"
37#include "TH1.h"
38#include "TF1.h"
39#include "TProfile.h"
40#include "TH2F.h"
41#include "TCanvas.h"
42#include "TPad.h"
43#include "TText.h"
44#include "TMinuit.h"
45#include "TVirtualFitter.h"
46#include "TLatex.h"
47#include "TGraphErrors.h"
48#include "TBenchmark.h"
49
50
51using CLHEP::HepLorentzVector;
52using Athena::Units::MeV;
53using Athena::Units::GeV;
54
55
57
58
60 m_data (nullptr),
62 m_HadDMCoeff (nullptr),
63 m_isTestbeam(false),
64 m_nstep_fcn(0),
65 m_iBinGlob(0),
66 m_engClusMin(1.*GeV),
67 m_engBeamMin(1.*GeV),
68 m_area_index(0),
71{
72 // list of parameters available for minimization
73 m_minimPars.emplace_back("PreSamplerB", 1.0, 0.5, 0.99, 20.0 );
74 m_minimPars.emplace_back("EMB1", 1.0, 0.5, 0.99, 20.0 );
75 m_minimPars.emplace_back("EMB2", 1.0, 0.5, 0.99, 20.0 );
76 m_minimPars.emplace_back("EMB3", 1.0, 0.5, 0.99, 20.0 );
77 m_minimPars.emplace_back("PreSamplerE", 1.0, 0.5, 0.99, 20.0 );
78 m_minimPars.emplace_back("EME1", 1.0, 0.5, 0.99, 20.0 );
79 m_minimPars.emplace_back("EME2", 1.0, 0.5, 0.99, 2000.0 ); // 6
80 m_minimPars.emplace_back("EME3", 1.0, 0.5, 0.99, 2000.0 );
81 m_minimPars.emplace_back("HEC0", 1.0, 0.5, 0.99, 2000.0 );
82 m_minimPars.emplace_back("HEC1", 1.0, 0.5, 0.99, 2000.0 );
83 m_minimPars.emplace_back("HEC2", 1.0, 0.5, 0.99, 20.0 );
84 m_minimPars.emplace_back("HEC3", 1.0, 0.5, 0.99, 20.0 );
85 m_minimPars.emplace_back("TileBar0", 1.0, 0.5, 0.99, 20.0 );
86 m_minimPars.emplace_back("TileBar1", 1.0, 0.5, 0.99, 20.0 );
87 m_minimPars.emplace_back("TileBar2", 1.0, 0.5, 0.99, 20.0 );
88 m_minimPars.emplace_back("TileGap1", 1.0, 0.5, 0.99, 20.0 );
89 m_minimPars.emplace_back("TileGap2", 1.0, 0.5, 0.99, 20.0 );
90 m_minimPars.emplace_back("TileGap3", 1.0, 0.5, 0.99, 20.0 );
91 m_minimPars.emplace_back("TileExt0", 1.0, 0.5, 0.99, 20.0 );
92 m_minimPars.emplace_back("TileExt1", 1.0, 0.5, 0.99, 20.0 );
93 m_minimPars.emplace_back("TileExt2", 1.0, 0.5, 0.99, 20.0 );
94 m_minimPars.emplace_back("FCAL0", 1.0, 0.01, 0.99, 3.0 );
95 m_minimPars.emplace_back("FCAL1", 1.0, 0.01, 0.99, 3.0 );
96 m_minimPars.emplace_back("FCAL2", 1.0, 0.5, 0.99, 20.0 );
97 m_minimPars.emplace_back("MINIFCAL0", 1.0, 0.5, 0.99, 20.0 );
98 m_minimPars.emplace_back("MINIFCAL1", 1.0, 0.5, 0.99, 20.0 );
99 m_minimPars.emplace_back("MINIFCAL2", 1.0, 0.5, 0.99, 20.0 );
100 m_minimPars.emplace_back("MINIFCAL3", 1.0, 0.5, 0.99, 20.0 );
101 m_minimPars.emplace_back("CONST", 0.0, 10., 0.0, 5000. );
102
103 m_distance_cut = 1.5;
104
105 s_instance = this;
106}
107
108
112
113
114/* ****************************************************************************
115Runs minimization to get new sampling weights for optimum reconstruction of
116dead material before FCAL
117**************************************************************************** */
118CaloLocalHadCoeff * CaloHadDMCoeffMinim::process(CaloHadDMCoeffData *myData, CaloLocalHadCoeff *myHadDMCoeff, bool isSingleParticle, bool tbflag)
119{
120 m_isTestbeam = tbflag;
121
122 std::cout << std::endl;
123 std::cout << std::endl;
124 std::cout << "--- CaloHadDMCoeffMinim::process() --- " << std::endl;
125
126 if(m_isTestbeam) std::cout << "Processing TESTBEAM data" << std::endl;
127
128 if ( m_NormalizationType == "Lin" ) {
129 std::cout << "Using weighting proportional to E_calib" << std::endl;
131 } else if ( m_NormalizationType == "Log" ) {
132 std::cout << "Using weighting proportional to log(E_calib)" << std::endl;
134 } else if ( m_NormalizationType == "NClus" ) {
135 std::cout << "Using weighting proportional to 1/N_Clus_E_calib>0" << std::endl;
137 } else {
138 std::cout << "Using constant weighting" << std::endl;
140 }
141
142 m_data = myData; // pointer to TChain data
143 m_HadDMCoeff = myHadDMCoeff; // pointer to the initial coefficients
144
145 m_data->fChain->SetBranchStatus("*",0);
146 m_data->fChain->SetBranchStatus("mc_ener",1);
147 m_data->fChain->SetBranchStatus("mc_eta",1);
148 m_data->fChain->SetBranchStatus("mc_phi",1);
149 m_data->fChain->SetBranchStatus("mc_pdg",1);
150 m_data->fChain->SetBranchStatus("ncls",1);
151 m_data->fChain->SetBranchStatus("cls_eta",1);
152 m_data->fChain->SetBranchStatus("cls_phi",1);
153 m_data->fChain->SetBranchStatus("cls_lambda",1);
154 m_data->fChain->SetBranchStatus("cls_calib_emfrac",1);
155 m_data->fChain->SetBranchStatus("cls_engcalib",1);
156 m_data->fChain->SetBranchStatus("engClusSumCalib",1);
157 m_data->fChain->SetBranchStatus("cls_ener_unw",1);
158 m_data->fChain->SetBranchStatus("narea",1);
159 //m_data->fChain->SetBranchStatus("cls_eprep",1);
160 m_data->fChain->SetBranchStatus("cls_dmener",1);
161 m_data->fChain->SetBranchStatus("cls_smpener_unw",1);
162 //m_data->fChain->SetBranchStatus("m_cls_oocener",1);
163 //m_data->fChain->SetBranchStatus("cls_engcalibpres",1);
164
165 if( !m_data->GetEntries() ) {
166 std::cout << "CaloHadDMCoeffMinim::process -> Error! No entries in DeadMaterialTree." << std::endl;
167 return nullptr;
168 }
169
170 m_data->GetEntry(0);
171 if(m_data->m_narea != m_HadDMCoeff->getSizeAreaSet()) {
172 std::cout << "CaloHadDMCoeffFit::process -> Error! Different numbers of areas for DM definition" << std::endl;
173 std::cout << "m_data->m_narea:" << m_data->m_narea << " m_HadDMCoeff->getSizeAreaSet():" << m_HadDMCoeff->getSizeAreaSet() << std::endl;
174 return nullptr;
175 }
176
177 // We are going to receive dead material correction coefficients only for one
178 // dead material area corresponding 'ENG_CALIB_DEAD_FCAL' calibration moment
179 const CaloLocalHadCoeff::LocalHadArea *dmArea = m_HadDMHelper->getAreaFromName(m_HadDMCoeff, "ENG_CALIB_DEAD_FCAL", m_area_index);
180 std::cout << "CaloHadDMCoeffMinim::process() -> Info. Preparing for '" << dmArea->getTitle() << " index:" << m_area_index
181 << " npars:" << dmArea->getNpars() << ", for minimization:" << m_validNames.size() << std::endl;
182 if( (int)m_minimPars.size() != dmArea->getNpars()) {
183 std::cout << "CaloHadDMCoeffMinim::process() -> FATAL! Number of parameters for dead material area is different from number of mininuit pars." << std::endl;
184 exit(0);
185 }
186
187 /* ********************************************
188 Let's fill sample with data to calculate chi2
189 1. loop through data sample
190 3. filling minimisation sample with clusters having appropriate iBin
191 ********************************************* */
192 std::cout << "CaloHadDMCoeffMinim::process() -> Info. Step 2 - making cluster set..." << std::endl;
193 m_minimSample.clear();
194 m_sample_size.resize(dmArea->getLength(), 0);
195 int nGoodEvents = 0;
196 for(int i_ev=0; m_data->GetEntry(i_ev)>0;i_ev++) {
197
198 //if(m_data->m_mc_ener < m_engBeamMin) continue;
199
200 if(i_ev%20000==0) std::cout << " i_ev: " << i_ev << " (" << nGoodEvents << ") '" << static_cast<TChain *>(m_data->fChain)->GetFile()->GetName() << "'" << std::endl;
201
202 double EnergyResolution; // in GeV
203 if( abs(m_data->m_mc_pdg) == 211) {
204 EnergyResolution = sqrt((0.5*0.5/GeV)*m_data->m_mc_ener+pow((0.03/GeV*m_data->m_mc_ener),2));// in GeV
205 } else {
206 //EnergyResolution = sqrt(0.1*0.1*m_data->m_mc_ener/GeV+0.003*0.003+0.007*0.007*pow((m_data->m_mc_ener/GeV),2)); // in GeV
207 EnergyResolution = sqrt((0.5*0.5/GeV)*m_data->m_mc_ener+pow((0.03/GeV*m_data->m_mc_ener),2));// in GeV
208 }
209
210 // checking event quality
211 if(isSingleParticle) {
212 bool GoodClusterFound(false);
213 if( m_data->m_ncls ) {
214 HepLorentzVector hlv_pion(1,0,0,1);
215 hlv_pion.setREtaPhi(1./cosh(m_data->m_mc_eta), m_data->m_mc_eta, m_data->m_mc_phi);
216 for(int i_cls=0; i_cls<m_data->m_ncls; i_cls++){ // loop over clusters
217 HepLorentzVector hlv_cls(1,0,0,1);
218 hlv_cls.setREtaPhi(1./cosh( (*m_data->m_cls_eta)[i_cls] ), (*m_data->m_cls_eta)[i_cls], (*m_data->m_cls_phi)[i_cls]);
219 double r = hlv_pion.angle(hlv_cls.vect());
221 && (*m_data->m_cls_engcalib)[i_cls] > 20.0*MeV
222 //&& (*m_data->m_cls_ener)[i_cls] > 0.01*m_data->m_mc_ener
223 ) {
224 GoodClusterFound = true;
225 break;
226 }
227 } // i_cls
228 } // m_ncls
229 if(!GoodClusterFound) continue;
230 }
231
232 if(m_data->m_engClusSumCalib <=0.0) continue;
233
234 for(int i_cls=0; i_cls<m_data->m_ncls; i_cls++){ // loop over clusters
235 if( (*m_data->m_cls_ener_unw)[i_cls] < m_engClusMin
236 || (*m_data->m_cls_engcalib)[i_cls] < 20.0*MeV
237 ) continue;
238 std::vector<float> vars;
239 m_data->PackClusterVars(i_cls, vars);
240 int iBin = m_HadDMCoeff->getBin(m_area_index, vars );
241
242 if(iBin >= 0 && iBin >= dmArea->getOffset() && iBin < (dmArea->getOffset()+dmArea->getLength()) && m_data->m_engClusSumCalib > 0.0 && m_data->m_mc_ener > 0.0) {
243 auto ev = std::make_unique<MinimSample>();
244 // we need only edmtrue and energy in cluster samplings to calculate fcn
245 ev->ibin = iBin;
246 ev->edmtrue = (*m_data->m_cls_dmener)[i_cls][m_area_index];
247 if(ev->edmtrue<0) ev->edmtrue=0.0;
248 if(m_data->m_cls_smpener_unw) {
249 ev->clsm_smp_energy_unw.resize((*m_data->m_cls_smpener_unw)[i_cls].size());
250 for(unsigned int i_smp=0; i_smp<(*m_data->m_cls_smpener_unw)[i_cls].size(); i_smp++){
251 ev->clsm_smp_energy_unw[i_smp] = (*m_data->m_cls_smpener_unw)[i_cls][i_smp];
252 }
253 }
254 // Calculation of cluster weight, which shows siginicance of it for chi2 calculation
255 double clus_weight = 1.0;
257 clus_weight = (*m_data->m_cls_engcalib)[i_cls]/m_data->m_engClusSumCalib;
258 }
259 ev->weight = clus_weight;
260
261 // error which will be used during chi2 calculation, currently it is simply the energy resolution
262 ev->sigma2 = EnergyResolution*EnergyResolution;
263 m_minimSample.push_back(std::move(ev));
264 m_sample_size[iBin - dmArea->getOffset()]++;
265 }
266 } // i_cls
267
268 nGoodEvents++;
269 } // i_ev
270
271
272 /* ********************************************
273 run minimization
274 ********************************************* */
275 std::cout << "CaloHadDMCoeffMinim::process() -> Info. Starting minimization, m_minimSample.size(): " << m_minimSample.size() << "( " << float(m_minimSample.size())*(26.0/1e+06) << " Mb)"<< std::endl;
276 for(int i_data=0; i_data<dmArea->getLength(); i_data++) {
277 TBenchmark mb;
278 mb.Start("minuitperf");
279 m_iBinGlob = dmArea->getOffset() + i_data;
280 m_minimSubSample.clear();
281 for (std::unique_ptr<MinimSample>& event : m_minimSample) {
282 if(event->ibin == m_iBinGlob) {
283 m_minimSubSample.push_back(event.get());
284 if(m_minimSubSample.size() > 100000) break;
285 }
286 }
287
288 std::vector<int > indexes;
289 m_HadDMCoeff->bin2indexes(m_iBinGlob, indexes);
290 std::cout << "==============================================================================" << std::endl;
291 std::cout << "run " << i_data
292 << " out of " << dmArea->getLength()
293 << " m_iBinGlob:" << m_iBinGlob
294 << " frac:" << indexes[CaloLocalHadCoeffHelper::DIM_EMFRAC]
295 << " side:" << indexes[CaloLocalHadCoeffHelper::DIM_SIDE]
296 << " eta:" << indexes[CaloLocalHadCoeffHelper::DIM_ETA]
297 << " phi:" << indexes[CaloLocalHadCoeffHelper::DIM_PHI]
298 << " ener:" << indexes[CaloLocalHadCoeffHelper::DIM_ENER]
299 << " lambda:" << indexes[CaloLocalHadCoeffHelper::DIM_LAMBDA]
300 << " size_of_subset:" << m_sample_size[i_data]
301 << std::endl;
302
303 // name of parameters to be minimized
304 m_validNames.clear();
305 if(indexes[CaloLocalHadCoeffHelper::DIM_EMFRAC] == 0) {
306 // list of samplings to minimise for charged pions
307 m_validNames.emplace_back("EME2");
308 m_validNames.emplace_back("EME3");
309 m_validNames.emplace_back("HEC0");
310 m_validNames.emplace_back("HEC1");
311 m_validNames.emplace_back("FCAL0");
312 m_validNames.emplace_back("FCAL1");
313 m_validNames.emplace_back("CONST");
314 }else{
315 // list of samplings to minimise for neutral pions
316 m_validNames.emplace_back("EME2");
317 m_validNames.emplace_back("EME3");
318 m_validNames.emplace_back("HEC0");
319 m_validNames.emplace_back("FCAL0");
320 m_validNames.emplace_back("CONST");
321 }
322
323 // setting up parameters which we are going to minimize
324 for (MinimPar& par : m_minimPars) {
325 bool fixIt = true;
326 for (const std::string& name : m_validNames) {
327 if(name == par.name) {
328 fixIt = false;
329 break;
330 }
331 }
332 par.fixIt = fixIt;
333 }
334
335 for(unsigned int i_par=0; i_par<m_minimPars.size(); i_par++){
336 m_minimPars[i_par].value = 1.0;
337 m_minimPars[i_par].error = 0.0;
338 }
339
340 // skip minimization if size of minimization sample is too small (no clusters falling in given iBinGlob
341 if(m_minimSubSample.size() > 80) {
342 // preparing for minimization
343 TVirtualFitter::SetDefaultFitter("Minuit");
344 TVirtualFitter * minuit = TVirtualFitter::Fitter(nullptr, m_minimPars.size());
345 for(unsigned int i_par=0; i_par<m_minimPars.size(); i_par++){
346 MinimPar *par = &m_minimPars[i_par];
347 minuit->SetParameter(i_par,par->name.c_str(), par->initVal, par->initErr, par->lowerLim, par->upperLim);
348 if( par->fixIt ) minuit->FixParameter(i_par);
349 }
350 m_nstep_fcn = 0;
351 minuit->SetFCN(CaloHadDMCoeffMinim::fcnWrapper);
352 double arglist[100];
353 arglist[0] = 0;
354 // set print level
355 minuit->ExecuteCommand("SET PRINT",arglist,2);
356 // minimize
357 arglist[0] = 2000; // number of function calls
358 arglist[1] = 0.001; // tolerance
359 // It is where minimization begins
360 minuit->ExecuteCommand("MIGRAD",arglist,2);
361
362 // Saving data
363 std::cout << "Minuit results:" << std::endl;
364 for(unsigned int i_par=0; i_par<m_minimPars.size(); i_par++){
365 m_minimPars[i_par].value = minuit->GetParameter(i_par);
366 m_minimPars[i_par].error = minuit->GetParError(i_par);
367 std::cout << " i_par:" << i_par << " '" << m_minimPars[i_par].name << "' val:" << minuit->GetParameter(i_par) << " err:" << minuit->GetParError(i_par) << std::endl;
368 }
369 delete minuit;
370 } // if minim sample is big enough
371 // saving minimisation data
373 mb.Stop("minuitperf");
374 std::cout << "CPU: " << mb.GetCpuTime("minuitperf") << std::endl;
375 } // loop over i_data
376
377
378 /* *********************************************
379 Making set with of new coefficients
380 ********************************************* */
381 std::cout << "CaloHadDMCoeffMinim::process() -> Info. Making output coefficients set " << std::endl;
382 CaloLocalHadCoeff *newHadDMCoeff = new CaloLocalHadCoeff(*m_HadDMCoeff);
383 for (std::pair<const int, std::vector<MinimPar > >& p : m_minimResults) {
384 int iBin = p.first;
385
386 m_minimPars = p.second;
388 pars.resize(m_minimPars.size(),0.0);
389 std::cout << std::format("{:.3f} ", static_cast<double>(iBin));
390 for(unsigned int i_par = 0; i_par<m_minimPars.size(); i_par++){
391 pars[i_par] = m_minimPars[i_par].value;
392 if(m_minimPars[i_par].fixIt == 1) continue;
393 std::cout << std::format("({} {:.3f} {:.3f}) ",
394 m_minimPars[i_par].name,
395 m_minimPars[i_par].value,
396 m_minimPars[i_par].error);
397 }
398 std::cout << std::endl;
399
400 if(m_isTestbeam) {
401 std::vector<int > indexes;
402 m_HadDMCoeff->bin2indexes(iBin, indexes);
405 float eta = dimEta->getXmin() + dimEta->getDx()*(indexes[CaloLocalHadCoeffHelper::DIM_ETA]+0.5);
406 if( (fabs(eta)>2.9 && fabs(eta)<3.15)) {
407 //pars[CaloSampling::EME2] *= 0.96;
408 //pars[CaloSampling::EME2] *= 0.97;
409 pars[CaloSampling::EME2] *= 0.98;
410 }
411 if( fabs(eta) > 3.25) {
412 //pars[CaloSampling::FCAL0] *= 0.93;
413 //pars[CaloSampling::FCAL0] *= 0.94;
414 pars[CaloSampling::FCAL0] *= 0.95;
415 }
416 }
417 } // m_isTestbeam
418
419 newHadDMCoeff->setCoeff(iBin, pars);
420 }
421
422 return newHadDMCoeff;
423}
424
425
426
427/* ****************************************************************************
428Making nice postscript report
429**************************************************************************** */
430void CaloHadDMCoeffMinim::make_report(std::string &sreport)
431{
432 std::cout << "CaloHadDMCoeffMinim::make_report() -> Info. Making report..." << std::endl;
433 gStyle->SetCanvasColor(10);
434 gStyle->SetCanvasBorderMode(0);
435 gStyle->SetPadColor(10);
436 gStyle->SetPadBorderMode(0);
437 gStyle->SetPalette(1);
438 gStyle->SetTitleBorderSize(1);
439 gStyle->SetTitleFillColor(10);
440 int cc_xx = 768, cc_yy = 1024;
441 gROOT->SetBatch(kTRUE);
442 gErrorIgnoreLevel=3; // root global variables to supress text output in ->Print() methods
443 std::string sfname = sreport;
444 TCanvas *ctmp = new TCanvas("ctmp","ctmp", cc_xx, cc_yy);
445 sfname += "[";
446 ctmp->Print(sfname.c_str());
447 sfname = sreport;
448 // ---------------------
449 int area_indx;
450 const CaloLocalHadCoeff::LocalHadArea *dmArea = m_HadDMHelper->getAreaFromName(m_HadDMCoeff, "ENG_CALIB_DEAD_FCAL", area_indx);
451 TLatex *tex = new TLatex(); tex->SetNDC();
452
459
460 for(int i_frac=0; i_frac<dimFrac->getNbins(); i_frac++){
461 for(int i_ener=0; i_ener<dimEner->getNbins(); i_ener++){
462 for(int i_lambda=0; i_lambda<dimLambda->getNbins(); i_lambda++){
463 for(int i_side=0; i_side<dimSide->getNbins(); i_side++){
464 for(int i_phi=0; i_phi<dimPhi->getNbins(); i_phi++){
465 const std::string cname = std::format("c1_dmfcal_minuit_weights_frac{}_ener{}_lambda{}_phi{}_side{}",
466 i_frac, i_ener, i_lambda, i_phi, i_side);
467 TCanvas *c1_weights = new TCanvas(cname.c_str(), cname.c_str(), cc_xx, cc_yy);
468 c1_weights->cd();
469 TPad *pad1=nullptr, *pad2=nullptr;
470 float y_edge = 0.85;
471 pad1 = new TPad("p1ps","p1ps",0.0, y_edge, 1.0, 1.0); pad1->Draw();
472 pad2 = new TPad("p2ps","p2ps",0.0, 0.0, 1.0, y_edge); pad2->Draw();
473 // top pad
474 pad1->cd(); gPad->SetGrid(); gPad->SetLeftMargin(0.07); gPad->SetTopMargin(0.05); gPad->SetRightMargin(0.05); gPad->SetBottomMargin(0.08);
475 std::string str = std::format("frac:{} ener:{} lambda:{} phi:{} side:{}",
476 i_frac, i_ener, i_lambda, i_phi, i_side);
477 tex->SetTextColor(1); tex->SetTextSize(0.20); tex->DrawLatex(0.1,0.4,str.c_str());
478 pad2->Divide(3,3);
479 int i_canvas = 0;
480 // lets draw sample size
481 pad2->cd(i_canvas+1);
482 TGraph *gr = new TGraph(dimEta->getNbins());
483 float smpsize=0.0;
484 for(int i_eta=0; i_eta<dimEta->getNbins(); i_eta++){
485 std::vector<int > v_indx;
486 v_indx.resize(CaloLocalHadCoeffHelper::DIM_UNKNOWN, 0);
488 v_indx[CaloLocalHadCoeffHelper::DIM_SIDE] = i_side;
489 v_indx[CaloLocalHadCoeffHelper::DIM_ETA] = i_eta;
490 v_indx[CaloLocalHadCoeffHelper::DIM_PHI] = i_phi;
491 v_indx[CaloLocalHadCoeffHelper::DIM_ENER] = i_ener;
492 v_indx[CaloLocalHadCoeffHelper::DIM_LAMBDA] = i_lambda;
493 int iBin = m_HadDMCoeff->getBin(area_indx, v_indx);
494 if (iBin >= 0 && iBin >= dmArea->getOffset()) {
495 float xx = dimEta->getXmin() + dimEta->getDx()*i_eta;
496 float w = (float)m_sample_size[iBin-dmArea->getOffset()];
497 smpsize += w;
498 gr->SetPoint(i_eta, xx, w);
499 }
500 }
501 str = std::format("Sample size {}",int(smpsize));
502 gr->SetTitle(str.c_str());
503 gr->Draw("apl");
504 i_canvas++;
505 for(unsigned int i_par=0; i_par<m_minimPars.size(); i_par++){
506 std::vector<float> vx;
507 std::vector<float> vy;
508 std::vector<float> vye;
509 for(int i_eta=0; i_eta<dimEta->getNbins(); i_eta++){
510 std::vector<int > v_indx;
511 v_indx.resize(CaloLocalHadCoeffHelper::DIM_UNKNOWN, 0);
513 v_indx[CaloLocalHadCoeffHelper::DIM_SIDE] = i_side;
514 v_indx[CaloLocalHadCoeffHelper::DIM_ETA] = i_eta;
515 v_indx[CaloLocalHadCoeffHelper::DIM_PHI] = i_phi;
516 v_indx[CaloLocalHadCoeffHelper::DIM_ENER] = i_ener;
517 v_indx[CaloLocalHadCoeffHelper::DIM_LAMBDA] = i_lambda;
518 int iBin = m_HadDMCoeff->getBin(area_indx, v_indx);
519 if(!m_minimResults[iBin][i_par].fixIt){
520 vx.push_back(dimEta->getXmin() + dimEta->getDx()*i_eta);
521 vy.push_back(m_minimResults[iBin][i_par].value);
522 vye.push_back(m_minimResults[iBin][i_par].error);
523 }
524 } // i_eta
525 if(!vx.empty()) {
526 TGraphErrors *gr = new TGraphErrors(dimEta->getNbins());
527 for(unsigned int i_p=0; i_p<vx.size(); i_p++){
528 gr->SetPoint(i_p, vx[i_p], vy[i_p]);
529 gr->SetPointError(i_p, 0.0, vye[i_p]);
530 }
531 pad2->cd(i_canvas+1);
532 gPad->SetGrid();
533 gr->SetMinimum(0.0);
534 gr->SetLineColor(4);
535 gr->SetTitle(m_minimPars[i_par].name.c_str());
536 gr->Draw("apl");
537 i_canvas++;
538 }
539 } // i_weight
540 c1_weights->Print(sfname.c_str());
541 } // i_phi
542 } // i_side
543 } // i_lambda
544 } // i_ener
545 } // i_frac
546
547 sfname = sreport;
548 sfname += "]";
549 ctmp->Print(sfname.c_str());
550}
551
552
553
554/* ****************************************************************************
555
556**************************************************************************** */
557void CaloHadDMCoeffMinim::fcn(Int_t &npar, Double_t *gin, Double_t &f, Double_t *par, Int_t iflag)
558{
559 if(gin && iflag){
560 // to avoid warnings during compilation
561 }
562 double hi2 = 0.0;
563 int nsel = 0;
564 double sum_edm_rec = 0.0;
565 double sum_edm_true = 0.0;
566 for (MinimSample *event : m_minimSubSample) {
567 double edm_rec = 0.0;
568 double edm_true = event->edmtrue;
569 for(int i_smp=0; i_smp<CaloSampling::Unknown; i_smp++){
570 edm_rec += (par[i_smp] - 1.0) * (double)(event->clsm_smp_energy_unw[i_smp]);
571 }
572 edm_rec += par[CaloSampling::Unknown];
573
574// if(edm_rec < 0.0) edm_rec = 0.0;
575// if(edm_true < 0.0) edm_true = 0.0;
576 edm_rec = edm_rec/GeV;
577 edm_true = edm_true/GeV;
578
579 sum_edm_rec += edm_rec/( event->sigma2 );
580 sum_edm_true += edm_true/( event->sigma2 );
581 hi2 += (event->weight*(edm_rec - edm_true)*(edm_rec - edm_true)/( event->sigma2 ) );
582 nsel++;
583 }
584
585 if(nsel == 0) {
586 std::cout << "nsel == 0 ! PANIC!" << std::endl;
587 hi2=99999999999.;
588 }else{
589 if(m_nstep_fcn%20 == 0) {
590 std::cout << ">>> step:" << m_nstep_fcn
591 << " size:(" << m_minimSample.size() << "," << nsel
592 << ") sum_edm_rec:" << sum_edm_rec/float(nsel)
593 << " sum_edm_true:" << sum_edm_true/float(nsel)
594 << " hi2:" << hi2
595 << " npar:" << npar
596 << std::endl;
597 for(unsigned int i_par=0; i_par<m_minimPars.size(); i_par++){
598 if( !m_minimPars[i_par].fixIt ) std::cout << "( " << i_par << " " << m_minimPars[i_par].name << " " << par[i_par] << ")";
599 }
600 std::cout << std::endl;
601 }
602 }
603 f = hi2;
604 m_nstep_fcn++;
605}
606
607
Scalar eta() const
pseudorapidity method
#define gr
static const double MeV
Wrapper to avoid constant divisions when using units.
Data to read from special DeadMaterialTree.
CaloLocalHadCoeff * process(CaloHadDMCoeffData *myData, CaloLocalHadCoeff *myHadDMCoeff, bool isSingleParticle=true, bool tbflag=false)
std::map< int, std::vector< MinimPar > > m_minimResults
void fcn(Int_t &npar, Double_t *gin, Double_t &f, Double_t *par, Int_t iflag)
CaloHadDMCoeffData * m_data
std::unique_ptr< CaloLocalHadCoeffHelper > m_HadDMHelper
static CaloHadDMCoeffMinim * s_instance
CaloLocalHadCoeff * m_HadDMCoeff
std::vector< std::unique_ptr< MinimSample > > m_minimSample
std::vector< std::string > m_validNames
static void fcnWrapper(Int_t &npar, Double_t *gin, Double_t &f, Double_t *par, Int_t iflag)
std::vector< int > m_sample_size
std::vector< MinimSample * > m_minimSubSample
void make_report(std::string &sfname)
std::vector< MinimPar > m_minimPars
Definition of correction area.
const CaloLocalHadCoeff::LocalHadDimension * getDimension(int n_dim) const
to get dimension
int getLength() const
return area length
const std::string & getTitle() const
return name
int getNpars() const
return number of parameters
int getOffset() const
return area offset
Class defines binning for user dimension.
float getDx() const
return size of bin
int getNbins() const
return number of bins
float getXmin() const
return minimum value for the first bin
Hold binned correction data for local hadronic calibration procedure.
void setCoeff(const int iBin, const LocalHadCoeff &theCoeff)
set new data
std::vector< float > LocalHadCoeff
Correction parameters for one general bin.
static double angle_mollier_factor(double x)
int r
Definition globals.cxx:22
int ev
Definition globals.cxx:25
STL namespace.