CMS 3D CMS Logo

CSCTimingExtractor.cc
Go to the documentation of this file.
1 // -*- C++ -*-
2 //
3 // Package: MuonIdentification
4 // Class: CSCTimingExtractor
5 //
11 //
12 // Original Author: Traczyk Piotr
13 // Created: Thu Oct 11 15:01:28 CEST 2007
14 //
15 //
16 
18 
19 // user include files
22 
24 
26 
28 
31 
35 
43 
48 
49 // system include files
50 #include <memory>
51 #include <vector>
52 #include <string>
53 #include <iostream>
54 
55 namespace edm {
56  class ParameterSet;
57  class EventSetup;
58  class InputTag;
59 } // namespace edm
60 
61 class MuonServiceProxy;
62 
63 //
64 // constructors and destructor
65 //
67  MuonSegmentMatcher* segMatcher,
69  : thePruneCut_(iConfig.getParameter<double>("PruneCut")),
70  theStripTimeOffset_(iConfig.getParameter<double>("CSCStripTimeOffset")),
71  theWireTimeOffset_(iConfig.getParameter<double>("CSCWireTimeOffset")),
72  theStripError_(iConfig.getParameter<double>("CSCStripError")),
73  theWireError_(iConfig.getParameter<double>("CSCWireError")),
74  UseWireTime(iConfig.getParameter<bool>("UseWireTime")),
75  UseStripTime(iConfig.getParameter<bool>("UseStripTime")),
76  debug(iConfig.getParameter<bool>("debug")),
77  thePropagatorToken(iC.esConsumes(edm::ESInputTag("", "SteppingHelixPropagatorAny"))) {
78  edm::ParameterSet serviceParameters = iConfig.getParameter<edm::ParameterSet>("ServiceParameters");
79  theService = std::make_unique<MuonServiceProxy>(serviceParameters, edm::ConsumesCollector(iC));
80  theMatcher = segMatcher;
81 }
82 
84 
85 //
86 // member functions
87 //
88 
90  const std::vector<const CSCSegment*>& segments,
91  reco::TrackRef muonTrack,
92  const edm::Event& iEvent,
93  const edm::EventSetup& iSetup) {
94  theService->update(iSetup);
95 
96  const GlobalTrackingGeometry* theTrackingGeometry = &*theService->trackingGeometry();
97 
98  // get the propagator
99  const Propagator* propag = &iSetup.getData(thePropagatorToken);
100 
101  math::XYZPoint pos = muonTrack->innerPosition();
102  math::XYZVector mom = muonTrack->innerMomentum();
103  if (sqrt(muonTrack->innerPosition().mag2()) > sqrt(muonTrack->outerPosition().mag2())) {
104  pos = muonTrack->outerPosition();
105  mom = -1 * muonTrack->outerMomentum();
106  }
107  GlobalPoint posp(pos.x(), pos.y(), pos.z());
108  GlobalVector momv(mom.x(), mom.y(), mom.z());
109  FreeTrajectoryState muonFTS(posp, momv, (TrackCharge)muonTrack->charge(), theService->magneticField().product());
110 
111  // create a collection on TimeMeasurements for the track
112  std::vector<TimeMeasurement> tms;
113  for (const auto& rechit : segments) {
114  // Create the ChamberId
115  DetId id = rechit->geographicalId();
116  CSCDetId chamberId(id.rawId());
117  // int station = chamberId.station();
118 
119  if (rechit->specificRecHits().empty())
120  continue;
121 
122  const std::vector<CSCRecHit2D>& hits2d(rechit->specificRecHits());
123 
124  // store all the hits from the segment
125  for (const auto& hiti : hits2d) {
126  const GeomDet* cscDet = theTrackingGeometry->idToDet(hiti.geographicalId());
127  TimeMeasurement thisHit;
128 
129  std::pair<TrajectoryStateOnSurface, double> tsos;
130  tsos = propag->propagateWithPath(muonFTS, cscDet->surface());
131 
132  double dist;
133  if (tsos.first.isValid())
134  dist = tsos.second + posp.mag();
135  else
136  dist = cscDet->toGlobal(hiti.localPosition()).mag();
137 
138  thisHit.distIP = dist;
139  if (UseStripTime) {
140  thisHit.weightInvbeta = dist * dist / (theStripError_ * theStripError_ * 30. * 30.);
141  thisHit.weightTimeVtx = 1. / (theStripError_ * theStripError_);
142  thisHit.timeCorr = hiti.tpeak() - theStripTimeOffset_;
143  tms.push_back(thisHit);
144  }
145 
146  if (UseWireTime) {
147  thisHit.weightInvbeta = dist * dist / (theWireError_ * theWireError_ * 30. * 30.);
148  thisHit.weightTimeVtx = 1. / (theWireError_ * theWireError_);
149  thisHit.timeCorr = hiti.wireTime() - theWireTimeOffset_;
150  tms.push_back(thisHit);
151  }
152 
153  // std::cout << " CSC Hit. Dist= " << dist << " Time= " << thisHit.timeCorr
154  // << " invBeta= " << (1.+thisHit.timeCorr/dist*30.) << std::endl;
155  }
156 
157  } // rechit
158 
159  bool modified = false;
160  std::vector<double> dstnc, local_t0, hitWeightInvbeta, hitWeightTimeVtx;
161  double totalWeightInvbeta = 0;
162  double totalWeightTimeVtx = 0;
163 
164  // Now loop over the measurements, calculate 1/beta and cut away outliers
165  do {
166  modified = false;
167  dstnc.clear();
168  local_t0.clear();
169  hitWeightInvbeta.clear();
170  hitWeightTimeVtx.clear();
171 
172  totalWeightInvbeta = 0;
173  totalWeightTimeVtx = 0;
174 
175  for (auto& tm : tms) {
176  dstnc.push_back(tm.distIP);
177  local_t0.push_back(tm.timeCorr);
178  hitWeightInvbeta.push_back(tm.weightInvbeta);
179  hitWeightTimeVtx.push_back(tm.weightTimeVtx);
180  totalWeightInvbeta += tm.weightInvbeta;
181  totalWeightTimeVtx += tm.weightTimeVtx;
182  }
183 
184  if (totalWeightInvbeta == 0)
185  break;
186 
187  // calculate the value and error of 1/beta and timeVtx from the complete set of 1D hits
188  if (debug)
189  std::cout << " Points for global fit: " << dstnc.size() << std::endl;
190 
191  double invbeta = 0, invbetaErr = 0;
192  double timeVtx = 0, timeVtxErr = 0;
193 
194  for (unsigned int i = 0; i < dstnc.size(); i++) {
195  invbeta += (1. + local_t0.at(i) / dstnc.at(i) * 30.) * hitWeightInvbeta.at(i) / totalWeightInvbeta;
196  timeVtx += local_t0.at(i) * hitWeightTimeVtx.at(i) / totalWeightTimeVtx;
197  }
198 
199  double chimax = 0.;
200  std::vector<TimeMeasurement>::iterator tmmax;
201 
202  // Calculate the inv beta and time at vertex dispersion
203  double diff_ibeta, diff_tvtx;
204  for (unsigned int i = 0; i < dstnc.size(); i++) {
205  diff_ibeta = (1. + local_t0.at(i) / dstnc.at(i) * 30.) - invbeta;
206  diff_ibeta = diff_ibeta * diff_ibeta * hitWeightInvbeta.at(i);
207  diff_tvtx = local_t0.at(i) - timeVtx;
208  diff_tvtx = diff_tvtx * diff_tvtx * hitWeightTimeVtx.at(i);
209  invbetaErr += diff_ibeta;
210  timeVtxErr += diff_tvtx;
211 
212  // decide if we cut away time at vertex outliers or inverse beta outliers
213  // currently not configurable.
214  if (diff_tvtx > chimax) {
215  tmmax = tms.begin() + i;
216  chimax = diff_tvtx;
217  }
218  }
219 
220  // cut away the outliers
221  if (chimax > thePruneCut_) {
222  tms.erase(tmmax);
223  modified = true;
224  }
225 
226  if (debug) {
227  double cf = 1. / (dstnc.size() - 1);
228  invbetaErr = sqrt(invbetaErr / totalWeightInvbeta * cf);
229  timeVtxErr = sqrt(timeVtxErr / totalWeightTimeVtx * cf);
230  std::cout << " Measured 1/beta: " << invbeta << " +/- " << invbetaErr << std::endl;
231  std::cout << " Measured time: " << timeVtx << " +/- " << timeVtxErr << std::endl;
232  }
233 
234  } while (modified);
235 
236  for (unsigned int i = 0; i < dstnc.size(); i++) {
237  tmSequence.dstnc.push_back(dstnc.at(i));
238  tmSequence.local_t0.push_back(local_t0.at(i));
239  tmSequence.weightInvbeta.push_back(hitWeightInvbeta.at(i));
240  tmSequence.weightTimeVtx.push_back(hitWeightTimeVtx.at(i));
241  }
242 
243  tmSequence.totalWeightInvbeta = totalWeightInvbeta;
244  tmSequence.totalWeightTimeVtx = totalWeightTimeVtx;
245 }
246 
247 // ------------ method called to produce the data ------------
249  reco::TrackRef muonTrack,
250  const edm::Event& iEvent,
251  const edm::EventSetup& iSetup) {
252  if (debug)
253  std::cout << " *** CSC Timimng Extractor ***" << std::endl;
254 
255  // get the CSC segments that were used to construct the muon
256  std::vector<const CSCSegment*> range = theMatcher->matchCSC(*muonTrack, iEvent);
257 
258  fillTiming(tmSequence, range, muonTrack, iEvent, iSetup);
259 }
260 
261 //define this as a plug-in
262 //DEFINE_FWK_MODULE(CSCTimingExtractor);
ESGetTokenH3DDVariant esConsumes(std::string const &Record, edm::ConsumesCollector &)
Definition: DeDxTools.cc:283
T getParameter(std::string const &) const
Definition: ParameterSet.h:307
T const & getData(const ESGetToken< T, R > &iToken) const noexcept(false)
Definition: EventSetup.h:119
std::vector< double > local_t0
std::vector< const CSCSegment * > matchCSC(const reco::Track &muon, const edm::Event &event)
const GeomDet * idToDet(DetId) const override
std::unique_ptr< MuonServiceProxy > theService
int TrackCharge
Definition: TrackCharge.h:4
int iEvent
Definition: GenABIO.cc:224
MuonSegmentMatcher * theMatcher
T sqrt(T t)
Definition: SSEVec.h:19
edm::ESHandle< GlobalTrackingGeometry > theTrackingGeometry
std::vector< double > weightInvbeta
CSCTimingExtractor(const edm::ParameterSet &, MuonSegmentMatcher *segMatcher, edm::ConsumesCollector &)
Constructor.
virtual std::pair< TrajectoryStateOnSurface, double > propagateWithPath(const FreeTrajectoryState &, const Surface &) const final
Definition: Propagator.cc:10
GlobalPoint toGlobal(const Local2DPoint &lp) const
Conversion to the global R.F. from the R.F. of the GeomDet.
Definition: GeomDet.h:49
void fillTiming(TimeMeasurementSequence &tmSequence, const std::vector< const CSCSegment *> &segments, reco::TrackRef muonTrack, const edm::Event &iEvent, const edm::EventSetup &iSetup)
Definition: DetId.h:17
const Plane & surface() const
The nominal surface of the GeomDet.
Definition: GeomDet.h:37
T mag() const
The vector magnitude. Equivalent to sqrt(vec.mag2())
#define debug
Definition: HDRShower.cc:19
XYZVectorD XYZVector
spatial vector with cartesian internal representation
Definition: Vector3D.h:31
XYZPointD XYZPoint
point in space with cartesian internal representation
Definition: Point3D.h:12
std::vector< double > weightTimeVtx
HLT enums.
std::vector< double > dstnc
edm::ESGetToken< Propagator, TrackingComponentsRecord > thePropagatorToken
~CSCTimingExtractor()
Destructor.