Report problems to ATLAS LXR Team (with time and IP address indicated)

The LXR Cross Referencer

source navigation ]
diff markup ]
identifier search ]
general search ]
 
 
Architecture: linux ]
Version: head ] [ nightly ] [ GaudiDev ]
  Links to LXR source navigation pages for stable releases [ 12.*.* ]   [ 13.*.* ]   [ 14.*.* ] 

001 // $Id: CaloFillRectangularCluster.cxx,v 1.18 2008/12/09 20:39:51 gunal Exp $
002 /**
003  * @file  CaloFillRectangularCluster.h
004  * @author scott snyder <snyder@bnl.gov>, D. Lelas, H. Ma, S. Rajagopalan
005  * @date March, 2006
006  * @brief Calculates the per-layer position, size, etc. of a cluster.
007  *        Optionally, fills the cluster with cells from StoreGate.
008  */
009 
010 #include "CaloClusterCorrection/CaloFillRectangularCluster.h"
011 #include "CaloUtils/CaloLayerCalculator.h"
012 #include "CaloEvent/CaloCell.h"
013 #include "CaloDetDescr/CaloDetDescrElement.h"
014 #include "CaloDetDescr/CaloDetDescriptor.h"
015 #include "CaloDetDescr/CaloPhiRange.h"
016 #include "GeoModelSvc/IGeoModelSvc.h"
017 
018 #include "GaudiKernel/MsgStream.h"
019 
020 #include "StoreGate/StoreGate.h"
021 #include "StoreGate/StoreGateSvc.h"
022 #include "CaloEvent/CaloCellContainer.h"
023 #include "CaloUtils/CaloCellList.h"
024 #include "AthenaKernel/errorcheck.h"
025 #include <algorithm>
026 
027 
028 namespace CaloClusterCorr {
029 
030 
031 //**************************************************************************
032 
033 
034 /**
035  * @brief Return eta/phi ranges encompassing +- 1 cell.
036  * @param eta Central eta value.
037  * @param phi Central phi value.
038  * @param sampling The sampling to use.
039  * @param[out] deta Range in eta.
040  * @param[out] dphi Range in phi.
041  *
042  * This can be a little tricky due to misalignments and the fact
043  * that cells have different sizes in different regions.  Also,
044  * CaloLayerCalculator takes only a symmetric eta range.
045  * We try to find the neighboring cells by starting from the center
046  * cell and looking a little bit more than half its width in either
047  * direction, and finding the centers of those cells.  Then we use
048  * the larger of these for the symmetric range.
049  */
050 void etaphi_range (double eta,
051                    double phi,
052                    CaloCell_ID::CaloSample sampling,
053                    double& deta,
054                    double& dphi)
055 {
056   static CaloPhiRange range;
057   deta = 0;
058   dphi = 0;
059 
060   // Get the DD element for the central cell.
061   const CaloDetDescrManager* dd_man = CaloDetDescrManager::instance();
062   CaloDetDescrElement* elt = dd_man->get_element (sampling, eta, phi);
063   if (!elt) return;
064 
065   // Should be smaller than the eta half-width of any cell.
066   const double eps = 0.001;
067 
068   // Now look in the negative eta direction.
069   CaloDetDescrElement* elt_l = dd_man->get_element
070     (sampling,
071      eta - elt->deta() - eps,
072      phi);
073   double deta_l = 0; // Eta difference on the low (left) side.
074   if (elt_l)
075     deta_l = std::abs (eta - elt_l->eta()) + eps;
076 
077   // Now look in the positive eta direction.
078   CaloDetDescrElement* elt_r = dd_man->get_element
079     (sampling,
080      eta + elt->deta() + eps,
081      phi);
082   double deta_r = 0; // Eta difference on the high (right) side.
083   if (elt_r)
084     deta_r = std::abs (eta - elt_r->eta()) + eps;
085 
086   // Total deta is twice the maximum.
087   deta = 2 * std::max (deta_r, deta_l);
088 
089   // Now for the phi variation.
090   // The phi size can change as a function of eta, but not of phi.
091   // Thus we have to look again at the adjacent eta cells, and
092   // take the largest variation.
093 
094   // Now look in the negative eta direction.
095   elt_l = dd_man->get_element
096     (sampling,
097      eta  - elt->deta() - eps,
098      range.fix (phi - elt->dphi() - eps));
099   double dphi_l = 0; // Phi difference on the low-eta () side.
100   if (elt_l)
101     dphi_l = std::abs (range.fix (phi - elt_l->phi())) + eps;
102 
103   // Now look in the positive eta direction.
104   elt_r = dd_man->get_element
105     (sampling,
106      eta + elt->deta() + eps,
107      range.fix (phi - elt->dphi() - eps));
108   double dphi_r = 0; // Phi difference on the positive (down) side.
109   if (elt_r)
110     dphi_r = std::abs (range.fix (phi - elt_r->phi())) + eps;
111 
112   // Total dphi is twice the maximum.
113   dphi = 2 * std::max (dphi_l, dphi_r);
114 }
115 
116 
117 //**************************************************************************
118 
119 
120 /**
121  * @brief Sampling calculator helper class.
122  *
123  * This helper class is used to decouple the layer calculations
124  * from the decision of the origin of the cells (a StoreGate container
125  * or the existing cluster cells).
126  *
127  * This is an abstract base class; there are concrete implementations
128  * of this for the two cases of cells coming from StoreGate
129  * and cells coming from the clusters.
130  */
131 class SamplingHelper
132 {
133 public:
134   /**
135    * @brief Constructor.
136    * @param parent The parent correction class.
137    * @param cluster The cluster being operated on.
138    */
139   SamplingHelper (CaloClusterCorrection& parent,
140                   CaloCluster* cluster);
141 
142 
143   /// Destructor --- just to get a vtable.
144   virtual ~SamplingHelper() {}
145 
146 
147   /**
148    * @brief Calculate layer variables --- abstract method.
149    * @param eta Center of the cluster in @f$\eta$@f.
150    * @param phi Center of the cluster in @f$\phi$@f.
151    * @param deta Full width of the cluster in @f$\eta$@f.
152    * @param dphi Full width of the cluster in @f$\phi$@f.
153    * @param sampling The sampling for which to do the calculation.
154    * @param dofill If true, add selected cells to the cluster (if possible).
155    *
156    * This virtual method should select the cells within the specified
157    * window in the specified sampling from the list of candidate cells
158    * and calculate the layer variables.  If @c dofill is true, then
159    * the selected cells will also be added to the cluster, provided
160    * that this makes sense (it will not be done if the cluster
161    * is the source of the cells).
162    *
163    * The result of the calculation will be held in internal variables.
164    */
165   virtual void
166   calculate (double eta,
167              double phi,
168              double deta,
169              double dphi,
170              CaloSampling::CaloSample sampling,
171              bool dofill = false) = 0;
172 
173 
174   /// Return the cell with the maximum energy --- abstract method.
175   virtual const CaloCell* max_et_cell() const = 0;
176 
177   /// Test for empty candidate cell list --- abstract method.
178   virtual bool empty() const = 0;
179 
180 
181   /**
182    * @brief Calculate layer variables for cells in the cluster.
183    * @param eta Center of the cluster in @f$\eta$@f.
184    * @param phi Center of the cluster in @f$\phi$@f.
185    * @param deta Full width of the cluster in @f$\eta$@f.
186    * @param dphi Full width of the cluster in @f$\phi$@f.
187    * @param sampling The sampling for which to do the calculation.
188    *
189    * This method selects the cells within the specified
190    * window in the specified sampling from the current list of cells
191    * in the cluster and calculates the layer variables.
192    *
193    * The result of the calculation will be held in internal variables.
194    */
195   void
196   calculate_cluster (double eta,
197                      double phi,
198                      double deta,
199                      double dphi,
200                      CaloSampling::CaloSample sampling);
201 
202 
203   /**
204    * @brief Calculate layer variables and update cluster.
205    * @param eta Center of the cluster in @f$\eta$@f.
206    * @param phi Center of the cluster in @f$\phi$@f.
207    * @param deta Full width of the cluster in @f$\eta$@f.
208    * @param dphi Full width of the cluster in @f$\phi$@f.
209    * @param fallback_eta @f$\eta$@f result to use if there's an error.
210    * @param fallback_phi @f$\phi$@f result to use if there's an error.
211    * @param sampling The sampling for which to do the calculation.
212    * @param allow_badpos Should error flags be allowed into the cluster?
213    *
214    * This method selects the cells within the specified
215    * window in the specified sampling from the current list of cells
216    * in the cluster and calculates the layer variables.
217    *
218    * The result of the calculation will be held in internal variables.
219    * In addition, the cluster variables for this sampling will
220    * be updated with the result.
221    *
222    * In some cases, the calculation of the cluster position may yield
223    * an error (for example, if there are no selected cells).  In this case,
224    * the values specified by @c fallback_eta and @c fallback_phi are used
225    * instead of the calculated result.  If @c allow_badpos is true,
226    * then the error flags are used to update the cluster variables;
227    * otherwise, the fallback position is used when updating the cluster.
228    */
229   void
230   calculate_and_set (double eta,
231                      double phi,
232                      double deta,
233                      double dphi,
234                      double fallback_eta,
235                      double fallback_phi,
236                      CaloSampling::CaloSample sampling,
237                      bool allow_badpos = false);
238 
239 
240   /// Return the cluster we're updating.
241   CaloCluster* cluster() const;
242 
243   /// Return the @f$\eta$@f position from the last calculation.
244   double etam() const;
245 
246   /// Return the @f$\phi$@f position from the last calculation.
247   double phim() const;
248 
249   /// Return the @f$\eta$@f maximum position from the last calculation.
250   double etamax() const;
251 
252   /// Return the @f$\phi$@f maximum position from the last calculation.
253   double phimax() const;
254 
255 
256 protected:
257   /// The calculator object.
258   CaloLayerCalculator m_calc;
259 
260   /// The correction object using us.
261   CaloClusterCorrection& m_parent;
262 
263   /// The cluster we're updating.
264   CaloCluster* m_cluster;
265 
266   /// @f$\eta$@f position from last calculation.
267   double m_etam;
268 
269   /// @f$\phi$@f position from last calculation.
270   double m_phim;
271 };
272 
273 
274 /**
275  * @brief Constructor.
276  * @param parent The parent correction class.
277  * @param cluster The cluster being operated on.
278  */
279 SamplingHelper::SamplingHelper (CaloClusterCorrection& parent,
280                                 CaloCluster* cluster)
281   : m_parent (parent),
282     m_cluster (cluster)
283 {
284 }
285 
286 
287 /**
288  * @brief Calculate layer variables and update cluster.
289  * @param eta Center of the cluster in @f$\eta$@f.
290  * @param phi Center of the cluster in @f$\phi$@f.
291  * @param deta Full width of the cluster in @f$\eta$@f.
292  * @param dphi Full width of the cluster in @f$\phi$@f.
293  * @param fallback_eta @f$\eta$@f result to use if there's an error.
294  * @param fallback_phi @f$\phi$@f result to use if there's an error.
295  * @param sampling The sampling for which to do the calculation.
296  * @param allow_badpos Should error flags be allowed into the cluster?
297  *
298  * This method selects the cells within the specified
299  * window in the specified sampling from the current list of cells
300  * in the cluster and calculates the layer variables.
301  *
302  * The result of the calculation will be held in internal variables.
303  * In addition, the cluster variables for this sampling will
304  * be updated with the result.
305  *
306  * In some cases, the calculation of the cluster position may yield
307  * an error (for example, if there are no selected cells).  In this case,
308  * the values specified by @c fallback_eta and @c fallback_phi are used
309  * instead of the calculated result.  If @c allow_badpos is true,
310  * then the error flags are used to update the cluster variables;
311  * otherwise, the fallback position is used when updating the cluster.
312  */
313 void
314 SamplingHelper::calculate_and_set
315   (double eta,
316    double phi,
317    double deta,
318    double dphi,
319    double fallback_eta,
320    double fallback_phi,
321    CaloSampling::CaloSample sampling,
322    bool allow_badpos)
323 {
324   calculate (eta, phi, deta, dphi, sampling, true);
325   if (!allow_badpos) {
326     if (m_etam == -999) m_etam = fallback_eta;
327     if (m_phim == -999) m_phim = fallback_phi;
328   }
329   m_parent.setsample (m_cluster,
330                       sampling,
331                       m_calc.em(),
332                       m_etam,
333                       m_phim,
334                       m_calc.emax(),
335                       m_calc.etamax(),
336                       m_calc.phimax(),
337                       m_calc.etas(),
338                       m_calc.phis());
339   if (allow_badpos) {
340     if (m_etam == -999) m_etam = fallback_eta;
341     if (m_phim == -999) m_phim = fallback_phi;
342   }
343 }
344 
345 
346 /**
347  * @brief Calculate layer variables for cells in the cluster.
348  * @param eta Center of the cluster in @f$\eta$@f.
349  * @param phi Center of the cluster in @f$\phi$@f.
350  * @param deta Full width of the cluster in @f$\eta$@f.
351  * @param dphi Full width of the cluster in @f$\phi$@f.
352  * @param sampling The sampling for which to do the calculation.
353  *
354  * This method selects the cells within the specified
355  * window in the specified sampling from the current list of cells
356  * in the cluster and calculates the layer variables.
357  *
358  * The result of the calculation will be held in internal variables.
359  */
360 void
361 SamplingHelper::calculate_cluster
362   (double eta,
363    double phi,
364    double deta,
365    double dphi,
366    CaloSampling::CaloSample sampling)
367 {
368   m_calc.fill (m_cluster->begin(), m_cluster->end(),
369                eta, phi, deta, dphi, sampling);
370   m_etam = m_calc.etam();
371   m_phim = m_calc.phim();
372 }
373 
374 
375 /// Return the cluster we're updating.
376 inline
377 CaloCluster* SamplingHelper::cluster() const
378 {
379   return m_cluster;
380 }
381 
382 
383 /// Return the @f$\eta$@f position from the last calculation.
384 inline
385 double SamplingHelper::etam() const
386 {
387   return m_etam;
388 }
389 
390 
391 /// Return the @f$\phi$@f position from the last calculation.
392 inline
393 double SamplingHelper::phim() const
394 {
395   return m_phim;
396 }
397 
398 
399 /// Return the @f$\eta$@f maximum position from the last calculation.
400 inline
401 double SamplingHelper::etamax() const
402 {
403   return m_calc.etamax();
404 }
405 
406 
407 /// Return the @f$\phi$@f maximum position from the last calculation.
408 inline
409 double SamplingHelper::phimax() const
410 {
411   return m_calc.phimax();
412 }
413 
414 
415 /**
416  * @brief Helper to compare two cells by Et.
417  *
418  * When we find the maximum cell, we only want to find those
419  * in LAr EM.  The list may contain other cells, though.
420  * So, bias their energies down by some large value.
421  */
422 struct et_compare_larem_only
423 {
424   bool operator() (const CaloCell* a, const CaloCell* b);
425   static double et (const CaloCell* cell);
426 };
427 
428 
429 bool et_compare_larem_only::operator() (const CaloCell* a,
430                                         const CaloCell* b)
431 {
432   return et(a) < et(b);
433 }
434 
435 
436 double et_compare_larem_only::et (const CaloCell* cell)
437 {
438   double et = cell->et();
439   if (cell->caloDDE()->getSubCalo() != CaloCell_ID::LAREM)
440     et -= 1000*GeV;
441   return et;
442 }
443 
444 
445 //**************************************************************************
446 
447 
448 /**
449  * @brief Version of helper class for cells taken from StoreGate.
450  */
451 class SamplingHelper_CaloCellList
452   : public SamplingHelper
453 {
454 public:
455   /**
456    * @brief Constructor.
457    * @param parent The parent correction class.
458    * @param cluster The cluster being operated on.
459    * @param list The cell list.
460    * @parma cell_container The container from which the cells came.
461    */
462   SamplingHelper_CaloCellList (CaloClusterCorrection& parent,
463                                CaloCluster* cluster,
464                                const CaloCellList& list,
465                                const CaloCellContainer* cell_container);
466 
467 
468   /**
469    * @brief Calculate layer variables.
470    * @param eta Center of the cluster in @f$\eta$@f.
471    * @param phi Center of the cluster in @f$\phi$@f.
472    * @param deta Full width of the cluster in @f$\eta$@f.
473    * @param dphi Full width of the cluster in @f$\phi$@f.
474    * @param sampling The sampling for which to do the calculation.
475    * @param dofill If true, add selected cells to the cluster.
476    *
477    * This method selects the cells within the specified
478    * window in the specified sampling from the list of candidate cells
479    * and calculates the layer variables.  If @c dofill is true, then
480    * the selected cells will also be added to the cluster.
481    *
482    * The result of the calculation will be held in internal variables.
483    */
484   virtual void
485   calculate (double eta,
486              double phi,
487              double deta,
488              double dphi,
489              CaloSampling::CaloSample sampling,
490              bool dofill = false);
491 
492 
493   /// Return the cell with the maximum energy.
494   virtual const CaloCell* max_et_cell() const;
495 
496   /// Test for empty candidate cell list.
497   virtual bool empty() const;
498 
499 
500 private:
501   /// The cell list.
502   const CaloCellList& m_list;
503 
504   /// The container from which the cells came.
505   const CaloCellContainer* m_cell_container;
506 };
507 
508 
509 /**
510  * @brief Constructor.
511  * @param parent The parent correction class.
512  * @param cluster The cluster being operated on.
513  * @param list The cell list.
514  * @parma cell_container The container from which the cells came.
515  */
516 SamplingHelper_CaloCellList::SamplingHelper_CaloCellList
517    (CaloClusterCorrection& parent,
518     CaloCluster* cluster,
519     const CaloCellList& list,
520     const CaloCellContainer* cell_container)
521      : SamplingHelper (parent, cluster),
522        m_list (list),
523        m_cell_container (cell_container)
524 {
525 }
526 
527 
528 /**
529  * @brief Calculate layer variables.
530  * @param eta Center of the cluster in @f$\eta$@f.
531  * @param phi Center of the cluster in @f$\phi$@f.
532  * @param deta Full width of the cluster in @f$\eta$@f.
533  * @param dphi Full width of the cluster in @f$\phi$@f.
534  * @param sampling The sampling for which to do the calculation.
535  * @param dofill If true, add selected cells to the cluster.
536  *
537  * This method selects the cells within the specified
538  * window in the specified sampling from the list of candidate cells
539  * and calculates the layer variables.  If @c dofill is true, then
540  * the selected cells will also be added to the cluster.
541  *
542  * The result of the calculation will be held in internal variables.
543  */
544 void
545 SamplingHelper_CaloCellList::calculate
546   (double eta,
547    double phi,
548    double deta,
549    double dphi,
550    CaloSampling::CaloSample sampling,
551    bool dofill)
552 {
553   m_calc.fill (m_list.begin(), m_list.end(),
554                eta, phi, deta, dphi, sampling,
555                dofill ? m_cluster : 0,
556                m_cell_container);
557   m_etam = m_calc.etam();
558   m_phim = m_calc.phim();
559 }
560 
561   
562 /// Return the cell with the maximum energy.
563 const CaloCell* SamplingHelper_CaloCellList::max_et_cell() const
564 {
565   return *std::max_element (m_list.begin(), m_list.end(),
566                             et_compare_larem_only());
567 }
568 
569 
570 /// Test for empty candidate cell list.
571 bool SamplingHelper_CaloCellList::empty() const
572 {
573   return m_list.begin() == m_list.end();
574 }
575 
576 
577 //**************************************************************************
578 
579 
580 /**
581  * @brief Version of helper class for cells taken from the cluster itself.
582  */
583 class SamplingHelper_Cluster
584   : public SamplingHelper
585 {
586 public:
587   /**
588    * @brief Constructor.
589    * @param parent The parent correction class.
590    * @param cluster The cluster being operated on.
591    */
592   SamplingHelper_Cluster (CaloClusterCorrection& parent,
593                           CaloCluster* cluster);
594 
595   /**
596    * @brief Calculate layer variables.
597    * @param eta Center of the cluster in @f$\eta$@f.
598    * @param phi Center of the cluster in @f$\phi$@f.
599    * @param deta Full width of the cluster in @f$\eta$@f.
600    * @param dphi Full width of the cluster in @f$\phi$@f.
601    * @param sampling The sampling for which to do the calculation.
602    * @param dofill (Ignored for this implementation.)
603    *
604    * This method selects the cells within the specified
605    * window in the specified sampling from the list of candidate cells
606    * and calculates the layer variables.
607    *
608    * The result of the calculation will be held in internal variables.
609    */
610   virtual void
611   calculate (double eta,
612              double phi,
613              double deta,
614              double dphi,
615              CaloSampling::CaloSample sampling,
616              bool dofill = false);
617 
618   /// Return the cell with the maximum energy.
619   virtual const CaloCell* max_et_cell() const;
620 
621   /// Test for empty candidate cell list.
622   virtual bool empty() const;
623 };
624 
625 
626 /**
627  * @brief Constructor.
628  * @param parent The parent correction class.
629  * @param cluster The cluster being operated on.
630  */
631 SamplingHelper_Cluster::SamplingHelper_Cluster (CaloClusterCorrection& parent,
632                                                 CaloCluster* cluster)
633   : SamplingHelper (parent, cluster)
634 {
635 }
636 
637 
638 /**
639  * @brief Calculate layer variables.
640  * @param eta Center of the cluster in @f$\eta$@f.
641  * @param phi Center of the cluster in @f$\phi$@f.
642  * @param deta Full width of the cluster in @f$\eta$@f.
643  * @param dphi Full width of the cluster in @f$\phi$@f.
644  * @param sampling The sampling for which to do the calculation.
645  * @param dofill (Ignored for this implementation.)
646  *
647  * This method selects the cells within the specified
648  * window in the specified sampling from the list of candidate cells
649  * and calculates the layer variables.
650  *
651  * The result of the calculation will be held in internal variables.
652  */
653 void
654 SamplingHelper_Cluster::calculate
655   (double eta,
656    double phi,
657    double deta,
658    double dphi,
659    CaloSampling::CaloSample sampling,
660    bool /*dofill*/)
661 {
662   calculate_cluster (eta, phi, deta, dphi, sampling);
663 }
664 
665   
666 /// Return the cell with the maximum energy.
667 const CaloCell* SamplingHelper_Cluster::max_et_cell() const
668 {
669   return *std::max_element(m_cluster->begin(), m_cluster->end(),
670                            et_compare_larem_only());
671 }
672 
673 
674 /// Test for empty candidate cell list.
675 bool SamplingHelper_Cluster::empty() const
676 {
677   return m_cluster->begin() == m_cluster->end();
678 }
679 
680 
681 } // namespace CaloClusterCorr
682 
683 
684 //**************************************************************************
685 
686 
687 /**
688  * @brief Standard Gaudi constructor.
689  * @param type The type of the tool.
690  * @param name The name of the tool.
691  * @param parent The parent algorithm of the tool.
692  */
693 CaloFillRectangularCluster::CaloFillRectangularCluster
694   (const std::string& type,
695    const std::string& name,
696    const IInterface* parent)
697   : CaloClusterCorrection(type, name, parent)
698 { 
699   // properties 
700   declareProperty("eta_size",     m_neta = 5);
701   declareProperty("phi_size",     m_nphi = 5);
702   declareProperty("fill_cluster", m_fill_cluster = true);
703   declareProperty("cells_name",   m_cellsName = "AllCalo");
704 }
705 
706 
707 /**
708  * @brief Standard Gaudi initialize method.
709  *
710  * Derived classes can extend this to change the sampling window sizes.
711  */
712 StatusCode CaloFillRectangularCluster::initialize()
713 {
714   // The method from the base class.
715   CHECK( CaloClusterCorrection::initialize() );
716 
717   // Get the StoreGate service.
718   CHECK( service("StoreGateSvc", m_storeGate) );
719   MsgStream  log(msgSvc(),name());
720 
721   StoreGateSvc* detStore;
722   if (service("DetectorStore", detStore).isFailure()) {
723     log << MSG::ERROR   << "Unable to access DetectoreStore" << endreq ;
724     return StatusCode::FAILURE;
725   }
726 
727   const IGeoModelSvc *geoModel=0;
728   StatusCode sc = service("GeoModelSvc", geoModel);
729   if(sc.isFailure())
730   {
731     log << MSG::ERROR << "Could not locate GeoModelSvc" << endreq;
732     return sc;
733   }
734 
735   // dummy parameters for the callback:
736   int dummyInt=0;
737   std::list<std::string> dummyList;
738 
739   if (geoModel->geoInitialized())
740   {
741     return geoInit(dummyInt,dummyList);
742   }
743   else
744   {
745     sc = detStore->regFcn(&IGeoModelSvc::geoInit,
746                           geoModel,
747                           &CaloFillRectangularCluster::geoInit,this);
748     if(sc.isFailure())
749     {
750       log << MSG::ERROR << "Could not register geoInit callback" << endreq;
751       return sc;
752     }
753   }
754   return sc;
755 }
756 
757 StatusCode
758 CaloFillRectangularCluster::geoInit(IOVSVC_CALLBACK_ARGS)
759 {
760   // Look up the middle layer cell segmentation.
761   {
762     const CaloDetDescrManager* dd_man = CaloDetDescrManager::instance();
763     CaloDetDescrElement* elt = dd_man->get_element (CaloCell_ID::EMB2,
764                                                     0.001,
765                                                     0.001);
766     if (elt) {
767       m_detas2 = elt->deta();
768       m_dphis2 = elt->dphi();
769     }
770     else {
771       // various TB configurations might have other eta/phi ranges or
772       // no access at all to EMB2 but would need still the standard
773       // EMB2 cell width as reference. Therefore the nominal eta and
774       // phi width is assumed here
775       m_detas2 = 0.025;
776       m_dphis2 = M_PI/128.;
777     }
778   }
779 
780   // set up the sampling windows:
781   m_deta0 = m_detas2*m_neta;
782   m_dphi0 = m_dphis2*4;
783 
784   if (m_nphi >= 7)
785     m_dphi0 = m_dphi0*2;
786   else
787     m_dphi0 = m_dphi0*1.5;
788 
789   m_deta1 = m_deta0;
790   m_dphi1 = m_dphi0;
791 
792   m_deta2 = m_detas2*m_neta;
793   m_dphi2 = m_dphis2*m_nphi;
794 
795   m_deta3 = (2*m_detas2)*(0.5 + (m_neta/2.));
796   m_dphi3 = m_dphi2;
797 
798   return StatusCode::SUCCESS;
799 }
800 
801 
802 /*
803  * @brief Actually make the correction for one region (barrel or endcap).
804  * @param helper Sampling calculation helper object.
805  * @param eta The @f$\eta$@f seed of the cluster.
806  * @param phi The @f$\phi$@f seed of the cluster.
807  * @param samplings List of samplings for this region.
808  */
809 void
810 CaloFillRectangularCluster::makeCorrection1(CaloClusterCorr::SamplingHelper&
811                                              helper,
812                                             double eta,
813                                             double phi,
814                                             const CaloSampling::CaloSample 
815                                              samplings[4])
816 {
817   // Do sampling 2.
818   helper.calculate_and_set (eta, phi, m_deta2, m_dphi2, eta, phi,
819                             samplings[2], true);
820   double eta2 = helper.etam();
821   double phi2 = helper.phim();
822 
823   // Now do sampling 1; use the result from sampling 2 as the seed.
824   helper.calculate_and_set (eta2, phi2, m_deta1, m_dphi1, eta2, phi2,
825                             samplings[1]);
826   double eta1 = helper.etam();
827   double phi1 = helper.phim();
828 
829   // For some silly reason, we have TWO different sampling enums.
830   // The clusters use one, the detector description uses the other.
831   CaloCell_ID::CaloSample xsample;
832   if (samplings[1] == CaloSampling::EMB1)
833     xsample = CaloCell_ID::EMB1;
834   else
835     xsample = CaloCell_ID::EME1;
836 
837   // Now refine the eta position using +-1 strip around hot cell
838   double detastr, dphistr;
839   CaloClusterCorr::etaphi_range (helper.etamax(), helper.phimax(),
840                                  xsample,
841                                  detastr, dphistr);
842 
843   if (detastr > 0 && dphistr > 0) {
844     helper.calculate_cluster (helper.etamax(), helper.phimax(),
845                               detastr, dphistr, samplings[1]);
846 
847     if (helper.etam()!=-999.) {
848       eta1 = helper.etam();
849       helper.cluster()->seteta(samplings[1], eta1);
850     }
851   }
852 
853   // Now do sampling 0 using the eta1 point: 
854   helper.calculate_and_set (eta1, phi2, m_deta0, m_dphi0, eta1, phi1,
855                             samplings[0]);
856 
857   // Do for sampling 3 (using the sampling 2 seed).
858   helper.calculate_and_set (eta2, phi2, m_deta3, m_dphi3, eta2, phi2,
859                             samplings[3]);
860 }
861 
862 
863 /*
864  * @brief Execute the correction, given a helper object.
865  * @param helper Sampling calculation helper object.
866  */
867 void
868 CaloFillRectangularCluster::makeCorrection2 (CaloClusterCorr::SamplingHelper&
869                                              helper)
870 {
871 
872   // Don't do anything if we don't have any cells.
873   if (helper.empty())
874     return;
875 
876   // Get the seed position of the cluster.
877   CaloCluster* cluster = helper.cluster();
878   double eta, phi;
879   const CaloCell* cell_max = helper.max_et_cell();
880   get_seed (cluster, cell_max, eta, phi);
881   double aeta = fabs(eta);  
882 
883   // set the appropriate cluster size
884   int neta = cluster->getClusterEtaSize();
885   int nphi = cluster->getClusterPhiSize();
886 
887   if (m_neta != neta || m_nphi != nphi) {
888      unsigned int oldSize = cluster->getClusterSize();
889      unsigned int newSize = oldSize;
890      switch(oldSize) {
891        case CaloCluster::SW_softe:
892           break;
893        case CaloCluster::SW_55ele:
894        case CaloCluster::SW_35ele:
895        case CaloCluster::SW_37ele:
896           if (m_neta==5 && m_nphi==5) newSize=CaloCluster::SW_55ele;
897           if (m_neta==3 && m_nphi==5) newSize=CaloCluster::SW_35ele;
898           if (m_neta==3 && m_nphi==7) newSize=CaloCluster::SW_37ele;
899           if (m_neta==7 && m_nphi==11) newSize=CaloCluster::SW_7_11;
900           break;
901        case CaloCluster::SW_55gam:
902        case CaloCluster::SW_35gam:
903        case CaloCluster::SW_37gam:
904           if (m_neta==5 && m_nphi==5) newSize=CaloCluster::SW_55gam;
905           if (m_neta==3 && m_nphi==5) newSize=CaloCluster::SW_35gam;
906           if (m_neta==3 && m_nphi==7) newSize=CaloCluster::SW_37gam;
907           if (m_neta==7 && m_nphi==11) newSize=CaloCluster::SW_7_11;
908           break;
909        case CaloCluster::SW_55Econv:
910        case CaloCluster::SW_35Econv:
911        case CaloCluster::SW_37Econv:
912           if (m_neta==5 && m_nphi==5) newSize=CaloCluster::SW_55Econv;
913           if (m_neta==3 && m_nphi==5) newSize=CaloCluster::SW_35Econv;
914           if (m_neta==3 && m_nphi==7) newSize=CaloCluster::SW_37Econv;
915           if (m_neta==7 && m_nphi==11) newSize=CaloCluster::SW_7_11;
916           break;
917        default:
918           if (m_neta==5 && m_nphi==5) newSize=CaloCluster::SW_55ele;
919           if (m_neta==3 && m_nphi==5) newSize=CaloCluster::SW_35ele;
920           if (m_neta==3 && m_nphi==7) newSize=CaloCluster::SW_37ele;
921           if (m_neta==7 && m_nphi==11) newSize=CaloCluster::SW_7_11;
922           break;
923      }
924      cluster->setClusterSize(newSize);
925   }
926 
927   // Lists of samplings in the barrel and endcap.
928   static const CaloSampling::CaloSample samplings_b[4] = 
929     { CaloSampling::PreSamplerB, CaloSampling::EMB1,
930       CaloSampling::EMB2, CaloSampling::EMB3 };
931   static const CaloSampling::CaloSample samplings_e[4] = 
932     { CaloSampling::PreSamplerE, CaloSampling::EME1,
933       CaloSampling::EME2, CaloSampling::EME3 };
934 
935   // We need to calculate sampling properties for barrel and endcap 
936   // separately.
937   // FIXME: the overlap with barrel should be checked!!
938 
939   // Barrel
940   if (aeta < 1.6) {
941     cluster->setBarrel (true);
942     makeCorrection1 (helper, eta, phi, samplings_b);
943   }
944 
945   // Endcap
946   if (aeta > 1.3) {
947     cluster->setEndcap (true);
948     makeCorrection1 (helper, eta, phi, samplings_e);
949   }
950 
951   ////FIXME: Following two ifs are needed for proper "inBarrel" and "inEndcap" 
952   
953   if (aeta >= 1.3 && aeta < 1.6){
954     cluster->setEndcap (true);
955     cluster->setBarrel (true);
956   }
957 
958   if (aeta >= 1.6){
959     cluster->setEndcap (true);
960     cluster->setBarrel (false);
961   }
962   
963   // Set the total cluster energy to the sum over all samplings.
964   double cl_ene = 0;
965   for(int i=0; i<4; i++ ){
966     cl_ene += cluster->eSample(samplings_b[i]);
967     cl_ene += cluster->eSample(samplings_e[i]);
968   }
969   cluster->setE(cl_ene);
970 
971 }
972 
973 
974 /**
975  * @brief CaloClusterCorrection virtual method
976  * @param cluster The cluster on which to operate.
977  */
978 void CaloFillRectangularCluster::makeCorrection(CaloCluster* cluster)
979 {
980   MsgStream log( msgSvc(), name() );
981   log << MSG::DEBUG << "Executing CaloFillRectangularCluster" << endreq;
982 
983   if (m_fill_cluster) {
984     // We're filling the cluster with cells from StoreGate.
985     // First, remove existing cells.
986     cluster->removeCells();
987 
988     // Get the list of cells from StoreGate.
989     const CaloCellContainer* cell_container = 0;
990     if ( ! m_storeGate->retrieve (cell_container, m_cellsName).isSuccess()) {
991       REPORT_ERROR(StatusCode::FAILURE)
992         << "Can't retrieve cell container " << m_cellsName;
993       return;
994     }
995 
996     // Define the center for building the list of candidate cells.
997     double eta = cluster->eta0();
998     double phi = cluster->phi0();
999     static CaloPhiRange range;
1000     phi = range.fix (phi);
1001 
1002     // Build the candidate cell list.
1003     // This 5 is a safe margin for cell_list calculation
1004     // and should not be changed.
1005     CaloCellList cell_list(cell_container); 
1006     cell_list.select(eta,phi,m_detas2*(m_neta+5),m_dphis2*(m_nphi+5));
1007 
1008     // Do the calculation.
1009     CaloClusterCorr::SamplingHelper_CaloCellList helper (*this,
1010                                                          cluster,
1011                                                          cell_list,
1012                                                          cell_container);
1013     makeCorrection2 (helper);
1014   }
1015   else {
1016     // We're recalculating a cluster using the existing cells.
1017     CaloClusterCorr::SamplingHelper_Cluster helper (*this, cluster);
1018     makeCorrection2 (helper);
1019   }
1020 }
1021 
1022 
1023 /*
1024  * @brief Return the seed position of a cluster.
1025  * @param cluster The cluster on which to operate.
1026  * @param max_et_cell The cell with the largest energy
1027  *  (of those being considered for inclusion in the cluster).
1028  * @param[out] eta The @f$\eta@f$ location of the cluster seed.
1029  * @param[out] phi The @f$\phi@f$ location of the cluster seed.
1030  *
1031  * The cluster seed is the center of rectangular cluster windows.
1032  * This may be overridden by derived classes to change the seed definition.
1033  */
1034 void CaloFillRectangularCluster::get_seed (const CaloCluster* cluster,
1035                                            const CaloCell* max_et_cell,
1036                                            double& eta,
1037                                            double& phi)
1038 {
1039   ///!!! NEW way of the endcap-shift treatment (same for barrel and endcap)
1040   // a.b.c 2004 : for barrel, correct for the alignment before 
1041   //               comparing the Tower direction and the cell's
1042   // ( for Atlas the difference is null, but it's not true for TB )
1043   static CaloPhiRange range;
1044   const CaloDetDescrElement* elt = max_et_cell->caloDDE();
1045   double phi_shift = elt->phi()-elt->phi_raw();
1046   double eta_shift = elt->eta()-elt->eta_raw();
1047   eta = cluster->eta0()+eta_shift;
1048   phi = range.fix(cluster->phi0()+phi_shift);
1049 
1050   // Special case to handle a pathology seen at the edge of the calorimeter
1051   // with clusters with an eta size of 3.  The cluster size used for the SW
1052   // clustering is 5x5.  The SW clustering will find the window that contains
1053   // the maximum amount of energy.  So, suppose that there's a cluster
1054   // near the edge of the calorimeter such that the most energetic cell
1055   // is right at the edge of the calorimeter.  In this case, the SW clustering
1056   // is likely to position the seed cell two cells from the edge
1057   // (the next-to-next-to-last cell), as in that case, all 5 eta cells
1058   // are contained within the calorimeter.  But in that case, if we then
1059   // build a cluster of size 3 around this seed, then we'll be missing
1060   // the cell with the highest energy!  This will severely bias the
1061   // energy and eta measurements.
1062   //
1063   // So, what I'll do is this.  If the maximum cell is at the outer
1064   // edge of the (outer) EC and it is not within our eta window, then I'll
1065   // use the maximum cell position as the seed instead of what
1066   // the SW clustering gives.  I restrict this to the outer edge
1067   // of the EC to avoid any chance of changing the clustering results
1068   // in the bulk of the calorimeter.
1069   // Also do this if the maximum cell is on the edge of the inner endcap --- 
1070   // we can get the same effect.
1071   if ((elt->is_lar_em_endcap_inner() &&
1072        std::abs(elt->eta_raw()) - elt->deta() <
1073            elt->descriptor()->calo_eta_min()) ||
1074       (elt->is_lar_em_endcap_outer() &&
1075        std::abs(elt->eta_raw()) + elt->deta() >
1076            elt->descriptor()->calo_eta_max()))
1077   {
1078     // Max cell is at the edge.  Is it outside the window?
1079     if (std::abs (eta - elt->eta()) > m_deta2/2) {
1080       // Yes --- change the seed.
1081       eta = elt->eta();
1082     }
1083   }
1084 }

source navigation ] diff markup ] identifier search ] general search ]

Due to the LXR bug, the updates fail sometimes to remove references to deleted files. The Saturday's full rebuilds fix these problems
This page was automatically generated by the LXR engine. Valid HTML 4.01!