Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:29:46

0001 #include "SimFastTiming/FastTimingCommon/interface/BTLDeviceSim.h"
0002 #include "DataFormats/Math/interface/GeantUnits.h"
0003 #include "DataFormats/DetId/interface/DetId.h"
0004 #include "DataFormats/ForwardDetId/interface/MTDDetId.h"
0005 #include "DataFormats/ForwardDetId/interface/BTLDetId.h"
0006 #include "FWCore/Framework/interface/ConsumesCollector.h"
0007 
0008 #include "Geometry/CommonDetUnit/interface/GeomDetType.h"
0009 #include "Geometry/MTDGeometryBuilder/interface/ProxyMTDTopology.h"
0010 #include "Geometry/MTDGeometryBuilder/interface/RectangularMTDTopology.h"
0011 #include "Geometry/MTDCommonData/interface/MTDTopologyMode.h"
0012 
0013 #include "CLHEP/Random/RandGaussQ.h"
0014 
0015 BTLDeviceSim::BTLDeviceSim(const edm::ParameterSet& pset, edm::ConsumesCollector iC)
0016     : geomToken_(iC.esConsumes()),
0017       topoToken_(iC.esConsumes()),
0018       geom_(nullptr),
0019       topo_(nullptr),
0020       bxTime_(pset.getParameter<double>("bxTime")),
0021       LightYield_(pset.getParameter<double>("LightYield")),
0022       LightCollEff_(pset.getParameter<double>("LightCollectionEff")),
0023       LightCollSlope_(pset.getParameter<double>("LightCollectionSlope")),
0024       PDE_(pset.getParameter<double>("PhotonDetectionEff")),
0025       LCEpositionSlope_(pset.getParameter<double>("LCEpositionSlope")) {}
0026 
0027 void BTLDeviceSim::getEventSetup(const edm::EventSetup& evs) {
0028   geom_ = &evs.getData(geomToken_);
0029   topo_ = &evs.getData(topoToken_);
0030 }
0031 
0032 void BTLDeviceSim::getHitsResponse(const std::vector<std::tuple<int, uint32_t, float> >& hitRefs,
0033                                    const edm::Handle<edm::PSimHitContainer>& hits,
0034                                    mtd_digitizer::MTDSimHitDataAccumulator* simHitAccumulator,
0035                                    CLHEP::HepRandomEngine* hre) {
0036   using namespace geant_units::operators;
0037 
0038   //loop over sorted simHits
0039   for (auto const& hitRef : hitRefs) {
0040     const int hitidx = std::get<0>(hitRef);
0041     const uint32_t id = std::get<1>(hitRef);
0042     const MTDDetId detId(id);
0043     const PSimHit& hit = hits->at(hitidx);
0044 
0045     // --- Safety check on the detector ID
0046     if (detId.det() != DetId::Forward || detId.mtdSubDetector() != 1)
0047       continue;
0048 
0049     if (id == 0)
0050       continue;  // to be ignored at RECO level
0051 
0052     BTLDetId btlid(detId);
0053     DetId geoId = btlid.geographicalId(MTDTopologyMode::crysLayoutFromTopoMode(topo_->getMTDTopologyMode()));
0054     const MTDGeomDet* thedet = geom_->idToDet(geoId);
0055 
0056     if (thedet == nullptr) {
0057       throw cms::Exception("BTLDeviceSim") << "GeographicalID: " << std::hex << geoId.rawId() << " (" << detId.rawId()
0058                                            << ") is invalid!" << std::dec << std::endl;
0059     }
0060     const ProxyMTDTopology& topoproxy = static_cast<const ProxyMTDTopology&>(thedet->topology());
0061     const RectangularMTDTopology& topo = static_cast<const RectangularMTDTopology&>(topoproxy.specificTopology());
0062     // calculate the simhit row and column
0063     const auto& position = hit.localPosition();
0064     Local3DPoint simscaled(convertMmToCm(position.x()), convertMmToCm(position.y()), convertMmToCm(position.z()));
0065     // translate from crystal-local coordinates to module-local coordinates to get the row and column
0066     simscaled = topo.pixelToModuleLocalPoint(simscaled, btlid.row(topo.nrows()), btlid.column(topo.nrows()));
0067 
0068     const auto& thepixel = topo.pixelIndex(simscaled);
0069     uint8_t row = static_cast<uint8_t>(thepixel.first);
0070     uint8_t col = static_cast<uint8_t>(thepixel.second);
0071 
0072     if (btlid.row(topo.nrows()) != row || btlid.column(topo.nrows()) != col) {
0073       edm::LogWarning("BTLDeviceSim") << "BTLDetId (row,column): (" << btlid.row(topo.nrows()) << ','
0074                                       << btlid.column(topo.nrows()) << ") is not equal to "
0075                                       << "topology (row,column): (" << uint32_t(row) << ',' << uint32_t(col)
0076                                       << "), overriding to detid";
0077       row = btlid.row(topo.nrows());
0078       col = btlid.column(topo.nrows());
0079     }
0080 
0081     // --- Store the detector element ID as a key of the MTDSimHitDataAccumulator map
0082     auto simHitIt =
0083         simHitAccumulator->emplace(mtd_digitizer::MTDCellId(id, row, col), mtd_digitizer::MTDCellInfo()).first;
0084 
0085     // --- Get the simHit energy and convert it from MeV to photo-electrons
0086     float Npe = convertGeVToMeV(hit.energyLoss()) * LightYield_ * LightCollEff_ * PDE_;
0087 
0088     // --- Calculate the light propagation time to the crystal bases (labeled L and R)
0089     double distR = 0.5 * topo.pitch().first - convertMmToCm(hit.localPosition().x());
0090     double distL = 0.5 * topo.pitch().first + convertMmToCm(hit.localPosition().x());
0091 
0092     double tR = std::get<2>(hitRef) + LightCollSlope_ * distR;
0093     double tL = std::get<2>(hitRef) + LightCollSlope_ * distL;
0094 
0095     // --- Accumulate in 15 buckets of 25ns (9 pre-samples, 1 in-time, 5 post-samples)
0096     const int iBXR = std::floor(tR / bxTime_) + mtd_digitizer::kInTimeBX;
0097     const int iBXL = std::floor(tL / bxTime_) + mtd_digitizer::kInTimeBX;
0098 
0099     // --- Right side
0100     if (iBXR > 0 && iBXR < mtd_digitizer::kNumberOfBX) {
0101       // Accumulate the energy of simHits in the same crystal
0102       (simHitIt->second).hit_info[0][iBXR] += Npe * (1. + LCEpositionSlope_ * convertMmToCm(hit.localPosition().x()));
0103 
0104       // Store the time of the first SimHit in the i-th BX
0105       if ((simHitIt->second).hit_info[1][iBXR] == 0 || tR < (simHitIt->second).hit_info[1][iBXR])
0106         (simHitIt->second).hit_info[1][iBXR] = tR - (iBXR - mtd_digitizer::kInTimeBX) * bxTime_;
0107     }
0108 
0109     // --- Left side
0110     if (iBXL > 0 && iBXL < mtd_digitizer::kNumberOfBX) {
0111       // Accumulate the energy of simHits in the same crystal
0112       (simHitIt->second).hit_info[2][iBXL] += Npe * (1. - LCEpositionSlope_ * convertMmToCm(hit.localPosition().x()));
0113 
0114       // Store the time of the first SimHit in the i-th BX
0115       if ((simHitIt->second).hit_info[3][iBXL] == 0 || tL < (simHitIt->second).hit_info[3][iBXL])
0116         (simHitIt->second).hit_info[3][iBXL] = tL - (iBXL - mtd_digitizer::kInTimeBX) * bxTime_;
0117     }
0118 
0119   }  // hitRef loop
0120 }