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 
7 
11 
13 
19 
22 
27 
28 #include <random>
29 #include <memory>
30 
32 #include "CLHEP/Units/SystemOfUnits.h"
34 
36 public:
39 
40  void produce(edm::StreamID, edm::Event&, const edm::EventSetup&) const override;
41 
42 private:
43  // inputs
46  // options
47  std::vector<std::unique_ptr<const ResolutionModel> > _resolutions;
48  const float minFraction_, minEnergy_;
49  const unsigned ecalDepth_;
50  // functions
51  std::pair<float, DetId> getTimeForECALPFCluster(const EcalRecHitCollection&,const reco::PFCluster&) const;
52  float correctTimeToVertex(const float intime, const DetId& timeDet, const reco::Vertex& vtx,
53  const CaloSubdetectorGeometry* ecalGeom) const;
54 };
55 
57 
58 namespace {
59  const std::string resolution("Resolution");
60 
61  constexpr float cm_per_ns = 29.9792458;
62 
63  template<typename T>
65  const edm::Handle<std::vector<reco::PFCluster> > & handle,
66  const std::vector<T> & values,
67  const std::string & label) {
68  auto valMap = std::make_unique<edm::ValueMap<T>>();
69  typename edm::ValueMap<T>::Filler filler(*valMap);
70  filler.insert(handle, values.begin(), values.end());
71  filler.fill();
72  iEvent.put(std::move(valMap), label);
73  }
74 }
75 
77  ebTimeHitsToken_(consumes<EcalRecHitCollection>( conf.getParameter<edm::InputTag>("ebTimeHits") ) ),
78  ebClustersToken_(consumes<std::vector<reco::PFCluster> >( conf.getParameter<edm::InputTag>("ebClusters") ) ),
79  minFraction_( conf.getParameter<double>("minFractionToConsider") ),
80  minEnergy_(conf.getParameter<double>("minEnergyToConsider") ),
81  ecalDepth_(conf.getParameter<double>("ecalDepth") )
82 {
83  // setup resolution models
84  const std::vector<edm::ParameterSet>& resos = conf.getParameterSetVector("resolutionModels");
85  for( const auto& reso : resos ) {
86  const std::string& name = reso.getParameter<std::string>("modelName");
87  _resolutions.emplace_back( ResolutionModelFactory::get()->create(name,reso) );
88 
89  // times and time resolutions for general tracks
90  produces<edm::ValueMap<float> >(name);
91  produces<edm::ValueMap<float> >(name+resolution);
92  }
93 }
94 
98 
99  evt.getByToken(ebClustersToken_,clustersH);
100  evt.getByToken(ebTimeHitsToken_,timehitsH);
101 
102  const auto& clusters = *clustersH;
103  const auto& timehits = *timehitsH;
104 
105  // get event-based seed for RNG
106  unsigned int runNum_uint = static_cast <unsigned int> (evt.id().run());
107  unsigned int lumiNum_uint = static_cast <unsigned int> (evt.id().luminosityBlock());
108  unsigned int evNum_uint = static_cast <unsigned int> (evt.id().event());
109  std::uint32_t seed = (lumiNum_uint<<10) + (runNum_uint<<20) + evNum_uint;
110  std::mt19937 rng(seed);
111 
112  std::vector<std::pair<float,DetId> > times; // perfect times keyed to cluster index
113  times.reserve(clusters.size());
114 
115  for( const auto& cluster : clusters ) {
116  times.push_back( getTimeForECALPFCluster( timehits, cluster ) );
117  }
118 
119  for( const auto& reso : _resolutions ) {
120  const std::string& name = reso->name();
121  std::vector<float> resolutions;
122  std::vector<float> smeared_times;
123  resolutions.reserve(clusters.size());
124  smeared_times.reserve(clusters.size());
125 
126  // smear once then correct to multiple vertices
127  for( unsigned i = 0 ; i < clusters.size(); ++i ) {
128  const float theresolution = reso->getTimeResolution(clusters[i]);
129  std::normal_distribution<float> gausTime(times[i].first, theresolution);
130 
131  smeared_times.emplace_back( gausTime(rng) );
132  resolutions.push_back( theresolution );
133  }
134 
135  writeValueMap(evt,clustersH,smeared_times,name);
136  writeValueMap(evt,clustersH,resolutions,name+resolution);
137  }
138 
139 }
140 
141 std::pair<float,DetId> EcalBarrelClusterFastTimer::getTimeForECALPFCluster(const EcalRecHitCollection& timehits, const reco::PFCluster& cluster) const {
142 
143  const auto& rhfs = cluster.recHitFractions();
144  unsigned best_hit = 0;
145  float best_energy = -1.f;
146  for( const auto& rhf : rhfs ) {
147  const auto& hitref = rhf.recHitRef();
148  const unsigned detid = hitref->detId();
149  const auto fraction = rhf.fraction();
150  const auto energy = hitref->energy();
151  if( fraction < minFraction_ || energy < minEnergy_ ) continue;
152  auto timehit = timehits.find(detid);
153  float e_hit = rhf.fraction() * hitref->energy();
154  if( e_hit > best_energy && timehit->isTimeValid() ) {
155  best_energy = e_hit;
156  best_hit = detid;
157  }
158  }
159 
160  float best_time_guess = std::numeric_limits<float>::max();
161  if( best_energy > 0. ) {
162  best_time_guess = timehits.find(best_hit)->time();
163  }
164 
165  //std::cout << "EcalBarrelFastTimer: " << best_time_guess << ' ' << best_energy << ' ' << best_hit << std::endl;
166 
167  return std::make_pair(best_time_guess,DetId(best_hit));
168 }
169 
170 float EcalBarrelClusterFastTimer::correctTimeToVertex(const float intime, const DetId& timeDet, const reco::Vertex& vtx,
171  const CaloSubdetectorGeometry* ecalGeom) const {
172  if( timeDet.rawId() == 0 ) return -999.;
173  // correct the cluster time from 0,0,0 to the primary vertex given
174  auto cellGeometry = ecalGeom->getGeometry(timeDet);
175  if( nullptr == cellGeometry ) {
176  throw cms::Exception("BadECALBarrelCell")
177  << std::hex << timeDet.rawId() << std::dec<< " is not a valid ECAL Barrel DetId!";
178  }
179  //depth in mm in the middle of the layer position;
180  GlobalPoint layerPos = cellGeometry->getPosition( ecalDepth_+0.5 );
181  const math::XYZPoint layerPos_cm( layerPos.x(), layerPos.y(), layerPos.z() );
182  const math::XYZVector to_center = layerPos_cm - math::XYZPoint(0.,0.,0.);
183  const math::XYZVector to_vtx = layerPos_cm - vtx.position();
184 
185  /*
186  std::cout << intime << ' ' << to_center.r()/cm_per_ns << ' ' << to_vtx.r()/cm_per_ns
187  << ' ' << intime + to_center.r()/cm_per_ns - to_vtx.r()/cm_per_ns << std::endl;
188  */
189 
190  return intime + to_center.r()/cm_per_ns - to_vtx.r()/cm_per_ns;
191 }
RunNumber_t run() const
Definition: EventID.h:39
EventNumber_t event() const
Definition: EventID.h:41
VParameterSet const & getParameterSetVector(std::string const &name) const
OrphanHandle< PROD > put(std::unique_ptr< PROD > product)
Put a new product.
Definition: Event.h:125
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:47
bool getByToken(EDGetToken token, Handle< PROD > &result) const
Definition: Event.h:517
constexpr uint32_t rawId() const
get the raw id
Definition: DetId.h:50
T y() const
Definition: PV3DBase.h:63
LuminosityBlockNumber_t luminosityBlock() const
Definition: EventID.h:40
const Point & position() const
position
Definition: Vertex.h:109
void writeValueMap(edm::Event &iEvent, const edm::Handle< HandleType > &handle, const std::vector< ValueType > &values, const std::string &label)
Definition: Utils.h:13
EDGetTokenT< ProductType > consumes(edm::InputTag const &tag)
std::vector< std::unique_ptr< const ResolutionModel > > _resolutions
char const * label
int iEvent
Definition: GenABIO.cc:224
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
T z() const
Definition: PV3DBase.h:64
EcalBarrelClusterFastTimer(const edm::ParameterSet &)
float correctTimeToVertex(const float intime, const DetId &timeDet, const reco::Vertex &vtx, const CaloSubdetectorGeometry *ecalGeom) const
edm::EDGetTokenT< EcalRecHitCollection > ebTimeHitsToken_
Definition: DetId.h:18
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.
XYZVectorD XYZVector
spatial vector with cartesian internal representation
Definition: Vector3D.h:30
XYZPointD XYZPoint
point in space with cartesian internal representation
Definition: Point3D.h:12
edm::EventID id() const
Definition: EventBase.h:59
iterator find(key_type k)
fixed size matrix
HLT enums.
void produce(edm::StreamID, edm::Event &, const edm::EventSetup &) const override
const std::vector< reco::PFRecHitFraction > & recHitFractions() const
vector of rechit fractions
Definition: PFCluster.h:72
std::pair< float, DetId > getTimeForECALPFCluster(const EcalRecHitCollection &, const reco::PFCluster &) const
T x() const
Definition: PV3DBase.h:62
def move(src, dest)
Definition: eostools.py:511
T get(const Candidate &c)
Definition: component.h:55
#define constexpr