CMS 3D CMS Logo

EcalBarrelClusterFastTimer.cc
Go to the documentation of this file.
1 // This producer eats standard PF ECAL clusters
2 // finds the corresponding fast-timing det IDs and attempts to
3 // assign a reasonable time guess
4 
5 #include "CLHEP/Units/SystemOfUnits.h"
25 
26 #include <random>
27 #include <memory>
28 
30 public:
32 
33  static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
34 
35  void produce(edm::StreamID, edm::Event&, const edm::EventSetup&) const override;
36 
37 private:
38  // inputs
41  // options
42  std::vector<std::unique_ptr<const ResolutionModel>> _resolutions;
43  const float minFraction_, minEnergy_;
44  const unsigned ecalDepth_;
45  // functions
46  std::pair<float, DetId> getTimeForECALPFCluster(const EcalRecHitCollection&, const reco::PFCluster&) const;
47  float correctTimeToVertex(const float intime,
48  const DetId& timeDet,
49  const reco::Vertex& vtx,
50  const CaloSubdetectorGeometry* ecalGeom) const;
51 };
52 
55 
57  // ecalBarrelClusterFastTimer
59  desc.add<double>("ecalDepth", 7.0);
60  {
62  vpsd1.add<std::string>("modelName", "PerfectResolutionModel");
63  std::vector<edm::ParameterSet> temp1;
64  temp1.reserve(1);
65  {
66  edm::ParameterSet temp2;
67  temp2.addParameter<std::string>("modelName", "PerfectResolutionModel");
68  temp1.push_back(temp2);
69  }
70  desc.addVPSet("resolutionModels", vpsd1, temp1);
71  }
72  desc.add<edm::InputTag>("timedVertices", edm::InputTag("offlinePrimaryVertices4D"));
73  desc.add<double>("minFractionToConsider", 0.1);
74  desc.add<edm::InputTag>("ebClusters", edm::InputTag("particleFlowClusterECALUncorrected"));
75  desc.add<double>("minEnergyToConsider", 0.0);
76  desc.add<edm::InputTag>("ebTimeHits", edm::InputTag("ecalDetailedTimeRecHit", "EcalRecHitsEB"));
77  descriptions.add("ecalBarrelClusterFastTimer", desc);
78 }
79 
80 namespace {
81  const std::string resolution("Resolution");
82 
83  constexpr float cm_per_ns = 29.9792458;
84 
85  template <typename T>
86  void writeValueMap(edm::Event& iEvent,
87  const edm::Handle<std::vector<reco::PFCluster>>& handle,
88  const std::vector<T>& values,
89  const std::string& label) {
90  auto valMap = std::make_unique<edm::ValueMap<T>>();
91  typename edm::ValueMap<T>::Filler filler(*valMap);
92  filler.insert(handle, values.begin(), values.end());
93  filler.fill();
94  iEvent.put(std::move(valMap), label);
95  }
96 } // namespace
97 
99  : ebTimeHitsToken_(consumes<EcalRecHitCollection>(conf.getParameter<edm::InputTag>("ebTimeHits"))),
100  ebClustersToken_(consumes<std::vector<reco::PFCluster>>(conf.getParameter<edm::InputTag>("ebClusters"))),
101  minFraction_(conf.getParameter<double>("minFractionToConsider")),
102  minEnergy_(conf.getParameter<double>("minEnergyToConsider")),
103  ecalDepth_(conf.getParameter<double>("ecalDepth")) {
104  // setup resolution models
105  const std::vector<edm::ParameterSet>& resos = conf.getParameterSetVector("resolutionModels");
106  for (const auto& reso : resos) {
107  const std::string& name = reso.getParameter<std::string>("modelName");
108  _resolutions.emplace_back(ResolutionModelFactory::get()->create(name, reso));
109 
110  // times and time resolutions for general tracks
111  produces<edm::ValueMap<float>>(name);
112  produces<edm::ValueMap<float>>(name + resolution);
113  }
114 }
115 
119 
120  evt.getByToken(ebClustersToken_, clustersH);
121  evt.getByToken(ebTimeHitsToken_, timehitsH);
122 
123  const auto& clusters = *clustersH;
124  const auto& timehits = *timehitsH;
125 
126  // get event-based seed for RNG
127  unsigned int runNum_uint = static_cast<unsigned int>(evt.id().run());
128  unsigned int lumiNum_uint = static_cast<unsigned int>(evt.id().luminosityBlock());
129  unsigned int evNum_uint = static_cast<unsigned int>(evt.id().event());
130  std::uint32_t seed = (lumiNum_uint << 10) + (runNum_uint << 20) + evNum_uint;
131  std::mt19937 rng(seed);
132 
133  std::vector<std::pair<float, DetId>> times; // perfect times keyed to cluster index
134  times.reserve(clusters.size());
135 
136  for (const auto& cluster : clusters) {
137  times.push_back(getTimeForECALPFCluster(timehits, cluster));
138  }
139 
140  for (const auto& reso : _resolutions) {
141  const std::string& name = reso->name();
142  std::vector<float> resolutions;
143  std::vector<float> smeared_times;
144  resolutions.reserve(clusters.size());
145  smeared_times.reserve(clusters.size());
146 
147  // smear once then correct to multiple vertices
148  for (unsigned i = 0; i < clusters.size(); ++i) {
149  const float theresolution = reso->getTimeResolution(clusters[i]);
150  std::normal_distribution<float> gausTime(times[i].first, theresolution);
151 
152  smeared_times.emplace_back(gausTime(rng));
153  resolutions.push_back(theresolution);
154  }
155 
156  writeValueMap(evt, clustersH, smeared_times, name);
157  writeValueMap(evt, clustersH, resolutions, name + resolution);
158  }
159 }
160 
162  const reco::PFCluster& cluster) const {
163  const auto& rhfs = cluster.recHitFractions();
164  unsigned best_hit = 0;
165  float best_energy = -1.f;
166  for (const auto& rhf : rhfs) {
167  const auto& hitref = rhf.recHitRef();
168  const unsigned detid = hitref->detId();
169  const auto fraction = rhf.fraction();
170  const auto energy = hitref->energy();
172  continue;
173  auto timehit = timehits.find(detid);
174  float e_hit = rhf.fraction() * hitref->energy();
175  if (e_hit > best_energy && timehit->isTimeValid()) {
176  best_energy = e_hit;
177  best_hit = detid;
178  }
179  }
180 
181  float best_time_guess = std::numeric_limits<float>::max();
182  if (best_energy > 0.) {
183  best_time_guess = timehits.find(best_hit)->time();
184  }
185 
186  //std::cout << "EcalBarrelFastTimer: " << best_time_guess << ' ' << best_energy << ' ' << best_hit << std::endl;
187 
188  return std::make_pair(best_time_guess, DetId(best_hit));
189 }
190 
192  const DetId& timeDet,
193  const reco::Vertex& vtx,
194  const CaloSubdetectorGeometry* ecalGeom) const {
195  if (timeDet.rawId() == 0)
196  return -999.;
197  // correct the cluster time from 0,0,0 to the primary vertex given
198  auto cellGeometry = ecalGeom->getGeometry(timeDet);
199  if (nullptr == cellGeometry) {
200  throw cms::Exception("BadECALBarrelCell")
201  << std::hex << timeDet.rawId() << std::dec << " is not a valid ECAL Barrel DetId!";
202  }
203  //depth in mm in the middle of the layer position;
204  GlobalPoint layerPos = cellGeometry->getPosition(ecalDepth_ + 0.5);
205  const math::XYZPoint layerPos_cm(layerPos.x(), layerPos.y(), layerPos.z());
206  const math::XYZVector to_center = layerPos_cm - math::XYZPoint(0., 0., 0.);
207  const math::XYZVector to_vtx = layerPos_cm - vtx.position();
208 
209  /*
210  std::cout << intime << ' ' << to_center.r()/cm_per_ns << ' ' << to_vtx.r()/cm_per_ns
211  << ' ' << intime + to_center.r()/cm_per_ns - to_vtx.r()/cm_per_ns << std::endl;
212  */
213 
214  return intime + to_center.r() / cm_per_ns - to_vtx.r() / cm_per_ns;
215 }
edm::EDGetTokenT< std::vector< reco::PFCluster > > ebClustersToken_
def create(alignables, pedeDump, additionalData, outputFile, config)
Particle flow cluster, see clustering algorithm in PFClusterAlgo.
Definition: PFCluster.h:42
T z() const
Definition: PV3DBase.h:61
const std::vector< reco::PFRecHitFraction > & recHitFractions() const
vector of rechit fractions
Definition: PFCluster.h:65
bool getByToken(EDGetToken token, Handle< PROD > &result) const
Definition: Event.h:539
float correctTimeToVertex(const float intime, const DetId &timeDet, const reco::Vertex &vtx, const CaloSubdetectorGeometry *ecalGeom) const
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
LuminosityBlockNumber_t luminosityBlock() const
Definition: EventID.h:39
std::vector< std::unique_ptr< const ResolutionModel > > _resolutions
char const * label
T x() const
Definition: PV3DBase.h:59
T y() const
Definition: PV3DBase.h:60
int iEvent
Definition: GenABIO.cc:224
void addParameter(std::string const &name, T const &value)
Definition: ParameterSet.h:135
EcalBarrelClusterFastTimer(const edm::ParameterSet &)
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
edm::EventID id() const
Definition: EventBase.h:59
ParameterDescriptionBase * add(U const &iLabel, T const &value)
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.
std::pair< float, DetId > getTimeForECALPFCluster(const EcalRecHitCollection &, const reco::PFCluster &) const
RunNumber_t run() const
Definition: EventID.h:38
edm::EDGetTokenT< EcalRecHitCollection > ebTimeHitsToken_
Definition: DetId.h:17
void produce(edm::StreamID, edm::Event &, const edm::EventSetup &) const override
XYZVectorD XYZVector
spatial vector with cartesian internal representation
Definition: Vector3D.h:31
constexpr uint32_t rawId() const
get the raw id
Definition: DetId.h:57
XYZPointD XYZPoint
point in space with cartesian internal representation
Definition: Point3D.h:12
void add(std::string const &label, ParameterSetDescription const &psetDescription)
iterator find(key_type k)
fixed size matrix
HLT enums.
VParameterSet const & getParameterSetVector(std::string const &name) const
#define get
def move(src, dest)
Definition: eostools.py:511
EventNumber_t event() const
Definition: EventID.h:40