CMS 3D CMS Logo

MuonTimingFiller.cc
Go to the documentation of this file.
1 //
2 // Package: MuonTimingFiller
3 // Class: MuonTimingFiller
4 //
12 //
13 // Original Author: Piotr Traczyk, CERN
14 // Created: Mon Mar 16 12:27:22 CET 2009
15 //
16 //
17 
18 // system include files
19 #include <memory>
20 
21 // user include files
24 
27 
29 
35 
39 
40 //
41 // constructors and destructor
42 //
44  // Load parameters for the DTTimingExtractor
45  edm::ParameterSet dtTimingParameters = iConfig.getParameter<edm::ParameterSet>("DTTimingParameters");
46 
47  // Load parameters for the CSCTimingExtractor
48  edm::ParameterSet cscTimingParameters = iConfig.getParameter<edm::ParameterSet>("CSCTimingParameters");
49 
50  // Fallback mechanism for old configs (there the segment matcher was built inside the timing extractors)
51  edm::ParameterSet matchParameters;
52  if (iConfig.existsAs<edm::ParameterSet>("MatchParameters"))
53  matchParameters = iConfig.getParameter<edm::ParameterSet>("MatchParameters");
54  else
55  matchParameters = dtTimingParameters.getParameter<edm::ParameterSet>("MatchParameters");
56 
57  theMatcher_ = std::make_unique<MuonSegmentMatcher>(matchParameters, iC);
58  theDTTimingExtractor_ = std::make_unique<DTTimingExtractor>(dtTimingParameters, theMatcher_.get());
59  theCSCTimingExtractor_ = std::make_unique<CSCTimingExtractor>(cscTimingParameters, theMatcher_.get());
60 
61  errorEB_ = iConfig.getParameter<double>("ErrorEB");
62  errorEE_ = iConfig.getParameter<double>("ErrorEE");
63  ecalEcut_ = iConfig.getParameter<double>("EcalEnergyCut");
64 
65  useDT_ = iConfig.getParameter<bool>("UseDT");
66  useCSC_ = iConfig.getParameter<bool>("UseCSC");
67  useECAL_ = iConfig.getParameter<bool>("UseECAL");
68 }
69 
71 
72 //
73 // member functions
74 //
75 
77  reco::MuonTimeExtra& dtTime,
78  reco::MuonTimeExtra& cscTime,
79  reco::MuonTime& rpcTime,
80  reco::MuonTimeExtra& combinedTime,
82  const edm::EventSetup& iSetup) {
83  TimeMeasurementSequence dtTmSeq, cscTmSeq;
84 
85  if (!(muon.combinedMuon().isNull())) {
86  theDTTimingExtractor_->fillTiming(dtTmSeq, muon.combinedMuon(), iEvent, iSetup);
87  theCSCTimingExtractor_->fillTiming(cscTmSeq, muon.combinedMuon(), iEvent, iSetup);
88  } else {
89  if (!(muon.standAloneMuon().isNull())) {
90  theDTTimingExtractor_->fillTiming(dtTmSeq, muon.standAloneMuon(), iEvent, iSetup);
91  theCSCTimingExtractor_->fillTiming(cscTmSeq, muon.standAloneMuon(), iEvent, iSetup);
92  } else {
93  if (muon.isTrackerMuon()) {
94  std::vector<const DTRecSegment4D*> dtSegments;
95  std::vector<const CSCSegment*> cscSegments;
96  for (auto& chamber : muon.matches()) {
97  for (auto& segment : chamber.segmentMatches) {
98  // Use only the segments that passed arbitration to avoid mixing
99  // segments from in-time and out-of-time muons that may bias the result
100  // SegmentAndTrackArbitration
101  if (segment.isMask(reco::MuonSegmentMatch::BestInStationByDR) &&
103  if (!(segment.dtSegmentRef.isNull()))
104  dtSegments.push_back(segment.dtSegmentRef.get());
105  if (!(segment.cscSegmentRef.isNull()))
106  cscSegments.push_back(segment.cscSegmentRef.get());
107  }
108  }
109  }
110  theDTTimingExtractor_->fillTiming(dtTmSeq, dtSegments, muon.innerTrack(), iEvent, iSetup);
111  theCSCTimingExtractor_->fillTiming(cscTmSeq, cscSegments, muon.innerTrack(), iEvent, iSetup);
112  }
113  }
114  }
115 
116  // Fill DT-specific timing information block
117  fillTimeFromMeasurements(dtTmSeq, dtTime);
118 
119  // Fill CSC-specific timing information block
120  fillTimeFromMeasurements(cscTmSeq, cscTime);
121 
122  // Fill RPC-specific timing information block
123  fillRPCTime(muon, rpcTime, iEvent);
124 
125  // Combine the TimeMeasurementSequences from DT/CSC subdetectors
126  TimeMeasurementSequence combinedTmSeq;
127  combineTMSequences(muon, dtTmSeq, cscTmSeq, combinedTmSeq);
128  // add ECAL info
129  if (useECAL_)
130  addEcalTime(muon, combinedTmSeq);
131 
132  // Fill the master timing block
133  fillTimeFromMeasurements(combinedTmSeq, combinedTime);
134 
135  LogTrace("MuonTime") << "Global 1/beta: " << combinedTime.inverseBeta() << " +/- " << combinedTime.inverseBetaErr()
136  << std::endl;
137  LogTrace("MuonTime") << " Free 1/beta: " << combinedTime.freeInverseBeta() << " +/- "
138  << combinedTime.freeInverseBetaErr() << std::endl;
139  LogTrace("MuonTime") << " Vertex time (in-out): " << combinedTime.timeAtIpInOut() << " +/- "
140  << combinedTime.timeAtIpInOutErr() << " # of points: " << combinedTime.nDof() << std::endl;
141  LogTrace("MuonTime") << " Vertex time (out-in): " << combinedTime.timeAtIpOutIn() << " +/- "
142  << combinedTime.timeAtIpOutInErr() << std::endl;
143  LogTrace("MuonTime") << " direction: " << combinedTime.direction() << std::endl;
144 }
145 
147  std::vector<double> x, y;
148  double invbeta(0), invbetaerr(0);
149  double vertexTime(0), vertexTimeErr(0), vertexTimeR(0), vertexTimeRErr(0);
150  double freeBeta(0), freeBetaErr(0), freeTime(0), freeTimeErr(0);
151 
152  if (tmSeq.dstnc.size() <= 1)
153  return;
154 
155  for (unsigned int i = 0; i < tmSeq.dstnc.size(); i++) {
156  invbeta +=
157  (1. + tmSeq.local_t0.at(i) / tmSeq.dstnc.at(i) * 30.) * tmSeq.weightInvbeta.at(i) / tmSeq.totalWeightInvbeta;
158  x.push_back(tmSeq.dstnc.at(i) / 30.);
159  y.push_back(tmSeq.local_t0.at(i) + tmSeq.dstnc.at(i) / 30.);
160  vertexTime += tmSeq.local_t0.at(i) * tmSeq.weightTimeVtx.at(i) / tmSeq.totalWeightTimeVtx;
161  vertexTimeR +=
162  (tmSeq.local_t0.at(i) + 2 * tmSeq.dstnc.at(i) / 30.) * tmSeq.weightTimeVtx.at(i) / tmSeq.totalWeightTimeVtx;
163  }
164 
165  double diff;
166  for (unsigned int i = 0; i < tmSeq.dstnc.size(); i++) {
167  diff = (1. + tmSeq.local_t0.at(i) / tmSeq.dstnc.at(i) * 30.) - invbeta;
168  invbetaerr += diff * diff * tmSeq.weightInvbeta.at(i);
169  diff = tmSeq.local_t0.at(i) - vertexTime;
170  vertexTimeErr += diff * diff * tmSeq.weightTimeVtx.at(i);
171  diff = tmSeq.local_t0.at(i) + 2 * tmSeq.dstnc.at(i) / 30. - vertexTimeR;
172  vertexTimeRErr += diff * diff * tmSeq.weightTimeVtx.at(i);
173  }
174 
175  double cf = 1. / (tmSeq.dstnc.size() - 1);
176  invbetaerr = sqrt(invbetaerr / tmSeq.totalWeightInvbeta * cf);
177  vertexTimeErr = sqrt(vertexTimeErr / tmSeq.totalWeightTimeVtx * cf);
178  vertexTimeRErr = sqrt(vertexTimeRErr / tmSeq.totalWeightTimeVtx * cf);
179 
180  muTime.setInverseBeta(invbeta);
181  muTime.setInverseBetaErr(invbetaerr);
182  muTime.setTimeAtIpInOut(vertexTime);
183  muTime.setTimeAtIpInOutErr(vertexTimeErr);
184  muTime.setTimeAtIpOutIn(vertexTimeR);
185  muTime.setTimeAtIpOutInErr(vertexTimeRErr);
186 
187  rawFit(freeBeta, freeBetaErr, freeTime, freeTimeErr, x, y);
188 
189  muTime.setFreeInverseBeta(freeBeta);
190  muTime.setFreeInverseBetaErr(freeBetaErr);
191 
192  muTime.setNDof(tmSeq.dstnc.size());
193 }
194 
196  double trpc = 0, trpc2 = 0;
197 
198  reco::TrackRef staTrack = muon.standAloneMuon();
199  if (staTrack.isNull())
200  return;
201 
202  const std::vector<const RPCRecHit*> rpcHits = theMatcher_->matchRPC(*staTrack, iEvent);
203  const int nrpc = rpcHits.size();
204  for (const auto& hitRPC : rpcHits) {
205  const double time = hitRPC->timeError() < 0 ? hitRPC->BunchX() * 25. : hitRPC->time();
206  trpc += time;
207  trpc2 += time * time;
208  }
209 
210  if (nrpc == 0)
211  return;
212 
213  trpc2 = trpc2 / nrpc;
214  trpc = trpc / nrpc;
215  const double trpcerr = sqrt(std::max(0., trpc2 - trpc * trpc));
216 
217  rpcTime.timeAtIpInOut = trpc;
218  rpcTime.timeAtIpInOutErr = trpcerr;
219  rpcTime.nDof = nrpc;
220 
221  // currently unused
222  rpcTime.timeAtIpOutIn = 0.;
223  rpcTime.timeAtIpOutInErr = 0.;
224 }
225 
227  const TimeMeasurementSequence& dtSeq,
228  const TimeMeasurementSequence& cscSeq,
229  TimeMeasurementSequence& cmbSeq) {
230  if (useDT_)
231  for (unsigned int i = 0; i < dtSeq.dstnc.size(); i++) {
232  cmbSeq.dstnc.push_back(dtSeq.dstnc.at(i));
233  cmbSeq.local_t0.push_back(dtSeq.local_t0.at(i));
234  cmbSeq.weightTimeVtx.push_back(dtSeq.weightTimeVtx.at(i));
235  cmbSeq.weightInvbeta.push_back(dtSeq.weightInvbeta.at(i));
236 
237  cmbSeq.totalWeightTimeVtx += dtSeq.weightTimeVtx.at(i);
238  cmbSeq.totalWeightInvbeta += dtSeq.weightInvbeta.at(i);
239  }
240 
241  if (useCSC_)
242  for (unsigned int i = 0; i < cscSeq.dstnc.size(); i++) {
243  cmbSeq.dstnc.push_back(cscSeq.dstnc.at(i));
244  cmbSeq.local_t0.push_back(cscSeq.local_t0.at(i));
245  cmbSeq.weightTimeVtx.push_back(cscSeq.weightTimeVtx.at(i));
246  cmbSeq.weightInvbeta.push_back(cscSeq.weightInvbeta.at(i));
247 
248  cmbSeq.totalWeightTimeVtx += cscSeq.weightTimeVtx.at(i);
249  cmbSeq.totalWeightInvbeta += cscSeq.weightInvbeta.at(i);
250  }
251 }
252 
254  reco::MuonEnergy muonE;
255  if (muon.isEnergyValid())
256  muonE = muon.calEnergy();
257 
258  // Cut on the crystal energy and restrict to the ECAL barrel for now
259  // if (muonE.emMax<ecalEcut_ || fabs(muon.eta())>1.5) return;
260  if (muonE.emMax < ecalEcut_)
261  return;
262 
263  // A simple parametrization of the error on the ECAL time measurement
264  double emErr;
265  if (muonE.ecal_id.subdetId() == EcalBarrel)
266  emErr = errorEB_ / muonE.emMax;
267  else
268  emErr = errorEE_ / muonE.emMax;
269  double hitWeight = 1 / (emErr * emErr);
270  double hitDist = muonE.ecal_position.r();
271 
272  cmbSeq.local_t0.push_back(muonE.ecal_time);
273  cmbSeq.weightTimeVtx.push_back(hitWeight);
274  cmbSeq.weightInvbeta.push_back(hitDist * hitDist * hitWeight / (30. * 30.));
275 
276  cmbSeq.dstnc.push_back(hitDist);
277 
278  cmbSeq.totalWeightTimeVtx += hitWeight;
279  cmbSeq.totalWeightInvbeta += hitDist * hitDist * hitWeight / (30. * 30.);
280 }
281 
282 void MuonTimingFiller::rawFit(double& freeBeta,
283  double& freeBetaErr,
284  double& freeTime,
285  double& freeTimeErr,
286  const std::vector<double>& hitsx,
287  const std::vector<double>& hitsy) {
288  double s = 0, sx = 0, sy = 0, x, y;
289  double sxx = 0, sxy = 0;
290 
291  freeBeta = 0;
292  freeBetaErr = 0;
293  freeTime = 0;
294  freeTimeErr = 0;
295 
296  if (hitsx.empty())
297  return;
298  if (hitsx.size() == 1) {
299  freeTime = hitsy[0];
300  } else {
301  for (unsigned int i = 0; i != hitsx.size(); i++) {
302  x = hitsx[i];
303  y = hitsy[i];
304  sy += y;
305  sxy += x * y;
306  s += 1.;
307  sx += x;
308  sxx += x * x;
309  }
310 
311  double d = s * sxx - sx * sx;
312  freeTime = (sxx * sy - sx * sxy) / d;
313  freeBeta = (s * sxy - sx * sy) / d;
314  freeBetaErr = sqrt(sxx / d);
315  freeTimeErr = sqrt(s / d);
316  }
317 }
T getParameter(std::string const &) const
void setTimeAtIpOutInErr(const float timeErr)
Definition: MuonTimeExtra.h:51
void addEcalTime(const reco::Muon &muon, TimeMeasurementSequence &cmbSeq)
float inverseBetaErr() const
Definition: MuonTimeExtra.h:28
bool existsAs(std::string const &parameterName, bool trackiness=true) const
checks if a parameter exists as a given type
Definition: ParameterSet.h:160
void combineTMSequences(const reco::Muon &muon, const TimeMeasurementSequence &dtSeq, const TimeMeasurementSequence &cscSeq, TimeMeasurementSequence &cmbSeq)
std::vector< double > local_t0
std::unique_ptr< DTTimingExtractor > theDTTimingExtractor_
float inverseBeta() const
Definition: MuonTimeExtra.h:27
virtual TrackRef innerTrack() const
Definition: Muon.h:45
void fillRPCTime(const reco::Muon &muon, reco::MuonTime &muTime, edm::Event &iEvent)
Direction direction() const
direction estimation based on time dispersion
Definition: MuonTimeExtra.h:54
void fillTiming(const reco::Muon &muon, reco::MuonTimeExtra &dtTime, reco::MuonTimeExtra &cscTime, reco::MuonTime &rpcTime, reco::MuonTimeExtra &combinedTime, edm::Event &iEvent, const edm::EventSetup &iSetup)
float timeAtIpOutInErr() const
Definition: MuonTimeExtra.h:49
int nDof() const
number of measurements used in timing calculation
Definition: MuonTimeExtra.h:22
float timeAtIpOutInErr
Definition: MuonTime.h:17
MuonTimingFiller(const edm::ParameterSet &, edm::ConsumesCollector &&iC)
static const unsigned int BestInStationByDR
float ecal_time
Calorimeter timing.
Definition: MuonEnergy.h:47
bool isTrackerMuon() const override
Definition: Muon.h:299
void setTimeAtIpOutIn(const float timeIp)
Definition: MuonTimeExtra.h:50
int iEvent
Definition: GenABIO.cc:224
T sqrt(T t)
Definition: SSEVec.h:19
void rawFit(double &a, double &da, double &b, double &db, const std::vector< double > &hitsx, const std::vector< double > &hitsy)
std::unique_ptr< MuonSegmentMatcher > theMatcher_
float timeAtIpInOutErr
Definition: MuonTime.h:14
constexpr int subdetId() const
get the contents of the subdetector field (not cast into any detector&#39;s numbering enum) ...
Definition: DetId.h:48
float timeAtIpOutIn
b) particle is moving from outside in
Definition: MuonTime.h:16
int nDof
number of muon stations used
Definition: MuonTime.h:9
float timeAtIpInOutErr() const
Definition: MuonTimeExtra.h:44
std::vector< double > weightInvbeta
void setNDof(const int nDof)
Definition: MuonTimeExtra.h:23
float freeInverseBetaErr() const
Definition: MuonTimeExtra.h:37
d
Definition: ztail.py:151
bool isNull() const
Checks for null.
Definition: Ref.h:235
#define LogTrace(id)
void fillTimeFromMeasurements(const TimeMeasurementSequence &tmSeq, reco::MuonTimeExtra &muTime)
bool isEnergyValid() const
Definition: Muon.h:104
TrackRef standAloneMuon() const override
reference to a stand-alone muon Track
Definition: Muon.h:49
std::unique_ptr< CSCTimingExtractor > theCSCTimingExtractor_
MuonEnergy calEnergy() const
get energy deposition information
Definition: Muon.h:106
float emMax
maximal energy of ECAL crystal in the 5x5 shape
Definition: MuonEnergy.h:32
float timeAtIpInOut() const
Definition: MuonTimeExtra.h:43
void setInverseBetaErr(const float iBetaErr)
Definition: MuonTimeExtra.h:30
std::vector< double > weightTimeVtx
TrackRef combinedMuon() const override
reference to a stand-alone muon Track
Definition: Muon.h:52
std::vector< MuonChamberMatch > & matches()
get muon matching information
Definition: Muon.h:145
DetId ecal_id
DetId of the central ECAL crystal.
Definition: MuonEnergy.h:57
static const unsigned int BelongsToTrackByDR
float freeInverseBeta() const
Definition: MuonTimeExtra.h:36
void setFreeInverseBetaErr(const float iBetaErr)
Definition: MuonTimeExtra.h:39
float timeAtIpOutIn() const
b) particle is moving from outside in
Definition: MuonTimeExtra.h:48
std::vector< double > dstnc
math::XYZPointF ecal_position
Trajectory position at the calorimeter.
Definition: MuonEnergy.h:53
void setFreeInverseBeta(const float iBeta)
Definition: MuonTimeExtra.h:38
float timeAtIpInOut
Definition: MuonTime.h:13
void setTimeAtIpInOut(const float timeIp)
Definition: MuonTimeExtra.h:45
void setTimeAtIpInOutErr(const float timeErr)
Definition: MuonTimeExtra.h:46
void setInverseBeta(const float iBeta)
Definition: MuonTimeExtra.h:29