00001
00002
00003
00004
00005
00006
00007
00008
00009 #include "RecoLocalMuon/DTRecHit/plugins/DTParametrizedDriftAlgo.h"
00010 #include "CalibMuon/DTDigiSync/interface/DTTTrigBaseSync.h"
00011 #include "RecoLocalMuon/DTRecHit/plugins/DTTime2DriftParametrization.h"
00012
00013 #include "DataFormats/MuonDetId/interface/DTWireId.h"
00014 #include "Geometry/DTGeometry/interface/DTLayer.h"
00015
00016 #include "MagneticField/Records/interface/IdealMagneticFieldRecord.h"
00017 #include "MagneticField/Engine/interface/MagneticField.h"
00018
00019 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00020 #include "FWCore/Framework/interface/ESHandle.h"
00021 #include "FWCore/Framework/interface/EventSetup.h"
00022
00023 #include <iostream>
00024 #include <iomanip>
00025
00026 using namespace std;
00027 using namespace edm;
00028
00029
00030 DTParametrizedDriftAlgo::DTParametrizedDriftAlgo(const ParameterSet& config) :
00031 DTRecHitBaseAlgo(config) {
00032 interpolate = config.getParameter<bool>("interpolate");
00033
00034 minTime = config.getParameter<double>("minTime");
00035
00036 maxTime = config.getParameter<double>("maxTime");
00037
00038
00039 debug = config.getUntrackedParameter<bool>("debug","false");
00040
00041 }
00042
00043
00044
00045 DTParametrizedDriftAlgo::~DTParametrizedDriftAlgo(){}
00046
00047
00048
00049 void DTParametrizedDriftAlgo::setES(const EventSetup& setup) {
00050 theSync->setES(setup);
00051
00052 ESHandle<MagneticField> magneticField;
00053 setup.get<IdealMagneticFieldRecord>().get(magneticField);
00054 magField = &*magneticField;
00055 }
00056
00057
00058
00059
00060 bool DTParametrizedDriftAlgo::compute(const DTLayer* layer,
00061 const DTDigi& digi,
00062 LocalPoint& leftPoint,
00063 LocalPoint& rightPoint,
00064 LocalError& error) const {
00065
00066 DTLayerId layerId = layer->id();
00067 const DTWireId wireId(layerId, digi.wire());
00068
00069
00070 if(!layer->specificTopology().isWireValid(wireId.wire())) return false;
00071 LocalPoint locWirePos(layer->specificTopology().wirePosition(wireId.wire()), 0, 0);
00072 const GlobalPoint globWirePos = layer->toGlobal(locWirePos);
00073
00074
00075
00076
00077 float angle=0.0;
00078
00079 if (layerId.superlayer() == 2 ) {
00080
00081 GlobalVector lDir=(GlobalPoint()-globWirePos).unit();
00082 LocalVector lDirLoc=layer->toLocal(lDir);
00083
00084 angle = atan(lDirLoc.x()/-lDirLoc.z());
00085 }
00086
00087 return compute(layer, wireId, digi.time(), angle, globWirePos,
00088 leftPoint, rightPoint, error, 1);
00089 }
00090
00091
00092
00093
00094 bool DTParametrizedDriftAlgo::compute(const DTLayer* layer,
00095 const DTRecHit1D& recHit1D,
00096 const float& angle,
00097 DTRecHit1D& newHit1D) const {
00098 const DTWireId wireId = recHit1D.wireId();
00099
00100
00101 if(!layer->specificTopology().isWireValid(wireId.wire())) return false;
00102 LocalPoint locWirePos(layer->specificTopology().wirePosition(wireId.wire()), 0, 0);
00103 const GlobalPoint globWirePos = layer->toGlobal(locWirePos);
00104
00105 return compute(layer, wireId, recHit1D.digiTime(), angle, globWirePos,
00106 newHit1D, 2);
00107 }
00108
00109
00110
00111
00112 bool DTParametrizedDriftAlgo::compute(const DTLayer* layer,
00113 const DTRecHit1D& recHit1D,
00114 const float& angle,
00115 const GlobalPoint& globPos,
00116 DTRecHit1D& newHit1D) const {
00117 return compute(layer, recHit1D.wireId(), recHit1D.digiTime(), angle,
00118 globPos, newHit1D, 3);
00119 }
00120
00121
00122
00123
00124 bool DTParametrizedDriftAlgo::compute(const DTLayer* layer,
00125 const DTWireId& wireId,
00126 const float digiTime,
00127 const float& angle,
00128 const GlobalPoint& globPos,
00129 LocalPoint& leftPoint,
00130 LocalPoint& rightPoint,
00131 LocalError& error,
00132 int step) const {
00133
00134
00135 float driftTime = digiTime - theSync->offset(layer, wireId, globPos);
00136
00137
00138 if (step==1 && (driftTime < minTime || driftTime > maxTime)) {
00139 if (debug)
00140 cout << "*** Drift time out of window for in-time hits "
00141 << driftTime << endl;
00142
00143 if(step == 1) {
00144
00145
00146 return false;
00147 }
00148 }
00149
00150
00151 if (driftTime<0.) driftTime=0;
00152
00153
00154
00155 const LocalVector BLoc =
00156 layer->toLocal(magField->inTesla(globPos));
00157
00158 float By = BLoc.y();
00159 float Bz = BLoc.z();
00160
00161
00162
00163
00164 DTTime2DriftParametrization::drift_distance DX;
00165 static DTTime2DriftParametrization par;
00166
00167 bool parStatus =
00168 par.computeDriftDistance_mean(driftTime, angle, By, Bz, interpolate, &DX);
00169
00170 if (!parStatus) {
00171 if (debug)
00172 cout << "[DTParametrizedDriftAlgo]*** WARNING: call to parametrization failed" << endl;
00173 return false;
00174 }
00175
00176 float sigma_l = DX.x_width_m;
00177 float sigma_r = DX.x_width_p;
00178 float drift = DX.x_drift;
00179
00180
00181 float reso = 0;
00182
00183 bool variableSigma = false;
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197 int wheel = abs(wireId.wheel());
00198 if (variableSigma) {
00199 float sTDelays=0;
00200 if (step==1) {
00201 reso = (sigma_l+sigma_r)/2.;
00202 if (wireId.superlayer()==2) {
00203 sTDelays = 2.92;
00204 } else {
00205 if (wheel==0) {
00206 sTDelays = 2.74;
00207 } else if (wheel==1) {
00208 sTDelays = 1.83;
00209 } else if (wheel==2){
00210 sTDelays = 1.25;
00211 }
00212 }
00213 } else if (step==2) {
00214 reso = (sigma_l+sigma_r)/2.;
00215 if (wireId.superlayer()==2) {
00216 sTDelays = 0.096;
00217 } else {
00218 if (wheel==0) {
00219 sTDelays = 0.022;
00220 } else if (wheel==1) {
00221 sTDelays = 0.079;
00222 } else if (wheel==2){
00223 sTDelays = 0.124;
00224 }
00225 }
00226 } else if (step==3) {
00227 reso = (sigma_l+sigma_r)/2.;
00228 if (wireId.superlayer()==2) {
00229 sTDelays = 0.096;
00230 } else {
00231 if (wheel==0) {
00232 sTDelays = 0.022;
00233 } else if (wheel==1) {
00234 sTDelays = 0.079;
00235 } else if (wheel==2){
00236 sTDelays = 0.124;
00237 }
00238 }
00239 }
00240 float sXDelays = sTDelays*DX.v_drift/10.;
00241 reso = sqrt(reso*reso + sXDelays*sXDelays);
00242 } else {
00243 if (step==1) {
00244 if (wireId.superlayer()==2) {
00245 if (wheel==0) {
00246 reso = 0.0250;
00247 } else if (wheel==1) {
00248 reso = 0.0271;
00249 } else if (wheel==2){
00250 reso = 0.0308;
00251 }
00252 } else {
00253 reso = 0.0237;
00254 }
00255 } else if (step==2) {
00256 if (wireId.superlayer()==2) {
00257 if (wheel==0) {
00258 reso = 0.0250;
00259 } else if (wheel==1) {
00260 reso = 0.0271;
00261 } else if (wheel==2){
00262 reso = 0.0305;
00263 }
00264 } else {
00265 reso = 0.0231;
00266 }
00267 } else if (step==3) {
00268 if (wireId.superlayer()==2) {
00269 if (wheel==0) {
00270 reso = 0.0196;
00271 } else if (wheel==1) {
00272 reso = 0.0210;
00273 } else if (wheel==2){
00274 reso = 0.0228;
00275 }
00276 } else {
00277 reso = 0.0207;
00278 }
00279 }
00280 }
00281
00282
00283 error = LocalError(reso*reso,0.,0.);
00284
00285
00286 if(!layer->specificTopology().isWireValid(wireId.wire())) return false;
00287 LocalPoint locWirePos(layer->specificTopology().wirePosition(wireId.wire()), 0, 0);
00288
00289
00290 leftPoint = LocalPoint(locWirePos.x()-drift,
00291 locWirePos.y(),
00292 locWirePos.z());
00293 rightPoint = LocalPoint(locWirePos.x()+drift,
00294 locWirePos.y(),
00295 locWirePos.z());
00296
00297 if (debug) {
00298 int prevW = cout.width();
00299 cout << setiosflags(ios::showpoint | ios::fixed) << setw(3)
00300 << "[DTParametrizedDriftAlgo]: step " << step << endl
00301 << " Global Position " << globPos << endl
00302 << " Local Position " << layer->toLocal(globPos) << endl
00303
00304 << " Digi time " << digiTime << endl
00305
00306
00307 << " >Drif time " << driftTime << endl
00308 << " >Angle " << angle * 180./M_PI << endl
00309 << " <Drift distance " << drift << endl
00310 << " <sigma_l " << sigma_l << endl
00311 << " <sigma_r " << sigma_r << endl
00312 << " reso " << reso << endl
00313 << " leftPoint " << leftPoint << endl
00314 << " rightPoint " << rightPoint << endl
00315 << " error " << error
00316 << resetiosflags(ios::showpoint | ios::fixed) << setw(prevW) << endl
00317 << endl;
00318 }
00319
00320 return true;
00321 }
00322
00323
00324
00325 bool DTParametrizedDriftAlgo::compute(const DTLayer* layer,
00326 const DTWireId& wireId,
00327 const float digiTime,
00328 const float& angle,
00329 const GlobalPoint& globPos,
00330 DTRecHit1D& newHit1D,
00331 int step) const {
00332 LocalPoint leftPoint;
00333 LocalPoint rightPoint;
00334 LocalError error;
00335
00336 if(compute(layer, wireId, digiTime, angle, globPos, leftPoint, rightPoint, error, step)) {
00337
00338 switch(newHit1D.lrSide()) {
00339
00340 case DTEnums::Left:
00341 {
00342
00343
00344 LocalPoint leftPoint3D(leftPoint.x(), newHit1D.localPosition().y(), leftPoint.z());
00345 newHit1D.setPositionAndError(leftPoint3D, error);
00346 break;
00347 }
00348
00349 case DTEnums::Right:
00350 {
00351
00352 LocalPoint rightPoint3D(rightPoint.x(), newHit1D.localPosition().y(), rightPoint.z());
00353 newHit1D.setPositionAndError(rightPoint3D, error);
00354 break;
00355 }
00356
00357 default:
00358 throw cms::Exception("InvalidDTCellSide") << "[DTParametrizedDriftAlgo] Compute at Step "
00359 << step << ", Hit side "
00360 << newHit1D.lrSide()
00361 << " is invalid!" << endl;
00362 return false;
00363 }
00364
00365 return true;
00366 }else {
00367 return false;
00368 }
00369 }
00370
00371
00372 bool DTParametrizedDriftAlgo::interpolate;
00373
00374
00375 float DTParametrizedDriftAlgo::minTime;
00376
00377
00378 float DTParametrizedDriftAlgo::maxTime;
00379
00380
00381 bool DTParametrizedDriftAlgo::debug;