CMS 3D CMS Logo

HGCalLayerClusterProducer.cc
Go to the documentation of this file.
1 // Authors: Olivie Franklova - olivie.abigail.franklova@cern.ch
2 // Date: 03/2023
3 // @file create layer clusters
4 
5 #define DEBUG_CLUSTERS_ALPAKA 0
6 
7 // user include files
11 
17 
25 
28 
31 
34 
36 
37 #if DEBUG_CLUSTERS_ALPAKA
39 #endif
40 
42 public:
57  static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
58 
65  void produce(edm::Event&, const edm::EventSetup&) override;
66 
67 private:
69 
71 
72  std::unique_ptr<HGCalClusteringAlgoBase> algo_;
74 
76  unsigned int hitsTime_;
77 
78  // for calculate position
79  std::vector<double> thresholdW0_;
84 #if DEBUG_CLUSTERS_ALPAKA
85  std::string moduleLabel_;
86 #endif
87 
91  void setAlgoId();
92 
100  math::XYZPoint calculatePosition(std::unordered_map<uint32_t, const HGCRecHit*>& hitmap,
101  const std::vector<std::pair<DetId, float>>& hitsAndFractions);
102 
110  std::pair<float, float> calculateTime(std::unordered_map<uint32_t, const HGCRecHit*>& hitmap,
111  const std::vector<std::pair<DetId, float>>& hitsAndFractions,
112  size_t sizeCluster);
113 };
114 
116  : algoId_(reco::CaloCluster::undefined),
117  detector_(ps.getParameter<std::string>("detector")), // one of EE, FH, BH, HFNose
118  timeClname_(ps.getParameter<std::string>("timeClname")),
119  hitsTime_(ps.getParameter<unsigned int>("nHitsTime")),
120  caloGeomToken_(consumesCollector().esConsumes<CaloGeometry, CaloGeometryRecord>()),
121  calculatePositionInAlgo_(ps.getParameter<bool>("calculatePositionInAlgo")) {
122 #if DEBUG_CLUSTERS_ALPAKA
123  moduleLabel_ = ps.getParameter<std::string>("@module_label");
124 #endif
125  setAlgoId(); //sets algo id according to detector type
126  hits_token_ = consumes<HGCRecHitCollection>(ps.getParameter<edm::InputTag>("recHits"));
127 
128  auto pluginPSet = ps.getParameter<edm::ParameterSet>("plugin");
129  if (detector_ == "HFNose") {
130  algo_ = HGCalLayerClusterAlgoFactory::get()->create("HFNoseCLUE", pluginPSet);
131  algo_->setAlgoId(algoId_, true);
132  } else {
133  algo_ = HGCalLayerClusterAlgoFactory::get()->create(pluginPSet.getParameter<std::string>("type"), pluginPSet);
134  algo_->setAlgoId(algoId_);
135  }
136  thresholdW0_ = pluginPSet.getParameter<std::vector<double>>("thresholdW0");
137  positionDeltaRho2_ = pluginPSet.getParameter<double>("positionDeltaRho2");
138 
139  produces<std::vector<float>>("InitialLayerClustersMask");
140  produces<std::vector<reco::BasicCluster>>();
141  //time for layer clusters
142  produces<edm::ValueMap<std::pair<float, float>>>(timeClname_);
143 }
144 
146  // hgcalLayerClusters
148  edm::ParameterSetDescription pluginDesc;
149  pluginDesc.addNode(edm::PluginDescription<HGCalLayerClusterAlgoFactory>("type", "SiCLUE", true));
150 
151  desc.add<edm::ParameterSetDescription>("plugin", pluginDesc);
152  desc.add<std::string>("detector", "EE")->setComment("options EE, FH, BH, HFNose; other value defaults to EE");
153  desc.add<edm::InputTag>("recHits", edm::InputTag("HGCalRecHit", "HGCEERecHits"));
154  desc.add<std::string>("timeClname", "timeLayerCluster");
155  desc.add<unsigned int>("nHitsTime", 3);
156  desc.add<bool>("calculatePositionInAlgo", true);
157  descriptions.add("hgcalLayerClusters", desc);
158 }
159 
161  std::unordered_map<uint32_t, const HGCRecHit*>& hitmap,
162  const std::vector<std::pair<DetId, float>>& hitsAndFractions) {
163  float total_weight = 0.f;
164  float maxEnergyValue = 0.f;
165  DetId maxEnergyIndex;
166  float x = 0.f;
167  float y = 0.f;
168 
169  for (auto const& hit : hitsAndFractions) {
170  //time is computed wrt 0-25ns + offset and set to -1 if no time
171  const HGCRecHit* rechit = hitmap[hit.first];
172  total_weight += rechit->energy();
173  if (rechit->energy() > maxEnergyValue) {
174  maxEnergyValue = rechit->energy();
175  maxEnergyIndex = rechit->detid();
176  }
177  }
178  float total_weight_log = 0.f;
179  auto thick = rhtools_.getSiThickIndex(maxEnergyIndex);
180  const GlobalPoint positionMaxEnergy(rhtools_.getPosition(maxEnergyIndex));
181  for (auto const& hit : hitsAndFractions) {
182  //time is computed wrt 0-25ns + offset and set to -1 if no time
183  const HGCRecHit* rechit = hitmap[hit.first];
184 
185  const GlobalPoint position(rhtools_.getPosition(rechit->detid()));
186 
187  if (thick != -1) { //silicon
188  //for silicon only just use 1+6 cells = 1.3cm for all thicknesses
189  const float d1 = position.x() - positionMaxEnergy.x();
190  const float d2 = position.y() - positionMaxEnergy.y();
191  if ((d1 * d1 + d2 * d2) > positionDeltaRho2_)
192  continue;
193 
194  float Wi = std::max(thresholdW0_[thick] + std::log(rechit->energy() / total_weight), 0.);
195  x += position.x() * Wi;
196  y += position.y() * Wi;
197  total_weight_log += Wi;
198  } else { //scintillator
199  x += position.x() * rechit->energy();
200  y += position.y() * rechit->energy();
201  }
202  }
203  if (thick != -1) {
204  total_weight = total_weight_log;
205  }
206  if (total_weight != 0.) {
207  float inv_tot_weight = 1.f / total_weight;
208  return math::XYZPoint(x * inv_tot_weight, y * inv_tot_weight, positionMaxEnergy.z());
209  } else {
210  return {positionMaxEnergy.x(), positionMaxEnergy.y(), positionMaxEnergy.z()};
211  }
212 }
213 
215  std::unordered_map<uint32_t, const HGCRecHit*>& hitmap,
216  const std::vector<std::pair<DetId, float>>& hitsAndFractions,
217  size_t sizeCluster) {
218  std::pair<float, float> timeCl(-99., -1.);
219 
220  if (sizeCluster >= hitsTime_) {
221  std::vector<float> timeClhits;
222  std::vector<float> timeErrorClhits;
223 
224  for (auto const& hit : hitsAndFractions) {
225  //time is computed wrt 0-25ns + offset and set to -1 if no time
226  const HGCRecHit* rechit = hitmap[hit.first];
227 
228  float rhTimeE = rechit->timeError();
229  //check on timeError to exclude scintillator
230  if (rhTimeE < 0.f)
231  continue;
232  timeClhits.push_back(rechit->time());
233  timeErrorClhits.push_back(1.f / (rhTimeE * rhTimeE));
234  }
236  timeCl = timeEstimator.fixSizeHighestDensity(timeClhits, timeErrorClhits, hitsTime_);
237  }
238  return timeCl;
239 }
242 
243  std::unique_ptr<std::vector<reco::BasicCluster>> clusters(new std::vector<reco::BasicCluster>);
244 
247  algo_->getEventSetup(es, rhtools_);
248 
249  //make a map detid-rechit
250  // NB for the moment just host EE and FH hits
251  // timing in digi for BH not implemented for now
252  std::unordered_map<uint32_t, const HGCRecHit*> hitmap;
253 
255  algo_->populate(*hits);
256  for (auto const& it : *hits) {
257  hitmap[it.detid().rawId()] = &(it);
258  }
259 
260  algo_->makeClusters();
261  *clusters = algo_->getClusters(false);
262 
263  std::vector<std::pair<float, float>> times;
264  times.reserve(clusters->size());
265 
266  for (unsigned i = 0; i < clusters->size(); ++i) {
267  reco::CaloCluster& sCl = (*clusters)[i];
269  sCl.setPosition(calculatePosition(hitmap, sCl.hitsAndFractions()));
270  }
271  if (detector_ != "BH") {
272  times.push_back(calculateTime(hitmap, sCl.hitsAndFractions(), sCl.size()));
273  } else {
274  times.push_back(std::pair<float, float>(-99.f, -1.f));
275  }
276  }
277 
278 #if DEBUG_CLUSTERS_ALPAKA
280  auto runNumber = evt.eventAuxiliary().run();
281  auto lumiNumber = evt.eventAuxiliary().luminosityBlock();
282  auto evtNumber = evt.eventAuxiliary().id().event();
283 
284  dumper.dumpInfos(*clusters, moduleLabel_, runNumber, lumiNumber, evtNumber, true);
285 #endif
286 
287  auto clusterHandle = evt.put(std::move(clusters));
288 
289  if (detector_ == "HFNose") {
290  std::unique_ptr<std::vector<float>> layerClustersMask(new std::vector<float>);
291  layerClustersMask->resize(clusterHandle->size(), 1.0);
292  evt.put(std::move(layerClustersMask), "InitialLayerClustersMask");
293  }
294 
295  auto timeCl = std::make_unique<edm::ValueMap<std::pair<float, float>>>();
297  filler.insert(clusterHandle, times.begin(), times.end());
298  filler.fill();
299  evt.put(std::move(timeCl), timeClname_);
300 
301  algo_->reset();
302 }
303 
305  if (detector_ == "EE") {
307  } else if (detector_ == "FH") {
309  } else if (detector_ == "BH") {
311  } else if (detector_ == "HFNose") {
313  }
314 }
315 
ESGetTokenH3DDVariant esConsumes(std::string const &Record, edm::ConsumesCollector &)
Definition: DeDxTools.cc:283
T getParameter(std::string const &) const
Definition: ParameterSet.h:307
OrphanHandle< PROD > put(std::unique_ptr< PROD > product)
Put a new product.
Definition: Event.h:133
math::XYZPoint calculatePosition(std::unordered_map< uint32_t, const HGCRecHit *> &hitmap, const std::vector< std::pair< DetId, float >> &hitsAndFractions)
Counts position for all points in the cluster.
const std::vector< std::pair< DetId, float > > & hitsAndFractions() const
Definition: CaloCluster.h:210
void produce(edm::Event &, const edm::EventSetup &) override
Method run the algoritm to get clusters.
constexpr const DetId & detid() const
Definition: CaloRecHit.h:33
std::pair< float, float > calculateTime(std::unordered_map< uint32_t, const HGCRecHit *> &hitmap, const std::vector< std::pair< DetId, float >> &hitsAndFractions, size_t sizeCluster)
Counts time for all points in the cluster.
LuminosityBlockNumber_t luminosityBlock() const
void setPosition(const math::XYZPoint &p)
Definition: CaloCluster.h:140
ParameterDescriptionNode * addNode(ParameterDescriptionNode const &node)
edm::ESGetToken< CaloGeometry, CaloGeometryRecord > caloGeomToken_
void dumpInfos(const T &clusters, const std::string &moduleLabel, edm::RunNumber_t run, edm::LuminosityBlockNumber_t lumi, edm::EventNumber_t event, bool dumpCellsDetId=false) const
bool getByToken(EDGetToken token, Handle< PROD > &result) const
Definition: Event.h:526
EventAuxiliary const & eventAuxiliary() const override
Definition: Event.h:95
constexpr float energy() const
Definition: CaloRecHit.h:29
EventID const & id() const
std::pair< float, float > fixSizeHighestDensity(std::vector< float > &time, std::vector< float > weight=std::vector< float >(), unsigned int minNhits=3, float deltaT=0.210, float timeWidthBy=0.5)
std::unique_ptr< HGCalClusteringAlgoBase > algo_
GlobalPoint getPosition(const DetId &id) const
Definition: RecHitTools.cc:140
reco::CaloCluster::AlgoId algoId_
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
Method fill description which will be used in pyhton file.
double f[11][100]
size_t size() const
size in number of hits (e.g. in crystals for ECAL)
Definition: CaloCluster.h:187
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
void setAlgoId()
Sets algoId accordingly to the detector type.
ESHandle< T > getHandle(const ESGetToken< T, R > &iToken) const
Definition: EventSetup.h:130
Definition: DetId.h:17
edm::EDGetTokenT< HGCRecHitCollection > hits_token_
XYZPointD XYZPoint
point in space with cartesian internal representation
Definition: Point3D.h:12
void add(std::string const &label, ParameterSetDescription const &psetDescription)
void setGeometry(CaloGeometry const &)
Definition: RecHitTools.cc:79
constexpr float time() const
Definition: CaloRecHit.h:31
HGCalLayerClusterProducer(const edm::ParameterSet &)
Constructor with parameter settings - which can be changed in hgcalLayerCluster_cff.py. Constructor will set all variables by input param ps. algoID variables will be set accordingly to the detector type.
fixed size matrix
static int position[264][3]
Definition: ReadPGInfo.cc:289
float timeError() const
Definition: HGCRecHit.cc:79
#define get
static constexpr float d1
int getSiThickIndex(const DetId &) const
Definition: RecHitTools.cc:216
def move(src, dest)
Definition: eostools.py:511
EventNumber_t event() const
Definition: EventID.h:40
RunNumber_t run() const