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