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