Back to home page

sPhenix code displayed by LXR

 
 

    


File indexing completed on 2025-08-06 08:17:35

0001 #ifndef CALORECO_RAWTOWERCOMBINER_H
0002 #define CALORECO_RAWTOWERCOMBINER_H
0003 
0004 #include <fun4all/SubsysReco.h>
0005 
0006 #include <string>
0007 
0008 class PHCompositeNode;
0009 class RawTowerContainer;
0010 
0011 //! \brief RawTowerCombiner module that joints multiple RawTower together to form a single readout in a separate node
0012 //! Use this class to simulate ganged readout or trigger channels that combined multiple towers
0013 //! Should be called after RawTowerBuilder but before RawTowerDigitizer
0014 /*
0015 ## Introduction
0016 
0017 A new tower analysis module to enable analysis of sPHENIX simulation to use multi-tower ganging of EMCal readout. For example 2x2-ganging as proposed for some CEMC de-scoping options.
0018 
0019 Technically, a new module ```RawTowerCombiner``` is introduced to combine MxN towers into one readout channel on an eta-phi tower grid exiting on the DST tree. Therefore, it needs to be called after ```RawTowerBuilder``` and before ```RawTowerDigitizer```. During the merging, truth structure (Cells and showers) is maintained. In the default mode, both RawTower and RawTowerGeometry are edited on the DST tree, rather than introducing a new node for combined towers. I found this is least intrusive to our analysis code base.
0020 
0021 If one need to use this module for ALD charge (e.g. photon position resolution, jet finding, etc.), please contact me directly, in order to speed up verification and feedback.
0022 
0023 ## Verification
0024 
0025 The single particle simulation in the 2016-02-01 Geant4 production (```/sphenix/sim/sim01/production/2016-02-01```) was used for testing.
0026 
0027 One example is distance between best CEMC cluster from the trajectory projection of 24 GeV/c electrons. Green reference plot is default towering and blue curve is after 2x2 ganging. The ganged distribution is roughly twice wider while the central value remain zeroed.
0028 <img width="194" alt="2x2test" src="https://cloud.githubusercontent.com/assets/7947083/15116941/546e3fd2-15d3-11e6-8a19-3e720c302ddd.png">
0029 Note: here cluster position is calculated with simple energy weighted average, without more sophisticated discretization corrections.
0030 
0031 ## Example macros
0032 
0033 By default, this new module is NOT used in analysis and no ganging is applied.
0034 
0035 Example macro to enabling 2x2 ganging as proposed for some de-scoping otpions: https://github.com/blackcathj/macros/blob/EMCal2x2/macros/g4simulations/G4_CEmc_Spacal.C
0036 Or specifically these lines added:
0037 
0038 \code
0039 
0040 void CEMC_Towers(int verbosity = 0) {
0041  ...
0042   // TowerBuilder
0043  ...
0044 
0045   // Make ganged output for CEMC
0046   if (combin_CEMC_tower_2x2)
0047   {
0048     // group CEMC RawTower to CEMC2x2
0049     RawTowerCombiner * TowerCombiner = new RawTowerCombiner("RawTowerCombiner_CEMC");
0050     TowerCombiner->Detector("CEMC");
0051     TowerCombiner->set_combine_eta(2);
0052     TowerCombiner->set_combine_phi(2);
0053 //    TowerCombiner->Verbosity(RawTowerCombiner::VERBOSITY_SOME);
0054     se->registerSubsystem( TowerCombiner );
0055   }
0056 
0057  // TowerDigitizer
0058  ...
0059 }
0060 
0061 \endcode
0062 
0063  * */
0064 
0065 class RawTowerCombiner : public SubsysReco
0066 {
0067  public:
0068   RawTowerCombiner(const std::string &name = "RawTowerCombiner");
0069 
0070   ~RawTowerCombiner() override = default;
0071 
0072   int InitRun(PHCompositeNode *topNode) override;
0073   int process_event(PHCompositeNode *topNode) override;
0074   int End(PHCompositeNode *topNode) override;
0075 
0076   void
0077   Detector(const std::string &d)
0078   {
0079     detector = d;
0080   }
0081 
0082   //! prefix to the tower node
0083   const std::string &get_tower_node_prefix() const
0084   {
0085     return _tower_node_prefix;
0086   }
0087 
0088   //! prefix to the tower node
0089   void
0090   set_tower_node_prefix(const std::string &simTowerNodePrefix)
0091   {
0092     _tower_node_prefix = simTowerNodePrefix;
0093   }
0094 
0095   //! number of eta towers to be merged into a new tower
0096   unsigned int
0097   get_combine_eta() const
0098   {
0099     return _n_combine_eta;
0100   }
0101 
0102   //! number of eta towers to be merged into a new tower
0103   void
0104   set_combine_eta(unsigned int combineEta)
0105   {
0106     _n_combine_eta = combineEta;
0107   }
0108 
0109   //! number of eta towers to be merged into a new tower
0110   unsigned int
0111   get_combine_phi() const
0112   {
0113     return _n_combine_phi;
0114   }
0115 
0116   //! number of eta towers to be merged into a new tower
0117   void
0118   set_combine_phi(unsigned int combinePhi)
0119   {
0120     _n_combine_phi = combinePhi;
0121   }
0122 
0123  protected:
0124   //! prefix to the tower node
0125   std::string _tower_node_prefix;
0126 
0127   //! number of eta towers to be merged into a new tower
0128   unsigned int _n_combine_eta;
0129   //! number of phi towers to be merged into a new tower
0130   unsigned int _n_combine_phi;
0131 
0132   //! get the new ieta from the old
0133   inline int get_output_bin_eta(int input_bin) const { return input_bin / _n_combine_eta; }
0134   //! get the new iphi from the old
0135   inline int get_output_bin_phi(int input_bin) const { return input_bin / _n_combine_phi; }
0136 
0137   void
0138   CreateNodes(PHCompositeNode *topNode);
0139 
0140   RawTowerContainer *_towers;
0141 
0142   std::string detector;
0143 };
0144 
0145 #endif