CMS 3D CMS Logo

DTParametrizedDriftAlgo.cc
Go to the documentation of this file.
1 /*
2  * See header file for a description of this class.
3  *
4  * \author G. Cerminara - INFN Torino
5  */
6 
10 
13 
16 
20 
21 #include <iostream>
22 #include <iomanip>
23 
24 using namespace std;
25 using namespace edm;
26 
27 
29  DTRecHitBaseAlgo(config),
30  interpolate(config.getParameter<bool>("interpolate")),
31  minTime(config.getParameter<double>("minTime")), // FIXME: Default was -3 ns
32  maxTime(config.getParameter<double>("maxTime")), // FIXME: Default was 415 ns
33  // Set verbose output
34  debug(config.getUntrackedParameter<bool>("debug","false"))
35  {}
36 
37 
38 
40 
41 
42 
44  theSync->setES(setup);
45  // Access the magnetic field
47  setup.get<IdealMagneticFieldRecord>().get(magneticField);
49 }
50 
51 
52 
53 // First Step
55  const DTDigi& digi,
56  LocalPoint& leftPoint,
57  LocalPoint& rightPoint,
58  LocalError& error) const {
59  // Get the layerId
60  DTLayerId layerId = layer->id();//FIXME: pass it instead of get it from layer
61  const DTWireId wireId(layerId, digi.wire());
62 
63  // Get Wire position
64  if(!layer->specificTopology().isWireValid(wireId.wire())) return false;
65  LocalPoint locWirePos(layer->specificTopology().wirePosition(wireId.wire()), 0, 0);
66  const GlobalPoint globWirePos = layer->toGlobal(locWirePos);
67 
68  // impact angle on DT chamber
69  // compute the impact angle using the centre of the wire,
70  // only for RZ superlayer (eta). In the other cases theta is very close to 0.
71  float angle=0.0;
72 
73  if (layerId.superlayer() == 2 ) {
74  //GlobalPoint lPos=layer->position();
75  GlobalVector lDir=(GlobalPoint()-globWirePos).unit();
76  LocalVector lDirLoc=layer->toLocal(lDir);
77 
78  angle = atan(lDirLoc.x()/-lDirLoc.z());
79  }
80 
81  return compute(layer, wireId, digi.time(), angle, globWirePos,
82  leftPoint, rightPoint, error, 1);
83 }
84 
85 
86 
87 // Second step
89  const DTRecHit1D& recHit1D,
90  const float& angle,
91  DTRecHit1D& newHit1D) const {
92  const DTWireId wireId = recHit1D.wireId();
93 
94  // Get Wire position
95  if(!layer->specificTopology().isWireValid(wireId.wire())) return false;
96  LocalPoint locWirePos(layer->specificTopology().wirePosition(wireId.wire()), 0, 0);
97  const GlobalPoint globWirePos = layer->toGlobal(locWirePos);
98 
99  return compute(layer, wireId, recHit1D.digiTime(), angle, globWirePos,
100  newHit1D, 2);
101 }
102 
103 
104 
105 // Third step
106 bool DTParametrizedDriftAlgo::compute(const DTLayer* layer,
107  const DTRecHit1D& recHit1D,
108  const float& angle,
109  const GlobalPoint& globPos,
110  DTRecHit1D& newHit1D) const {
111  return compute(layer, recHit1D.wireId(), recHit1D.digiTime(), angle,
112  globPos, newHit1D, 3);
113 }
114 
115 
116 
117 // Do the actual work.
118 bool DTParametrizedDriftAlgo::compute(const DTLayer* layer,
119  const DTWireId& wireId,
120  const float digiTime,
121  const float& angle,
122  const GlobalPoint& globPos,
123  LocalPoint& leftPoint,
124  LocalPoint& rightPoint,
125  LocalError& error,
126  int step) const {
127  // Subtract Offset according to DTTTrigBaseSync concrete instance
128  // chosen with the 'tZeroMode' parameter
129  float driftTime = digiTime - theSync->offset(layer, wireId, globPos);
130 
131  // check for out-of-time only at step 1
132  if (step==1 && (driftTime < minTime || driftTime > maxTime)) {
133  if (debug)
134  cout << "*** Drift time out of window for in-time hits "
135  << driftTime << endl;
136 
137  if(step == 1) { //FIXME: protection against failure at 2nd and 3rd steps, must be checked!!!
138  // Hits are interpreted as coming from out-of-time pile-up and recHit
139  // is ignored.
140  return false;
141  }
142  }
143 
144  // Small negative times interpreted as hits close to the wire.
145  if (driftTime<0.) driftTime=0;
146 
147  //----------------------------------------------------------------------
148  // Magnetic Field in layer frame
149  const LocalVector BLoc =
150  layer->toLocal(magField->inTesla(globPos));
151 
152  float By = BLoc.y();
153  float Bz = BLoc.z();
154 
155  //--------------------------------------------------------------------
156  // Calculate the drift distance and the resolution from the parametrization
157 
159  static const DTTime2DriftParametrization par;
160 
161  bool parStatus =
162  par.computeDriftDistance_mean(driftTime, angle, By, Bz, interpolate, &DX);
163 
164  if (!parStatus) {
165  if (debug)
166  cout << "[DTParametrizedDriftAlgo]*** WARNING: call to parametrization failed" << endl;
167  return false;
168  }
169 
170  float sigma_l = DX.x_width_m;
171  float sigma_r = DX.x_width_p;
172  float drift = DX.x_drift;
173 
174 
175  float reso = 0;
176 
177  bool variableSigma = false;
178  // By defualt the errors are obtained from a fit of the residuals in the various
179  // stations/SL.
180  // The error returned by DTTime2DriftParametrization can not be used easily
181  // to determine the hit error due to the way the parametrization of the error
182  // is done (please contcat the authors for details).
183  // Anyhow changing variableSigma==true, an attempt is done to set a variable error
184  // according to the sigma calculated by DTTime2DriftParametrization.
185  // Additionally, contributions from uncertaionties in TOF and signal propagation
186  // corrections are added.
187  // Uncertainty in the determination of incident angle and hit position
188  // (ie B value) are NOT accounted.
189  // This is not the default since it does not give good results...
190 
191  int wheel = abs(wireId.wheel());
192  if (variableSigma) {
193  float sTDelays=0;
194  if (step==1) { // 1. step
195  reso = (sigma_l+sigma_r)/2.; // FIXME: theta/B are not yet known...
196  if (wireId.superlayer()==2) { // RZ
197  sTDelays = 2.92;
198  } else { // RPhi
199  if (wheel==0) {
200  sTDelays = 2.74;
201  } else if (wheel==1) {
202  sTDelays = 1.83;
203  } else if (wheel==2){
204  sTDelays = 1.25;
205  }
206  }
207  } else if (step==2) { // 2. step
208  reso = (sigma_l+sigma_r)/2.; // FIXME: B is not yet known...
209  if (wireId.superlayer()==2) { // RZ
210  sTDelays = 0.096;
211  } else { // RPhi
212  if (wheel==0) {
213  sTDelays = 0.022;
214  } else if (wheel==1) {
215  sTDelays = 0.079;
216  } else if (wheel==2){
217  sTDelays = 0.124;
218  }
219  }
220  } else if (step==3) { // 3. step
221  reso = (sigma_l+sigma_r)/2.;
222  if (wireId.superlayer()==2) { // RZ
223  sTDelays = 0.096;
224  } else { // RPhi
225  if (wheel==0) {
226  sTDelays = 0.022;
227  } else if (wheel==1) {
228  sTDelays = 0.079;
229  } else if (wheel==2){
230  sTDelays = 0.124;
231  }
232  }
233  }
234  float sXDelays = sTDelays*DX.v_drift/10.;
235  reso = sqrt(reso*reso + sXDelays*sXDelays);
236  } else { // Use a fixed sigma, from fit of residuals.
237  if (step==1) { // 1. step
238  if (wireId.superlayer()==2) {
239  if (wheel==0) {
240  reso = 0.0250;
241  } else if (wheel==1) {
242  reso = 0.0271;
243  } else if (wheel==2){
244  reso = 0.0308;
245  }
246  } else {
247  reso = 0.0237;
248  }
249  } else if (step==2) { // 2. step //FIXME
250  if (wireId.superlayer()==2) {
251  if (wheel==0) {
252  reso = 0.0250;
253  } else if (wheel==1) {
254  reso = 0.0271;
255  } else if (wheel==2){
256  reso = 0.0305;
257  }
258  } else {
259  reso = 0.0231;
260  }
261  } else if (step==3) { // 3. step
262  if (wireId.superlayer()==2) {
263  if (wheel==0) {
264  reso = 0.0196;
265  } else if (wheel==1) {
266  reso = 0.0210;
267  } else if (wheel==2){
268  reso = 0.0228;
269  }
270  } else {
271  reso = 0.0207;
272  }
273  }
274  }
275  //--------------------------------------------------------------------
276 
277  error = LocalError(reso*reso,0.,0.);
278 
279  // Get Wire position
280  if(!layer->specificTopology().isWireValid(wireId.wire())) return false;
281  LocalPoint locWirePos(layer->specificTopology().wirePosition(wireId.wire()), 0, 0);
282 
283  //Build the two possible points and the error on the position
284  leftPoint = LocalPoint(locWirePos.x()-drift,
285  locWirePos.y(),
286  locWirePos.z());
287  rightPoint = LocalPoint(locWirePos.x()+drift,
288  locWirePos.y(),
289  locWirePos.z());
290 
291  if (debug) {
292  int prevW = cout.width();
293  cout << setiosflags(ios::showpoint | ios::fixed) << setw(3)
294  << "[DTParametrizedDriftAlgo]: step " << step << endl
295  << " Global Position " << globPos << endl
296  << " Local Position " << layer->toLocal(globPos) << endl
297  // << " y along Wire " << wireCoord << endl
298  << " Digi time " << digiTime << endl
299  // << " dpropDelay " << propDelay << endl
300  // << " deltaTOF " << deltaTOF << endl
301  << " >Drif time " << driftTime << endl
302  << " >Angle " << angle * 180./M_PI << endl
303  << " <Drift distance " << drift << endl
304  << " <sigma_l " << sigma_l << endl
305  << " <sigma_r " << sigma_r << endl
306  << " reso " << reso << endl
307  << " leftPoint " << leftPoint << endl
308  << " rightPoint " << rightPoint << endl
309  << " error " << error
310  << resetiosflags(ios::showpoint | ios::fixed) << setw(prevW) << endl
311  << endl;
312  }
313 
314  return true;
315 }
316 
317 
318 // Interface to the method which does the actual work suited for 2nd and 3rd steps
319 bool DTParametrizedDriftAlgo::compute(const DTLayer* layer,
320  const DTWireId& wireId,
321  const float digiTime,
322  const float& angle,
323  const GlobalPoint& globPos,
324  DTRecHit1D& newHit1D,
325  int step) const {
326  LocalPoint leftPoint;
327  LocalPoint rightPoint;
329 
330  if(compute(layer, wireId, digiTime, angle, globPos, leftPoint, rightPoint, error, step)) {
331  // Set the position and the error of the rechit which is being updated
332  switch(newHit1D.lrSide()) {
333 
334  case DTEnums::Left:
335  {
336  // Keep the original y position of newHit1D: for step==3, it's the
337  // position along the wire. Needed for rotation alignment
338  LocalPoint leftPoint3D(leftPoint.x(), newHit1D.localPosition().y(), leftPoint.z());
339  newHit1D.setPositionAndError(leftPoint3D, error);
340  break;
341  }
342 
343  case DTEnums::Right:
344  {
345  // as above: 3d position
346  LocalPoint rightPoint3D(rightPoint.x(), newHit1D.localPosition().y(), rightPoint.z());
347  newHit1D.setPositionAndError(rightPoint3D, error);
348  break;
349  }
350 
351  default:
352  throw cms::Exception("InvalidDTCellSide") << "[DTParametrizedDriftAlgo] Compute at Step "
353  << step << ", Hit side "
354  << newHit1D.lrSide()
355  << " is invalid!" << endl;
356  return false;
357  }
358 
359  return true;
360  }else {
361  return false;
362  }
363 }
LocalPoint localPosition() const override
Return the 3-dimensional local position.
Definition: DTRecHit1D.h:60
float wirePosition(int wireNumber) const
Returns the x position in the layer of a given wire number.
Definition: DTTopology.cc:86
void setES(const edm::EventSetup &setup) override
Pass the Event Setup to the algo at each event.
Point3DBase< Scalar, LocalTag > LocalPoint
Definition: Definitions.h:32
bool computeDriftDistance_mean(double time, double alpha, double by, double bz, short interpolate, drift_distance *dx) const
DTLayerId id() const
Return the DetId of this SL.
Definition: DTLayer.cc:46
GlobalPoint toGlobal(const Local2DPoint &lp) const
Conversion to the global R.F. from the R.F. of the GeomDet.
Definition: GeomDet.h:54
double offset(const DTLayer *layer, const DTWireId &wireId, const GlobalPoint &globalPos)
LocalVector drift(const StripGeomDetUnit *, const MagneticField &, const SiStripLorentzAngle &)
Definition: ShallowTools.cc:38
Global3DPoint GlobalPoint
Definition: GlobalPoint.h:10
T y() const
Definition: PV3DBase.h:63
def setup(process, global_tag, zero_tesla=False)
Definition: GeneralSetup.py:1
LocalPoint toLocal(const GlobalPoint &gp) const
Conversion to the R.F. of the GeomDet.
Definition: GeomDet.h:69
~DTParametrizedDriftAlgo() override
Destructor.
Definition: config.py:1
int wire() const
Return wire number.
Definition: DTDigi.cc:67
const MagneticField * magField
virtual void setES(const edm::EventSetup &setup)=0
Pass the Event Setup to the synchronization module at each event.
const DTTopology & specificTopology() const
Definition: DTLayer.cc:42
double time() const
Get time in ns.
Definition: DTDigi.cc:63
T sqrt(T t)
Definition: SSEVec.h:18
T z() const
Definition: PV3DBase.h:64
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
float digiTime() const
Return the time (ns) of the digi used to build the rechit.
Definition: DTRecHit1D.h:113
Definition: DTDigi.h:17
virtual GlobalVector inTesla(const GlobalPoint &gp) const =0
Field value ad specified global point, in Tesla.
DTParametrizedDriftAlgo(const edm::ParameterSet &config)
Constructor.
DTTTrigBaseSync * theSync
#define M_PI
int wire() const
Return the wire number.
Definition: DTWireId.h:56
int superlayer() const
Return the superlayer number (deprecated method name)
bool compute(const DTLayer *layer, const DTDigi &digi, LocalPoint &leftPoint, LocalPoint &rightPoint, LocalError &error) const override
#define debug
Definition: HDRShower.cc:19
const T & get() const
Definition: EventSetup.h:55
HLT enums.
bool isWireValid(const int wireNumber) const
Definition: DTTopology.h:65
step
void setPositionAndError(LocalPoint pos, LocalError err)
Set the local position and its error.
Definition: DTRecHit1D.h:100
int wheel() const
Return the wheel number.
Definition: DTChamberId.h:45
T x() const
Definition: PV3DBase.h:62
Structure used to return output values.
DTEnums::DTCellSide lrSide() const
The side of the cell.
Definition: DTRecHit1D.h:82
T angle(T x1, T y1, T z1, T x2, T y2, T z2)
Definition: angle.h:11
DTWireId wireId() const
Return the wireId.
Definition: DTRecHit1D.h:107