Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2023-03-17 11:19:16

0001 /*
0002  *  See header file for a description of this class.
0003  *
0004  *  \author Martijn Mulders - CERN (martijn.mulders@cern.ch)
0005  *  based on DTLinearDriftAlgo
0006  */
0007 
0008 #include "RecoLocalMuon/DTRecHit/plugins/DTNoDriftAlgo.h"
0009 #include "DataFormats/MuonDetId/interface/DTWireId.h"
0010 #include "Geometry/DTGeometry/interface/DTLayer.h"
0011 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0012 #include "FWCore/Framework/interface/EventSetup.h"
0013 #include "FWCore/Framework/interface/ConsumesCollector.h"
0014 #include "FWCore/Utilities/interface/Exception.h"
0015 
0016 using namespace std;
0017 using namespace edm;
0018 
0019 DTNoDriftAlgo::DTNoDriftAlgo(const ParameterSet& config, ConsumesCollector cc)
0020     : DTRecHitBaseAlgo(config, cc),
0021       fixedDrift(config.getParameter<double>("fixedDrift")),
0022       hitResolution(config.getParameter<double>("hitResolution")),  // Set to size of (half)cell
0023       minTime(config.getParameter<double>("minTime")),
0024       maxTime(config.getParameter<double>("maxTime")),
0025       debug(config.getUntrackedParameter<bool>("debug"))  // Set verbose output
0026 {}
0027 
0028 DTNoDriftAlgo::~DTNoDriftAlgo() {}
0029 
0030 void DTNoDriftAlgo::setES(const EventSetup& setup) {
0031   //  theSync->setES(setup);
0032 }
0033 
0034 // Build all hits in the range associated to the layerId, at the 1st step.
0035 OwnVector<DTRecHit1DPair> DTNoDriftAlgo::reconstruct(const DTLayer* layer,
0036                                                      const DTLayerId& layerId,
0037                                                      const DTDigiCollection::Range& digiRange) {
0038   OwnVector<DTRecHit1DPair> result;
0039 
0040   // Loop over all digis in the given range
0041   for (DTDigiCollection::const_iterator digi = digiRange.first; digi != digiRange.second; digi++) {
0042     // Get the wireId
0043     DTWireId wireId(layerId, (*digi).wire());
0044 
0045     bool isDouble = false;
0046     for (OwnVector<DTRecHit1DPair>::const_iterator doubleWireCheck = result.begin(); doubleWireCheck != result.end();
0047          doubleWireCheck++) {
0048       if (wireId == (*doubleWireCheck).wireId()) {
0049         isDouble = true;
0050         //  std::cout << " Reject this hit with time " << (*digi).time() << std::endl;
0051         break;
0052       }
0053     }
0054 
0055     if (isDouble)
0056       continue;
0057 
0058     LocalError tmpErr;
0059     LocalPoint lpoint, rpoint;
0060     // Call the compute method
0061     bool OK = compute(layer, *digi, lpoint, rpoint, tmpErr);
0062 
0063     if (!OK)
0064       continue;
0065 
0066     // Build a new pair of 1D rechit
0067     DTRecHit1DPair* recHitPair = new DTRecHit1DPair(wireId, *digi);
0068 
0069     // Set the position and the error of the 1D rechits
0070     recHitPair->setPositionAndError(DTEnums::Left, lpoint, tmpErr);
0071     recHitPair->setPositionAndError(DTEnums::Right, rpoint, tmpErr);
0072 
0073     result.push_back(recHitPair);
0074   }
0075   return result;
0076 }
0077 
0078 // First Step
0079 bool DTNoDriftAlgo::compute(
0080     const DTLayer* layer, const DTDigi& digi, LocalPoint& leftPoint, LocalPoint& rightPoint, LocalError& error) const {
0081   // Get the wireId
0082   DTLayerId layerId = layer->id();
0083   const DTWireId wireId(layerId, digi.wire());
0084 
0085   // Get Wire position
0086   if (!layer->specificTopology().isWireValid(digi.wire()))
0087     return false;
0088   LocalPoint locWirePos(layer->specificTopology().wirePosition(digi.wire()), 0, 0);
0089   const GlobalPoint globWirePos = layer->toGlobal(locWirePos);
0090 
0091   return compute(layer, wireId, digi.time(), globWirePos, leftPoint, rightPoint, error, 1);
0092 }
0093 
0094 // Second step: the same as 1st step
0095 bool DTNoDriftAlgo::compute(const DTLayer* layer,
0096                             const DTRecHit1D& recHit1D,
0097                             const float& angle,
0098                             DTRecHit1D& newHit1D) const {
0099   newHit1D.setPositionAndError(recHit1D.localPosition(), recHit1D.localPositionError());
0100   return true;
0101 }
0102 
0103 // Third step.
0104 bool DTNoDriftAlgo::compute(const DTLayer* layer,
0105                             const DTRecHit1D& recHit1D,
0106                             const float& angle,
0107                             const GlobalPoint& globPos,
0108                             DTRecHit1D& newHit1D) const {
0109   return compute(layer, recHit1D.wireId(), recHit1D.digiTime(), globPos, newHit1D, 3);
0110 }
0111 
0112 // Do the actual work.
0113 bool DTNoDriftAlgo::compute(const DTLayer* layer,
0114                             const DTWireId& wireId,
0115                             const float digiTime,
0116                             const GlobalPoint& globPos,
0117                             LocalPoint& leftPoint,
0118                             LocalPoint& rightPoint,
0119                             LocalError& error,
0120                             int step) const {
0121   //}
0122 
0123   // Small negative times interpreted as hits close to the wire.
0124   //if (driftTime<0.) driftTime=0;
0125 
0126   // check for out-of-time
0127   if (digiTime < minTime || digiTime > maxTime) {
0128     if (debug)
0129       cout << "[DTNoDriftAlgo]*** Drift time out of window for in-time hits " << digiTime << endl;
0130 
0131     if (step == 1) {  //FIXME: protection against failure at 2nd and 3rd steps, must be checked!!!
0132       // Hits are interpreted as coming from out-of-time pile-up and recHit
0133       // is ignored.
0134       return false;
0135     }
0136   }
0137 
0138   // Compute the drift distance
0139   float drift = fixedDrift;
0140 
0141   // Get Wire position
0142   if (!layer->specificTopology().isWireValid(wireId.wire()))
0143     return false;
0144   LocalPoint locWirePos(layer->specificTopology().wirePosition(wireId.wire()), 0, 0);
0145   //Build the two possible points and the error on the position
0146   leftPoint = LocalPoint(locWirePos.x() - drift, locWirePos.y(), locWirePos.z());
0147   rightPoint = LocalPoint(locWirePos.x() + drift, locWirePos.y(), locWirePos.z());
0148   error = LocalError(hitResolution * hitResolution, 0., 0.);
0149 
0150   if (debug) {
0151     cout << "[DTNoDriftAlgo] Compute drift distance, for digi at wire: " << wireId << endl
0152          << "       Step:           " << step << endl
0153          << "       Digi time:      " << digiTime
0154          << endl
0155          //  << "       Drift time:     " << driftTime << endl
0156          << "       Fixed Drift distance: " << drift << endl
0157          << "       Hit Resolution: " << hitResolution << endl
0158          << "       Left point:     " << leftPoint << endl
0159          << "       Right point:    " << rightPoint << endl
0160          << "       Error:          " << error << endl;
0161   }
0162 
0163   return true;
0164 }
0165 
0166 // Interface to the method which does the actual work suited for 2nd and 3rd steps
0167 bool DTNoDriftAlgo::compute(const DTLayer* layer,
0168                             const DTWireId& wireId,
0169                             const float digiTime,
0170                             const GlobalPoint& globPos,
0171                             DTRecHit1D& newHit1D,
0172                             int step) const {
0173   LocalPoint leftPoint;
0174   LocalPoint rightPoint;
0175   LocalError error;
0176 
0177   if (compute(layer, wireId, digiTime, globPos, leftPoint, rightPoint, error, step)) {
0178     // Set the position and the error of the rechit which is being updated
0179     switch (newHit1D.lrSide()) {
0180       case DTEnums::Left:
0181         newHit1D.setPositionAndError(leftPoint, error);
0182         break;
0183 
0184       case DTEnums::Right:
0185         newHit1D.setPositionAndError(rightPoint, error);
0186         break;
0187 
0188       default:
0189         throw cms::Exception("InvalidDTCellSide") << "[DTNoDriftAlgo] Compute at Step " << step << ", Hit side "
0190                                                   << newHit1D.lrSide() << " is invalid!" << endl;
0191         return false;
0192     }
0193 
0194     return true;
0195   } else {
0196     return false;
0197   }
0198 }