ImagingPixelReco.cpp 5.76 KB
Newer Older
Chao Peng's avatar
Chao Peng committed
1
// Reconstruct digitized outputs of ImagingCalorimeter
Sylvester Joosten's avatar
Sylvester Joosten committed
2
3
// It converts digitized ADC/TDC values to energy/time, and looks for geometrical information of the
// readout pixels Author: Chao Peng Date: 06/02/2021
Chao Peng's avatar
Chao Peng committed
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

#include <algorithm>
#include <bitset>

#include "Gaudi/Property.h"
#include "GaudiAlg/GaudiAlgorithm.h"
#include "GaudiAlg/GaudiTool.h"
#include "GaudiAlg/Transformer.h"
#include "GaudiKernel/PhysicalConstants.h"
#include "GaudiKernel/RndmGenerators.h"
#include "GaudiKernel/ToolHandle.h"

#include "DDRec/CellIDPositionConverter.h"
#include "DDRec/Surface.h"
#include "DDRec/SurfaceManager.h"

// FCCSW
#include "JugBase/DataHandle.h"
#include "JugBase/IGeoSvc.h"

// Event Model related classes
Sylvester Joosten's avatar
Sylvester Joosten committed
25
#include "eicd/CalorimeterHitCollection.h"
Chao Peng's avatar
Chao Peng committed
26
27
28
29
30
31
#include "eicd/RawCalorimeterHitCollection.h"

using namespace Gaudi::Units;

namespace Jug::Reco {

Whitney Armstrong's avatar
Whitney Armstrong committed
32
33
34
35
36
37
38
  /** Imaging calorimeter pixel hit reconstruction.
   *
   * Reconstruct digitized outputs of ImagingCalorimeter
   * It converts digitized ADC/TDC values to energy/time, and looks for geometrical information of the
   *
   * \ingroup reco
   */
Sylvester Joosten's avatar
Sylvester Joosten committed
39
40
  class ImagingPixelReco : public GaudiAlgorithm {
  public:
Chao Peng's avatar
Chao Peng committed
41
    // geometry service
Sylvester Joosten's avatar
Sylvester Joosten committed
42
43
44
45
    Gaudi::Property<std::string> m_geoSvcName{this, "geoServiceName", "GeoSvc"};
    Gaudi::Property<std::string> m_readout{this, "readoutClass", ""};
    Gaudi::Property<std::string> m_layerField{this, "layerField", "layer"};
    Gaudi::Property<std::string> m_sectorField{this, "sectorField", "sector"};
Chao Peng's avatar
Chao Peng committed
46
    // length unit (from dd4hep geometry service)
Sylvester Joosten's avatar
Sylvester Joosten committed
47
    Gaudi::Property<double> m_lUnit{this, "lengthUnit", dd4hep::mm};
Chao Peng's avatar
Chao Peng committed
48
    // digitization parameters
Sylvester Joosten's avatar
Sylvester Joosten committed
49
50
51
52
53
    Gaudi::Property<int>    m_capADC{this, "capacityADC", 8096};
    Gaudi::Property<int>    m_pedMeanADC{this, "pedestalMean", 400};
    Gaudi::Property<double> m_dyRangeADC{this, "dynamicRangeADC", 100 * MeV};
    Gaudi::Property<double> m_pedSigmaADC{this, "pedestalSigma", 3.2};
    Gaudi::Property<double> m_thresholdADC{this, "thresholdFactor", 3.0};
Sylvester Joosten's avatar
Sylvester Joosten committed
54
55
    // Calibration!
    Gaudi::Property<double> m_sampFrac{this, "samplingFraction", 1.0};
56
57
58
59

    // unitless counterparts for the input parameters
    double dyRangeADC;

Chao Peng's avatar
Chao Peng committed
60
    // hits containers
Sylvester Joosten's avatar
Sylvester Joosten committed
61
62
    DataHandle<eic::RawCalorimeterHitCollection> m_inputHitCollection{
        "inputHitCollection", Gaudi::DataHandle::Reader, this};
Sylvester Joosten's avatar
Sylvester Joosten committed
63
64
    DataHandle<eic::CalorimeterHitCollection> m_outputHitCollection{"outputHitCollection",
                                                                    Gaudi::DataHandle::Writer, this};
Chao Peng's avatar
Chao Peng committed
65
66
67
68

    // Pointer to the geometry service
    SmartIF<IGeoSvc> m_geoSvc;
    // visit readout fields
Sylvester Joosten's avatar
Sylvester Joosten committed
69
70
    dd4hep::BitFieldCoder* id_dec;
    size_t                 sector_idx, layer_idx;
Chao Peng's avatar
Chao Peng committed
71
72
73

    ImagingPixelReco(const std::string& name, ISvcLocator* svcLoc) : GaudiAlgorithm(name, svcLoc)
    {
Sylvester Joosten's avatar
Sylvester Joosten committed
74
75
      declareProperty("inputHitCollection", m_inputHitCollection, "");
      declareProperty("outputHitCollection", m_outputHitCollection, "");
Chao Peng's avatar
Chao Peng committed
76
77
78
79
    }

    StatusCode initialize() override
    {
Sylvester Joosten's avatar
Sylvester Joosten committed
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
      if (GaudiAlgorithm::initialize().isFailure()) {
        return StatusCode::FAILURE;
      }
      m_geoSvc = service(m_geoSvcName);
      if (!m_geoSvc) {
        error() << "Unable to locate Geometry Service. "
                << "Make sure you have GeoSvc and SimSvc in the right order in the configuration."
                << endmsg;
        return StatusCode::FAILURE;
      }

      if (m_readout.value().empty()) {
        error() << "readoutClass is not provided, it is needed to know the fields in readout ids"
                << endmsg;
        return StatusCode::FAILURE;
      }

      try {
        id_dec     = m_geoSvc->detector()->readout(m_readout).idSpec().decoder();
        sector_idx = id_dec->index(m_sectorField);
        layer_idx  = id_dec->index(m_layerField);
      } catch (...) {
        error() << "Failed to load ID decoder for " << m_readout << endmsg;
        return StatusCode::FAILURE;
      }

106
107
108
      // unitless conversion
      dyRangeADC = m_dyRangeADC.value()/GeV;

Sylvester Joosten's avatar
Sylvester Joosten committed
109
      return StatusCode::SUCCESS;
Chao Peng's avatar
Chao Peng committed
110
111
112
113
    }

    StatusCode execute() override
    {
Sylvester Joosten's avatar
Sylvester Joosten committed
114
115
116
117
118
119
      // input collections
      const auto& rawhits = *m_inputHitCollection.get();
      // Create output collections
      auto& hits = *m_outputHitCollection.createAndPut();

      // energy time reconstruction
Sylvester Joosten's avatar
Sylvester Joosten committed
120
      int nhits = 0;
Sylvester Joosten's avatar
Sylvester Joosten committed
121
122
123
124
      for (const auto& rh : rawhits) {
        // did not pass the threshold
        if ((rh.amplitude() - m_pedMeanADC) < m_thresholdADC * m_pedSigmaADC) {
          continue;
Chao Peng's avatar
Chao Peng committed
125
        }
Sylvester Joosten's avatar
Sylvester Joosten committed
126
127
        double energy = (rh.amplitude() - m_pedMeanADC) / (double)m_capADC * dyRangeADC / m_sampFrac;   // convert ADC -> energy
        double time = rh.time() * 1.e-6; // ns
Sylvester Joosten's avatar
Sylvester Joosten committed
128
129
130
131
132
133
134
135
136
137
        auto   id   = rh.cellID();
        int    lid  = (int)id_dec->get(id, layer_idx);
        int    sid  = (int)id_dec->get(id, sector_idx);

        // global positions
        auto gpos = m_geoSvc->cellIDPositionConverter()->position(id);
        // local positions
        auto volman    = m_geoSvc->detector()->volumeManager();
        auto alignment = volman.lookupDetElement(id).nominal();
        auto pos       = alignment.worldToLocal(dd4hep::Position(gpos.x(), gpos.y(), gpos.z()));
Sylvester Joosten's avatar
Sylvester Joosten committed
138
139

        hits.push_back(eic::CalorimeterHit{
140
141
142
143
144
145
146
147
            id,           // cellID
            nhits++,      // ID
            lid,          // layer
            sid,          // sector
            0,            // type
            static_cast<float>(energy), // energy
            0,                          // energyError
            static_cast<float>(time),   // time
Sylvester Joosten's avatar
Sylvester Joosten committed
148
            {gpos.x() / m_lUnit, gpos.y() / m_lUnit, gpos.z() / m_lUnit}, // global pos
149
            {pos.x() / m_lUnit, pos.y() / m_lUnit, pos.z() / m_lUnit},    // local pos
Sylvester Joosten's avatar
Sylvester Joosten committed
150
            {0, 0, 0}}); // @TODO: add dimension
Sylvester Joosten's avatar
Sylvester Joosten committed
151
152
      }
      return StatusCode::SUCCESS;
Chao Peng's avatar
Chao Peng committed
153
    }
Sylvester Joosten's avatar
Sylvester Joosten committed
154
  };
Chao Peng's avatar
Chao Peng committed
155

Sylvester Joosten's avatar
Sylvester Joosten committed
156
  DECLARE_COMPONENT(ImagingPixelReco)
Chao Peng's avatar
Chao Peng committed
157
158

} // namespace Jug::Reco