File indexing completed on 2024-04-06 12:26:06
0001
0002
0003
0004
0005
0006
0007 #include "RecoLocalMuon/DTRecHit/plugins/DTParametrizedDriftAlgo.h"
0008 #include "CalibMuon/DTDigiSync/interface/DTTTrigBaseSync.h"
0009 #include "RecoLocalMuon/DTRecHit/plugins/DTTime2DriftParametrization.h"
0010
0011 #include "DataFormats/MuonDetId/interface/DTWireId.h"
0012 #include "Geometry/DTGeometry/interface/DTLayer.h"
0013
0014 #include "MagneticField/Records/interface/IdealMagneticFieldRecord.h"
0015 #include "MagneticField/Engine/interface/MagneticField.h"
0016
0017 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0018 #include "FWCore/Framework/interface/ESHandle.h"
0019 #include "FWCore/Framework/interface/EventSetup.h"
0020 #include "FWCore/Framework/interface/ConsumesCollector.h"
0021
0022 #include <iostream>
0023 #include <iomanip>
0024
0025 using namespace std;
0026 using namespace edm;
0027
0028 DTParametrizedDriftAlgo::DTParametrizedDriftAlgo(const ParameterSet& config, ConsumesCollector cc)
0029 : DTRecHitBaseAlgo(config, cc),
0030 interpolate(config.getParameter<bool>("interpolate")),
0031 minTime(config.getParameter<double>("minTime")),
0032 maxTime(config.getParameter<double>("maxTime")),
0033
0034 debug(config.getUntrackedParameter<bool>("debug", "false")),
0035 magField(nullptr),
0036 magFieldToken_(cc.esConsumes()) {}
0037
0038 DTParametrizedDriftAlgo::~DTParametrizedDriftAlgo() {}
0039
0040 void DTParametrizedDriftAlgo::setES(const EventSetup& setup) {
0041 theSync->setES(setup);
0042
0043 magField = &setup.getData(magFieldToken_);
0044 }
0045
0046
0047 bool DTParametrizedDriftAlgo::compute(
0048 const DTLayer* layer, const DTDigi& digi, LocalPoint& leftPoint, LocalPoint& rightPoint, LocalError& error) const {
0049
0050 DTLayerId layerId = layer->id();
0051 const DTWireId wireId(layerId, digi.wire());
0052
0053
0054 if (!layer->specificTopology().isWireValid(wireId.wire()))
0055 return false;
0056 LocalPoint locWirePos(layer->specificTopology().wirePosition(wireId.wire()), 0, 0);
0057 const GlobalPoint globWirePos = layer->toGlobal(locWirePos);
0058
0059
0060
0061
0062 float angle = 0.0;
0063
0064 if (layerId.superlayer() == 2) {
0065
0066 GlobalVector lDir = (GlobalPoint() - globWirePos).unit();
0067 LocalVector lDirLoc = layer->toLocal(lDir);
0068
0069 angle = atan(lDirLoc.x() / -lDirLoc.z());
0070 }
0071
0072 return compute(layer, wireId, digi.time(), angle, globWirePos, leftPoint, rightPoint, error, 1);
0073 }
0074
0075
0076 bool DTParametrizedDriftAlgo::compute(const DTLayer* layer,
0077 const DTRecHit1D& recHit1D,
0078 const float& angle,
0079 DTRecHit1D& newHit1D) const {
0080 const DTWireId wireId = recHit1D.wireId();
0081
0082
0083 if (!layer->specificTopology().isWireValid(wireId.wire()))
0084 return false;
0085 LocalPoint locWirePos(layer->specificTopology().wirePosition(wireId.wire()), 0, 0);
0086 const GlobalPoint globWirePos = layer->toGlobal(locWirePos);
0087
0088 return compute(layer, wireId, recHit1D.digiTime(), angle, globWirePos, newHit1D, 2);
0089 }
0090
0091
0092 bool DTParametrizedDriftAlgo::compute(const DTLayer* layer,
0093 const DTRecHit1D& recHit1D,
0094 const float& angle,
0095 const GlobalPoint& globPos,
0096 DTRecHit1D& newHit1D) const {
0097 return compute(layer, recHit1D.wireId(), recHit1D.digiTime(), angle, globPos, newHit1D, 3);
0098 }
0099
0100
0101 bool DTParametrizedDriftAlgo::compute(const DTLayer* layer,
0102 const DTWireId& wireId,
0103 const float digiTime,
0104 const float& angle,
0105 const GlobalPoint& globPos,
0106 LocalPoint& leftPoint,
0107 LocalPoint& rightPoint,
0108 LocalError& error,
0109 int step) const {
0110
0111
0112 float driftTime = digiTime - theSync->offset(layer, wireId, globPos);
0113
0114
0115 if (step == 1 && (driftTime < minTime || driftTime > maxTime)) {
0116 if (debug)
0117 cout << "*** Drift time out of window for in-time hits " << driftTime << endl;
0118
0119 if (step == 1) {
0120
0121
0122 return false;
0123 }
0124 }
0125
0126
0127 if (driftTime < 0.)
0128 driftTime = 0;
0129
0130
0131
0132 const LocalVector BLoc = layer->toLocal(magField->inTesla(globPos));
0133
0134 float By = BLoc.y();
0135 float Bz = BLoc.z();
0136
0137
0138
0139
0140 DTTime2DriftParametrization::drift_distance DX;
0141 static const DTTime2DriftParametrization par;
0142
0143 bool parStatus = par.computeDriftDistance_mean(driftTime, angle, By, Bz, interpolate, &DX);
0144
0145 if (!parStatus) {
0146 if (debug)
0147 cout << "[DTParametrizedDriftAlgo]*** WARNING: call to parametrization failed" << endl;
0148 return false;
0149 }
0150
0151 float sigma_l = DX.x_width_m;
0152 float sigma_r = DX.x_width_p;
0153 float drift = DX.x_drift;
0154
0155 float reso = 0;
0156
0157 bool variableSigma = false;
0158
0159
0160
0161
0162
0163
0164
0165
0166
0167
0168
0169
0170
0171 int wheel = abs(wireId.wheel());
0172 if (variableSigma) {
0173 float sTDelays = 0;
0174 if (step == 1) {
0175 reso = (sigma_l + sigma_r) / 2.;
0176 if (wireId.superlayer() == 2) {
0177 sTDelays = 2.92;
0178 } else {
0179 if (wheel == 0) {
0180 sTDelays = 2.74;
0181 } else if (wheel == 1) {
0182 sTDelays = 1.83;
0183 } else if (wheel == 2) {
0184 sTDelays = 1.25;
0185 }
0186 }
0187 } else if (step == 2) {
0188 reso = (sigma_l + sigma_r) / 2.;
0189 if (wireId.superlayer() == 2) {
0190 sTDelays = 0.096;
0191 } else {
0192 if (wheel == 0) {
0193 sTDelays = 0.022;
0194 } else if (wheel == 1) {
0195 sTDelays = 0.079;
0196 } else if (wheel == 2) {
0197 sTDelays = 0.124;
0198 }
0199 }
0200 } else if (step == 3) {
0201 reso = (sigma_l + sigma_r) / 2.;
0202 if (wireId.superlayer() == 2) {
0203 sTDelays = 0.096;
0204 } else {
0205 if (wheel == 0) {
0206 sTDelays = 0.022;
0207 } else if (wheel == 1) {
0208 sTDelays = 0.079;
0209 } else if (wheel == 2) {
0210 sTDelays = 0.124;
0211 }
0212 }
0213 }
0214 float sXDelays = sTDelays * DX.v_drift / 10.;
0215 reso = sqrt(reso * reso + sXDelays * sXDelays);
0216 } else {
0217 if (step == 1) {
0218 if (wireId.superlayer() == 2) {
0219 if (wheel == 0) {
0220 reso = 0.0250;
0221 } else if (wheel == 1) {
0222 reso = 0.0271;
0223 } else if (wheel == 2) {
0224 reso = 0.0308;
0225 }
0226 } else {
0227 reso = 0.0237;
0228 }
0229 } else if (step == 2) {
0230 if (wireId.superlayer() == 2) {
0231 if (wheel == 0) {
0232 reso = 0.0250;
0233 } else if (wheel == 1) {
0234 reso = 0.0271;
0235 } else if (wheel == 2) {
0236 reso = 0.0305;
0237 }
0238 } else {
0239 reso = 0.0231;
0240 }
0241 } else if (step == 3) {
0242 if (wireId.superlayer() == 2) {
0243 if (wheel == 0) {
0244 reso = 0.0196;
0245 } else if (wheel == 1) {
0246 reso = 0.0210;
0247 } else if (wheel == 2) {
0248 reso = 0.0228;
0249 }
0250 } else {
0251 reso = 0.0207;
0252 }
0253 }
0254 }
0255
0256
0257 error = LocalError(reso * reso, 0., 0.);
0258
0259
0260 if (!layer->specificTopology().isWireValid(wireId.wire()))
0261 return false;
0262 LocalPoint locWirePos(layer->specificTopology().wirePosition(wireId.wire()), 0, 0);
0263
0264
0265 leftPoint = LocalPoint(locWirePos.x() - drift, locWirePos.y(), locWirePos.z());
0266 rightPoint = LocalPoint(locWirePos.x() + drift, locWirePos.y(), locWirePos.z());
0267
0268 if (debug) {
0269 int prevW = cout.width();
0270 cout << setiosflags(ios::showpoint | ios::fixed) << setw(3) << "[DTParametrizedDriftAlgo]: step " << step << endl
0271 << " Global Position " << globPos << endl
0272 << " Local Position " << layer->toLocal(globPos)
0273 << endl
0274
0275 << " Digi time " << digiTime
0276 << endl
0277
0278
0279 << " >Drif time " << driftTime << endl
0280 << " >Angle " << angle * 180. / M_PI << endl
0281 << " <Drift distance " << drift << endl
0282 << " <sigma_l " << sigma_l << endl
0283 << " <sigma_r " << sigma_r << endl
0284 << " reso " << reso << endl
0285 << " leftPoint " << leftPoint << endl
0286 << " rightPoint " << rightPoint << endl
0287 << " error " << error << resetiosflags(ios::showpoint | ios::fixed) << setw(prevW) << endl
0288 << endl;
0289 }
0290
0291 return true;
0292 }
0293
0294
0295 bool DTParametrizedDriftAlgo::compute(const DTLayer* layer,
0296 const DTWireId& wireId,
0297 const float digiTime,
0298 const float& angle,
0299 const GlobalPoint& globPos,
0300 DTRecHit1D& newHit1D,
0301 int step) const {
0302 LocalPoint leftPoint;
0303 LocalPoint rightPoint;
0304 LocalError error;
0305
0306 if (compute(layer, wireId, digiTime, angle, globPos, leftPoint, rightPoint, error, step)) {
0307
0308 switch (newHit1D.lrSide()) {
0309 case DTEnums::Left: {
0310
0311
0312 LocalPoint leftPoint3D(leftPoint.x(), newHit1D.localPosition().y(), leftPoint.z());
0313 newHit1D.setPositionAndError(leftPoint3D, error);
0314 break;
0315 }
0316
0317 case DTEnums::Right: {
0318
0319 LocalPoint rightPoint3D(rightPoint.x(), newHit1D.localPosition().y(), rightPoint.z());
0320 newHit1D.setPositionAndError(rightPoint3D, error);
0321 break;
0322 }
0323
0324 default:
0325 throw cms::Exception("InvalidDTCellSide") << "[DTParametrizedDriftAlgo] Compute at Step " << step
0326 << ", Hit side " << newHit1D.lrSide() << " is invalid!" << endl;
0327 return false;
0328 }
0329
0330 return true;
0331 } else {
0332 return false;
0333 }
0334 }