CMS 3D CMS Logo

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