CMS 3D CMS Logo

EcalHitMaker.cc
Go to the documentation of this file.
5 
6 //#include "Geometry/EcalAlgo/interface/EcalBarrelGeometry.h"
7 //#include "Geometry/EcalAlgo/interface/EcalEndcapGeometry.h"
8 //#include "Geometry/CaloGeometry/interface/CaloCellGeometry.h"
9 
21 //#include "FastSimulation/Utilities/interface/Histos.h"
22 
23 //#include "Math/GenVector/Transform3D.h"
25 
26 #include <algorithm>
27 #include <cmath>
28 
32 
34  const XYZPoint& ecalentrance,
35  const DetId& cell, int onEcal,
36  unsigned size, unsigned showertype,
37  const RandomEngineAndDistribution* engine):
38  CaloHitMaker(theCalo,DetId::Ecal,((onEcal==1)?EcalBarrel:EcalEndcap),onEcal,showertype),
39  EcalEntrance_(ecalentrance),
40  onEcal_(onEcal),
41  myTrack_(nullptr),
42  random(engine)
43 {
44 #ifdef FAMOSDEBUG
45  myHistos = Histos::instance();
46 #endif
47  // myHistos->debug("Constructeur EcalHitMaker");
48  simulatePreshower_ = true;
49  X0depthoffset_ = 0. ;
50  X0PS1_ = 0.;
51  X0PS2_ = 0.;
52  X0PS2EE_ = 0.;
53  X0ECAL_ = 0.;
54  X0EHGAP_ = 0.;
55  X0HCAL_ = 0.;
56  L0PS1_ = 0.;
57  L0PS2_ = 0.;
58  L0PS2EE_ = 0.;
59  L0ECAL_ = 0.;
60  L0EHGAP_ = 0.;
61  L0HCAL_ = 0.;
62  maxX0_ = 0.;
63  totalX0_ = 0;
64  totalL0_ = 0.;
67  rearleakage_ = 0.;
68  bfactor_ = 1.;
69  ncrystals_ = 0;
70 
71  doreorg_ = !showertype;
72 
74 
75  if(onEcal)
77  else
78  pivot_=Crystal();
79  central_=onEcal==1;
81 
82  myCrystalWindowMap_ = nullptr;
83  // In some cases, a "dummy" grid, not based on a cell, can be built. The previous variables
84  // should however be initialized. In such a case onEcal=0
85  if(!onEcal) return;
86 
87  // Same size in eta-phi
88  etasize_ = size;
89  phisize_ = size;
90 
91  // Build the grid
92  // The result is put in CellsWindow and is ordered by distance to the pivot
94 
95  buildGeometry();
96  // std::cout << " Geometry built " << regionOfInterest_.size() << std::endl;
97 
99 
100  // A local vector of corners
101  mycorners.resize(4);
102  corners.resize(4);
103 
104 #ifdef DEBUGGW
105  myHistos->fill("h10",EcalEntrance_.eta(),CellsWindow_.size());
106  if(onEcal==2)
107  {
108  myHistos->fill("h20",EcalEntrance_.perp(),CellsWindow_.size());
109  if(EcalEntrance_.perp()>70&&EcalEntrance_.perp()<80&&CellsWindow_.size()<35)
110  {
111  std::cout << " Truncated grid " << CellsWindow_.size() << " " << EcalEntrance_.perp() << std::endl;
112  std::cout << " Pivot " << myCalorimeter->getEcalEndcapGeometry()->getGeometry(pivot_.getDetId())->getPosition().perp();
113  std::cout << EEDetId(pivot_.getDetId()) << std::endl;
114 
115  std::cout << " Test getClosestCell " << EcalEntrance_ << std::endl;
116  DetId testcell = myCalorimeter->getClosestCell(EcalEntrance_, true, false);
117  std::cout << " Result "<< EEDetId(testcell) << std::endl;
118  std::cout << " Position " << myCalorimeter->getEcalEndcapGeometry()->getGeometry(testcell)->getPosition() << std::endl;
119  }
120  }
121 
122 #endif
123 
124 }
125 
127 {
128  if (myCrystalWindowMap_ != nullptr)
129  {
130  delete myCrystalWindowMap_;
131  }
132 }
133 
134 bool
135 EcalHitMaker::addHitDepth(double r,double phi,double depth)
136 {
137 // std::cout << " Add hit depth called; Current deph is " << currentdepth_;
138 // std::cout << " Required depth is " << depth << std::endl;
139  depth+=X0depthoffset_;
140  double sp(1.);
141  r*=radiusFactor_;
142  CLHEP::Hep2Vector point(r*std::cos(phi),r*std::sin(phi));
143 
144  unsigned xtal=fastInsideCell(point,sp);
145  // if(cellid.isZero()) std::cout << " cell is Zero " << std::endl;
146 // if(xtal<1000)
147 // {
148 // std::cout << "Result " << regionOfInterest_[xtal].getX0Back() << " " ;
149 // std::cout << depth << std::endl;
150 // }
151 // myHistos->fill("h5000",depth);
152  if(xtal<1000)
153  {
154  // myHistos->fill("h5002",regionOfInterest_[xtal].getX0Back(),depth);
155  // myHistos->fill("h5003",ecalentrance_.eta(),maxX0_);
156  if(regionOfInterest_[xtal].getX0Back()>depth)
157  {
158  hits_[xtal]+=spotEnergy;
159  // myHistos->fill("h5005",r);
160  return true;
161  }
162  else
163  {
165  }
166  }
167  else
168  {
169 // std::cout << " Return false " << std::endl;
170 // std::cout << " Add hit depth called; Current deph is " << currentdepth_;
171 // std::cout << " Required depth is " << depth << std::endl;
172 // std::cout << " R = " << r << " " << radiusFactor_ << std::endl;
173  }
174 
176  return false;
177 }
178 
179 
180 //bool EcalHitMaker::addHitDepth(double r,double phi,double depth)
181 //{
182 // std::map<unsigned,float>::iterator itcheck=hitMap_.find(pivot_.getDetId().rawId());
183 // if(itcheck==hitMap_.end())
184 // {
185 // hitMap_.insert(std::pair<uint32_t,float>(pivot_.getDetId().rawId(),spotEnergy));
186 // }
187 // else
188 // {
189 // itcheck->second+=spotEnergy;
190 // }
191 // return true;
192 //}
193 
194 bool
195 EcalHitMaker::addHit(double r,double phi,unsigned layer)
196 {
197  // std::cout <<" Addhit " << std::endl;
198  // std::cout << " Before insideCell " << std::endl;
199  double sp(1.);
200  // std::cout << " Trying to add " << r << " " << phi << " " << radiusFactor_ << std::endl;
201  r*=radiusFactor_;
202  CLHEP::Hep2Vector point(r*std::cos(phi),r*std::sin(phi));
203  // std::cout << "point " << point << std::endl;
204  // CellID cellid=insideCell(point,sp);
205  unsigned xtal=fastInsideCell(point,sp);
206  // if(cellid.isZero()) std::cout << " cell is Zero " << std::endl;
207  if(xtal<1000)
208  {
209  if(sp==1.)
210  hits_[xtal]+=spotEnergy;
211  else
212  hits_[xtal]+=(random->flatShoot()<sp)*spotEnergy;
213  return true;
214  }
215 
217 // std::cout << " This hit ; r= " << point << " hasn't been added "<<std::endl;
218 // std::cout << " Xtal " << xtal << std::endl;
219 // for(unsigned ip=0;ip<npadsatdepth_;++ip)
220 // {
221 // std::cout << padsatdepth_[ip] << std::endl;
222 // }
223 
224  return false;
225 }
226 
227 // Temporary solution
228 //bool EcalHitMaker::addHit(double r,double phi,unsigned layer)
229 //{
230 // std::map<unsigned,float>::iterator itcheck=hitMap_.find(pivot_.getDetId().rawId());
231 // if(itcheck==hitMap_.end())
232 // {
233 // hitMap_.insert(std::pair<uint32_t,float>(pivot_.getDetId().rawId(),spotEnergy));
234 // }
235 // else
236 // {
237 // itcheck->second+=spotEnergy;
238 // }
239 // return true;
240 //}
241 
242 
243 unsigned
244 EcalHitMaker::fastInsideCell(const CLHEP::Hep2Vector & point,double & sp,bool debug)
245 {
246 
247  // debug = true;
248  bool found=false;
249  unsigned niter=0;
250  // something clever has to be implemented here
251  unsigned d1,d2;
252  convertIntegerCoordinates(point.x(),point.y(),d1,d2);
253  // std::cout << "Fastinside cell " << point.x() << " " << point.y() << " " << d1 << " "<< d2 << " " << nx_ << " " << ny_ << std::endl;
254  if(d1>=nx_||d2>=ny_)
255  {
256  // std::cout << " Not in the map " <<std::endl;
257  return 9999;
258  }
259  unsigned cell=myCrystalNumberArray_[d1][d2];
260  // We are likely to be lucky
261  // std::cout << " Got the cell " << cell << std::endl;
262  if (validPads_[cell]&&padsatdepth_[cell].inside(point))
263  {
264  // std::cout << " We are lucky " << cell << std::endl;
265  sp = padsatdepth_[cell].survivalProbability();
266  return cell;
267  }
268 
269  // std::cout << "Starting the loop " << std::endl;
270  bool status(true);
271  const std::vector<unsigned>& localCellVector(myCrystalWindowMap_->getCrystalWindow(cell,status));
272  if(status)
273  {
274  unsigned size=localCellVector.size();
275  // std::cout << " Starting from " << EBDetId(regionOfInterest_[cell].getDetId()) << std::endl;
276  // const std::vector<DetId>& neighbours=myCalorimeter->getNeighbours(regionOfInterest_[cell].getDetId());
277 // std::cout << " The neighbours are " << std::endl;
278 // for(unsigned ic=0;ic<neighbours.size(); ++ic)
279 // {
280 // std::cout << EBDetId(neighbours[ic]) << std::endl;
281 // }
282 // std::cout << " Done " << std::endl;
283  for(unsigned ic=0;ic<8&&ic<size;++ic)
284  {
285  unsigned iq=localCellVector[ic];
286 // std::cout << " Testing " << EBDetId(regionOfInterest_[iq].getDetId()) << std::endl; ;
287 // std::cout << " " << iq << std::endl;
288 // std::cout << padsatdepth_[iq] ;
289  if(validPads_[iq]&&padsatdepth_[iq].inside(point))
290  {
291  // std::cout << " Yes " << std::endl;
292  // myHistos->fill("h1000",niter);
293  sp = padsatdepth_[iq].survivalProbability();
294  // std::cout << "Finished the loop " << niter << std::endl;
295  // std::cout << "Inside " << std::endl;
296  return iq;
297  }
298  // std::cout << " Not inside " << std::endl;
299  // std::cout << "No " << std::endl;
300  ++niter;
301  }
302  }
303  if(debug) std::cout << " not found in a quad, let's check the " << ncrackpadsatdepth_ << " cracks " << std::endl;
304  // std::cout << "Finished the loop " << niter << std::endl;
305  // Let's check the cracks
306  // std::cout << " Let's check the cracks " << ncrackpadsatdepth_ << " " << crackpadsatdepth_.size() << std::endl;
307  unsigned iquad=0;
308  unsigned iquadinside=999;
309  while(iquad<ncrackpadsatdepth_&&!found)
310  {
311  // std::cout << " Inside the while " << std::endl;
312  if(crackpadsatdepth_[iquad].inside(point))
313  {
314  iquadinside=iquad;
315  found=true;
316  sp = crackpadsatdepth_[iquad].survivalProbability();
317  }
318  ++iquad;
319  ++niter;
320  }
321  // myHistos->fill("h1002",niter);
322  if(!found&&debug) std::cout << " Not found in the cracks " << std::endl;
323  return (found) ? crackpadsatdepth_[iquadinside].getNumber(): 9999;
324 }
325 
326 
327 void
329  double X0depthoffset,
330  const FSimTrack& theTrack)
331 {
332  // myHistos->debug("setTrackParameters");
333  // std::cout << " Track " << theTrack << std::endl;
334  intersections_.clear();
335  // This is certainly enough
336  intersections_.reserve(50);
337  myTrack_=&theTrack;
338  normal_=normal.Unit();
339  X0depthoffset_=X0depthoffset;
342 // std::cout << " Segments " << segments_.size() << std::endl;
343 // for(unsigned ii=0; ii<segments_.size() ; ++ii)
344 // {
345 // std::cout << segments_[ii] << std::endl;
346 // }
347 
348 
349  // This is only needed in case of electromagnetic showers
350  if(EMSHOWER&&onEcal_&&ecalTotalX0()>0.)
351  {
352  // std::cout << "Total X0 " << ecalTotalX0() << std::endl;
353  for(unsigned ic=0;ic<ncrystals_;++ic)
354  {
355  for(unsigned idir=0;idir<4;++idir)
356  {
357  XYZVector norm=regionOfInterest_[ic].exitingNormal(CaloDirectionOperations::Side(idir));
358  regionOfInterest_[ic].crystalNeighbour(idir).setToBeGlued((norm.Dot(normal_)<0.));
359  }
360  // Now calculate the distance in X0 of the back sides of the crystals
361  // (only for EM showers)
362  if(EMSHOWER)
363  {
364  XYZVector dir=regionOfInterest_[ic].getBackCenter()-segments_[ecalFirstSegment_].entrance();
365  double dist=dir.Dot(normal_);
366  double absciss= dist+segments_[ecalFirstSegment_].sEntrance();
367  std::vector<CaloSegment>::const_iterator segiterator;
368  // First identify the correct segment
369  // std::cout << " Crystal " << ic << regionOfInterest_[ic].getBackCenter() ;
370  // std::cout << " Entrance : " << segments_[ecalFirstSegment_].entrance()<< std::endl;
371  // std::cout << " Looking for the segment " << dist << std::endl;
372  segiterator = find_if(segments_.begin(),segments_.end(),CaloSegment::inSegment(absciss));
373  // std::cout << " Done " << std::endl;
374  if(segiterator==segments_.end() )
375  {
376  // in this case, we won't have any problem. No need to
377  // calculate the real depth.
378  regionOfInterest_[ic].setX0Back(9999);
379  }
380  else
381  {
382  DetId::Detector det(segiterator->whichDetector());
383  if(det!=DetId::Ecal)
384  {
385  regionOfInterest_[ic].setX0Back(9999);
386  }
387  else
388  {
389  double x0=segiterator->x0FromCm(dist);
390  if(x0<maxX0_) maxX0_=x0;
391  regionOfInterest_[ic].setX0Back(x0);
392  }
393  }
394  // myHistos->fill("h4000",ecalentrance_.eta(), regionOfInterest_[ic].getX0Back());
395  //}
396  // else
397  //{
398  // // in this case, we won't have any problem. No need to
399  // // calculate the real depth.
400  // regionOfInterest_[ic].setX0Back(9999);
401  //}
402  }//EMSHOWER
403  } // ndir
404  // myHistos->fill("h6000",segments_[ecalFirstSegment_].entrance().eta(),maxX0_);
405  }
406  // std::cout << "Leaving setTrackParameters" << std::endl
407 }
408 
409 
410 void
411 EcalHitMaker::cellLine(std::vector<CaloPoint>& cp)
412 {
413  cp.clear();
414  // if(myTrack->onVFcal()!=2)
415  // {
418  // }
419 
420  XYZPoint vertex(myTrack_->vertex().position().Vect());
421 
422  //sort the points by distance (in the ECAL they are not necessarily ordered)
423  XYZVector dir(0.,0.,0.);
424  if(myTrack_->onLayer1())
425  {
426  vertex=(myTrack_->layer1Entrance().vertex()).Vect();
427  dir=myTrack_->layer1Entrance().Vect().Unit();
428  }
429  else if(myTrack_->onLayer2())
430  {
431  vertex=(myTrack_->layer2Entrance().vertex()).Vect();
432  dir=myTrack_->layer2Entrance().Vect().Unit();
433  }
434  else if(myTrack_->onEcal())
435  {
436  vertex=(myTrack_->ecalEntrance().vertex()).Vect();
437  dir=myTrack_->ecalEntrance().Vect().Unit();
438  }
439  else if(myTrack_->onHcal())
440  {
441  vertex=(myTrack_->hcalEntrance().vertex()).Vect();
442  dir=myTrack_->hcalEntrance().Vect().Unit();
443  }
444  else if(myTrack_->onVFcal()==2)
445  {
446  vertex=(myTrack_->vfcalEntrance().vertex()).Vect();
447  dir=myTrack_->vfcalEntrance().Vect().Unit();
448  }
449  else
450  {
451  std::cout << " Problem with the grid " << std::endl;
452  }
453 
454  // Move the vertex for distance comparison (5cm)
455  vertex -= 5.*dir;
456  CaloPoint::DistanceToVertex myDistance(vertex);
457  sort(cp.begin(),cp.end(),myDistance);
458 
459  // The intersections with the HCAL shouldn't need to be sorted
460  // with the N.I it is actually a source of problems
461  hcalCellLine(cp);
462 
463 // std::cout << " Intersections ordered by distance to " << vertex << std::endl;
464 //
465 // for (unsigned ic=0;ic<cp.size();++ic)
466 // {
467 // XYZVector t=cp[ic]-vertex;
468 // std::cout << cp[ic] << " " << t.mag() << std::endl;
469 // }
470 }
471 
472 
473 void
474 EcalHitMaker::preshowerCellLine(std::vector<CaloPoint>& cp) const
475 {
476  // FSimEvent& mySimEvent = myEventMgr->simSignal();
477  // FSimTrack myTrack = mySimEvent.track(fsimtrack_);
478  // std::cout << "FsimTrack " << fsimtrack_<< std::endl;
479  // std::cout << " On layer 1 " << myTrack.onLayer1() << std::endl;
480  // std::cout << " preshowerCellLine " << std::endl;
481  if(myTrack_->onLayer1())
482  {
483  XYZPoint point1=(myTrack_->layer1Entrance().vertex()).Vect();
484  double phys_eta=myTrack_->layer1Entrance().eta();
485  double cmthickness =
487 
488  if(cmthickness>0)
489  {
491  XYZPoint point2=point1+dir*cmthickness;
492 
493  CaloPoint cp1(DetId::Ecal,EcalPreshower,1,point1);
494  CaloPoint cp2(DetId::Ecal,EcalPreshower,1,point2);
495  cp.push_back(cp1);
496  cp.push_back(cp2);
497  }
498  else
499  {
500  // std::cout << "Track on ECAL " << myTrack.EcalEntrance_().vertex()*0.1<< std::endl;
501  }
502  }
503 
504  // std::cout << " On layer 2 " << myTrack.onLayer2() << std::endl;
505  if(myTrack_->onLayer2())
506  {
507  XYZPoint point1=(myTrack_->layer2Entrance().vertex()).Vect();
508  double phys_eta=myTrack_->layer2Entrance().eta();
509  double cmthickness =
511  if(cmthickness>0)
512  {
514  XYZPoint point2=point1+dir*cmthickness;
515 
516 
517  CaloPoint cp1(DetId::Ecal,EcalPreshower,2,point1);
518  CaloPoint cp2(DetId::Ecal,EcalPreshower,2,point2);
519 
520  cp.push_back(cp1);
521  cp.push_back(cp2);
522  }
523  else
524  {
525  // std::cout << "Track on ECAL " << myTrack.EcalEntrance_().vertex()*0.1 << std::endl;
526  }
527  }
528  // std::cout << " Exit preshower CellLine " << std::endl;
529 }
530 
531 void
532 EcalHitMaker::hcalCellLine(std::vector<CaloPoint>& cp) const
533 {
534  // FSimEvent& mySimEvent = myEventMgr->simSignal();
535  // FSimTrack myTrack = mySimEvent.track(fsimtrack_);
536  int onHcal=myTrack_->onHcal();
537 
538  if(onHcal<=2&&onHcal>0)
539  {
540  XYZPoint point1=(myTrack_->hcalEntrance().vertex()).Vect();
541 
542  double eta=point1.eta();
543  // HCAL thickness in cm (assuming that the particle is coming from 000)
544  double thickness= myCalorimeter->hcalProperties(onHcal)->thickness(eta);
545  cp.push_back(CaloPoint(DetId::Hcal,point1));
546  XYZVector dir=myTrack_->hcalEntrance().Vect().Unit();
547  XYZPoint point2=point1+dir*thickness;
548 
549  cp.push_back(CaloPoint(DetId::Hcal,point2));
550 
551  }
552  int onVFcal=myTrack_->onVFcal();
553  if(onVFcal==2)
554  {
555  XYZPoint point1=(myTrack_->vfcalEntrance().vertex()).Vect();
556  double eta=point1.eta();
557  // HCAL thickness in cm (assuming that the particle is coming from 000)
558  double thickness= myCalorimeter->hcalProperties(3)->thickness(eta);
559  cp.push_back(CaloPoint(DetId::Hcal,point1));
561  if(thickness>0)
562  {
563  XYZPoint point2=point1+dir*thickness;
564  cp.push_back(CaloPoint(DetId::Hcal,point2));
565  }
566 
567  }
568 }
569 
570 void
571 EcalHitMaker::ecalCellLine(const XYZPoint& a,const XYZPoint& b,std::vector<CaloPoint>& cp)
572 {
573  // std::vector<XYZPoint> corners;
574  // corners.resize(4);
575  unsigned ic=0;
576  double t;
577  XYZPoint xp;
578  DetId c_entrance,c_exit;
579  bool entrancefound(false),exitfound(false);
580  // std::cout << " Look for intersections " << ncrystals_ << std::endl;
581  // std::cout << " regionOfInterest_ " << truncatedGrid_ << " " << regionOfInterest_.size() << std::endl;
582  // try to determine the number of crystals to test
583  // First determine the incident angle
584  double angle=std::acos(normal_.Dot(regionOfInterest_[0].getAxis().Unit()));
585 
586  // std::cout << " Normal " << normal_<< " Axis " << regionOfInterest_[0].getAxis().Unit() << std::endl;
587  double backdistance=std::sqrt(regionOfInterest_[0].getAxis().mag2())*std::tan(angle);
588  // 1/2.2cm = 0.45
589 // std::cout << " Angle " << angle << std::endl;
590 // std::cout << " Back distance " << backdistance << std::endl;
591  unsigned ncrystals=(unsigned)(backdistance*0.45);
592  unsigned highlim=(ncrystals+4);
593  highlim*=highlim;
594  if(highlim>ncrystals_) highlim=ncrystals_;
595  // unsigned lowlim=(ncrystals>2)? (ncrystals-2):0;
596  // std::cout << " Ncrys " << ncrystals << std::endl;
597 
598 
599  while(ic<ncrystals_&&(ic<highlim||!exitfound))
600  {
601  // Check front side
602  // if(!entrancefound)
603  {
604  const Plane3D& plan=regionOfInterest_[ic].getFrontPlane();
605 // XYZVector axis1=(plan.Normal());
606 // XYZVector axis2=regionOfInterest_[ic].getFirstEdge();
607  xp=intersect(plan,a,b,t,false);
608  regionOfInterest_[ic].getFrontSide(corners);
609  // CrystalPad pad(9999,onEcal_,corners,regionOfInterest_[ic].getCorner(0),axis1,axis2);
610  // if(pad.globalinside(xp))
611  if(inside3D(corners,xp))
612  {
613  cp.push_back(CaloPoint(regionOfInterest_[ic].getDetId(),UP,xp));
614  entrancefound=true;
615  c_entrance=regionOfInterest_[ic].getDetId();
616  // myHistos->fill("j12",highlim,ic);
617  }
618  }
619 
620  // check rear side
621  // if(!exitfound)
622  {
623  const Plane3D& plan=regionOfInterest_[ic].getBackPlane();
624 // XYZVector axis1=(plan.Normal());
625 // XYZVector axis2=regionOfInterest_[ic].getFifthEdge();
626  xp=intersect(plan,a,b,t,false);
627  regionOfInterest_[ic].getBackSide(corners);
628  // CrystalPad pad(9999,onEcal_,corners,regionOfInterest_[ic].getCorner(4),axis1,axis2);
629  // if(pad.globalinside(xp))
630  if(inside3D(corners,xp))
631  {
632  cp.push_back(CaloPoint(regionOfInterest_[ic].getDetId(),DOWN,xp));
633  exitfound=true;
634  c_exit=regionOfInterest_[ic].getDetId();
635  // std::cout << " Crystal : " << ic << std::endl;
636  // myHistos->fill("j10",highlim,ic);
637  }
638  }
639 
640  if(entrancefound&&exitfound&&c_entrance==c_exit) return;
641  // check lateral sides
642  for(unsigned iside=0;iside<4;++iside)
643  {
644  const Plane3D& plan=regionOfInterest_[ic].getLateralPlane(iside);
645  xp=intersect(plan,a,b,t,false);
646 // XYZVector axis1=(plan.Normal());
647 // XYZVector axis2=regionOfInterest_[ic].getLateralEdge(iside);
648  regionOfInterest_[ic].getLateralSide(iside,corners);
649  // CrystalPad pad(9999,onEcal_,corners,regionOfInterest_[ic].getCorner(iside),axis1,axis2);
650  // if(pad.globalinside(xp))
651  if(inside3D(corners,xp))
652  {
653  cp.push_back(CaloPoint(regionOfInterest_[ic].getDetId(),CaloDirectionOperations::Side(iside),xp));
654  // std::cout << cp[cp.size()-1] << std::endl;
655  }
656  }
657  // Go to next crystal
658  ++ic;
659  }
660 }
661 
662 
663 void
664 EcalHitMaker::buildSegments(const std::vector<CaloPoint>& cp)
665 {
666  // myHistos->debug();
667  // TimeMe theT("FamosGrid::buildSegments");
668  unsigned size=cp.size();
669  if(size%2!=0)
670  {
671  // std::cout << " There is a problem " << std::endl;
672  return;
673  }
674  // myHistos->debug();
675  unsigned nsegments=size/2;
676  segments_.reserve(nsegments);
677  if (size==0) return;
678  // curv abs
679  double s=0.;
680  double sX0=0.;
681  double sL0=0.;
682 
683  unsigned ncrossedxtals = 0;
684  unsigned is=0;
685  while(is<nsegments)
686  {
687 
688  if(cp[2*is].getDetId()!=cp[2*is+1].getDetId()&&
689  cp[2*is].whichDetector()!=DetId::Hcal&&
690  cp[2*is+1].whichDetector()!=DetId::Hcal)
691  {
692 // std::cout << " Problem with the segments " << std::endl;
693 // std::cout << cp[2*is].whichDetector() << " " << cp[2*is+1].whichDetector() << std::endl;
694 // std::cout << is << " " <<cp[2*is].getDetId().rawId() << std::endl;
695 // std::cout << (2*is+1) << " " <<cp[2*is+1].getDetId().rawId() << std::endl;
696  ++is;
697  continue;
698  }
699 
700  // Check if it is a Preshower segment - Layer 1
701  // One segment per layer, nothing between
702  // myHistos->debug("Just avant Preshower");
703  if(cp[2*is].whichDetector()==DetId::Ecal && cp[2*is].whichSubDetector()==EcalPreshower && cp[2*is].whichLayer()==1)
704  {
705  if(cp[2*is+1].whichDetector()==DetId::Ecal && cp[2*is+1].whichSubDetector()==EcalPreshower && cp[2*is+1].whichLayer()==1)
706  {
707  CaloSegment preshsegment(cp[2*is],cp[2*is+1],s,sX0,sL0,CaloSegment::PS,myCalorimeter);
708  segments_.push_back(preshsegment);
709  // std::cout << " Added (1-1)" << preshsegment << std::endl;
710  s+=preshsegment.length();
711  sX0+=preshsegment.X0length();
712  sL0+=preshsegment.L0length();
713  X0PS1_+=preshsegment.X0length();
714  L0PS1_+=preshsegment.L0length();
715  }
716  else
717  {
718  std::cout << " Strange segment between Preshower1 and " << cp[2*is+1].whichDetector();
719  std::cout << std::endl;
720  }
721  ++is;
722  continue;
723  }
724 
725  // Check if it is a Preshower segment - Layer 2
726  // One segment per layer, nothing between
727  if(cp[2*is].whichDetector()==DetId::Ecal && cp[2*is].whichSubDetector()==EcalPreshower && cp[2*is].whichLayer()==2)
728  {
729  if(cp[2*is+1].whichDetector()==DetId::Ecal && cp[2*is+1].whichSubDetector()==EcalPreshower && cp[2*is+1].whichLayer()==2)
730  {
731  CaloSegment preshsegment(cp[2*is],cp[2*is+1],s,sX0,sL0,CaloSegment::PS,myCalorimeter);
732  segments_.push_back(preshsegment);
733  // std::cout << " Added (1-2)" << preshsegment << std::endl;
734  s+=preshsegment.length();
735  sX0+=preshsegment.X0length();
736  sL0+=preshsegment.L0length();
737  X0PS2_+=preshsegment.X0length();
738  L0PS2_+=preshsegment.L0length();
739 
740  // material between preshower and EE
741  if(is<(nsegments-1) && cp[2*is+2].whichDetector()==DetId::Ecal && cp[2*is+2].whichSubDetector()==EcalEndcap)
742  {
743  CaloSegment gapsef(cp[2*is+1],cp[2*is+2],s,sX0,sL0,CaloSegment::PSEEGAP,myCalorimeter);
744  segments_.push_back(gapsef);
745  s+=gapsef.length();
746  sX0+=gapsef.X0length();
747  sL0+=gapsef.L0length();
748  X0PS2EE_+=gapsef.X0length();
749  L0PS2EE_+=gapsef.L0length();
750  // std::cout << " Created a segment " << gapsef.length()<< " " << gapsef.X0length()<< std::endl;
751  }
752  }
753  else
754  {
755  std::cout << " Strange segment between Preshower2 and " << cp[2*is+1].whichDetector();
756  std::cout << std::endl;
757  }
758  ++is;
759  continue;
760  }
761  // Now deal with the ECAL
762  // One segment in each crystal. Segment corresponding to cracks/gaps are added
763  // myHistos->debug("Just avant ECAL");
764  if(cp[2*is].whichDetector()==DetId::Ecal && (cp[2*is].whichSubDetector()==EcalBarrel || cp[2*is].whichSubDetector()==EcalEndcap))
765  {
766  if(cp[2*is+1].whichDetector()==DetId::Ecal && (cp[2*is+1].whichSubDetector()==EcalBarrel || cp[2*is+1].whichSubDetector()==EcalEndcap) )
767  {
768  DetId cell2=cp[2*is+1].getDetId();
769  // set the real entrance
771 
772  // !! Approximatiom : the first segment is always in a crystal
773  if(cp[2*is].getDetId()==cell2)
774  {
775  CaloSegment segment(cp[2*is],cp[2*is+1],s,sX0,sL0,CaloSegment::PbWO4,myCalorimeter);
776  segments_.push_back(segment);
777  // std::cout << " Added (2)" << segment << std::endl;
778  s+=segment.length();
779  sX0+=segment.X0length();
780  sL0+=segment.L0length();
781  X0ECAL_+=segment.X0length();
782  L0ECAL_+=segment.L0length();
783  ++ncrossedxtals;
784  ++is;
785  }
786  else
787  {
788  std::cout << " One more bug in the segment " <<std::endl;
789  ++is;
790  }
791  // Now check if a gap or crack should be added
792  if(is>0 && is<nsegments)
793  {
794  DetId cell3=cp[2*is].getDetId();
795  if(cp[2*is].whichDetector()!=DetId::Hcal)
796  {
797  // Crack inside the ECAL
798  bool bordercrossing=myCalorimeter->borderCrossing(cell2,cell3);
799  CaloSegment cracksegment(cp[2*is-1],cp[2*is],s,sX0,sL0,(bordercrossing)?CaloSegment::CRACK:CaloSegment::GAP,myCalorimeter);
800  segments_.push_back(cracksegment);
801  s+=cracksegment.length();
802  sX0+=cracksegment.X0length();
803  sL0+=cracksegment.L0length();
804  X0ECAL_+=cracksegment.X0length();
805  L0ECAL_+=cracksegment.L0length();
806  // std::cout <<" Added(3) "<< cracksegment << std::endl;
807  }
808  else
809  {
810  // a segment corresponding to ECAL/HCAL transition should be
811  // added here
812  CaloSegment cracksegment(cp[2*is-1],cp[2*is],s,sX0,sL0,CaloSegment::ECALHCALGAP,myCalorimeter);
813  segments_.push_back(cracksegment);
814  s+=cracksegment.length();
815  sX0+=cracksegment.X0length();
816  sL0+=cracksegment.L0length();
817  X0EHGAP_+=cracksegment.X0length();
818  L0EHGAP_+=cracksegment.L0length();
819  }
820  }
821  continue;
822  }
823  else
824  {
825  std::cout << " Strange segment between " << cp[2*is].whichDetector();
826  std::cout << " and " << cp[2*is+1].whichDetector() << std::endl;
827  ++is;
828  continue;
829  }
830  }
831  // myHistos->debug("Just avant HCAL");
832  // HCAL
833  if(cp[2*is].whichDetector()==DetId::Hcal&&cp[2*is+1].whichDetector()==DetId::Hcal)
834  {
835  CaloSegment segment(cp[2*is],cp[2*is+1],s,sX0,sL0,CaloSegment::HCAL,myCalorimeter);
836  segments_.push_back(segment);
837  s+=segment.length();
838  sX0+=segment.X0length();
839  sL0+=segment.L0length();
840  X0HCAL_+=segment.X0length();
841  L0HCAL_+=segment.L0length();
842  // std::cout <<" Added(4) "<< segment << std::endl;
843  ++is;
844  }
845  }
846 // std::cout << " PS1 " << X0PS1_ << " " << L0PS1_ << std::endl;
847 // std::cout << " PS2 " << X0PS2_ << " " << L0PS2_ << std::endl;
848 // std::cout << " ECAL " << X0ECAL_ << " " << L0ECAL_ << std::endl;
849 // std::cout << " HCAL " << X0HCAL_ << " " << L0HCAL_ << std::endl;
850 
853  // myHistos->debug("Just avant le fill");
854 
855  #ifdef DEBUGCELLLINE
856  myHistos->fill("h200",fabs(EcalEntrance_.eta()),X0ECAL_);
857  myHistos->fill("h210",EcalEntrance_.phi(),X0ECAL_);
858  if(X0ECAL_<20)
859  myHistos->fill("h212",EcalEntrance_.phi(),X0ECAL_);
860 // if(X0ECAL_<1.)
861 // {
862 // for(unsigned ii=0; ii<segments_.size() ; ++ii)
863 // {
864 // std::cout << segments_[ii] << std::endl;
865 // }
866 // }
867  myHistos->fillByNumber("h30",ncrossedxtals,EcalEntrance_.eta(),X0ECAL_);
868 
869  double zvertex = myTrack_->vertex().position().z();
870 
871  myHistos->fill("h310",EcalEntrance_.eta(),X0ECAL_);
872  if(X0ECAL_<22) myHistos->fill("h410",EcalEntrance_.phi());
873  myHistos->fill("h400",zvertex,X0ECAL_);
874  #endif
875  // std::cout << " Finished the segments " << std::endl;
876 
877 }
878 
879 void
881 {
882  configuredGeometry_ = false;
883  ncrystals_ = CellsWindow_.size();
884  // create the vector with of pads with the appropriate size
885  padsatdepth_.resize(ncrystals_);
886 
887  // This is fully correct in the barrel.
888  ny_= phisize_;
890  std::vector<unsigned> empty;
891  empty.resize(ny_,0);
892  myCrystalNumberArray_.reserve((unsigned)nx_);
893  for(unsigned inx=0;inx<(unsigned)nx_;++inx)
894  {
895  myCrystalNumberArray_.push_back(empty);
896  }
897 
898  hits_.resize(ncrystals_,0.);
899  regionOfInterest_.clear();
901  validPads_.resize(ncrystals_);
902  for(unsigned ic=0;ic<ncrystals_;++ic)
903  {
905  regionOfInterest_[ic].setNumber(ic);
906  DetIdMap_.insert(std::pair<DetId,unsigned>(CellsWindow_[ic],ic));
907  }
908 
909  // Computes the map of the neighbours
911 }
912 
913 
914 
915 // depth is in X0 , L0 (depending on EMSHOWER/HADSHOWER) or in CM if inCM
916 bool
917 EcalHitMaker::getPads(double depth,bool inCm)
918 {
919  //std::cout << " New depth " << depth << std::endl;
920  // The first time, the relationship between crystals must be calculated
921  // but only in the case of EM showers
922 
924 
925 
927  detailedShowerTail_ = false;
928  if(EMSHOWER)
930  else
932 
933 // if(currentdepth_>maxX0_+ps1TotalX0()+ps2TotalX0())
934 // {
935 // currentdepth_=maxX0_+ps1TotalX0()+ps2TotalX0()-1.; // the -1 is for safety
936 // detailedShowerTail_=true;
937 // }
938 
939 // std::cout << " FamosGrid::getQuads " << currentdepth_ << " " << maxX0_ << std::endl;
940 
942 
943  xmin_=ymin_=999;
944  xmax_=ymax_=-999;
945  double locxmin,locxmax,locymin,locymax;
946 
947  // Get the depth of the pivot
948  std::vector<CaloSegment>::const_iterator segiterator;
949  // First identify the correct segment
950 
951  if(inCm) // centimeter
952  {
953  segiterator = find_if(segments_.begin(),segments_.end(),CaloSegment::inSegment(currentdepth_));
954  }
955  else
956  {
957  // EM shower
958  if(EMSHOWER)
959  segiterator = find_if(segments_.begin(),segments_.end(),CaloSegment::inX0Segment(currentdepth_));
960 
961  //Hadron shower
962  if(HADSHOWER)
963  segiterator = find_if(segments_.begin(),segments_.end(),CaloSegment::inL0Segment(currentdepth_));
964  }
965  if(segiterator==segments_.end())
966  {
967  std::cout << " FamosGrid: Could not go at such depth " << depth << std::endl;
968  std::cout << " EMSHOWER " << EMSHOWER << std::endl;
969  std::cout << " Track " << *myTrack_ << std::endl;
970  std::cout << " Segments " << segments_.size() << std::endl;
971  for(unsigned ii=0; ii<segments_.size() ; ++ii)
972  {
973  std::cout << segments_[ii] << std::endl;
974  }
975 
976  return false;
977  }
978  // std::cout << *segiterator << std::endl;
979 
980  if(segiterator->whichDetector()!=DetId::Ecal)
981  {
982  std::cout << " In " << segiterator->whichDetector() << std::endl;
983  // buildPreshower();
984  return false;
985  }
986 
987  // std::cout << *segiterator << std::endl;
988  // get the position of the origin
989 
990  XYZPoint origin;
991  if(inCm)
992  {
993  origin=segiterator->positionAtDepthincm(currentdepth_);
994  }
995  else
996  {
997  if(EMSHOWER)
998  origin=segiterator->positionAtDepthinX0(currentdepth_);
999  if(HADSHOWER)
1000  origin=segiterator->positionAtDepthinL0(currentdepth_);
1001  }
1002  // std::cout << " currentdepth_ " << currentdepth_ << " " << origin << std::endl;
1003  XYZVector newaxis=pivot_.getFirstEdge().Cross(normal_);
1004 
1005 // std::cout << "Normal " << normal_ << std::endl;
1006 // std::cout << " New axis " << newaxis << std::endl;
1007 
1008 // std::cout << " ncrystals " << ncrystals << std::endl;
1009  plan_ = Plane3D((Vector)normal_,(Point)origin);
1010 
1011  unsigned nquads=0;
1012  double sign=(central_) ? -1.: 1.;
1013  Transform3DR trans((Point)origin,(Point)(origin+normal_),(Point)(origin+newaxis),
1014  Point(0,0,0), Point(0.,0.,sign), Point(0.,1.,0.));
1015  for(unsigned ic=0;ic<ncrystals_;++ic)
1016  {
1017  // std::cout << " Building geometry for " << regionOfInterest_[ic].getCellID() << std::endl;
1018  XYZPoint a,b;
1019 
1020  // std::cout << " Origin " << origin << std::endl;
1021 
1022  // std::vector<XYZPoint> corners;
1023  // corners.reserve(4);
1024  double dummyt;
1025  bool hasbeenpulled=false;
1026  bool behindback=false;
1027  for(unsigned il=0;il<4;++il)
1028  {
1029  // a is the il-th front corner of the crystal. b is the corresponding rear corner
1030  regionOfInterest_[ic].getLateralEdges(il,a,b);
1031 
1032  // pull the surface if necessary (only in the front of the crystals)
1033  XYZPoint aprime=a;
1034  if(pulled(origin,normal_,a))
1035  {
1036  b=aprime;
1037  hasbeenpulled=true;
1038  }
1039 
1040  // compute the intersection.
1041  // Check that the intersection is in the [a,b] segment if HADSHOWER
1042  // if EMSHOWER the intersection is calculated as if the crystals were infinite
1043  XYZPoint xx=(EMSHOWER)?intersect(plan_,a,b,dummyt,false):intersect(plan_,a,b,dummyt,true);
1044 
1045  if(dummyt>1) behindback=true;
1046  // std::cout << " Intersect " << il << " " << a << " " << b << " " << plan_ << " " << xx << std::endl;
1047  // check that the intersection actually exists
1048  if(xx.mag2()!=0)
1049  {
1050  corners[il] = xx;
1051  }
1052  }
1053  // std::cout << " ncorners " << corners.size() << std::endl;
1054  if(behindback&&EMSHOWER) detailedShowerTail_=true;
1055  // If the quad is completly defined. Store it !
1056  if(corners.size()==4)
1057  {
1059  // Parameter to be tuned
1060  if(hasbeenpulled) padsatdepth_[ic].setSurvivalProbability(pulledPadProbability_);
1061  validPads_[ic]=true;
1062  ++nquads;
1063  // In principle, this should be done after the quads reorganization. But it would cost one more loop
1064  // quadsatdepth_[ic].extrems(locxmin,locxmax,locymin,locymax);
1065  // if(locxmin<xmin_) xmin_=locxmin;
1066  // if(locymin<ymin_) ymin_=locymin;
1067  // if(locxmax>xmax_) xmax_=locxmax;
1068  // if(locymax>ymax_) ymax_=locymax;
1069  }
1070  else
1071  {
1072  padsatdepth_[ic]=CrystalPad();
1073  validPads_[ic]=false;
1074  }
1075  }
1076  // std::cout << " Number of quads " << quadsatdepth_.size() << std::endl;
1077  if(doreorg_)reorganizePads();
1078  // std::cout << "Finished to reorganize " << std::endl;
1079  npadsatdepth_=nquads;
1080  // std::cout << " prepareCellIDMap " << std::endl;
1081 
1082 
1083  // Resize the Quads to allow for some numerical inaccuracy
1084  // in the "inside" function
1085  for(unsigned ic=0;ic<ncrystals_;++ic)
1086  {
1087 
1088  if (!validPads_[ic]) continue;
1089 
1090  if(EMSHOWER) padsatdepth_[ic].resetCorners();
1091 
1092  padsatdepth_[ic].extrems(locxmin,locxmax,locymin,locymax);
1093  if(locxmin<xmin_) xmin_=locxmin;
1094  if(locymin<ymin_) ymin_=locymin;
1095  if(locxmax>xmax_) xmax_=locxmax;
1096  if(locymax>ymax_) ymax_=locymax;
1097  }
1098 
1099  sizex_=(xmax_-xmin_)/nx_;
1100  sizey_=(ymax_-ymin_)/ny_;
1101 
1102 
1103  // Make sure that sizex_ and sizey_ are set before running prepareCellIDMap
1105 
1106  // std::cout << " Finished prepareCellIDMap " << std::endl;
1108 
1109  return true;
1110 }
1111 
1112 
1113 
1114 
1115 void
1117 {
1118  configuredGeometry_=true;
1119  for(unsigned ic=0;ic<ncrystals_;++ic)
1120  {
1121  // std::cout << " Building " << cellids_[ic] << std::endl;
1122  for(unsigned idir=0;idir<8;++idir)
1123  {
1124 
1125  unsigned oppdir=CaloDirectionOperations::oppositeDirection(idir);
1126  // Is there something else to do ?
1127  // The relationship with the neighbour may have been set previously.
1128  if(regionOfInterest_[ic].crystalNeighbour(idir).status()>=0)
1129  {
1130  // std::cout << " Nothing to do " << std::endl;
1131  continue ;
1132  }
1133 
1134  const DetId & oldcell(regionOfInterest_[ic].getDetId());
1136  DetId newcell(oldcell);
1137  if(!myCalorimeter->move(newcell,dir))
1138  {
1139  // no neighbour in this direction
1140  regionOfInterest_[ic].crystalNeighbour(idir).setStatus(-1);
1141  continue;
1142  }
1143  // Determine the number of this neighbour
1144  // std::cout << " The neighbour is " << newcell << std::endl;
1145  std::map<DetId,unsigned>::const_iterator niter(DetIdMap_.find(newcell));
1146  if(niter==DetIdMap_.end())
1147  {
1148  // std::cout << " The neighbour is not in the map " << std::endl;
1149  regionOfInterest_[ic].crystalNeighbour(idir).setStatus(-1);
1150  continue;
1151  }
1152  // Now there is a neighbour
1153  // std::cout << " The neighbour is " << niter->second << " " << cellids_[niter->second] << std::endl;
1154  regionOfInterest_[ic].crystalNeighbour(idir).setNumber(niter->second);
1155  // std::cout << " Managed to set crystalNeighbour " << ic << " " << idir << std::endl;
1156  // std::cout << " Trying " << niter->second << " " << oppdir << std::endl;
1157  regionOfInterest_[niter->second].crystalNeighbour(oppdir).setNumber(ic);
1158  // std::cout << " Crack/gap " << std::endl;
1159  if(myCalorimeter->borderCrossing(oldcell,newcell))
1160  {
1161  regionOfInterest_[ic].crystalNeighbour(idir).setStatus(1);
1162  regionOfInterest_[niter->second].crystalNeighbour(oppdir).setStatus(1);
1163  // std::cout << " Crack ! " << std::endl;
1164  }
1165  else
1166  {
1167  regionOfInterest_[ic].crystalNeighbour(idir).setStatus(0);
1168  regionOfInterest_[niter->second].crystalNeighbour(oppdir).setStatus(0);
1169  // std::cout << " Gap" << std::endl;
1170  }
1171  }
1172  }
1173  // Magnetic field a la Charlot
1174  double theta=EcalEntrance_.theta();
1175  if(theta>M_PI_2) theta=M_PI-theta;
1176  bfactor_=1./(1.+0.133*theta);
1177  if(myCalorimeter->magneticField()==0. ) bfactor_=1.;
1178 }
1179 
1180 // project fPoint on the plane (original,normal)
1181 bool
1183  const XYZNormal& normal,
1184  XYZPoint & fPoint) const
1185 {
1186  // check if fPoint is behind the origin
1187  double dotproduct=normal.Dot(fPoint-origin);
1188  if(dotproduct<=0.) return false;
1189 
1190  //norm of normal is 1
1191  fPoint -= (1+dotproduct)*normal;
1192  return true;
1193 }
1194 
1195 
1196 void
1198 {
1199  for(unsigned iq=0;iq<npadsatdepth_;++iq)
1200  {
1201  if(!validPads_[iq]) continue;
1202  unsigned d1,d2;
1203  convertIntegerCoordinates(padsatdepth_[iq].center().x(),padsatdepth_[iq].center().y(),d1,d2);
1204  myCrystalNumberArray_[d1][d2]=iq;
1205  }
1206 }
1207 
1208 void EcalHitMaker::convertIntegerCoordinates(double x, double y,unsigned &ix,unsigned &iy) const
1209 {
1210  int tix=(int)((x-xmin_)/sizex_);
1211  int tiy=(int)((y-ymin_)/sizey_);
1212  ix=iy=9999;
1213  if(tix>=0) ix=(unsigned)tix;
1214  if(tiy>=0) iy=(unsigned)tiy;
1215 }
1216 
1217 const std::map<CaloHitID,float>& EcalHitMaker::getHits()
1218 {
1219  if (hitmaphasbeencalculated_) return hitMap_;
1220  for(unsigned ic=0;ic<ncrystals_;++ic)
1221  {
1222  //calculate time of flight
1223  float tof = 0.0;
1224  if(onEcal_==1 || onEcal_==2) tof = (myCalorimeter->getEcalGeometry(onEcal_)->getGeometry(regionOfInterest_[ic].getDetId())->getPosition().mag())/29.98; //speed of light
1225 
1226  if(onEcal_==1){
1227  CaloHitID current_id(EBDetId(regionOfInterest_[ic].getDetId().rawId()).hashedIndex(),tof,0); //no track yet
1228  hitMap_.insert(std::pair<CaloHitID,float>(current_id,hits_[ic]));
1229  }
1230  else if(onEcal_==2){
1231  CaloHitID current_id(EEDetId(regionOfInterest_[ic].getDetId().rawId()).hashedIndex(),tof,0); //no track yet
1232  hitMap_.insert(std::pair<CaloHitID,float>(current_id,hits_[ic]));
1233  }
1234  }
1236  return hitMap_;
1237 }
1238 
1239 
1241 
1242 void
1244 {
1245 
1246  // Some cleaning first
1247  // std::cout << " Starting reorganize " << std::endl;
1248  crackpadsatdepth_.clear();
1251  std::vector<neighbour> gaps;
1252  std::vector<std::vector<neighbour> > cracks;
1253  // cracks.clear();
1254  cracks.resize(ncrystals_);
1255 
1256 
1257  for(unsigned iq=0;iq<ncrystals_;++iq)
1258  {
1259  if(!validPads_[iq]) continue;
1260 
1261  gaps.clear();
1262  // std::cout << padsatdepth_[iq] << std::endl;
1263  //check all the directions
1264  for(unsigned iside=0;iside<4;++iside)
1265  {
1266  // std::cout << " To be glued " << iside << " " << regionOfInterest_[iq].crystalNeighbour(iside).toBeGlued() << std::endl;
1268  if(regionOfInterest_[iq].crystalNeighbour(iside).toBeGlued())
1269  {
1270  // look for the neighbour and check that it exists
1271  int neighbourstatus=regionOfInterest_[iq].crystalNeighbour(iside).status();
1272  if(neighbourstatus<0)
1273  continue;
1274 
1275  unsigned neighbourNumber=regionOfInterest_[iq].crystalNeighbour(iside).number();
1276  if(!validPads_[neighbourNumber]) continue;
1277  // there is a crack between
1278  if(neighbourstatus==1)
1279  {
1280  // std::cout << " 1 Crack : " << thisside << " " << cellids_[iq]<< " " << cellids_[neighbourNumber] << std::endl;
1281  cracks[iq].push_back(neighbour(thisside,neighbourNumber));
1282  } // else it is a gap
1283  else
1284  {
1285  gaps.push_back(neighbour(thisside,neighbourNumber));
1286  }
1287  }
1288  }
1289  // Now lift the gaps
1290  gapsLifting(gaps,iq);
1291  }
1292 
1293  unsigned ncracks=cracks.size();
1294  // std::cout << " Cracks treatment : " << cracks.size() << std::endl;
1295  for(unsigned icrack=0;icrack<ncracks;++icrack)
1296  {
1297  // std::cout << " Crack number " << crackiter->first << std::endl;
1298  cracksPads(cracks[icrack],icrack);
1299  }
1300 
1301 }
1302 
1303 //dir 2 = N,E,W,S
1304 CLHEP::Hep2Vector &
1306 {
1309  // std::cout << "Corresponding Edge " << dir<< " " << dir2 << " " << corner << std::endl;
1310  return padsatdepth_[myneighbour.second].edge(corner);
1311 }
1312 
1313 bool EcalHitMaker::diagonalEdge(unsigned myPad, CaloDirection dir,CLHEP::Hep2Vector & point)
1314 {
1316  if(regionOfInterest_[myPad].crystalNeighbour(idir).status()<0)
1317  return false;
1318  unsigned nneighbour=regionOfInterest_[myPad].crystalNeighbour(idir).number();
1319  if(!validPads_[nneighbour])
1320  {
1321  // std::cout << " Wasn't able to move " << std::endl;
1322  return false;
1323  }
1324  point = padsatdepth_[nneighbour].edge(CaloDirectionOperations::oppositeSide(dir));
1325  return true;
1326 }
1327 
1328 bool EcalHitMaker::unbalancedDirection(const std::vector<neighbour>& dirs,unsigned & unb,unsigned & dir1, unsigned & dir2)
1329 {
1330  if(dirs.size()==1) return false;
1331  if(dirs.size()%2==0) return false;
1333  tmp=CaloDirectionOperations::add2d(dirs[0].first,dirs[1].first);
1334  if(tmp==NONE)
1335  {
1336  unb=2;
1337  dir1=0;
1338  dir2=1;
1339  return true;
1340  }
1341  tmp=CaloDirectionOperations::add2d(dirs[0].first,dirs[2].first);
1342  if(tmp==NONE)
1343  {
1344  unb=1;
1345  dir1=0;
1346  dir2=2;
1347  return true;
1348  }
1349  unb=0;
1350  dir1=1;
1351  dir2=2;
1352  return true;
1353 }
1354 
1355 
1356 void
1357 EcalHitMaker::gapsLifting(std::vector<neighbour>& gaps,unsigned iq)
1358 {
1359  // std::cout << " Entering gapsLifting " << std::endl;
1360  CrystalPad & myPad = padsatdepth_[iq];
1361  unsigned ngaps=gaps.size();
1362  constexpr bool debug=false;
1363  if(ngaps==1)
1364  {
1365  if(debug)
1366  {
1367  std::cout << " Avant " << ngaps << " " <<gaps[0].first<< std::endl;
1368  std::cout << myPad << std::endl;
1369  }
1370  if(gaps[0].first==NORTH||gaps[0].first==SOUTH)
1371  {
1374  myPad.edge(dir1)=correspondingEdge(gaps[0],EAST);
1375  myPad.edge(dir2)=correspondingEdge(gaps[0],WEST);
1376  }
1377  else
1378  {
1381  myPad.edge(dir1)=correspondingEdge(gaps[0],NORTH);
1382  myPad.edge(dir2)=correspondingEdge(gaps[0],SOUTH);
1383  }
1384  if(debug)
1385  {
1386  std::cout << " Apres " << std::endl;
1387  std::cout << myPad << std::endl;
1388  }
1389  }
1390  else
1391  if(ngaps==2)
1392  {
1393  if(debug)
1394  {
1395  std::cout << " Avant " << ngaps << " " <<gaps[0].first<< " " <<gaps[1].first << std::endl;
1396  std::cout << myPad << std::endl;
1397  std::cout << " Voisin 1 " << (gaps[0].second) << std::endl;
1398  std::cout << " Voisin 2 " << (gaps[1].second) << std::endl;
1399  }
1400  CaloDirection corner0=CaloDirectionOperations::add2d(gaps[0].first,gaps[1].first);
1401 
1402  CLHEP::Hep2Vector point(0.,0.);
1403  if(corner0!=NONE&&diagonalEdge(iq,corner0,point))
1404  {
1407  myPad.edge(corner0) = point;
1408  myPad.edge(corner1) = correspondingEdge(gaps[1],CaloDirectionOperations::oppositeSide(gaps[0].first));
1409  myPad.edge(corner2) = correspondingEdge(gaps[0],CaloDirectionOperations::oppositeSide(gaps[1].first));
1410  }
1411  else
1412  if(corner0==NONE)
1413  {
1414  if(gaps[0].first==EAST||gaps[0].first==WEST)
1415  {
1416  CaloDirection corner1=CaloDirectionOperations::add2d(gaps[0].first,NORTH);
1417  CaloDirection corner2=CaloDirectionOperations::add2d(gaps[0].first,SOUTH);
1418  myPad.edge(corner1)=correspondingEdge(gaps[0],NORTH);
1419  myPad.edge(corner2)=correspondingEdge(gaps[0],SOUTH);
1420 
1421  corner1=CaloDirectionOperations::add2d(gaps[1].first,NORTH);
1422  corner2=CaloDirectionOperations::add2d(gaps[1].first,SOUTH);
1423  myPad.edge(corner1)=correspondingEdge(gaps[1],NORTH);
1424  myPad.edge(corner2)=correspondingEdge(gaps[1],SOUTH);
1425  }
1426  else
1427  {
1428  CaloDirection corner1=CaloDirectionOperations::add2d(gaps[0].first,EAST);
1429  CaloDirection corner2=CaloDirectionOperations::add2d(gaps[0].first,WEST);
1430  myPad.edge(corner1)=correspondingEdge(gaps[0],EAST);
1431  myPad.edge(corner2)=correspondingEdge(gaps[0],WEST);
1432 
1433  corner1=CaloDirectionOperations::add2d(gaps[1].first,EAST);
1434  corner2=CaloDirectionOperations::add2d(gaps[1].first,WEST);
1435  myPad.edge(corner1)=correspondingEdge(gaps[1],EAST);
1436  myPad.edge(corner2)=correspondingEdge(gaps[1],WEST);
1437  }
1438  }
1439  if(debug)
1440  {
1441  std::cout << " Apres " << std::endl;
1442  std::cout << myPad << std::endl;
1443  }
1444  }
1445  else
1446  if(ngaps==3)
1447  {
1448  // in this case the four corners have to be changed
1449  unsigned iubd,idir1,idir2;
1450  CaloDirection diag;
1451  CLHEP::Hep2Vector point(0.,0.);
1452  // std::cout << " Yes : 3 gaps" << std::endl;
1453  if(unbalancedDirection(gaps,iubd,idir1,idir2))
1454  {
1455  CaloDirection ubd(gaps[iubd].first),dir1(gaps[idir1].first);
1456  CaloDirection dir2(gaps[idir2].first);
1457 
1458  // std::cout << " Avant " << std::endl << myPad << std::endl;
1459  // std::cout << ubd << " " << dir1 << " " << dir2 << std::endl;
1460  diag=CaloDirectionOperations::add2d(ubd,dir1);
1461  if(diagonalEdge(iq,diag,point))
1462  myPad.edge(diag)=point;
1463  diag=CaloDirectionOperations::add2d(ubd,dir2);
1464  if(diagonalEdge(iq,diag,point))
1465  myPad.edge(diag)=point;
1467  myPad.edge(CaloDirectionOperations::add2d(oppside,dir1))=correspondingEdge(gaps[idir1],oppside);
1468  myPad.edge(CaloDirectionOperations::add2d(oppside,dir2))=correspondingEdge(gaps[idir2],oppside);
1469  // std::cout << " Apres " << std::endl << myPad << std::endl;
1470  }
1471  }
1472  else
1473  if(ngaps==4)
1474  {
1475  // std::cout << " Waouh :4 gaps" << std::endl;
1476  // std::cout << " Avant " << std::endl;
1477  // std::cout << myPad<< std::endl;
1478  CLHEP::Hep2Vector point(0.,0.);
1479  if(diagonalEdge(iq,NORTHEAST,point))
1480  myPad.edge(NORTHEAST)=point;
1481  if(diagonalEdge(iq,NORTHWEST,point))
1482  myPad.edge(NORTHWEST)=point;
1483  if(diagonalEdge(iq,SOUTHWEST,point))
1484  myPad.edge(SOUTHWEST)=point;
1485  if(diagonalEdge(iq,SOUTHEAST,point))
1486  myPad.edge(SOUTHEAST)=point;
1487  // std::cout << " Apres " << std::endl;
1488  // std::cout << myPad<< std::endl;
1489  }
1490 }
1491 
1492 void
1493 EcalHitMaker::cracksPads(std::vector<neighbour> & cracks, unsigned iq)
1494 {
1495  // std::cout << " myPad " << &myPad << std::endl;
1496  unsigned ncracks=cracks.size();
1497  CrystalPad & myPad = padsatdepth_[iq];
1498  for(unsigned ic=0;ic<ncracks;++ic)
1499  {
1500  // std::vector<CLHEP::Hep2Vector> mycorners;
1501  // mycorners.reserve(4);
1502  switch(cracks[ic].first)
1503  {
1504  case NORTH:
1505  {
1506  mycorners[0] = (padsatdepth_[cracks[ic].second].edge(SOUTHWEST));
1507  mycorners[1] = (padsatdepth_[cracks[ic].second].edge(SOUTHEAST));
1508  mycorners[2] = (myPad.edge(NORTHEAST));
1509  mycorners[3] = (myPad.edge(NORTHWEST));
1510  }
1511  break;
1512  case SOUTH:
1513  {
1514  mycorners[0] = (myPad.edge(SOUTHWEST));
1515  mycorners[1] = (myPad.edge(SOUTHEAST));
1516  mycorners[2] = (padsatdepth_[cracks[ic].second].edge(NORTHEAST));
1517  mycorners[3] = (padsatdepth_[cracks[ic].second].edge(NORTHWEST));
1518  }
1519  break;
1520  case EAST:
1521  {
1522  mycorners[0] = (myPad.edge(NORTHEAST));
1523  mycorners[1] = (padsatdepth_[cracks[ic].second].edge(NORTHWEST));
1524  mycorners[2] = (padsatdepth_[cracks[ic].second].edge(SOUTHWEST));
1525  mycorners[3] = (myPad.edge(SOUTHEAST));
1526  }
1527  break;
1528  case WEST:
1529  {
1530  mycorners[0] = (padsatdepth_[cracks[ic].second].edge(NORTHEAST));
1531  mycorners[1] = (myPad.edge(NORTHWEST));
1532  mycorners[2] = (myPad.edge(SOUTHWEST));
1533  mycorners[3] = (padsatdepth_[cracks[ic].second].edge(SOUTHEAST));
1534  }
1535  break;
1536  default:
1537  {
1538  }
1539  }
1540  CrystalPad crackpad(ic,mycorners);
1541  // to be tuned. A simpleconfigurable should be used
1543  crackpadsatdepth_.push_back(crackpad);
1544  }
1545  // std::cout << " Finished cracksPads " << std::endl;
1546 }
1547 
1548 
1549 bool EcalHitMaker::inside3D(const std::vector<XYZPoint>& corners,
1550  const XYZPoint& p) const
1551 {
1552  // corners and p are in the same plane
1553  // p is inside "corners" if the four crossproducts (corners[i]xcorners[i+1])
1554  // are in the same direction
1555 
1556  XYZVector crossproduct(0.,0.,0.),previouscrossproduct(0.,0.,0.);
1557 
1558  for(unsigned ip=0;ip<4 ; ++ip) {
1559  crossproduct = (corners[ip]-p).Cross(corners[(ip+1)%4]-p);
1560  if(ip==0)
1561  previouscrossproduct=crossproduct;
1562  else
1563  if (crossproduct.Dot(previouscrossproduct)<0.) return false;
1564  }
1565 
1566  return true;
1567 }
size
Write out results.
XYZNormal normal_
Definition: EcalHitMaker.h:226
void ecalCellLine(const XYZPoint &, const XYZPoint &, std::vector< CaloPoint > &cp)
double pulledPadProbability_
Definition: EcalHitMaker.h:277
bool addHit(double r, double phi, unsigned layer=0) override
XYZVector Vect() const
the momentum threevector
Definition: RawParticle.h:342
bool detailedShowerTail_
Definition: EcalHitMaker.h:263
unsigned ny_
Definition: EcalHitMaker.h:233
CrystalWindowMap * myCrystalWindowMap_
Definition: EcalHitMaker.h:245
void buildCrystal(const DetId &id, Crystal &) const
std::map< DetId, unsigned > DetIdMap_
Definition: EcalHitMaker.h:243
const RawParticle & vfcalEntrance() const
The particle at VFCAL entrance.
Definition: FSimTrack.h:144
std::vector< CrystalPad > crackpadsatdepth_
Definition: EcalHitMaker.h:295
int onLayer2() const
Definition: FSimTrack.h:101
static CaloDirection add2d(const CaloDirection &dir1, const CaloDirection &dir2)
double flatShoot(double xmin=0.0, double xmax=1.0) const
void hcalCellLine(std::vector< CaloPoint > &cp) const
EcalHitMaker(CaloGeometryHelper *calo, const XYZPoint &ecalentrance, const DetId &cell, int onEcal, unsigned size, unsigned showertype, const RandomEngineAndDistribution *engine)
Definition: EcalHitMaker.cc:33
static CaloDirection oppositeSide(const CaloDirection &side)
void reorganizePads()
ROOT::Math::Plane3D::Vector Vector
Definition: EcalHitMaker.cc:29
std::pair< CaloDirection, unsigned > neighbour
Definition: EcalHitMaker.h:178
bool unbalancedDirection(const std::vector< neighbour > &dirs, unsigned &unb, unsigned &dir1, unsigned &dir2)
double length() const
length of the segment (in cm)
Definition: CaloSegment.h:41
std::vector< CrystalPad > padsatdepth_
Definition: EcalHitMaker.h:294
Sin< T >::type sin(const T &t)
Definition: Sin.h:22
#define nullptr
const RawParticle & layer1Entrance() const
The particle at Preshower Layer 1.
Definition: FSimTrack.h:132
math::XYZVector XYZPoint
Definition: CaloHitMaker.h:26
Geom::Theta< T > theta() const
double L0HCAL_
Definition: EcalHitMaker.h:216
double X0length() const
length of the segment (in X0)
Definition: CaloSegment.h:43
Plane3D plan_
Definition: EcalHitMaker.h:274
std::vector< CLHEP::Hep2Vector > mycorners
Definition: EcalHitMaker.h:300
#define M_PI_2
const RandomEngineAndDistribution * random
Definition: EcalHitMaker.h:303
static unsigned oppositeDirection(unsigned iside)
CLHEP::Hep2Vector & edge(unsigned iside, int n)
access to the corners in direction iside; n=0,1
Definition: CrystalPad.cc:263
bool pulled(const XYZPoint &origin, const XYZNormal &normal, XYZPoint &fPoint) const
TRandom random
Definition: MVATrainer.cc:138
const PreshowerLayer1Properties * layer1Properties(int onLayer1) const
Preshower Layer1 properties.
Definition: Calorimeter.cc:103
void prepareCrystalNumberArray()
std::vector< std::vector< unsigned > > myCrystalNumberArray_
Definition: EcalHitMaker.h:200
double currentdepth_
Definition: EcalHitMaker.h:265
bool borderCrossing(const DetId &, const DetId &) const
static unsigned neighbourDirection(const CaloDirection &side)
unsigned int -> Direction for the neighbours
bool simulatePreshower_
Definition: EcalHitMaker.h:269
unsigned ncrystals_
Definition: EcalHitMaker.h:231
double X0HCAL_
Definition: EcalHitMaker.h:211
int onEcal() const
Definition: FSimTrack.h:106
const CaloGeometryHelper * myCalorimeter
Definition: CaloHitMaker.h:47
const CaloSubdetectorGeometry * getEcalGeometry(int subdetn) const
Definition: Calorimeter.cc:136
ROOT::Math::Transform3DPJ Transform3DR
Definition: EcalHitMaker.cc:31
double L0length() const
length of the segment (in L9)
Definition: CaloSegment.h:45
unsigned etasize_
Definition: EcalHitMaker.h:251
int hashedIndex(int ieta, int iphi)
Definition: EcalPyUtils.cc:42
bool truncatedGrid_
Definition: EcalHitMaker.h:254
unsigned fastInsideCell(const CLHEP::Hep2Vector &point, double &sp, bool debug=false)
bool getCrystalWindow(unsigned, std::vector< unsigned > &) const
get the ordered list of the crystals around the crystal given as a first argument ...
double ecalTotalX0() const
in the ECAL
Definition: EcalHitMaker.h:71
bool configuredGeometry_
Definition: EcalHitMaker.h:230
double crackPadProbability_
Definition: EcalHitMaker.h:279
virtual double thickness(double eta) const =0
Thickness (in cm) of the homegeneous material as a function of rapidity.
const PreshowerLayer2Properties * layer2Properties(int onLayer2) const
Preshower Layer2 properties.
Definition: Calorimeter.cc:111
double thickness(const double eta) const override
bool addHitDepth(double r, double phi, double depth=-1)
double L0PS2EE_
Definition: EcalHitMaker.h:214
const std::map< CaloHitID, float > & getHits() override
not been done.
const math::XYZTLorentzVector & position() const
Temporary (until CMSSW moves to Mathcore) - No ! Actually very useful.
Definition: FSimVertex.h:49
double radiusCorrectionFactor_
Definition: EcalHitMaker.h:259
T sqrt(T t)
Definition: SSEVec.h:18
double radiusFactor_
Definition: EcalHitMaker.h:261
double L0ECAL_
Definition: EcalHitMaker.h:215
void setTrackParameters(const XYZNormal &normal, double X0depthoffset, const FSimTrack &theTrack)
T mag2() const
The vector magnitude squared. Equivalent to vec.dot(vec)
Cos< T >::type cos(const T &t)
Definition: Cos.h:22
double X0EHGAP_
Definition: EcalHitMaker.h:210
const FSimTrack * myTrack_
Definition: EcalHitMaker.h:284
const HCALProperties * hcalProperties(int onHcal) const
HCAL properties.
Definition: Calorimeter.cc:87
static Histos * instance()
Definition: Histos.cc:15
Tan< T >::type tan(const T &t)
Definition: Tan.h:22
const RawParticle & ecalEntrance() const
The particle at ECAL entrance.
Definition: FSimTrack.h:138
void cracksPads(std::vector< neighbour > &cracks, unsigned iq)
int onVFcal() const
Definition: FSimTrack.h:116
double totalL0_
Definition: EcalHitMaker.h:204
double L0EHGAP_
Definition: EcalHitMaker.h:217
static XYZPoint intersect(const Plane3D &p, const XYZPoint &a, const XYZPoint &b, double &t, bool segment, bool debug=false)
Definition: CaloHitMaker.cc:40
std::vector< CaloPoint > intersections_
Definition: EcalHitMaker.h:287
double magneticField() const
unsigned phisize_
Definition: EcalHitMaker.h:252
static CaloDirection Side(unsigned i)
unsigned int -> Side conversion
ii
Definition: cuy.py:590
#define M_PI
double outsideWindowEnergy_
Definition: EcalHitMaker.h:221
void gapsLifting(std::vector< neighbour > &gaps, unsigned iq)
CLHEP::Hep2Vector & correspondingEdge(neighbour &myneighbour, CaloDirection dir2)
const XYZTLorentzVector & vertex() const
the vertex fourvector
Definition: RawParticle.h:339
ROOT::Math::Plane3D Plane3D
Definition: EcalHitMaker.h:31
This class is used to determine if a point lies in the segment.
Definition: CaloSegment.h:86
Definition: DetId.h:18
unsigned ncrackpadsatdepth_
Definition: EcalHitMaker.h:272
std::vector< XYZPoint > corners
Definition: EcalHitMaker.h:301
std::map< CaloHitID, float > hitMap_
Definition: CaloHitMaker.h:65
#define debug
Definition: HDRShower.cc:19
double X0PS2EE_
Definition: EcalHitMaker.h:208
const XYZVector & getFirstEdge() const
Direction of the first edge.
Definition: Crystal.h:45
virtual std::shared_ptr< const CaloCellGeometry > getGeometry(const DetId &id) const
Get the cell geometry of a given detector id. Should return false if not found.
double bfactor_
Definition: EcalHitMaker.h:267
Crystal pivot_
Definition: EcalHitMaker.h:224
Detector
Definition: DetId.h:26
ROOT::Math::Plane3D Plane3D
Definition: CaloHitMaker.h:27
void getWindow(const DetId &pivot, int s1, int s2, std::vector< DetId > &) const
double thickness(double eta) const override
void configureGeometry()
double interactionLength
Definition: CaloHitMaker.h:50
double b
Definition: hdecay.h:120
XYZPoint EcalEntrance_
Definition: EcalHitMaker.h:225
double X0ECAL_
Definition: EcalHitMaker.h:209
bool getPads(double depth, bool inCm=false)
void cellLine(std::vector< CaloPoint > &cp)
int ecalFirstSegment_
Definition: EcalHitMaker.h:248
std::vector< float > hits_
Definition: EcalHitMaker.h:238
double moliereRadius
Definition: CaloHitMaker.h:49
std::vector< std::vector< double > > tmp
Definition: MVATrainer.cc:100
std::vector< Crystal > regionOfInterest_
Definition: EcalHitMaker.h:237
const DetId & getDetId() const
get the DetId
Definition: Crystal.h:49
void buildSegments(const std::vector< CaloPoint > &cp)
Structure Point Contains parameters of Gaussian fits to DMRs.
Definition: DMRtrends.cc:55
double a
Definition: hdecay.h:121
const RawParticle & layer2Entrance() const
The particle at Preshower Layer 2.
Definition: FSimTrack.h:135
~EcalHitMaker() override
int onLayer1() const
Definition: FSimTrack.h:96
int onHcal() const
Definition: FSimTrack.h:111
void preshowerCellLine(std::vector< CaloPoint > &cp) const
math::XYZVector XYZVector
Definition: CaloHitMaker.h:25
double eta() const
Definition: RawParticle.h:298
const RawParticle & hcalEntrance() const
The particle at HCAL entrance.
Definition: FSimTrack.h:141
void setSurvivalProbability(double val)
Definition: CrystalPad.h:66
void buildGeometry()
double X0depthoffset_
Definition: EcalHitMaker.h:205
const FSimVertex vertex() const
Origin vertex.
std::vector< bool > validPads_
Definition: EcalHitMaker.h:240
dbl *** dir
Definition: mlp_gen.cc:35
std::vector< DetId > CellsWindow_
Definition: EcalHitMaker.h:236
CaloDirection
Codes the local directions in the cell lattice.
Definition: CaloDirection.h:9
bool inside3D(const std::vector< XYZPoint > &, const XYZPoint &p) const
DetId getClosestCell(const XYZPoint &point, bool ecal, bool central) const
ROOT::Math::Plane3D::Point Point
Definition: EcalHitMaker.cc:30
bool hitmaphasbeencalculated_
Definition: EcalHitMaker.h:297
unsigned npadsatdepth_
Definition: EcalHitMaker.h:273
math::XYZVector XYZNormal
Definition: EcalHitMaker.h:30
const EcalEndcapGeometry * getEcalEndcapGeometry() const
Definition: Calorimeter.h:53
double rearleakage_
Definition: EcalHitMaker.h:220
void convertIntegerCoordinates(double x, double y, unsigned &ix, unsigned &iy) const
double spotEnergy
Definition: CaloHitMaker.h:51
#define constexpr
*vegas h *****************************************************used in the default bin number in original ***version of VEGAS is ***a higher bin number might help to derive a more precise ***grade subtle point
Definition: invegas.h:5
bool diagonalEdge(unsigned myPad, CaloDirection dir, CLHEP::Hep2Vector &point)
bool move(DetId &cell, const CaloDirection &dir, bool fast=true) const
double totalX0_
Definition: EcalHitMaker.h:203
std::vector< CaloSegment > segments_
Definition: EcalHitMaker.h:289
unsigned nx_
Definition: EcalHitMaker.h:233
T angle(T x1, T y1, T z1, T x2, T y2, T z2)
Definition: angle.h:11