ATLAS Offline Software
SingleTrackValidation.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
3 */
4 
8 
9 // For MC Truth information:
11 
12 // In order to be able to Ntuple & cet:
13 #include "GaudiKernel/NTuple.h"
14 #include "GaudiKernel/INTupleSvc.h"
15 #include "GaudiKernel/SmartDataPtr.h"
16 
17 // To get the Magnetic Field:
18 #include "CLHEP/GenericFunctions/FixedConstant.hh"
19 
20 // To get the particle properties:
21 #include "HepPDT/ParticleDataTable.hh"
22 #include "HepPDT/ParticleData.hh"
23 #include "GaudiKernel/IPartPropSvc.h"
24 
25 // To extrapolate:
26 #include "AtlasBComponent.h"
27 #include "GeoXPEngine.h"
28 
29 // To interpret LAr Geometry information:
30 #include "CaloDetDescr/CaloDetDescrElement.h"
34 
35 // pi etc
36 #include "CLHEP/Units/PhysicalConstants.h"
37 #include "AthenaKernel/Units.h"
38 
39 // To have histograms:
40 #include "GaudiKernel/ITHistSvc.h"
41 
42 // System libraries
43 #include <signal.h>
44 #include <unistd.h>
45 #include <sys/types.h>
46 #include <sstream>
47 #include <fstream>
48 #include <iostream>
49 #include <sys/times.h>
50 #include <string>
51 
52 namespace Units = Athena::Units;
53 using HepGeom::Point3D;
54 using CLHEP::HepLorentzVector;
55 using CLHEP::mm;
56 using CLHEP::pi;
57 using CLHEP::twopi;
58 
59 inline int iabs (int a) { return (a>=0)? a : -a;}
60 inline int getCpu() {
61  int cpuTime = 0;
62  {
63  static const int ticksPerJiffy = sysconf(_SC_CLK_TCK)/100;
64  struct tms buff{};
65  times(&buff);
66  cpuTime=(buff.tms_utime + buff.tms_stime + buff.tms_cutime + buff.tms_cstime)/ticksPerJiffy;
67  }
68  return cpuTime;
69 }
70 
71 // We will define some actual data, later.
73 
74 public:
75  Clockwork() {}
77 
78  IPartPropSvc* partPropSvc{nullptr};
79  ITHistSvc* histSvc{nullptr};
80  const CaloCell_ID* cellId{nullptr};
81  NTuple::Tuple* nt = nullptr;
82 
83  NTuple::Item<double> eta;
84  NTuple::Item<double> pt;
85  NTuple::Item<double> phi;
86 
87  // Impact point
88  NTuple::Item<double> x;
89  NTuple::Item<double> y;
90  NTuple::Item<double> z;
91 
92  // Indices run from 0 to 11: 4 in barrel, 4 in end cap, 3 in FCAL
93  // Energy within each sampling layer (directly struck cell):
94  NTuple::Item<double> s_c00[15];
95  NTuple::Item<double> s_hits[15];
96  NTuple::Item<double> s_sumE[15];
97  NTuple::Item<double> s_deltaPhi[15];
98  NTuple::Item<double> s_sigmaPhi[15];
99  NTuple::Item<double> s_deltaEta[15];
100  NTuple::Item<double> s_sigmaEta[15];
101  NTuple::Item<double> s_t00[15];
102  NTuple::Item<double> s_widthX[15];
103  NTuple::Item<double> s_widthY[15];
104 
105  NTuple::Item<double> cpuTime;
106  NTuple::Item<double> Energy;
107  NTuple::Item<double> PDG;
108  NTuple::Item<double> RunNo;
109  NTuple::Item<double> EventNo;
110  NTuple::Item<double> E_Deposit;
111 
112  bool coolField{true};
113 };
114 
115 SingleTrackValidation::SingleTrackValidation (const std::string & name, ISvcLocator * pSvcLocator) :
116  AthAlgorithm(name,pSvcLocator),m_c(new Clockwork())
117 {
118  for (unsigned int i=0;i<162;++i) m_histos[i] = nullptr;
119 }
120 
122  if (m_c!=nullptr){ delete m_c; m_c=nullptr; }
123 }
124 
126  std::string names[162] = { "eta", "pt", "phi", "pos_x", "pos_y", "pos_z",
127  "emb0_cell", "emb1_cell", "emb2_cell", "emb3_cell", "emec0_cell", "emec1_cell", "emec2_cell", "emec3_cell",
128  "hec0_cell", "hec1_cell", "hec2_cell", "hec3_cell", "fc1_cell", "fc2_cell", "fc3_cell",
129  "emb0_hits", "emb1_hits", "emb2_hits", "emb3_hits", "emec0_hits", "emec1_hits", "emec2_hits", "emec3_hits",
130  "hec0_hits", "hec1_hits", "hec2_hits", "hec3_hits", "fc1_hits", "fc2_hits", "fc3_hits",
131  "emb0_sumE", "emb1_sumE", "emb2_sumE", "emb3_sumE", "emec0_sumE", "emec1_sumE", "emec2_sumE", "emec3_sumE",
132  "hec0_sumE", "hec1_sumE", "hec2_sumE", "hec3_sumE", "fc1_sumE", "fc2_sumE", "fc3_sumE",
133  "emb0_dPhi", "emb1_dPhi", "emb2_dPhi", "emb3_dPhi", "emec0_dPhi", "emec1_dPhi", "emec2_dPhi", "emec3_dPhi",
134  "hec0_dPhi", "hec1_dPhi", "hec2_dPhi", "hec3_dPhi", "fc1_dX", "fc2_dX", "fc3_dX",
135  "emb0_sPhi", "emb1_sPhi", "emb2_sPhi", "emb3_sPhi", "emec0_sPhi", "emec1_sPhi", "emec2_sPhi", "emec3_sPhi",
136  "hec0_sPhi", "hec1_sPhi", "hec2_sPhi", "hec3_sPhi", "fc1_sX", "fc2_sX", "fc3_sX",
137  "emb0_dEta", "emb1_dEta", "emb2_dEta", "emb3_dEta", "emec0_dEta", "emec1_dEta", "emec2_dEta", "emec3_dEta",
138  "hec0_dEta", "hec1_dEta", "hec2_dEta", "hec3_dEta", "fc1_dY", "fc2_dY", "fc3_dY",
139  "emb0_sEta", "emb1_sEta", "emb2_sEta", "emb3_sEta", "emec0_sEta", "emec1_sEta", "emec2_sEta", "emec3_sEta",
140  "hec0_sEta", "hec1_sEta", "hec2_sEta", "hec3_sEta", "fc1_sY", "fc2_sY", "fc3_sY",
141  "emb0_time", "emb1_time", "emb2_time", "emb3_time", "emec0_time", "emec1_time", "emec2_time", "emec3_time",
142  "hec0_time", "hec1_time", "hec2_time", "hec3_time", "fc1_time", "fc2_time", "fc3_time",
143  "emb0_widthX", "emb1_widthX", "emb2_widthX", "emb3_widthX", "emec0_widthX", "emec1_widthX", "emec2_widthX", "emec3_widthX",
144  "hec0_widthX", "hec1_widthX", "hec2_widthX", "hec3_widthX", "fc1_widthX", "fc2_widthX", "fc3_widthX",
145  "emb0_widthY", "emb1_widthY", "emb2_widthY", "emb3_widthY", "emec0_widthY", "emec1_widthY", "emec2_widthY", "emec3_widthY",
146  "hec0_widthY", "hec1_widthY", "hec2_widthY", "hec3_widthY", "fc1_widthY", "fc2_widthY", "fc3_widthY",
147  "cpuTime", "Energy", "PDG_ID", "RunNo", "EventNo", "E_Dep" };
148 
149  double lim[162][2] = { {0,5}, {0,100}, {-4,4}, {-1600,1600}, {-1600,1600}, {-4000,4000},
150  {0,0.25}, {0,3}, {0,6}, {0,0.1}, {0,0.25}, {0,2}, {0,3}, {0,0.1}, {0,1}, {0,10}, {0,10}, {0,10}, {0,0.1}, {0,0.1}, {0,0.1}, //cell
151  {0,100}, {0,600}, {0,600}, {0,50}, {0,50}, {0,400}, {0,500}, {0,200}, {0,100}, {0,1000}, {0,1000}, {0,100}, {0,150}, {0,50}, {0,10}, //hits
152  {0,0.4}, {0,5}, {0,10}, {0,0.2}, {0,0.1}, {0,3}, {0,5}, {0,0.2}, {0,1}, {0,10}, {0,10}, {0,0.1}, {0,1}, {0,0.1}, {0,0.1}, //sumE
153  {-500,500}, {-100,100}, {-15,15}, {-200,200}, {-3000,3000}, {-60,60}, {-25,25}, {-200,200}, {-50,50}, {-50,50}, {-50,50}, {-50,50}, {-60,60}, {-500,500}, {-200,200}, //dPhi
154  {0,1000}, {0,500}, {0,200}, {0,500}, {0,2000}, {0,250}, {0,300}, {0,500}, {0,200}, {0,200}, {0,200}, {0,200}, {0,100}, {0,100}, {0,50}, //sPhi
155  {-150,150}, {-15,15}, {-20,20}, {-200,200}, {-0,2500}, {-50,20}, {-15,15}, {-150,150}, {-50,50}, {-50,50}, {-50,50}, {-50,50}, {-60,60}, {-500,500}, {-200,200}, //dEta
156  {0,500}, {0,100}, {0,100}, {0,400}, {0,1000}, {0,150}, {0,100}, {0,400}, {0,200}, {0,200}, {0,200}, {0,200}, {0,60}, {0,100}, {0,50}, //sPhi
157  {0,750}, {0,25}, {0,20}, {0,1000}, {0,10000}, {0,40}, {0,30}, {0,1000}, {0,1000}, {0,100}, {0,100}, {0,200}, {0,10}, {0,500}, {0,100}, //time
158  {-150,150}, {-15,15}, {-20,20}, {-200,200}, {-0,2500}, {-50,20}, {-15,15}, {-150,150}, {-50,50}, {-50,50}, {-50,50}, {-50,50}, {-60,60}, {-500,500}, {-200,200}, //widthX
159  {-150,150}, {-15,15}, {-20,20}, {-200,200}, {-0,2500}, {-50,20}, {-15,15}, {-150,150}, {-50,50}, {-50,50}, {-50,50}, {-50,50}, {-60,60}, {-500,500}, {-200,200}, //widthY
160  {0,50}, {0,100}, {-25,25}, {0,10}, {0,1000}, {0,10}};
161 
162  //-------------------------------------------------------------------------//
163  // //
164  // Initialize the Particle Property Service. This is necessary in order //
165  // to obtain charge & type & other properties of the primary particle and //
166  // other particles that may turn up in the debris. //
167  // //
168 
169  ATH_CHECK(service("PartPropSvc", m_c->partPropSvc));
170  ATH_CHECK(service("THistSvc", m_c->histSvc));
171  ATH_CHECK(detStore()->retrieve(m_c->cellId, "CaloCell_ID"));
174 
175  //----------------Now initialize the ntuples ----------------------//
176  // //
177  //==~ ~ ~==//
178  std::string filename="";
179  for (int i=0;i<162;i++){
180  m_histos[i] = new TH1F( names[i].data(), names[i].data(),50,lim[i][0],lim[i][1]);
181  filename = "/file1/Electron/";
182  filename.append(names[i]);
183  if (m_c->histSvc->regHist( filename.data() , m_histos[i] ).isFailure()){
184  ATH_MSG_WARNING( "Failed to register historam " << names[i] << ". Not sure what will happen now..." );
185  }
186  }
187 
188 
189  NTupleFilePtr file(ntupleSvc(),"/NTUPLES/FILE");
190  if (!file) throw std::runtime_error ("Ntuple MGR not open");
191  NTuple::Directory *col=ntupleSvc()->createDirectory("/NTUPLES/FILE/COL");
192  NTuplePtr nt(ntupleSvc(),"/NTUPLES/FILE/COL/SingleTrackValidation");
193  if (!nt) nt=ntupleSvc()->book(col, 1, CLID_ColumnWiseTuple, "SingleTrackValidation");
194 
195  if (nt->addItem("Eta", m_c->eta ).isFailure() ||
196  nt->addItem("Pt", m_c->pt ).isFailure() ||
197  nt->addItem("BarrelX", m_c->x ).isFailure() ||
198  nt->addItem("BarrelY", m_c->y ).isFailure() ||
199  nt->addItem("BarrelZ", m_c->z ).isFailure() ||
200  nt->addItem("Phi", m_c->phi ).isFailure() ){
201  ATH_MSG_WARNING( "Registration of some of the ntuple branches failed. No idea what will happen next..." );
202  }
203 
204 
205  char title[80];
206 
207  // Indices from 0 to 11: 4 EMB, 4 EMEC, and 4 FCAL sampling layers
208  // Handling FCAL layers separately for different titles (could do
209  // something more complicated if we wanted)
210  for (int i=0;i<15;i++){
211  if (i<12) sprintf(title,"S%i_C00",i);
212  else sprintf(title,"FC%i_C00",i-11);
213  if (nt->addItem(title,m_c->s_c00[i]).isFailure()) ATH_MSG_INFO( "Registration of a branch failed in the ntupler..." );
214  if (i<12) sprintf(title,"S%i_SumE",i);
215  else sprintf(title,"FC%i_SumE",i-11);
216  if (nt->addItem(title,m_c->s_sumE[i]).isFailure()) ATH_MSG_INFO( "Registration of a branch failed in the ntupler..." );
217  if (i<12) sprintf(title,"S%i_Hits",i);
218  else sprintf(title,"FC%i_Hits",i-11);
219  if (nt->addItem(title,m_c->s_hits[i]).isFailure()) ATH_MSG_INFO( "Registration of a branch failed in the ntupler..." );
220  if (i<12) sprintf(title,"S%i_DeltaPhi",i);
221  else sprintf(title,"FC%i_DeltaX",i-11);
222  if (nt->addItem(title,m_c->s_deltaPhi[i]).isFailure()) ATH_MSG_INFO( "Registration of a branch failed in the ntupler..." );
223  if (i<12) sprintf(title,"S%i_SigmaPhi",i);
224  else sprintf(title,"FC%i_SigmaX",i-11);
225  if (nt->addItem(title,m_c->s_sigmaPhi[i]).isFailure()) ATH_MSG_INFO( "Registration of a branch failed in the ntupler..." );
226  if (i<12) sprintf(title,"S%i_DeltaEta",i);
227  else sprintf(title,"FC%i_DeltaY",i-11);
228  if (nt->addItem(title,m_c->s_deltaEta[i]).isFailure()) ATH_MSG_INFO( "Registration of a branch failed in the ntupler..." );
229  if (i<12) sprintf(title,"S%i_SigmaEta",i);
230  else sprintf(title,"FC%i_SigmaY",i-11);
231  if (nt->addItem(title,m_c->s_sigmaEta[i]).isFailure()) ATH_MSG_INFO( "Registration of a branch failed in the ntupler..." );
232  if (i<12) sprintf(title,"S%i_Time",i);
233  else sprintf(title,"FC%i_Time",i-11);
234  if (nt->addItem(title,m_c->s_t00[i]).isFailure()) ATH_MSG_INFO( "Registration of a branch failed in the ntupler..." );
235  if (i<12) sprintf(title,"S%i_WidthX",i);
236  else sprintf(title,"FC%i_WidthX",i-11);
237  if (nt->addItem(title,m_c->s_widthX[i]).isFailure()) ATH_MSG_INFO( "Registration of a branch failed in the ntupler..." );
238  if (i<12) sprintf(title,"S%i_WidthY",i);
239  else sprintf(title,"FC%i_WidthY",i-11);
240  if (nt->addItem(title,m_c->s_widthY[i]).isFailure()) ATH_MSG_INFO( "Registration of a branch failed in the ntupler..." );
241  }
242 
243  if (nt->addItem("CPU" , m_c->cpuTime ).isFailure() ||
244  nt->addItem("TrackEnergy" , m_c->Energy ).isFailure() ||
245  nt->addItem("ParticleID" , m_c->PDG ).isFailure() ||
246  nt->addItem("Run#" , m_c->RunNo ).isFailure() ||
247  nt->addItem("Event#" , m_c->EventNo ).isFailure() ||
248  nt->addItem("DepositedEnergy", m_c->E_Deposit ).isFailure() ){
249  ATH_MSG_WARNING( "Registration of some of the ntuple branches failed. No idea what will happen next..." );
250  }
251 
252  m_c->cpuTime=0.0;
253  m_c->nt = nt;
254 
255  //==~ ~ ~==//
256  // //
257  //------------------------Done with initializations------------------------//
258 
259  return StatusCode::SUCCESS;
260 }
261 
263 
264  if (m_c->cpuTime==0) {
265  m_c->cpuTime=getCpu();
266  m_c->cpuTime+=1; // Fill the histogram with -1 for the first event
267  }
269  m_histos[156]->Fill( m_c->cpuTime/100. , 1. );
270 
271  StatusCode sc;
272 
273  StoreGateSvc *stg;
274  sc=service("StoreGateSvc", stg);
275 
276  const EventContext& context = getContext();
277  int RunNum=context.eventID().run_number();
278  int EvtNum=context.eventID().event_number();
279  double RunStr=double(RunNum);
280  double EvtStr=double(EvtNum);
281  m_c->EventNo=EvtStr;
282  m_c->RunNo=RunStr;
283  m_histos[160]->Fill(EvtStr);
284  m_histos[159]->Fill(RunNum);
285 
286  MagField::AtlasFieldCache fieldCache;
287  // Get field cache object
289  const AtlasFieldCacheCondObj* fieldCondObj{*readHandle};
290  if (fieldCondObj == nullptr) {
291  ATH_MSG_ERROR("Failed to retrieve AtlasFieldCacheCondObj with key " << m_fieldCacheCondObjInputKey.key());
292  return StatusCode::FAILURE;
293  }
294  fieldCondObj->getInitializedCache (fieldCache);
295 
296  // Get the MC Truth Information
297  const McEventCollection* mcEvent;
298  sc=stg->retrieve(mcEvent,"TruthEvent");
299  if (sc.isFailure()) return StatusCode::SUCCESS;
300  for (const HepMC::GenEvent* e : *mcEvent) {
301 
302  // Get just the primary, call it "theParticle"
303  auto theParticle = *HepMC::begin(*e);
304 
305  // Fetch whatever particle properties will be used in the following:
306  const HepPDT::ParticleDataTable * dataTable = m_c->partPropSvc->PDT();
307  const HepPDT::ParticleData * particleData = dataTable->particle(iabs(theParticle->pdg_id()));
308 
309  // Get the kinematic variables:
310  HepLorentzVector momentum(theParticle->momentum().px(),
311  theParticle->momentum().py(),
312  theParticle->momentum().pz(),
313  theParticle->momentum().e());
314  Point3D<double> origin(theParticle->production_vertex()->position().x(),
315  theParticle->production_vertex()->position().y(),
316  theParticle->production_vertex()->position().z());
317  double charge = theParticle->pdg_id() > 0 ? particleData->charge() : - particleData->charge();
318  // Put Eta and Phi into the Ntuple
319  m_c->phi = theParticle->momentum().phi();
320  m_c->eta = -log(tan(theParticle->momentum().theta()/2));
321  if (!finite(m_c->eta)) m_c->eta=0;
322  m_c->pt = theParticle->momentum().perp();
323  int partID = theParticle->pdg_id();
324  double pID = double(partID);
325  m_c->PDG = pID;
326  m_c->Energy = theParticle->momentum().e();
327  m_histos[2]->Fill( theParticle->momentum().phi() );
328  double myEta = -log(tan(theParticle->momentum().theta()/2));
329  if (!finite(myEta)) m_histos[0]->Fill(0);
330  else m_histos[0]->Fill( myEta );
331  m_histos[158]->Fill( pID );
332  m_histos[1]->Fill( theParticle->momentum().perp()/Units::GeV );
333  m_histos[157]->Fill( m_c->Energy = theParticle->momentum().e()/Units::GeV );
334 
335  // Make an extrapolator:
336  const Genfun::AtlasBComponent Bx(0,&fieldCache);
337  const Genfun::AtlasBComponent By(1,&fieldCache);
338  const Genfun::AtlasBComponent Bz(2,&fieldCache);
339  GeoXPEngine extrapolator(Bx, By, Bz, origin, momentum, charge);
340 
341  // Extrapolate to the first layer in the barrel:
342  m_c->x = 0;
343  m_c->y = 0;
344  m_c->z = 0;
345  double x=0,y=0,z=0;
346  bool hitsBarrel=false;
347  //bool hitsEndcap=false;
348  for (double t = 0; t< 50; t += 0.1) {
349  x = extrapolator.x()(t);
350  y = extrapolator.y()(t);
351  z = extrapolator.z()(t);
352  double magicZ=3640.0*mm;
353  double magicR=1500.0*mm;
354  if (x*x+y*y > magicR*magicR) {
355  m_c->x = x;
356  m_c->y = y;
357  m_c->z = z;
358  hitsBarrel=true;
359  break;
360  }
361  else if (z*z > magicZ*magicZ) {
362  m_c->x = x;
363  m_c->y = y;
364  m_c->z = z;
365  //hitsEndcap=true;
366  break;
367  }
368  }
369 
370  m_histos[3]->Fill( x );
371  m_histos[4]->Fill( y );
372  m_histos[5]->Fill( z );
373 
374  // You have an x,y, and z position. Now go and get the Element corresponding to
375  // that hit position. There are four, one for each sampling layer:
376  double radImpact = std::sqrt(x*x+y*y+z*z);
377  double phiImpact = std::atan2(y,x);
378  double thetaImpact = std::acos(z/radImpact);
379  double etaImpact = -std::log(std::tan(thetaImpact/2));
380 
382  ATH_CHECK(caloMgrHandle.isValid());
383  const CaloDetDescrManager* caloMgr = *caloMgrHandle;
384  const CaloDetDescrElement *element[15]={nullptr};
385 
386  for (int i=0;i<4;i++) {
387  try {
388  element[i] = caloMgr->get_element(CaloCell_ID::LAREM,i, hitsBarrel, etaImpact, phiImpact);
389  }
390  catch (const LArID_Exception & e) {
391  std::cerr << "SingleTrackValidation EXCEPTION (LAREM)" << e.message() << std::endl;
392  }
393  }
394  for (int i=0;i<4;i++) {
395  try {
396  element[i+4] = caloMgr->get_element(CaloCell_ID::LAREM,i, hitsBarrel, etaImpact, phiImpact);
397  }
398  catch (const LArID_Exception & e) {
399  std::cerr << "SingleTrackValidation EXCEPTION (LAREM)" << e.message() << std::endl;
400  }
401  }
402  for (int i=0;i<4;i++) {
403  try {
404  element[i+8] = caloMgr->get_element(CaloCell_ID::LARHEC,i, hitsBarrel, etaImpact, phiImpact);
405  }
406  catch (const LArID_Exception & e) {
407  std::cerr << "SingleTrackValidation EXCEPTION in (LARHEC)" << e.message() << std::endl;
408  }
409  }
410  for (int i=1;i<4;i++) {
411  try {
412  element[i+11] = caloMgr->get_element(CaloCell_ID::LARFCAL,i, hitsBarrel, etaImpact, phiImpact);
413  }
414  catch (const LArID_Exception & e) {
415  std::cerr << "SingleTrackValidation EXCEPTIONin LARFCAL" << e.message() << std::endl;
416  }
417  }
418 
419 
420  // Now go and find out how much energy is there:
421  for (int z=0;z<15;z++){
422  m_c->s_c00[z]=0;
423  m_c->s_t00[z]=0;
424  }
425 
426  std::string lArKey = hitsBarrel ? "LArHitEMB" : "LArHitEMEC" ;
427 
428  double eSum [15]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
429  double eEta [15]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
430  double eEtaEta [15]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
431  double ePhi [15]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
432  double ePhiPhi [15]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
433  int hit_count [15]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
434  double eX [15]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
435  double eXX [15]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
436  double eY [15]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
437  double eYY [15]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
438  double c00 [15]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
439  double t00 [15]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
440  // double width [15]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
441  double e_dep = 0;
442 
443  for (int i=0;i<4;i++) { // Loop over the four LAr collections
444  if (i==0) {
445  lArKey="LArHitEMB";
446  } else if (i==1) {
447  lArKey="LArHitEMEC";
448  } else if (i==2) {
449  lArKey="LArHitHEC";
450  } else if (i==3) {
451  lArKey="LArHitFCAL";
452  }
453 
455  const LArHitContainer* iter;
456  status=stg->retrieve(iter,lArKey);
457 
458  if (status==StatusCode::SUCCESS) {
459  LArHitContainer::const_iterator hi=(*iter).begin();//,he=(*iter).end();
460  for (hi = (*iter).begin();hi != (*iter).end(); ++hi){
461  const LArHit* larHit = *hi;
462 
463  const CaloDetDescrElement *hitElement = caloMgr->get_element(larHit->cellID());
464  int samplingLayer = m_c->cellId->sampling(larHit->cellID());
465  double energy = larHit->energy();
466 
467  for (int j=0;j<15;j++) {
468  if (hitElement==element[j]) {
469  c00[j] += energy;
470  }
471  }
472 
473  if (lArKey=="LArHitEMEC") samplingLayer += 4;
474  else if (lArKey=="LArHitHEC") samplingLayer += 8;
475  else if (lArKey=="LArHitFCAL") samplingLayer += 11;
476 
477  // Calculate phi of hit w.r.t phiImpact
478  // to avoid problems due to the 2pi modulus of phi
479  // we are thus calculating deltaphi directly, so don't subtract phiImpact again later
480  double hitPhi = hitElement->phi() - phiImpact;
481  if (hitPhi < -pi) hitPhi += twopi;
482  if (hitPhi > pi) hitPhi -= twopi;
483 
484  eSum [samplingLayer]+=energy;
485  eEta [samplingLayer]+=energy*hitElement->eta();
486  eEtaEta [samplingLayer]+=energy*hitElement->eta()*hitElement->eta();
487  ePhi [samplingLayer]+=energy*hitPhi;
488  ePhiPhi [samplingLayer]+=energy*hitPhi*hitPhi;
489  eX [samplingLayer]+=energy*hitElement->x();
490  eXX [samplingLayer]+=energy*hitElement->x()*hitElement->x();
491  eY [samplingLayer]+=energy*hitElement->y();
492  eYY [samplingLayer]+=energy*hitElement->y()*hitElement->y();
493  t00 [samplingLayer]+=energy*larHit->time();
494  hit_count[samplingLayer]+=1;
495  }
496  }
497  }
498 
499  for (int i=0;i<15;i++) {
500  if (eSum[i]!=0) eEta[i] /= eSum[i];
501  if (eSum[i]!=0) eEtaEta[i] /= eSum[i];
502  if (eSum[i]!=0) ePhi[i] /= eSum[i];
503  if (eSum[i]!=0) ePhiPhi[i] /= eSum[i];
504  if (eSum[i]!=0) eY[i] /= eSum[i];
505  if (eSum[i]!=0) eYY[i] /= eSum[i];
506  if (eSum[i]!=0) eX[i] /= eSum[i];
507  if (eSum[i]!=0) eXX[i] /= eSum[i];
508  if (eSum[i]!=0) t00[i] /= eSum[i];
509  e_dep+=eSum[i];
510  }
511 
512  double dThetaDEta = -1.0/cosh(etaImpact);
513 
514  //Fill the E Sum, center cell E, hit count fields:
515  m_c->E_Deposit=e_dep;
516  for (int z=0;z<15;z++){
517  m_c->s_sumE[z]=eSum[z];
518  m_c->s_c00[z]=c00[z];
519  m_c->s_t00[z]=t00[z];
520  m_c->s_hits[z]=hit_count[z];
521  if (z<12){
522  m_c->s_deltaPhi[z]=radImpact*std::sin(thetaImpact)*(ePhi[z]);
523  m_c->s_sigmaPhi[z]=radImpact*std::sin(thetaImpact)*std::sqrt(ePhiPhi[z]- ePhi[z]*ePhi[z]);
524  m_c->s_deltaEta[z]=radImpact*dThetaDEta*(eEta[z]-etaImpact);
525  m_c->s_sigmaEta[z]=radImpact*std::fabs(dThetaDEta)*std::sqrt(eEtaEta[z]- eEta[z]*eEta[z]);
526  } else {
527  m_c->s_deltaPhi[z]=(eX[z]-x);
528  m_c->s_sigmaPhi[z]=std::sqrt(eXX[z]- eX[z]*eX[z]);
529  m_c->s_deltaEta[z]=(eY[z]-y);
530  m_c->s_sigmaEta[z]=std::sqrt(eYY[z]-eY[z]*eY[z]);
531  }
532  m_c->s_widthX[z]=std::sqrt(eXX[z]-eX[z]*eX[z]);
533  m_c->s_widthY[z]=std::sqrt(eYY[z]-eY[z]*eY[z]);
534  }
535 
536  m_histos[161]->Fill(e_dep/Units::GeV);
537  for (int i=0;i<15;i++){
538  m_histos[6+i]->Fill( c00[i]/Units::GeV );
539  m_histos[21+i]->Fill( hit_count[i] );
540  m_histos[36+i]->Fill( eSum[i]/Units::GeV );
541  m_histos[111+i]->Fill( t00[i] );
542  m_histos[126+i]->Fill( sqrt(eXX[i]-eX[i]*eX[i]) );
543  m_histos[141+i]->Fill( sqrt(eYY[i]-eY[i]*eY[i]) );
544  if (i<8){
545  m_histos[51+i]->Fill( radImpact*std::sin(thetaImpact)*ePhi[i] );
546  m_histos[66+i]->Fill( radImpact*std::sin(thetaImpact)*std::sqrt(ePhiPhi[i]-ePhi[i]*ePhi[i]) );
547  m_histos[81+i]->Fill( radImpact*dThetaDEta*(eEta[i]-etaImpact) );
548  m_histos[96+i]->Fill( radImpact*std::fabs(dThetaDEta)*std::sqrt(eEtaEta[i]-eEta[i]*eEta[i]) );
549  } else {
550  m_histos[51+i]->Fill( eX[i]-x );
551  m_histos[66+i]->Fill( std::sqrt(eXX[i]-eX[i]*eX[i]) );
552  m_histos[81+i]->Fill( eY[i]-y );
553  m_histos[96+i]->Fill( std::sqrt(eYY[i]-eY[i]*eY[i]) );
554  }
555  }
556 
557  ATH_CHECK(ntupleSvc()->writeRecord(m_c->nt));
558 
559  }
560 
561  m_c->cpuTime= getCpu();
562 
563  return StatusCode::SUCCESS;
564 
565 }
566 
568  return StatusCode::SUCCESS;
569 }
python.PyKernel.retrieve
def retrieve(aClass, aKey=None)
Definition: PyKernel.py:110
SingleTrackValidation::Clockwork::eta
NTuple::Item< double > eta
Definition: SingleTrackValidation.cxx:83
SingleTrackValidation::Clockwork::z
NTuple::Item< double > z
Definition: SingleTrackValidation.cxx:90
get_hdefs.buff
buff
Definition: get_hdefs.py:64
data
char data[hepevt_bytes_allocation_ATLAS]
Definition: HepEvt.cxx:11
CaloCell_Base_ID::LARFCAL
@ LARFCAL
Definition: CaloCell_Base_ID.h:46
SingleTrackValidation::Clockwork::s_widthX
NTuple::Item< double > s_widthX[15]
Definition: SingleTrackValidation.cxx:102
SingleTrackValidation::execute
StatusCode execute() override
Definition: SingleTrackValidation.cxx:262
SG::ReadCondHandle
Definition: ReadCondHandle.h:44
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
CaloDetDescrElement::y
float y() const
cell y
Definition: Calorimeter/CaloDetDescr/CaloDetDescr/CaloDetDescrElement.h:365
AtlasFieldCacheCondObj
Definition: AtlasFieldCacheCondObj.h:19
SingleTrackValidation::Clockwork::cellId
const CaloCell_ID * cellId
Definition: SingleTrackValidation.cxx:80
python.CreateTierZeroArgdict.partID
partID
Definition: CreateTierZeroArgdict.py:135
SingleTrackValidation::Clockwork::pt
NTuple::Item< double > pt
Definition: SingleTrackValidation.cxx:84
SingleTrackValidation::Clockwork::s_sumE
NTuple::Item< double > s_sumE[15]
Definition: SingleTrackValidation.cxx:96
SingleTrackValidation::m_c
Clockwork * m_c
Definition: SingleTrackValidation.h:38
SingleTrackValidation::Clockwork::coolField
bool coolField
Definition: SingleTrackValidation.cxx:112
SingleTrackValidation::Clockwork::s_t00
NTuple::Item< double > s_t00[15]
Definition: SingleTrackValidation.cxx:101
CaloDetDescrElement
This class groups all DetDescr information related to a CaloCell. Provides a generic interface for al...
Definition: Calorimeter/CaloDetDescr/CaloDetDescr/CaloDetDescrElement.h:66
LArID_Exception.h
CaloDetDescrManager_Base::get_element
const CaloDetDescrElement * get_element(const Identifier &cellId) const
get element by its identifier
Definition: CaloDetDescrManager.cxx:159
CSV_InDetExporter.new
new
Definition: CSV_InDetExporter.py:145
SingleTrackValidation::m_histos
TH1F * m_histos[162]
Definition: SingleTrackValidation.h:41
LArHit::energy
double energy() const
Definition: LArHit.h:113
LArHitContainer
Hit collection.
Definition: LArHitContainer.h:26
CaloCell_Base_ID::LARHEC
@ LARHEC
Definition: CaloCell_Base_ID.h:46
SingleTrackValidation::Clockwork::phi
NTuple::Item< double > phi
Definition: SingleTrackValidation.cxx:85
read_hist_ntuple.t
t
Definition: read_hist_ntuple.py:5
SG::VarHandleKey::key
const std::string & key() const
Return the StoreGate ID for the referenced object.
Definition: AthToolSupport/AsgDataHandles/Root/VarHandleKey.cxx:141
GeoXPEngine::z
const Genfun::AbsFunction & z() const
Definition: GeoXPEngine.cxx:89
SingleTrackValidation::Clockwork::s_deltaPhi
NTuple::Item< double > s_deltaPhi[15]
Definition: SingleTrackValidation.cxx:97
x
#define x
SingleTrackValidation::Clockwork::PDG
NTuple::Item< double > PDG
Definition: SingleTrackValidation.cxx:107
ReadCondHandle.h
pi
#define pi
Definition: TileMuonFitter.cxx:65
AthenaPoolTestRead.sc
sc
Definition: AthenaPoolTestRead.py:27
CaloCell_ID.h
AthCommonDataStore< AthCommonMsg< Algorithm > >::detStore
const ServiceHandle< StoreGateSvc > & detStore() const
The standard StoreGateSvc/DetectorStore Returns (kind of) a pointer to the StoreGateSvc.
Definition: AthCommonDataStore.h:95
AthenaHitsVector< LArHit >::const_iterator
boost::transform_iterator< make_const, typename CONT::const_iterator > const_iterator
Definition: AthenaHitsVector.h:58
SingleTrackValidation::Clockwork::Energy
NTuple::Item< double > Energy
Definition: SingleTrackValidation.cxx:106
SingleTrackValidation::Clockwork::EventNo
NTuple::Item< double > EventNo
Definition: SingleTrackValidation.cxx:109
SingleTrackValidation::Clockwork::s_sigmaEta
NTuple::Item< double > s_sigmaEta[15]
Definition: SingleTrackValidation.cxx:100
StoreGateSvc::retrieve
StatusCode retrieve(const T *&ptr) const
Retrieve the default object into a const T*.
SingleTrackValidation::Clockwork::partPropSvc
IPartPropSvc * partPropSvc
Definition: SingleTrackValidation.cxx:78
SingleTrackValidation::initialize
StatusCode initialize() override
Definition: SingleTrackValidation.cxx:125
StoreGateSvc
The Athena Transient Store API.
Definition: StoreGateSvc.h:128
SingleTrackValidation::Clockwork::x
NTuple::Item< double > x
Definition: SingleTrackValidation.cxx:88
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
ParticleGun_FastCalo_ChargeFlip_Config.energy
energy
Definition: ParticleGun_FastCalo_ChargeFlip_Config.py:78
ParticleGun_EoverP_Config.momentum
momentum
Definition: ParticleGun_EoverP_Config.py:63
SingleTrackValidation::Clockwork::y
NTuple::Item< double > y
Definition: SingleTrackValidation.cxx:89
McEventCollection.h
lumiFormat.i
int i
Definition: lumiFormat.py:92
z
#define z
SingleTrackValidation::m_caloMgrKey
SG::ReadCondHandleKey< CaloDetDescrManager > m_caloMgrKey
Definition: SingleTrackValidation.h:27
CaloCell_Base_ID::sampling
int sampling(const Identifier id) const
LAr field values (NOT_VALID == invalid request)
Genfun::AtlasBComponent
Definition: AtlasBComponent.h:14
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
python.subdetectors.mmg.names
names
Definition: mmg.py:8
LArHit::time
double time() const
Definition: LArHit.h:118
covarianceTool.title
title
Definition: covarianceTool.py:542
SingleTrackValidation::Clockwork::histSvc
ITHistSvc * histSvc
Definition: SingleTrackValidation.cxx:79
file
TFile * file
Definition: tile_monitor.h:29
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
GeoXPEngine.h
CaloCell_ID
Helper class for offline cell identifiers.
Definition: CaloCell_ID.h:34
drawFromPickle.tan
tan
Definition: drawFromPickle.py:36
xAOD::double
double
Definition: CompositeParticle_v1.cxx:159
McEventCollection
This defines the McEventCollection, which is really just an ObjectVector of McEvent objects.
Definition: McEventCollection.h:33
AthAlgorithm
Definition: AthAlgorithm.h:47
SingleTrackValidation::m_fieldCacheCondObjInputKey
SG::ReadCondHandleKey< AtlasFieldCacheCondObj > m_fieldCacheCondObjInputKey
Definition: SingleTrackValidation.h:33
SingleTrackValidation.h
LArHit::cellID
Identifier cellID() const
Definition: LArHit.h:108
Athena::Units
Definition: Units.h:45
twopi
constexpr double twopi
Definition: VertexPointEstimator.cxx:16
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:195
GeoXPEngine::y
const Genfun::AbsFunction & y() const
Definition: GeoXPEngine.cxx:86
charge
double charge(const T &p)
Definition: AtlasPID.h:494
SingleTrackValidation::Clockwork::s_hits
NTuple::Item< double > s_hits[15]
Definition: SingleTrackValidation.cxx:95
SingleTrackValidation::Clockwork::Clockwork
Clockwork()
Definition: SingleTrackValidation.cxx:75
SG::CondHandleKey::initialize
StatusCode initialize(bool used=true)
LArHit
Class to store hit energy and time in LAr cell from G4 simulation.
Definition: LArHit.h:25
Units.h
Wrapper to avoid constant divisions when using units.
query_example.col
col
Definition: query_example.py:7
CaloDetDescrElement::x
float x() const
cell x
Definition: Calorimeter/CaloDetDescr/CaloDetDescr/CaloDetDescrElement.h:363
GeoXPEngine::x
const Genfun::AbsFunction & x() const
Definition: GeoXPEngine.cxx:83
GeoXPEngine
Definition: GeoXPEngine.h:22
python.SystemOfUnits.mm
int mm
Definition: SystemOfUnits.py:83
SingleTrackValidation::Clockwork::cpuTime
NTuple::Item< double > cpuTime
Definition: SingleTrackValidation.cxx:105
SingleTrackValidation::Clockwork::RunNo
NTuple::Item< double > RunNo
Definition: SingleTrackValidation.cxx:108
SingleTrackValidation::Clockwork::E_Deposit
NTuple::Item< double > E_Deposit
Definition: SingleTrackValidation.cxx:110
DiTauMassTools::MaxHistStrategyV2::e
e
Definition: PhysicsAnalysis/TauID/DiTauMassTools/DiTauMassTools/HelperFunctions.h:26
a
TList * a
Definition: liststreamerinfos.cxx:10
SingleTrackValidation::Clockwork::s_c00
NTuple::Item< double > s_c00[15]
Definition: SingleTrackValidation.cxx:94
y
#define y
CaloDetDescrManager
This class provides the client interface for accessing the detector description information common to...
Definition: CaloDetDescrManager.h:473
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
LArHitContainer.h
SingleTrackValidation::Clockwork::s_deltaEta
NTuple::Item< double > s_deltaEta[15]
Definition: SingleTrackValidation.cxx:99
SingleTrackValidation::SingleTrackValidation
SingleTrackValidation(const std::string &name, ISvcLocator *pSvcLocator)
Definition: SingleTrackValidation.cxx:115
SingleTrackValidation::Clockwork::nt
NTuple::Tuple * nt
Definition: SingleTrackValidation.cxx:81
iabs
int iabs(int a)
Definition: SingleTrackValidation.cxx:59
MagField::AtlasFieldCache
Local cache for magnetic field (based on MagFieldServices/AtlasFieldSvcTLS.h)
Definition: AtlasFieldCache.h:43
python.CaloCondTools.log
log
Definition: CaloCondTools.py:20
CaloCellTimeCorrFiller.filename
filename
Definition: CaloCellTimeCorrFiller.py:24
AtlasBComponent.h
HepMC::begin
GenEvent::particle_iterator begin(HepMC::GenEvent &e)
Definition: GenEvent.h:498
SingleTrackValidation::finalize
StatusCode finalize() override
Definition: SingleTrackValidation.cxx:567
SingleTrackValidation::Clockwork::s_sigmaPhi
NTuple::Item< double > s_sigmaPhi[15]
Definition: SingleTrackValidation.cxx:98
CaloDetDescrElement::eta
float eta() const
cell eta
Definition: Calorimeter/CaloDetDescr/CaloDetDescr/CaloDetDescrElement.h:344
SingleTrackValidation::Clockwork::~Clockwork
~Clockwork()
Definition: SingleTrackValidation.cxx:76
merge.status
status
Definition: merge.py:17
CaloDetDescrElement::phi
float phi() const
cell phi
Definition: Calorimeter/CaloDetDescr/CaloDetDescr/CaloDetDescrElement.h:346
python.TrigEgammaMonitorHelper.TH1F
def TH1F(name, title, nxbins, bins_par2, bins_par3=None, path='', **kwargs)
Definition: TrigEgammaMonitorHelper.py:24
drawFromPickle.sin
sin
Definition: drawFromPickle.py:36
beamspotnt.nt
def nt
Definition: bin/beamspotnt.py:1063
SingleTrackValidation::~SingleTrackValidation
~SingleTrackValidation()
Definition: SingleTrackValidation.cxx:121
CaloCell_Base_ID::LAREM
@ LAREM
Definition: CaloCell_Base_ID.h:46
ntupleSvc
INTupleSvc * ntupleSvc()
Definition: ServiceAccessor.h:14
GeV
#define GeV
Definition: CaloTransverseBalanceVecMon.cxx:30
StoreGateSvc.h
LArID_Exception
Exception class for LAr Identifiers.
Definition: LArID_Exception.h:20
SingleTrackValidation::Clockwork
Definition: SingleTrackValidation.cxx:72
getCpu
int getCpu()
Definition: SingleTrackValidation.cxx:60
plot_times.times
def times(fn)
Definition: plot_times.py:11
SingleTrackValidation::Clockwork::s_widthY
NTuple::Item< double > s_widthY[15]
Definition: SingleTrackValidation.cxx:103
Tuple
PerfMon::Tuple Tuple
Definition: PerfMonSvc.cxx:91