CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_5_3_14/src/RecoLocalMuon/DTRecHit/plugins/DTLinearDriftFromDBAlgo.cc

Go to the documentation of this file.
00001 /*
00002  *  See header file for a description of this class.
00003  *
00004  *  $Date: 2011/02/22 16:23:00 $
00005  *  $Revision: 1.8 $
00006  *  \author S. Bolognesi - INFN Torino
00007  */
00008 
00009 #include "RecoLocalMuon/DTRecHit/plugins/DTLinearDriftFromDBAlgo.h"
00010 #include "CalibMuon/DTDigiSync/interface/DTTTrigBaseSync.h"
00011 #include "DataFormats/MuonDetId/interface/DTWireId.h"
00012 #include "Geometry/DTGeometry/interface/DTLayer.h"
00013 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00014 #include "FWCore/Framework/interface/EventSetup.h"
00015 #include "FWCore/Framework/interface/ESHandle.h"
00016 #include "FWCore/Utilities/interface/Exception.h"
00017 #include "CondFormats/DTObjects/interface/DTMtime.h"
00018 #include "CondFormats/DataRecord/interface/DTMtimeRcd.h"
00019 
00020 using namespace std;
00021 using namespace edm;
00022 
00023 DTLinearDriftFromDBAlgo::DTLinearDriftFromDBAlgo(const ParameterSet& config) :
00024   DTRecHitBaseAlgo(config) {
00025 
00026     minTime = config.getParameter<double>("minTime"); 
00027 
00028     maxTime = config.getParameter<double>("maxTime"); 
00029 
00030     doVdriftCorr = config.getParameter<bool>("doVdriftCorr");
00031 
00032     // Option to force going back to digi time at Step 2 
00033     stepTwoFromDigi = config.getParameter<bool>("stepTwoFromDigi");
00034 
00035     // Set verbose output
00036     debug = config.getUntrackedParameter<bool>("debug");
00037     if(debug)
00038       cout<<"[DTLinearDriftFromDBAlgo] Constructor called"<<endl;
00039   }
00040 
00041 
00042 
00043 DTLinearDriftFromDBAlgo::~DTLinearDriftFromDBAlgo(){}
00044 
00045 
00046 
00047 void DTLinearDriftFromDBAlgo::setES(const EventSetup& setup) {
00048   if(debug)
00049     cout<<"[DTLinearDriftFromDBAlgo] setES called"<<endl;
00050   theSync->setES(setup);
00051   // Get the map of ttrig from the Setup
00052   ESHandle<DTMtime> mTimeHandle;
00053   setup.get<DTMtimeRcd>().get(mTimeHandle);
00054   mTimeMap = &*mTimeHandle;
00055   
00056   if(debug) 
00057     cout << "[DTLinearDriftFromDBAlgo] meanTimer version: " << mTimeMap->version()<<endl;
00058 }
00059 
00060 
00061 
00062 // First Step
00063 bool DTLinearDriftFromDBAlgo::compute(const DTLayer* layer,
00064                                 const DTDigi& digi,
00065                                 LocalPoint& leftPoint,
00066                                 LocalPoint& rightPoint,
00067                                 LocalError& error) const {
00068   // Get the wireId
00069   DTLayerId layerId = layer->id();
00070   const DTWireId wireId(layerId, digi.wire());
00071 
00072   // Get Wire position
00073   if(!layer->specificTopology().isWireValid(digi.wire())) return false;
00074   LocalPoint locWirePos(layer->specificTopology().wirePosition(digi.wire()), 0, 0);
00075   const GlobalPoint globWirePos = layer->toGlobal(locWirePos);
00076   
00077   return compute(layer, wireId, digi.time(), globWirePos, leftPoint, rightPoint, error, 1); 
00078 }
00079 
00080 
00081 
00082 // Second step: the same as 1st step (optionally, redo 1st step starting from digi time)
00083 bool DTLinearDriftFromDBAlgo::compute(const DTLayer* layer,
00084                                 const DTRecHit1D& recHit1D,
00085                                 const float& angle,
00086                                 DTRecHit1D& newHit1D) const {
00087 
00088   if (!stepTwoFromDigi) {
00089     newHit1D.setPositionAndError(recHit1D.localPosition(), recHit1D.localPositionError());
00090     return true;
00091   }
00092 
00093   const DTWireId wireId = recHit1D.wireId();
00094   
00095   // Get Wire position
00096   if(!layer->specificTopology().isWireValid(wireId.wire())) return false;
00097   LocalPoint locWirePos(layer->specificTopology().wirePosition(wireId.wire()), 0, 0);
00098   const GlobalPoint globWirePos = layer->toGlobal(locWirePos);
00099 
00100   return compute(layer, wireId, recHit1D.digiTime(), globWirePos, newHit1D, 2);
00101 
00102 }
00103 
00104 
00105 
00106 // Third step.
00107 bool DTLinearDriftFromDBAlgo::compute(const DTLayer* layer,
00108                                 const DTRecHit1D& recHit1D,
00109                                 const float& angle,
00110                                 const GlobalPoint& globPos, 
00111                                 DTRecHit1D& newHit1D) const {
00112   return compute(layer, recHit1D.wireId(), recHit1D.digiTime(), globPos, newHit1D, 3);
00113 }
00114 
00115 
00116 
00117 // Do the actual work.
00118 bool DTLinearDriftFromDBAlgo::compute(const DTLayer* layer,
00119                                 const DTWireId& wireId,
00120                                 const float digiTime,
00121                                 const GlobalPoint& globPos, 
00122                                 LocalPoint& leftPoint,
00123                                 LocalPoint& rightPoint,
00124                                 LocalError& error,
00125                                 int step) const {
00126   // Subtract the offset to the digi time accordingly to the DTTTrigBaseSync concrete instance
00127   float driftTime = digiTime - theSync->offset(layer, wireId, globPos); 
00128   
00129   // check for out-of-time
00130   if (driftTime < minTime || driftTime > maxTime) {
00131     if (debug) cout << "[DTLinearDriftFromDBAlgo]*** Drift time out of window for in-time hits "
00132                               << driftTime << endl;
00133 
00134     if(step == 1) { //FIXME: protection against failure at 2nd and 3rd steps, must be checked!!!
00135       // Hits are interpreted as coming from out-of-time pile-up and recHit
00136       // is ignored.
00137       return false;
00138     }
00139   }
00140 
00141   // Small negative times interpreted as hits close to the wire.
00142   if (driftTime<0.) driftTime=0;
00143 
00144   // Read the vDrift and reso for this wire
00145   float vDrift = 0;
00146   float hitResolution = 0;//FIXME: should use this!
00147   // vdrift is cm/ns , resolution is cm
00148   mTimeMap->get(wireId.superlayerId(),
00149                 vDrift,
00150                 hitResolution,
00151                 DTVelocityUnits::cm_per_ns);
00152 
00153   //only in step 3
00154   if(doVdriftCorr && step == 3){
00155     if (abs(wireId.wheel()) == 2 && 
00156         wireId.station() == 1 &&
00157         wireId.superLayer() != 2) {
00158       // Variation of vdrift along Y due to B field, 
00160       // vdrift is lower  a negative Y (lower global |Z|)
00161       const float k_param = 1.2e-04;
00162       LocalPoint local_pos = layer->toLocal(globPos);
00163       vDrift = vDrift*(1. - k_param*local_pos.y());
00164         } 
00165   }
00166 
00167   // Compute the drift distance
00168   float drift = driftTime * vDrift;
00169 
00170   // Get Wire position
00171   if(!layer->specificTopology().isWireValid(wireId.wire())) return false;
00172   LocalPoint locWirePos(layer->specificTopology().wirePosition(wireId.wire()), 0, 0);
00173   //Build the two possible points and the error on the position
00174   leftPoint  = LocalPoint(locWirePos.x()-drift,
00175                             locWirePos.y(),
00176                             locWirePos.z());
00177   rightPoint = LocalPoint(locWirePos.x()+drift,
00178                             locWirePos.y(),
00179                             locWirePos.z());
00180   error = LocalError(hitResolution*hitResolution,0.,0.);
00181 
00182 
00183   if(debug) {
00184     cout << "[DTLinearDriftFromDBAlgo] Compute drift distance, for digi at wire: " << wireId << endl
00185          << "       Step:           " << step << endl
00186          << "       Digi time:      " << digiTime << endl
00187          << "       Drift time:     " << driftTime << endl
00188          << "       Drift distance: " << drift << endl
00189          << "       Hit Resolution: " << hitResolution << endl
00190          << "       Left point:     " << leftPoint << endl
00191          << "       Right point:    " << rightPoint << endl
00192          << "       Error:          " << error << endl;
00193    }
00194   
00195   return true;
00196   
00197 }
00198 
00199 
00200 // Interface to the method which does the actual work suited for 2nd and 3rd steps 
00201 bool DTLinearDriftFromDBAlgo::compute(const DTLayer* layer,
00202                                 const DTWireId& wireId,
00203                                 const float digiTime,
00204                                 const GlobalPoint& globPos, 
00205                                 DTRecHit1D& newHit1D,
00206                                 int step) const {
00207   LocalPoint leftPoint;
00208   LocalPoint rightPoint;
00209   LocalError error;
00210 
00211   if(compute(layer, wireId, digiTime, globPos, leftPoint, rightPoint, error, step)) {
00212     // Set the position and the error of the rechit which is being updated
00213     switch(newHit1D.lrSide()) {
00214         
00215     case DTEnums::Left:
00216         {
00217           // Keep the original y position of newHit1D: for step==3, it's the
00218           // position along the wire. Needed for rotation alignment
00219           LocalPoint leftPoint3D(leftPoint.x(), newHit1D.localPosition().y(), leftPoint.z());
00220           newHit1D.setPositionAndError(leftPoint3D, error);
00221           break;
00222         }
00223         
00224     case DTEnums::Right:
00225         {
00226           // as above: 3d position
00227           LocalPoint rightPoint3D(rightPoint.x(), newHit1D.localPosition().y(), rightPoint.z());
00228           newHit1D.setPositionAndError(rightPoint3D, error);
00229           break;
00230         }
00231         
00232     default:
00233       throw cms::Exception("InvalidDTCellSide") << "[DTLinearDriftFromDBAlgo] Compute at Step "
00234                                                 << step << ", Hit side "
00235                                                 << newHit1D.lrSide()
00236                                                 << " is invalid!" << endl;
00237       return false;
00238     }
00239       
00240     return true;
00241   }else {
00242     return false;
00243   }
00244 }
00245 
00246 float DTLinearDriftFromDBAlgo::minTime;
00247 
00248   
00249 float DTLinearDriftFromDBAlgo::maxTime;
00250 
00251   
00252 bool DTLinearDriftFromDBAlgo::debug;