ATLAS Offline Software
Loading...
Searching...
No Matches
CaloGeometry.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
3*/
4
6#include <TTree.h>
7#include <TVector2.h>
8#include <TRandom.h>
9#include <TCanvas.h>
10#include <TH2D.h>
11#include <TGraphErrors.h>
12#include <TVector3.h>
13#include <TLegend.h>
14#include <fstream>
15#include <sstream>
16
17
18#include "CaloDetDescr/CaloDetDescrElement.h"
19//#include "ISF_FastCaloSimParametrization/CaloDetDescrElement.h"
20#include "CaloGeoHelpers/CaloSampling.h"
22//#include "TMVA/Tools.h"
23//#include "TMVA/Factory.h"
24
25using namespace std;
26
27const int CaloGeometry_calocol[24]={1,2,3,4, // LAr barrel
28 1,2,3,4, // LAr EM endcap
29 1,2,3,4, // Hadronic end cap cal.
30 1,2,3, // Tile barrel
31 -42,-28,6, // Tile gap (ITC & scint)
32 1,2,3, // Tile extended barrel
33 1,2,3 // Forward EM endcap
34};
35
36const int CaloGeometry::MAX_SAMPLING = CaloCell_ID_FCS::MaxSample; //number of calorimeter layers/samplings
37
39std::atomic<bool> CaloGeometry::m_debug=false;
40
42{
43 //TMVA::Tools::Instance();
44 for(int i=0;i<2;++i) {
45 m_min_eta_sample[i].resize(MAX_SAMPLING); //[side][calosample]
46 m_max_eta_sample[i].resize(MAX_SAMPLING); //[side][calosample]
47 m_rmid_map[i].resize(MAX_SAMPLING); //[side][calosample]
48 m_zmid_map[i].resize(MAX_SAMPLING); //[side][calosample]
49 m_rent_map[i].resize(MAX_SAMPLING); //[side][calosample]
50 m_zent_map[i].resize(MAX_SAMPLING); //[side][calosample]
51 m_rext_map[i].resize(MAX_SAMPLING); //[side][calosample]
52 m_zext_map[i].resize(MAX_SAMPLING); //[side][calosample]
53 }
55// for(unsigned int i=CaloCell_ID_FCS::FirstSample;i<CaloCell_ID_FCS::MaxSample;++i) {
56 for(unsigned int i=CaloSampling::PreSamplerB;i<=CaloSampling::FCAL2;++i) {
57 m_graph_layers[i]=nullptr;
60 }
62}
63
65= default;
66
68{
69 int sampling=cell->getSampling();
70 Identifier identify=cell->identify();
71
72 m_cells[identify]=cell;
73 m_cells_in_sampling[sampling][identify]=cell;
74
75 //m_cells[identify]= new CaloDetDescrElement(*cell);
76 //m_cells_in_sampling[sampling][identify]= new CaloDetDescrElement(*cell);
77
78 CaloGeometryLookup* lookup=nullptr;
79 for(unsigned int i=0;i<m_cells_in_regions[sampling].size();++i) {
80 if(m_cells_in_regions[sampling][i]->IsCompatible(cell)) {
81 lookup=m_cells_in_regions[sampling][i];
82 //cout<<sampling<<": found compatible map"<<endl;
83 break;
84 }
85 }
86 if(!lookup) {
87 lookup=new CaloGeometryLookup(m_cells_in_regions[sampling].size());
88 m_cells_in_regions[sampling].push_back(lookup);
89 }
90 lookup->add(cell);
91}
92
93void CaloGeometry::PrintMapInfo(int i, int j)
94{
95 cout<<" map "<<j<<": "<<m_cells_in_regions[i][j]->size()<<" cells";
96 if(i<21) {
97 cout<<", "<<m_cells_in_regions[i][j]->cell_grid_eta()<<"*"<<m_cells_in_regions[i][j]->cell_grid_phi();
98 cout<<", deta="<<m_cells_in_regions[i][j]->deta().mean()<<"+-"<<m_cells_in_regions[i][j]->deta().rms();
99 cout<<", dphi="<<m_cells_in_regions[i][j]->dphi().mean()<<"+-"<<m_cells_in_regions[i][j]->dphi().rms();
100 cout<<", mineta="<<m_cells_in_regions[i][j]->mineta()<<", maxeta="<<m_cells_in_regions[i][j]->maxeta();
101 cout<<", minphi="<<m_cells_in_regions[i][j]->minphi()<<", maxphi="<<m_cells_in_regions[i][j]->maxphi();
102 cout<<endl<<" ";
103 cout<<", mineta_raw="<<m_cells_in_regions[i][j]->mineta_raw()<<", maxeta_raw="<<m_cells_in_regions[i][j]->maxeta_raw();
104 cout<<", minphi_raw="<<m_cells_in_regions[i][j]->minphi_raw()<<", maxphi_raw="<<m_cells_in_regions[i][j]->maxphi_raw();
105 cout<<endl;
106 } else {
107 cout<<", "<<m_cells_in_regions[i][j]->cell_grid_eta()<<"*"<<m_cells_in_regions[i][j]->cell_grid_phi();
108 cout<<", dx="<<m_cells_in_regions[i][j]->dx().mean()<<"+-"<<m_cells_in_regions[i][j]->dx().rms();
109 cout<<", dy="<<m_cells_in_regions[i][j]->dy().mean()<<"+-"<<m_cells_in_regions[i][j]->dy().rms();
110 cout<<", mindx="<<m_cells_in_regions[i][j]->mindx();
111 cout<<", mindy="<<m_cells_in_regions[i][j]->mindy();
112 cout<<", minx="<<m_cells_in_regions[i][j]->minx()<<", maxx="<<m_cells_in_regions[i][j]->maxx();
113 cout<<", miny="<<m_cells_in_regions[i][j]->miny()<<", maxy="<<m_cells_in_regions[i][j]->maxy();
114 cout<<endl<<" ";
115 cout<<", minx_raw="<<m_cells_in_regions[i][j]->minx_raw()<<", maxx_raw="<<m_cells_in_regions[i][j]->maxx_raw();
116 cout<<", miny_raw="<<m_cells_in_regions[i][j]->miny_raw()<<", maxy_raw="<<m_cells_in_regions[i][j]->maxy_raw();
117 cout<<endl;
118 }
119}
120
122{
123 //cout<<"post processing sampling "<<sampling<<endl;
124 bool found_overlap=false;
125 for(unsigned int j=0;j<m_cells_in_regions[sampling].size();++j) {
126 /*
127 cout<<"Sample "<<sampling<<": checking map "<<j<<"/"<<m_cells_in_regions[sampling].size();
128 for(unsigned int k=0;k<m_cells_in_regions[sampling].size();++k) {
129 cout<<", "<<k<<":"<<m_cells_in_regions[sampling][k]->size();
130 }
131 cout<<endl;
132 */
133 for(unsigned int i=j+1;i<m_cells_in_regions[sampling].size();++i) {
134 if(m_cells_in_regions[sampling][i]->has_overlap(m_cells_in_regions[sampling][j])) {
135 if(!found_overlap) {
136 cout<<"Sample "<<sampling<<", starting maps : "<<m_cells_in_regions[sampling].size();
137 for(unsigned int k=0;k<m_cells_in_regions[sampling].size();++k) {
138 cout<<", "<<k<<":"<<m_cells_in_regions[sampling][k]->size();
139 }
140 cout<<endl;
141 }
142 found_overlap=true;
143 /*
144 cout<<"Sample "<<sampling<<": Found overlap between map "<<j<<" and "<<i<<", "
145 <<m_cells_in_regions[sampling].size()<<" total maps"<<endl;
146 cout<<" current configuration map "<<j<<"/"<<m_cells_in_regions[sampling].size();
147 for(unsigned int k=0;k<m_cells_in_regions[sampling].size();++k) {
148 cout<<", "<<k<<":"<<m_cells_in_regions[sampling][k]->size();
149 }
150 cout<<endl;
151
152 PrintMapInfo(sampling,j);
153 PrintMapInfo(sampling,i);
154 */
155
156 CaloGeometryLookup* toremove=m_cells_in_regions[sampling][i];
157 toremove->merge_into_ref(m_cells_in_regions[sampling][j]);
158
159 /*
160 cout<<" New ";
161 PrintMapInfo(sampling,j);
162 */
163
164 for(unsigned int k=i;k<m_cells_in_regions[sampling].size()-1;++k) {
165 m_cells_in_regions[sampling][k]=m_cells_in_regions[sampling][k+1];
166 m_cells_in_regions[sampling][k]->set_index(k);
167 }
168 m_cells_in_regions[sampling].resize(m_cells_in_regions[sampling].size()-1);
169
170 /*
171 cout<<" new configuration map "<<j<<"/"<<m_cells_in_regions[sampling].size();
172 for(unsigned int k=0;k<m_cells_in_regions[sampling].size();++k) {
173 cout<<", "<<k<<":"<<m_cells_in_regions[sampling][k]->size();
174 }
175 cout<<endl;
176 */
177
178 --i;
179 }
180 }
181 }
182
183 if(found_overlap) {
184 cout<<"Sample "<<sampling<<", final maps : "<<m_cells_in_regions[sampling].size();
185 for(unsigned int k=0;k<m_cells_in_regions[sampling].size();++k) {
186 cout<<", "<<k<<":"<<m_cells_in_regions[sampling][k]->size();
187 }
188 cout<<endl;
189 }
190
191 if(found_overlap) {
192 cout<<"Run another round of ";
193 post_process(sampling);
194 }
195}
196
198{
207
208
209 for(unsigned int side=0;side<=1;++side) for(unsigned int sample=0;sample<MAX_SAMPLING;++sample)
210 {
211 m_min_eta_sample[side][sample]=+1000;
212 m_max_eta_sample[side][sample]=-1000;
213 }
214
215
216 for(t_cellmap::iterator calo_iter=m_cells.begin();calo_iter!=m_cells.end();++calo_iter)
217 {
218 const CaloDetDescrElement* theDDE=(*calo_iter).second;
219 if(theDDE)
220 {
221 unsigned int sample=theDDE->getSampling();
222
223 int side=0;
224 int sign_side=-1;
225 double eta_raw=theDDE->eta_raw();
226 if(eta_raw>0) {
227 side=1;
228 sign_side=+1;
229 }
230
231 if(!m_cells_in_sampling_for_phi0[sample][eta_raw]) {
232 m_cells_in_sampling_for_phi0[sample][eta_raw]=theDDE;
233 } else {
234 if(TMath::Abs(theDDE->phi()) < TMath::Abs(m_cells_in_sampling_for_phi0[sample][eta_raw]->phi())) {
235 m_cells_in_sampling_for_phi0[sample][eta_raw]=theDDE;
236 }
237 }
238
239 double min_eta=theDDE->eta()-theDDE->deta()/2;
240 double max_eta=theDDE->eta()+theDDE->deta()/2;
241 if(min_eta<m_min_eta_sample[side][sample]) m_min_eta_sample[side][sample]=min_eta;
242 if(max_eta>m_max_eta_sample[side][sample]) m_max_eta_sample[side][sample]=max_eta;
243
244 if(rz_map_eta[side][sample].find(eta_raw)==rz_map_eta[side][sample].end()) {
245 rz_map_eta [side][sample][eta_raw]=0;
246 rz_map_rmid[side][sample][eta_raw]=0;
247 rz_map_zmid[side][sample][eta_raw]=0;
248 rz_map_rent[side][sample][eta_raw]=0;
249 rz_map_zent[side][sample][eta_raw]=0;
250 rz_map_rext[side][sample][eta_raw]=0;
251 rz_map_zext[side][sample][eta_raw]=0;
252 rz_map_n [side][sample][eta_raw]=0;
253 }
254 rz_map_eta [side][sample][eta_raw]+=theDDE->eta();
255 rz_map_rmid[side][sample][eta_raw]+=theDDE->r();
256 rz_map_zmid[side][sample][eta_raw]+=theDDE->z();
257 double drh=theDDE->dr()/2;
258 double dzh=theDDE->dz();
259 if(sample<=CaloSampling::EMB3) { // ensure we have a valid sampling
260 drh=theDDE->dr();
261 }
262 // An `else` would be good here since we can't continue with a *bad* sampling...
263 // Should most likely handle the situation nicely rather than with a crash.
264
265 rz_map_rent[side][sample][eta_raw]+=theDDE->r()-drh;
266 rz_map_zent[side][sample][eta_raw]+=theDDE->z()-dzh*sign_side;
267 rz_map_rext[side][sample][eta_raw]+=theDDE->r()+drh;
268 rz_map_zext[side][sample][eta_raw]+=theDDE->z()+dzh*sign_side;
269 rz_map_n [side][sample][eta_raw]++;
270
271 }
272 }
273
274 for(int side=0;side<=1;++side)
275 {
276 for(int sample=0;sample<MAX_SAMPLING;++sample)
277 {
278
279 if(!rz_map_n[side][sample].empty())
280 {
281 for(FSmap< double , int >::iterator iter=rz_map_n[side][sample].begin();iter!=rz_map_n[side][sample].end();++iter)
282 {
283 double eta_raw=iter->first;
284 if(iter->second<1)
285 {
286 //ATH_MSG_WARNING("rz-map for side="<<side<<" sample="<<sample<<" eta_raw="<<eta_raw<<" : #cells="<<iter->second<<" !!!");
287 }
288 else
289 {
290 double eta =rz_map_eta[side][sample][eta_raw]/iter->second;
291 double rmid=rz_map_rmid[side][sample][eta_raw]/iter->second;
292 double zmid=rz_map_zmid[side][sample][eta_raw]/iter->second;
293 double rent=rz_map_rent[side][sample][eta_raw]/iter->second;
294 double zent=rz_map_zent[side][sample][eta_raw]/iter->second;
295 double rext=rz_map_rext[side][sample][eta_raw]/iter->second;
296 double zext=rz_map_zext[side][sample][eta_raw]/iter->second;
297
298 m_rmid_map[side][sample][eta]=rmid;
299 m_zmid_map[side][sample][eta]=zmid;
300 m_rent_map[side][sample][eta]=rent;
301 m_zent_map[side][sample][eta]=zent;
302 m_rext_map[side][sample][eta]=rext;
303 m_zext_map[side][sample][eta]=zext;
304 }
305 }
306 //ATH_MSG_DEBUG("rz-map for side="<<side<<" sample="<<sample<<" #etas="<<m_rmid_map[side][sample].size());
307 }
308 else
309 {
310 std::cout<<"rz-map for side="<<side<<" sample="<<sample<<" is empty!!!"<<std::endl;
311 }
312 } //sample
313 } //side
314
315 if(DoGraphs()) {
316 for(int sample=0;sample<MAX_SAMPLING;++sample) {
317 m_graph_layers[sample]=new TGraphErrors(rz_map_n[0][sample].size()+rz_map_n[1][sample].size());
318 m_graph_layers[sample]->SetMarkerColor(TMath::Abs(CaloGeometry_calocol[sample]));
319 m_graph_layers[sample]->SetLineColor(TMath::Abs(CaloGeometry_calocol[sample]));
320 int np=0;
321 for(int side=0;side<=1;++side) {
322 for(FSmap< double , int >::iterator iter=rz_map_n[side][sample].begin();iter!=rz_map_n[side][sample].end();++iter) {
323 double eta_raw=iter->first;
324 int sign_side=-1;
325 if(eta_raw>0) sign_side=+1;
326 //double eta =rz_map_eta[side][sample][eta_raw]/iter->second;
327 double rmid=rz_map_rmid[side][sample][eta_raw]/iter->second;
328 double zmid=rz_map_zmid[side][sample][eta_raw]/iter->second;
329 //double rent=rz_map_rent[side][sample][eta_raw]/iter->second;
330 //double zent=rz_map_zent[side][sample][eta_raw]/iter->second;
331 double rext=rz_map_rext[side][sample][eta_raw]/iter->second;
332 double zext=rz_map_zext[side][sample][eta_raw]/iter->second;
333 m_graph_layers[sample]->SetPoint(np,zmid,rmid);
334 /*
335 if(isCaloBarrel(sample)) {
336 m_graph_layers[sample]->SetPointError(np,0,rext-rmid);
337 } else {
338 m_graph_layers[sample]->SetPointError(np,(zext-zent)*sign_side,0);
339 }
340 */
341 m_graph_layers[sample]->SetPointError(np,(zext-zmid)*sign_side,rext-rmid);
342 ++np;
343 }
344 }
345 }
346 }
347}
348
349TGraph* CaloGeometry::DrawGeoSampleForPhi0(int sample, int calocol, bool print)
350{
351 if (sample < CaloSampling::PreSamplerB || sample >= CaloSampling::Unknown) {
352 return nullptr;
353 }
354 TGraph* firstgr=nullptr;
355 cout<<"Start sample "<<sample<<" ("<<SamplingName(sample)<<")"<<endl;
356 int ngr=0;
357 for(t_eta_cellmap::iterator calo_iter=m_cells_in_sampling_for_phi0[sample].begin();calo_iter!=m_cells_in_sampling_for_phi0[sample].end();++calo_iter) {
358 const CaloDetDescrElement* theDDE=(*calo_iter).second;
359 if(theDDE) {
360 TVector3 cv;
361 TGraph* gr=new TGraph(5);
362 gr->SetLineColor(TMath::Abs(calocol));
363 gr->SetFillColor(TMath::Abs(calocol));
364 if(calocol<0) {
365 gr->SetFillStyle(1001);
366 } else {
367 gr->SetFillStyle(0);
368 }
369 gr->SetLineWidth(2);
370 double r=theDDE->r();
371 double dr=theDDE->dr();
372 double x=theDDE->x();
373 double dx=theDDE->dx();
374 double y=theDDE->y();
375 double dy=theDDE->dy();
376 double z=theDDE->z();
377 double dz=theDDE->dz()*2;
378 double eta=theDDE->eta();
379 double deta=theDDE->deta();
380
381 if(CaloSampling::PreSamplerB<=sample && sample<=CaloSampling::EMB3) {
382 dr*=2;
383 }
384 if(print) {
385 cout<<"sample="<<sample<<" r="<<r<<" dr="<<dr<<" eta="<<eta<<" deta="<<deta<<" x="<<x<<" y="<<y<<" z="<<z<<" dz="<<dz<<endl;
386 }
387 if(isCaloBarrel(sample)) {
388 cv.SetPtEtaPhi(r-dr/2,eta-deta/2,0);
389 gr->SetPoint(0,cv.Z(),cv.Pt());
390 gr->SetPoint(4,cv.Z(),cv.Pt());
391 cv.SetPtEtaPhi(r-dr/2,eta+deta/2,0);
392 gr->SetPoint(1,cv.Z(),cv.Pt());
393 cv.SetPtEtaPhi(r+dr/2,eta+deta/2,0);
394 gr->SetPoint(2,cv.Z(),cv.Pt());
395 cv.SetPtEtaPhi(r+dr/2,eta-deta/2,0);
396 gr->SetPoint(3,cv.Z(),cv.Pt());
397 } else {
398 if(sample<CaloSampling::FCAL0) {
399 cv.SetPtEtaPhi(1,eta-deta/2,0);cv*=(z-dz/2)/cv.Z();
400 gr->SetPoint(0,cv.Z(),cv.Pt());
401 gr->SetPoint(4,cv.Z(),cv.Pt());
402 cv.SetPtEtaPhi(1,eta+deta/2,0);cv*=(z-dz/2)/cv.Z();
403 gr->SetPoint(1,cv.Z(),cv.Pt());
404 cv.SetPtEtaPhi(1,eta+deta/2,0);cv*=(z+dz/2)/cv.Z();
405 gr->SetPoint(2,cv.Z(),cv.Pt());
406 cv.SetPtEtaPhi(1,eta-deta/2,0);cv*=(z+dz/2)/cv.Z();
407 gr->SetPoint(3,cv.Z(),cv.Pt());
408 } else {
409 double minr=r;
410 double maxr=r;
411 for(double px=x-dx/2;px<=x+dx/2;px+=dx) {
412 for(double py=y-dy/2;py<=y+dy/2;py+=dy) {
413 double pr=TMath::Sqrt(px*px+py*py);
414 minr=TMath::Min(minr,pr);
415 maxr=TMath::Max(maxr,pr);
416 }
417 }
418 cv.SetXYZ(minr,0,z-dz/2);
419 gr->SetPoint(0,cv.Z(),cv.Pt());
420 gr->SetPoint(4,cv.Z(),cv.Pt());
421 cv.SetXYZ(maxr,0,z-dz/2);
422 gr->SetPoint(1,cv.Z(),cv.Pt());
423 cv.SetXYZ(maxr,0,z+dz/2);
424 gr->SetPoint(2,cv.Z(),cv.Pt());
425 cv.SetXYZ(minr,0,z+dz/2);
426 gr->SetPoint(3,cv.Z(),cv.Pt());
427 }
428 }
429 //if(calocol[sample]>0) gr->Draw("Lsame");
430 // else gr->Draw("LFsame");
431 gr->Draw("LFsame");
432 if(ngr==0) firstgr=gr;
433 ++ngr;
434 }
435 }
436 cout<<"Done sample "<<sample<<" ("<<SamplingName(sample)<<")="<<ngr<<endl;
437 return firstgr;
438}
439
441{
442 TCanvas* c=new TCanvas("CaloGeoForPhi0","Calo geometry for #phi~0");
443 TH2D* hcalolayout=new TH2D("hcalolayoutPhi0","Reconstruction geometry: calorimeter layout;z [mm];r [mm]",50,-7000,7000,50,0,4000);
444 hcalolayout->Draw();
445 hcalolayout->SetStats(0);
446 hcalolayout->GetYaxis()->SetTitleOffset(1.4);
447
448 TLegend* leg=new TLegend(0.30,0.13,0.70,0.37);
449 leg->SetFillStyle(0);
450 leg->SetFillColor(10);
451 leg->SetBorderSize(1);
452 leg->SetNColumns(2);
453
454 for(int sample=0;sample<MAX_SAMPLING;++sample) {
455 TGraph* gr=DrawGeoSampleForPhi0(sample,CaloGeometry_calocol[sample],(sample==17));
456 if(gr) {
457 std::string sname=Form("Sampling %2d : ",sample);
458 sname+=SamplingName(sample);
459 leg->AddEntry(gr,sname.c_str(),"LF");
460 }
461 }
462 leg->Draw();
463 return c;
464}
465
467{
468 return m_cells.at(identify);
469}
470const CaloDetDescrElement* CaloGeometry::getDDE(int sampling,Identifier identify) const
471{
472 return m_cells_in_sampling.at(sampling).at(identify);
473}
474
475const CaloDetDescrElement* CaloGeometry::getDDE(int sampling,float eta,float phi,float* distance,int* steps) const
476{
477 if(sampling<0) return nullptr;
478 if(sampling>=MAX_SAMPLING) return nullptr;
479 if(m_cells_in_regions.at(sampling).empty()) return nullptr;
480
481 float dist = 0;
482 const CaloDetDescrElement* bestDDE=nullptr;
483 if(!distance) distance=&dist;
484 *distance=+10000000;
485 int intsteps;
486 int beststeps;
487 if(steps) beststeps=(*steps);
488 else beststeps=0;
489
490 if(sampling<21) {
491 for(int skip_range_check=0;skip_range_check<=1;++skip_range_check) {
492 for(unsigned int j=0;j<m_cells_in_regions.at(sampling).size();++j) {
493 if(!skip_range_check) {
494 if(eta<m_cells_in_regions.at(sampling).at(j)->mineta()) continue;
495 if(eta>m_cells_in_regions.at(sampling).at(j)->maxeta()) continue;
496 }
497 if(steps) intsteps=(*steps);
498 else intsteps=0;
499 if(m_debug) {
500 cout<<"CaloGeometry::getDDE : check map"<<j<<" skip_range_check="<<skip_range_check<<endl;
501 }
502 float newdist;
503 const CaloDetDescrElement* newDDE=m_cells_in_regions.at(sampling).at(j)->getDDE(eta,phi,&newdist,&intsteps);
504 if(m_debug) {
505 cout<<"CaloGeometry::getDDE : map"<<j<<" dist="<<newdist<<" best dist="<<*distance<<" steps="<<intsteps<<endl;
506 }
507 if(newdist<*distance) {
508 bestDDE=newDDE;
509 *distance=newdist;
510 if(steps) beststeps=intsteps;
511 if(newdist<-0.1) break; //stop, we are well within the hit cell
512 }
513 }
514 if(bestDDE) break;
515 }
516 } else {
517 return nullptr;
518 //for(int skip_range_check=0;skip_range_check<=1;++skip_range_check) {
519 //for(unsigned int j=0;j<m_cells_in_regions[sampling].size();++j) {
520 //if(!skip_range_check) {
521 //if(eta<m_cells_in_regions[sampling][j]->minx()) continue;
522 //if(eta>m_cells_in_regions[sampling][j]->maxx()) continue;
523 //if(phi<m_cells_in_regions[sampling][j]->miny()) continue;
524 //if(phi>m_cells_in_regions[sampling][j]->maxy()) continue;
525 //}
526 //if(steps) intsteps=*steps;
527 //else intsteps=0;
528 //if(m_debug) {
529 //cout<<"CaloGeometry::getDDE : check map"<<j<<" skip_range_check="<<skip_range_check<<endl;
530 //}
531 //float newdist;
532 //const CaloGeoDetDescrElement* newDDE=m_cells_in_regions[sampling][j]->getDDE(eta,phi,&newdist,&intsteps);
533 //if(m_debug) {
534 //cout<<"CaloGeometry::getDDE : map"<<j<<" dist="<<newdist<<" best dist="<<*distance<<" steps="<<intsteps<<endl;
535 //}
536 //if(newdist<*distance) {
537 //bestDDE=newDDE;
538 //*distance=newdist;
539 //if(steps) beststeps=intsteps;
540 //if(newdist<-0.1) break; //stop, we are well within the hit cell
541 //}
542 //}
543 //if(bestDDE) break;
544 //}
545 }
546 if(steps) *steps=beststeps;
547 return bestDDE;
548}
549
550const CaloDetDescrElement* CaloGeometry::getFCalDDE(int sampling,float x,float y,float z,float* distance,int* steps) const{
551 int isam = sampling - 20;
552 int iphi(-100000),ieta(-100000);
553 Long64_t mask1[]{0x34,0x34,0x35};
554 Long64_t mask2[]{0x36,0x36,0x37};
555 bool found = m_FCal_ChannelMap.getTileID(isam, x, y, ieta, iphi);
556 if(steps && found) *steps=0;
557 if(!found) {
558 //cout << "Warning: Hit is not matched with any FCal cell! Looking for the closest cell" << endl;
559 found = getClosestFCalCellIndex(sampling, x, y, ieta, iphi,steps);
560 }
561 if(!found) {
562 cout << "Error: Unable to find the closest FCal cell!" << endl;
563 return nullptr;
564 }
565
566
567 //cout << "CaloGeometry::getFCalDDE: x:" << x << " y: " << y << " ieta: " << ieta << " iphi: " << iphi << " cmap->x(): " << m_FCal_ChannelMap.x(isam,ieta,iphi) << " cmap->y(): " << m_FCal_ChannelMap.y(isam,ieta,iphi) << endl;
568 Long64_t id = (ieta << 5) + 2*iphi;
569 if(isam==2)id+= (8<<8);
570
571
572
573 if(z>0) id+=(mask2[isam-1] << 12);
574 else id+=(mask1[isam-1] << 12);
575
576 id = id << 44;
577 Identifier identify((unsigned long long)id);
578 const CaloDetDescrElement* foundcell=m_cells.at(identify);
579
580 // Report the shortest distance in x or y to the face of the cell if outside the cell.
581 // If inside the cell this will be negative and be the shortest distance to a cell face.
582 float dist = 0;
583 if(!distance) distance=&dist;
584 float distanceX = abs(foundcell->x()-x) - foundcell->dx()/2;
585 float distanceY = abs(foundcell->y()-y) - foundcell->dy()/2;
586 *distance = max(distanceX,distanceY);
587
588 return foundcell;
589}
590
591
592bool CaloGeometry::getClosestFCalCellIndex(int sampling,float x,float y,int& ieta, int& iphi,int* steps) const {
593
594 double rmin = m_FCal_rmin.at(sampling-21);
595 double rmax = m_FCal_rmax.at(sampling-21);
596 int isam=sampling-20;
597 double a=1.;
598 const double b=0.01;
599 const int nmax=100;
600 int i=0;
601
602 const double r = sqrt(x*x +y*y);
603 if(r==0.) return false;
604 const double r_inverse=1./r;
605
606 if((r/rmax)>(rmin*r_inverse)){
607 x=x*rmax*r_inverse;
608 y=y*rmax*r_inverse;
609 while((!m_FCal_ChannelMap.getTileID(isam, a*x, a*y, ieta, iphi)) && i<nmax){
610 a-=b;
611 i++;
612 }
613 }
614 else {
615 x=x*rmin*r_inverse;
616 y=y*rmin*r_inverse;
617 while((!m_FCal_ChannelMap.getTileID(isam, a*x, a*y, ieta, iphi)) && i<nmax){
618 a+=b;
619 i++;
620 }
621
622 }
623 if(steps)*steps=i+1;
624 return i<nmax;
625}
626
628{
629 for(int i=0;i<MAX_SAMPLING;++i) {
630 post_process(i);
631 for(unsigned int j=0;j<m_cells_in_regions[i].size();++j) {
632 m_cells_in_regions[i][j]->post_process();
633 }
634 //if(i>=21) break;
635 }
636
637 InitRZmaps();
638
639 /*
640 cout<<"all : "<<m_cells.size()<<endl;
641 for(int sampling=0;sampling<MAX_SAMPLING;++sampling) {
642 cout<<"cells sampling "<<sampling<<" : "<<m_cells_in_sampling[sampling].size()<<" cells";
643 cout<<", "<<m_cells_in_regions[sampling].size()<<" lookup map(s)"<<endl;
644 for(unsigned int j=0;j<m_cells_in_regions[sampling].size();++j) {
645 PrintMapInfo(sampling,j);
646 //break;
647 }
648 //if(i>0) break;
649 }
650 */
651
652 return true;
653}
654
655void CaloGeometry::Validate ATLAS_NOT_THREAD_SAFE (int nrnd)
656// ^ use of gRandom
657{
658 int ntest=0;
659 cout<<"start CaloGeometry::Validate()"<<endl;
660 for(t_cellmap::iterator ic=m_cells.begin();ic!=m_cells.end();++ic) {
661 const CaloDetDescrElement* cell=ic->second;
662 int sampling=cell->getSampling();
663 //if(sampling>=21) continue;
664
665 if(m_debug_identify==cell->identify()) {
666 cout<<"CaloGeometry::Validate(), cell "<<ntest<<" id="<<cell->identify()<<endl;
667 m_debug=true;
668 }
669
670 for(int irnd=0;irnd<nrnd;++irnd) {
671 std::stringstream pos;
672 std::stringstream cellpos;
673 std::stringstream foundcellpos;
674 int steps=0;
675 float distance=0;
676 bool is_inside;
677 bool is_inside_foundcell=false;
678 const CaloDetDescrElement* foundcell=nullptr;
679 if(sampling<21) {
680 float eta=cell->eta()+1.95*(gRandom->Rndm()-0.5)*cell->deta();
681 float phi=cell->phi()+1.95*(gRandom->Rndm()-0.5)*cell->dphi();
682 foundcell=getDDE(sampling,eta,phi,&distance,&steps);
683
684 pos<<"eta="<<eta<<" phi="<<phi;
685 cellpos<<"eta="<<cell->eta()<<" eta_raw="<<cell->eta_raw()<<" deta="<<cell->deta()
686 <<" ("<<(cell->eta_raw()-cell->eta())/cell->deta()<<") ; "
687 <<"phi="<<cell->phi()<<" phi_raw="<<cell->phi_raw()<<" dphi="<<cell->dphi()
688 <<" ("<<(cell->phi_raw()-cell->phi())/cell->dphi()<<")";
689 if(foundcell) {
690 foundcellpos<<"eta="<<foundcell->eta()<<" eta_raw="<<foundcell->eta_raw()<<" deta="<<foundcell->deta()
691 <<" ("<<(foundcell->eta_raw()-foundcell->eta())/foundcell->deta()<<") ; "
692 <<"phi="<<foundcell->phi()<<" phi_raw="<<foundcell->phi_raw()<<" dphi="<<foundcell->dphi()
693 <<" ("<<(foundcell->phi_raw()-foundcell->phi())/cell->dphi()<<")";
694 is_inside_foundcell=TMath::Abs( (eta-foundcell->eta())/foundcell->deta() )<0.55 && TMath::Abs( (phi-foundcell->phi())/foundcell->dphi() )<0.55;
695 }
696 is_inside=TMath::Abs( (eta-cell->eta())/cell->deta() )<0.49 && TMath::Abs( (phi-cell->phi())/cell->dphi() )<0.49;
697 } else {
698 float x=cell->x()+1.95*(gRandom->Rndm()-0.5)*cell->dx();
699 float y=cell->y()+1.95*(gRandom->Rndm()-0.5)*cell->dy();
700 float z=cell->z();
701 foundcell=getFCalDDE(sampling,x,y,z);
702
703 pos<<"x="<<x<<" y="<<y<<" z="<<z;
704 cellpos<<"x="<<cell->x()<<" x_raw="<<cell->x_raw()<<" dx="<<cell->dx()
705 <<" ("<<(cell->x_raw()-cell->x())/cell->dx()<<") ; "
706 <<"y="<<cell->y()<<" y_raw="<<cell->y_raw()<<" dy="<<cell->dy()
707 <<" ("<<(cell->y_raw()-cell->y())/cell->dy()<<")";
708 if(foundcell) {
709 foundcellpos<<"x="<<foundcell->x()<<" x_raw="<<foundcell->x_raw()<<" dx="<<foundcell->dx()
710 <<" ("<<(foundcell->x_raw()-foundcell->x())/foundcell->dx()<<") ; "
711 <<"y="<<foundcell->y()<<" y_raw="<<foundcell->y_raw()<<" dy="<<foundcell->dy()
712 <<" ("<<(foundcell->y_raw()-foundcell->y())/cell->dy()<<")";
713 is_inside_foundcell=TMath::Abs( (x-foundcell->x())/foundcell->dx() )<0.75 && TMath::Abs( (y-foundcell->y())/foundcell->dy() )<0.75;
714 }
715 is_inside=TMath::Abs( (x-cell->x())/cell->dx() )<0.49 && TMath::Abs( (y-cell->y())/cell->dy() )<0.49;
716 //m_debug=true;
717 }
718
719 if(m_debug && foundcell) {
720 cout<<"CaloGeometry::Validate(), irnd="<<irnd<<": cell id="<<cell->identify()<<", sampling="<<sampling
721 <<", foundcell id="<<foundcell->identify()<<", "<<steps<<" steps"<<endl;
722 cout<<" "<<cellpos.str()<<endl;
723 }
724 if(cell==foundcell) {
725 if(steps>3 && distance<-0.01) {
726 cout<<"cell id="<<cell->identify()<<", sampling="<<sampling<<" found in "<<steps<<" steps, dist="<<distance<<" "<<pos.str()<<endl;
727 cout<<" "<<cellpos.str()<<endl;
728 }
729 } else {
730 if(!foundcell) {
731 cout<<"cell id="<<cell->identify()<<" not found!";
732 cout<<" No cell found in "<<steps<<" steps, dist="<<distance<<" "<<pos.str()<<endl;
733 cout<<" input sampling="<<sampling<<" "<<cellpos.str()<<endl;
734 //return;
735 }
736 if( is_inside && foundcell && !is_inside_foundcell) {
737 cout<<"cell id="<<cell->identify()<<" not found, but inside cell area!";
738 cout<<" Found instead id="<<foundcell->identify()<<" in "<<steps<<" steps, dist="<<distance<<" "<<pos.str()<<endl;
739 cout<<" input sampling="<<sampling<<" "<<cellpos.str()<<endl;
740 cout<<" output sampling="<<foundcell->getSampling()<<" "<<foundcellpos.str()<<endl;
741 return;
742 }
743 }
744 }
745 m_debug=false;
746 if(ntest%25000==0) cout<<"Validate cell "<<ntest<<" with "<<nrnd<<" random hits"<<endl;
747 ++ntest;
748 }
749 cout<<"end CaloGeometry::Validate()"<<endl;
750}
751
752double CaloGeometry::deta(int sample,double eta) const
753{
754 int side=0;
755 if(eta>0) side=1;
756
757 double mineta=m_min_eta_sample[side][sample];
758 double maxeta=m_max_eta_sample[side][sample];
759
760 if(eta<mineta)
761 {
762 return fabs(eta-mineta);
763 }
764 else if(eta>maxeta)
765 {
766 return fabs(eta-maxeta);
767 }
768 else
769 {
770 double d1=fabs(eta-mineta);
771 double d2=fabs(eta-maxeta);
772 if(d1<d2) return -d1;
773 else return -d2;
774 }
775}
776
777
778void CaloGeometry::minmaxeta(int sample,double eta,double& mineta,double& maxeta) const
779{
780 int side=0;
781 if(eta>0) side=1;
782
783 mineta=m_min_eta_sample[side][sample];
784 maxeta=m_max_eta_sample[side][sample];
785}
786
787double CaloGeometry::rmid(int sample,double eta) const
788{
789 int side=0;
790 if(eta>0) side=1;
791
792 return m_rmid_map[side][sample].find_closest(eta)->second;
793}
794
795double CaloGeometry::zmid(int sample,double eta) const
796{
797 int side=0;
798 if(eta>0) side=1;
799
800 return m_zmid_map[side][sample].find_closest(eta)->second;
801}
802
803double CaloGeometry::rzmid(int sample,double eta) const
804{
805 int side=0;
806 if(eta>0) side=1;
807
808 if(isCaloBarrel(sample)) return m_rmid_map[side][sample].find_closest(eta)->second;
809 else return m_zmid_map[side][sample].find_closest(eta)->second;
810}
811
812double CaloGeometry::rent(int sample,double eta) const
813{
814 int side=0;
815 if(eta>0) side=1;
816
817 return m_rent_map[side][sample].find_closest(eta)->second;
818}
819
820double CaloGeometry::zent(int sample,double eta) const
821{
822 int side=0;
823 if(eta>0) side=1;
824
825 return m_zent_map[side][sample].find_closest(eta)->second;
826}
827
828double CaloGeometry::rzent(int sample,double eta) const
829{
830 int side=0;
831 if(eta>0) side=1;
832
833 if(isCaloBarrel(sample)) return m_rent_map[side][sample].find_closest(eta)->second;
834 else return m_zent_map[side][sample].find_closest(eta)->second;
835}
836
837double CaloGeometry::rext(int sample,double eta) const
838{
839 int side=0;
840 if(eta>0) side=1;
841
842 return m_rext_map[side][sample].find_closest(eta)->second;
843}
844
845double CaloGeometry::zext(int sample,double eta) const
846{
847 int side=0;
848 if(eta>0) side=1;
849
850 return m_zext_map[side][sample].find_closest(eta)->second;
851}
852
853double CaloGeometry::rzext(int sample,double eta) const
854{
855 int side=0;
856 if(eta>0) side=1;
857
858 if(isCaloBarrel(sample)) return m_rext_map[side][sample].find_closest(eta)->second;
859 else return m_zext_map[side][sample].find_closest(eta)->second;
860}
861
862double CaloGeometry::rpos(int sample,double eta,int subpos) const
863{
864
865 int side=0;
866 if(eta>0) side=1;
867
868 if(subpos==CaloSubPos::SUBPOS_ENT) return m_rent_map[side][sample].find_closest(eta)->second;
869 if(subpos==CaloSubPos::SUBPOS_EXT) return m_rext_map[side][sample].find_closest(eta)->second;
870
871 return m_rmid_map[side][sample].find_closest(eta)->second;
872}
873
874double CaloGeometry::zpos(int sample,double eta,int subpos) const
875{
876 int side=0;
877 if(eta>0) side=1;
878
879 if(subpos==CaloSubPos::SUBPOS_ENT) return m_zent_map[side][sample].find_closest(eta)->second;
880 if(subpos==CaloSubPos::SUBPOS_EXT) return m_zext_map[side][sample].find_closest(eta)->second;
881 return m_zmid_map[side][sample].find_closest(eta)->second;
882}
883
884double CaloGeometry::rzpos(int sample,double eta,int subpos) const
885{
886 int side=0;
887 if(eta>0) side=1;
888
889 if(isCaloBarrel(sample)) {
890 if(subpos==CaloSubPos::SUBPOS_ENT) return m_rent_map[side][sample].find_closest(eta)->second;
891 if(subpos==CaloSubPos::SUBPOS_EXT) return m_rext_map[side][sample].find_closest(eta)->second;
892 return m_rmid_map[side][sample].find_closest(eta)->second;
893 } else {
894 if(subpos==CaloSubPos::SUBPOS_ENT) return m_zent_map[side][sample].find_closest(eta)->second;
895 if(subpos==CaloSubPos::SUBPOS_EXT) return m_zext_map[side][sample].find_closest(eta)->second;
896 return m_zmid_map[side][sample].find_closest(eta)->second;
897 }
898}
899
900std::string CaloGeometry::SamplingName(int sample)
901{
902 return CaloSampling::getSamplingName(sample);
903}
904
906
907 m_FCal_rmin.resize(3,FLT_MAX);
908 m_FCal_rmax.resize(3,0.);
909
910 double x(0.),y(0.),r(0.);
911 for(int imap=1;imap<=3;imap++)for(auto it=m_FCal_ChannelMap.begin(imap);it!=m_FCal_ChannelMap.end(imap);it++){
912 x=it->second.x();
913 y=it->second.y();
914 r=sqrt(x*x+y*y);
915 if(r<m_FCal_rmin[imap-1])m_FCal_rmin[imap-1]=r;
916 if(r>m_FCal_rmax[imap-1])m_FCal_rmax[imap-1]=r;
917 }
918
919}
920
921
923
924 unsigned long long phi_index,eta_index;
925 float x,y,dx,dy;
926 long id;
927
928 long mask1[]{0x34,0x34,0x35};
929 long mask2[]{0x36,0x36,0x37};
930
931 m_FCal_rmin.resize(3,FLT_MAX);
932 m_FCal_rmax.resize(3,0.);
933
934
935 for(int imap=1;imap<=3;imap++){
936
937 int sampling = imap+20;
938
939 if((int)m_cells_in_sampling[sampling].size() != 2*std::distance(m_FCal_ChannelMap.begin(imap), m_FCal_ChannelMap.end(imap))){
940 cout << "Error: Incompatibility between FCalChannel map and GEO file: Different number of cells in m_cells_in_sampling and FCal_ChannelMap" << endl;
941 cout << "m_cells_in_sampling: " << m_cells_in_sampling[sampling].size() << endl;
942 cout << "FCal_ChannelMap: " << 2*std::distance(m_FCal_ChannelMap.begin(imap), m_FCal_ChannelMap.end(imap)) << endl;
943 return false;
944 }
945
946 for(auto it=m_FCal_ChannelMap.begin(imap);it!=m_FCal_ChannelMap.end(imap);it++){
947
948
949 phi_index = it->first & 0xffff;
950 eta_index = it->first >> 16;
951 x=it->second.x();
952 y=it->second.y();
953 m_FCal_ChannelMap.tileSize(imap, eta_index, phi_index,dx,dy);
954
955 id=(mask1[imap-1]<<12) + (eta_index << 5) +2*phi_index;
956
957 if(imap==2) id+= (8<<8);
958
959 Identifier id1((unsigned long long)(id<<44));
960 const CaloDetDescrElement *DDE1 =getDDE(id1);
961
962 id=(mask2[imap-1]<<12) + (eta_index << 5) +2*phi_index;
963 if(imap==2) id+= (8<<8);
964 Identifier id2((unsigned long long)(id<<44));
965 const CaloDetDescrElement *DDE2=getDDE(id2);
966
967 if(!TMath::AreEqualRel(x, DDE1->x(),1.E-8) || !TMath::AreEqualRel(y, DDE1->y(),1.E-8) || !TMath::AreEqualRel(x, DDE2->x(),1.E-8) || !TMath::AreEqualRel(y, DDE2->y(),1.E-8) ){
968 cout << "Error: Incompatibility between FCalChannel map and GEO file \n" << x << " " << DDE1->x() << " " << DDE2->x() << y << " " << DDE1->y() << " " << DDE2->y() << endl;
969 return false;
970 }
971 }
972
973
974
975 }
976
977 return true;
978}
979
980
Scalar eta() const
pseudorapidity method
Scalar phi() const
phi method
const int CaloGeometry_calocol[24]
#define gr
static Double_t a
HWIdentifier id2
const int nmax(200)
void print(char *figname, TCanvas *c1)
#define y
#define x
#define z
static const Attributes_t empty
#define max(a, b)
Definition cfImp.cxx:41
#define ATLAS_NOT_THREAD_SAFE
getNoisyStrip() Find noisy strips from hitmaps and write out into xml/db formats
This class groups all DetDescr information related to a CaloCell.
CaloCell_ID::CaloSample getSampling() const
cell sampling
Identifier identify() const override final
cell identifier
void merge_into_ref(CaloGeometryLookup *ref)
std::vector< FSmap< double, double > > m_zent_map[2]
t_cellmap m_cells
virtual void InitRZmaps()
double deta(int sample, double eta) const
std::vector< t_cellmap > m_cells_in_sampling
std::vector< t_eta_cellmap > m_cells_in_sampling_for_phi0
virtual void post_process(int layer)
std::vector< double > m_max_eta_sample[2]
double zmid(int sample, double eta) const
double rent(int sample, double eta) const
bool isCaloBarrel(int sample) const
double zent(int sample, double eta) const
std::vector< FSmap< double, double > > m_rext_map[2]
virtual const CaloDetDescrElement * getFCalDDE(int sampling, float x, float y, float z, float *distance=0, int *steps=0) const
std::vector< FSmap< double, double > > m_zext_map[2]
FCAL_ChannelMap m_FCal_ChannelMap
std::vector< FSmap< double, double > > m_zmid_map[2]
double rmid(int sample, double eta) const
static std::string SamplingName(int sample)
static std::atomic< bool > m_debug
virtual bool PostProcessGeometry()
TGraph * DrawGeoSampleForPhi0(int sample, int calocol, bool print=false)
static const int MAX_SAMPLING
double zpos(int sample, double eta, int subpos=CaloSubPos::SUBPOS_MID) const
double rzpos(int sample, double eta, int subpos=CaloSubPos::SUBPOS_MID) const
void calculateFCalRminRmax()
bool getClosestFCalCellIndex(int sampling, float x, float y, int &ieta, int &iphi, int *steps=0) const
double rext(int sample, double eta) const
virtual void PrintMapInfo(int i, int j)
virtual const CaloDetDescrElement * getDDE(Identifier identify) const
double rzmid(int sample, double eta) const
std::vector< double > m_min_eta_sample[2]
bool DoGraphs() const
std::vector< TGraphErrors * > m_graph_layers
TCanvas * DrawGeoForPhi0()
std::vector< double > m_FCal_rmin
virtual void addcell(const CaloDetDescrElement *cell)
void minmaxeta(int sample, double eta, double &mineta, double &maxeta) const
std::vector< std::vector< CaloGeometryLookup * > > m_cells_in_regions
double zext(int sample, double eta) const
virtual bool checkFCalGeometryConsistency()
static const Identifier m_debug_identify
std::vector< FSmap< double, double > > m_rmid_map[2]
double rzext(int sample, double eta) const
double rpos(int sample, double eta, int subpos=CaloSubPos::SUBPOS_MID) const
std::vector< bool > m_isCaloBarrel
std::vector< FSmap< double, double > > m_rent_map[2]
std::vector< double > m_FCal_rmax
virtual ~CaloGeometry()
double rzent(int sample, double eta) const
static constexpr unsigned int barrelPattern()
Get the bit-pattern for barrel samplings.
static std::string getSamplingName(CaloSample theSample)
Returns a string (name) for each CaloSampling.
static unsigned int getSamplingPattern(const CaloSample s)
Get a unsigned with one bit set.
Definition FSmap.h:11
std::map< _Key, _Tp >::iterator iterator
Definition FSmap.h:14
int r
Definition globals.cxx:22
std::string find(const std::string &s)
return a remapped string
Definition hcg.cxx:138
STL namespace.