1 #ifndef SimMuon_GEMDigitizer_ME0ReDigiProducer_h
2 #define SimMuon_GEMDigitizer_ME0ReDigiProducer_h
29 #include "CLHEP/Random/RandGaussQ.h"
30 #include "CLHEP/Random/RandFlat.h"
31 #include "CLHEP/Units/PhysicalConstants.h"
67 std::vector<std::vector<double>>
tofs;
83 CLHEP::HepRandomEngine* engine);
100 typedef std::tuple<unsigned int, unsigned int, unsigned int>
DigiIndicies;
123 std::vector<std::vector<double>>
tofs;
133 <<
"ME0ReDigiProducer::TemporaryGeometry::TemporaryGeometry() - No ME0Chambers in geometry.";
134 const auto* mainChamber =
chambers.front();
138 <<
"ME0ReDigiProducer::TemporaryGeometry::TemporaryGeometry() - ME0Chamber has no layers.";
139 const auto* mainLayer = mainChamber->layers()[0];
140 if (!mainLayer->nEtaPartitions())
142 <<
"ME0ReDigiProducer::TemporaryGeometry::TemporaryGeometry() - ME0Layer has no partitions.";
143 if (mainLayer->nEtaPartitions() != 1)
144 throw cms::Exception(
"Setup") <<
"ME0ReDigiProducer::TemporaryGeometry::TemporaryGeometry() - This module is only "
145 "compatitble with geometries that contain only one partition per ME0Layer.";
147 const auto* mainPartition = mainLayer->etaPartitions()[0];
148 const TrapezoidalStripTopology* mainTopo = dynamic_cast<const TrapezoidalStripTopology*>(&mainPartition->topology());
150 throw cms::Exception(
"Setup") <<
"ME0ReDigiProducer::TemporaryGeometry::TemporaryGeometry() - ME0 strip topology "
151 "must be of type TrapezoidalStripTopology. This module cannot be used";
155 throw cms::Exception(
"Setup") <<
"ME0ReDigiProducer::TemporaryGeometry::TemporaryGeometry() - Not all "
156 "ME0Chambers have the same number of layers. This module cannot be used.";
157 for (
unsigned int iL = 0; iL <
nLayers; ++iL) {
158 if (
chamber->layers()[iL]->nEtaPartitions() != mainLayer->nEtaPartitions())
159 throw cms::Exception(
"Setup") <<
"ME0ReDigiProducer::TemporaryGeometry::TemporaryGeometry() - Not all "
160 "ME0Layers have the same number of partitions. This module cannot be used.";
161 if (
chamber->layers()[iL]->etaPartitions()[0]->specs()->parameters() != mainPartition->specs()->parameters())
162 throw cms::Exception(
"Setup") <<
"ME0ReDigiProducer::TemporaryGeometry::TemporaryGeometry() - Not all ME0 ETA "
163 "partitions have the same properties. This module cannot be used.";
164 if (std::fabs(
chamber->layers()[iL]->etaPartitions()[0]->position().z()) !=
165 std::fabs(mainChamber->layers()[iL]->etaPartitions()[0]->position().z()))
167 <<
"ME0ReDigiProducer::TemporaryGeometry::TemporaryGeometry() - Not all ME0 ETA partitions in a single "
168 "layer have the same Z position. This module cannot be used.";
178 const auto globalTop = mainPartition->toGlobal(localTop);
179 const auto globalBottom = mainPartition->toGlobal(localBottom);
180 const double etaTop = globalTop.
eta();
181 const double etaBottom = globalBottom.eta();
182 const double zBottom = globalBottom.z();
187 const auto& mainPars = mainPartition->specs()->parameters();
190 const double distFromBeam = std::fabs(zBottom / std::sinh(
eta));
192 LogDebug(
"ME0ReDigiProducer::TemporaryGeometry") <<
"Top of new partition: " <<
partitionTops.back() << std::endl;
194 std::vector<float>
params(4, 0);
197 auto getWidth = [&](
float locY) ->
float {
198 return (mainPars[2] * (mainPars[1] + mainPars[0]) + locY * (mainPars[1] - mainPars[0])) / (2 * mainPars[2]);
214 LogDebug(
"ME0ReDigiProducer::TemporaryGeometry") <<
"TOF numbers [layer][partition]: ";
215 for (
unsigned int iL = 0; iL <
nLayers; ++iL) {
219 const GlobalPoint centralGP(mainChamber->layers()[iL]->etaPartitions()[0]->toGlobal(partCenter));
220 tofs[iL][iP] = (centralGP.mag() / (CLHEP::c_light / CLHEP::cm));
221 LogDebug(
"ME0ReDigiProducer::TemporaryGeometry")
222 <<
"[" << iL <<
"][" << iP <<
"]=" <<
tofs[iL][iP] <<
" " << std::endl;
228 unsigned int etaPart = stripTopos.size() - 1;
229 for (
unsigned int iP = 0; iP < stripTopos.size(); ++iP) {
230 if (locY < partitionTops[iP]) {
239 return stripTopos[
partIdx]->radius() - middleDistanceFromBeam;
243 for (
auto*
p : stripTopos) {
252 float r0 =
h * (
B +
b) / (
B -
b);
253 float striplength =
h * 2;
256 int nstrip = static_cast<int>(
strips);
258 LogDebug(
"ME0ReDigiProducer::TemporaryGeometry")
259 <<
"New partition parameters: "
260 <<
"bottom width(" << 2 *
b <<
") top width(" << 2 *
B <<
") height(" << 2 *
h <<
") radius to center(" << r0
261 <<
") nStrips(" <<
strips <<
") pitch(" << pitch <<
")" << std::endl;
279 produces<ME0DigiPreRecoCollection>();
280 produces<ME0DigiPreRecoMap>();
285 <<
"ME0ReDigiProducer::ME0PreRecoDigiProducer() - RandomNumberGeneratorService is not present in configuration "
287 <<
"Add the service in the configuration file or remove the modules that require it.";
298 <<
"ME0ReDigiProducer::ME0PreRecoDigiProducer() - Must have at least one strip if using custom geometry.";
301 <<
"ME0ReDigiProducer::ME0PreRecoDigiProducer() - Must have at least one partition if using custom geometry.";
305 throw cms::Exception(
"Setup") <<
"ME0ReDigiProducer::ME0PreRecoDigiProducer() - neutronAcceptance must be >= 0.";
321 throw cms::Exception(
"Setup") <<
"ME0ReDigiProducer::beginRun() - No ME0Chambers in geometry.";
325 throw cms::Exception(
"Setup") <<
"ME0ReDigiProducer::beginRun() - No layers in ME0 geometry.";
327 const unsigned int nPartitions =
chambers.front()->layers()[0]->nEtaPartitions();
336 <<
"ME0ReDigiProducer::beginRun() - The geometry has " <<
nLayers <<
" layers, but the readout of "
337 <<
layerReadout.size() <<
" were specified with the layerReadout parameter.";
340 LogDebug(
"ME0ReDigiProducer") <<
"Building temporary geometry:" << std::endl;
342 LogDebug(
"ME0ReDigiProducer") <<
"Done building temporary geometry!" << std::endl;
346 <<
"ME0ReDigiProducer::beginRun() - The geometry has " <<
tempGeo->
numLayers()
347 <<
" layers, but the readout of " <<
layerReadout.size()
348 <<
" were specified with the layerReadout parameter.";
354 CLHEP::HepRandomEngine* engine = &rng->
getEngine(
e.streamID());
357 e.getByToken(
token, input_digis);
373 CLHEP::HepRandomEngine* engine) {
388 LogDebug(
"ME0ReDigiProducer::buildDigis") <<
"Begin building digis." << std::endl;
390 for (me0dgIt = input_digis.begin(); me0dgIt != input_digis.end(); ++me0dgIt) {
391 const auto& me0Id = (*me0dgIt).first;
392 LogTrace(
"ME0ReDigiProducer::buildDigis") <<
"Starting with roll: " << me0Id << std::endl;
400 LogTrace(
"ME0ReDigiProducer::buildDigis") << std::endl
401 <<
"(" << digi->x() <<
"," << digi->y() <<
"," << digi->tof() <<
","
402 << digi->pdgid() <<
"," << digi->prompt() <<
")-> ";
421 int mapPartIDX = me0Id.roll() - 1;
432 const int bxIdx = std::round(tof /
bxWidth);
433 LogTrace(
"ME0ReDigiProducer::buildDigis") << tof <<
"(" << bxIdx <<
") ";
445 LogTrace(
"ME0ReDigiProducer::buildDigis") <<
"(" << bxIdx <<
"," << mapPartIDX <<
"," <<
strip <<
") ";
447 int matchIDX =
fillDigiMap(chDigiMap, bxIdx, mapPartIDX,
strip, newDigiIdx);
461 digiLocalPoint.
x(), digiLocalPoint.
y(),
sigmaX,
sigmaY, corrCoef, tof, digi->pdgid(), digi->prompt());
462 output_digis.insertDigi(me0Id, out_digi);
468 LogTrace(
"ME0ReDigiProducer::buildDigis") <<
"(" << digiLocalPoint.
x() <<
"," << digiLocalPoint.
y() <<
","
477 const auto* mainChamber =
geometry->chambers().front();
478 const unsigned int nLayers = mainChamber->nLayers();
482 LogDebug(
"ME0ReDigiProducer::fillCentralTOFs()") <<
"TOF numbers [layer][partition]: ";
483 for (
unsigned int iL = 0; iL <
nLayers; ++iL) {
484 const auto* layer = mainChamber->layers()[iL];
485 const unsigned int mapLayIDX = layer->id().layer() - 1;
486 const unsigned int nPartitions = layer->nEtaPartitions();
488 throw cms::Exception(
"Setup") <<
"ME0ReDigiProducer::fillCentralTOFs() - ME0Layer has no partitions.";
489 tofs[mapLayIDX].resize(nPartitions);
490 for (
unsigned int iP = 0; iP < nPartitions; ++iP) {
491 const unsigned int mapPartIDX = layer->etaPartitions()[iP]->id().roll() - 1;
492 const GlobalPoint centralGP(layer->etaPartitions()[iP]->position());
493 tofs[mapLayIDX][mapPartIDX] = (centralGP.mag() / (CLHEP::c_light / CLHEP::cm));
494 LogDebug(
"ME0ReDigiProducer::fillCentralTOFs()")
495 <<
"[" << mapLayIDX <<
"][" << mapPartIDX <<
"]=" <<
tofs[mapLayIDX][mapPartIDX] <<
" " << std::endl;
517 const LocalPoint partLocalPoint(inDigi->
x(), inDigi->
y() - partCenter, 0.);
518 strip = topo->channel(partLocalPoint);
522 LocalPoint digiPartLocalPoint = topo->localPosition(stripF);
523 digiLocalError = topo->localError(
528 digiLocalPoint =
LocalPoint(digiPartLocalPoint.
x(), digiPartLocalPoint.
y() + partCenter, 0.0);
546 const LocalPoint partLocalPoint(inDigi->
x(), inDigi->
y(), 0.);
547 strip = topo.channel(partLocalPoint);
551 digiLocalPoint = topo.localPosition(stripF);
552 digiLocalError = topo.localError(stripF, 1. /
sqrt(12.));
558 auto it1 = chDigiMap.find(newIDX);
559 if (it1 == chDigiMap.end()) {
560 chDigiMap[newIDX] = currentIDX;