1 #ifndef SimMuon_GEMDigitizer_ME0ReDigiProducer_h
2 #define SimMuon_GEMDigitizer_ME0ReDigiProducer_h
30 #include "CLHEP/Random/RandGaussQ.h"
31 #include "CLHEP/Random/RandFlat.h"
32 #include "CLHEP/Units/PhysicalConstants.h"
68 std::vector<std::vector<double>>
tofs;
84 CLHEP::HepRandomEngine* engine);
101 typedef std::tuple<unsigned int, unsigned int, unsigned int>
DigiIndicies;
125 std::vector<std::vector<double>>
tofs;
135 <<
"ME0ReDigiProducer::TemporaryGeometry::TemporaryGeometry() - No ME0Chambers in geometry.";
136 const auto* mainChamber =
chambers.front();
140 <<
"ME0ReDigiProducer::TemporaryGeometry::TemporaryGeometry() - ME0Chamber has no layers.";
141 const auto* mainLayer = mainChamber->layers()[0];
142 if (!mainLayer->nEtaPartitions())
144 <<
"ME0ReDigiProducer::TemporaryGeometry::TemporaryGeometry() - ME0Layer has no partitions.";
145 if (mainLayer->nEtaPartitions() != 1)
146 throw cms::Exception(
"Setup") <<
"ME0ReDigiProducer::TemporaryGeometry::TemporaryGeometry() - This module is only "
147 "compatitble with geometries that contain only one partition per ME0Layer.";
149 const auto* mainPartition = mainLayer->etaPartitions()[0];
150 const TrapezoidalStripTopology* mainTopo = dynamic_cast<const TrapezoidalStripTopology*>(&mainPartition->topology());
152 throw cms::Exception(
"Setup") <<
"ME0ReDigiProducer::TemporaryGeometry::TemporaryGeometry() - ME0 strip topology "
153 "must be of type TrapezoidalStripTopology. This module cannot be used";
157 throw cms::Exception(
"Setup") <<
"ME0ReDigiProducer::TemporaryGeometry::TemporaryGeometry() - Not all "
158 "ME0Chambers have the same number of layers. This module cannot be used.";
159 for (
unsigned int iL = 0; iL <
nLayers; ++iL) {
160 if (
chamber->layers()[iL]->nEtaPartitions() != mainLayer->nEtaPartitions())
161 throw cms::Exception(
"Setup") <<
"ME0ReDigiProducer::TemporaryGeometry::TemporaryGeometry() - Not all "
162 "ME0Layers have the same number of partitions. This module cannot be used.";
163 if (
chamber->layers()[iL]->etaPartitions()[0]->specs()->parameters() != mainPartition->specs()->parameters())
164 throw cms::Exception(
"Setup") <<
"ME0ReDigiProducer::TemporaryGeometry::TemporaryGeometry() - Not all ME0 ETA "
165 "partitions have the same properties. This module cannot be used.";
166 if (std::fabs(
chamber->layers()[iL]->etaPartitions()[0]->position().z()) !=
167 std::fabs(mainChamber->layers()[iL]->etaPartitions()[0]->position().z()))
169 <<
"ME0ReDigiProducer::TemporaryGeometry::TemporaryGeometry() - Not all ME0 ETA partitions in a single "
170 "layer have the same Z position. This module cannot be used.";
180 const auto globalTop = mainPartition->toGlobal(localTop);
181 const auto globalBottom = mainPartition->toGlobal(localBottom);
182 const double etaTop = globalTop.
eta();
183 const double etaBottom = globalBottom.eta();
184 const double zBottom = globalBottom.z();
189 const auto& mainPars = mainPartition->specs()->parameters();
192 const double distFromBeam = std::fabs(zBottom / std::sinh(
eta));
194 LogDebug(
"ME0ReDigiProducer::TemporaryGeometry") <<
"Top of new partition: " <<
partitionTops.back() << std::endl;
196 std::vector<float>
params(4, 0);
199 auto getWidth = [&](
float locY) ->
float {
200 return (mainPars[2] * (mainPars[1] + mainPars[0]) + locY * (mainPars[1] - mainPars[0])) / (2 * mainPars[2]);
216 LogDebug(
"ME0ReDigiProducer::TemporaryGeometry") <<
"TOF numbers [layer][partition]: ";
217 for (
unsigned int iL = 0; iL <
nLayers; ++iL) {
221 const GlobalPoint centralGP(mainChamber->layers()[iL]->etaPartitions()[0]->toGlobal(partCenter));
222 tofs[iL][iP] = (centralGP.mag() / (CLHEP::c_light / CLHEP::cm));
223 LogDebug(
"ME0ReDigiProducer::TemporaryGeometry")
224 <<
"[" << iL <<
"][" << iP <<
"]=" <<
tofs[iL][iP] <<
" " << std::endl;
230 unsigned int etaPart = stripTopos.size() - 1;
231 for (
unsigned int iP = 0; iP < stripTopos.size(); ++iP) {
232 if (locY < partitionTops[iP]) {
241 return stripTopos[
partIdx]->radius() - middleDistanceFromBeam;
245 for (
auto*
p : stripTopos) {
254 float r0 =
h * (
B +
b) / (
B -
b);
255 float striplength =
h * 2;
258 int nstrip = static_cast<int>(
strips);
260 LogDebug(
"ME0ReDigiProducer::TemporaryGeometry")
261 <<
"New partition parameters: "
262 <<
"bottom width(" << 2 *
b <<
") top width(" << 2 *
B <<
") height(" << 2 *
h <<
") radius to center(" << r0
263 <<
") nStrips(" <<
strips <<
") pitch(" << pitch <<
")" << std::endl;
282 produces<ME0DigiPreRecoCollection>();
283 produces<ME0DigiPreRecoMap>();
288 <<
"ME0ReDigiProducer::ME0PreRecoDigiProducer() - RandomNumberGeneratorService is not present in configuration "
290 <<
"Add the service in the configuration file or remove the modules that require it.";
301 <<
"ME0ReDigiProducer::ME0PreRecoDigiProducer() - Must have at least one strip if using custom geometry.";
304 <<
"ME0ReDigiProducer::ME0PreRecoDigiProducer() - Must have at least one partition if using custom geometry.";
308 throw cms::Exception(
"Setup") <<
"ME0ReDigiProducer::ME0PreRecoDigiProducer() - neutronAcceptance must be >= 0.";
323 throw cms::Exception(
"Setup") <<
"ME0ReDigiProducer::beginRun() - No ME0Chambers in geometry.";
327 throw cms::Exception(
"Setup") <<
"ME0ReDigiProducer::beginRun() - No layers in ME0 geometry.";
329 const unsigned int nPartitions =
chambers.front()->layers()[0]->nEtaPartitions();
338 <<
"ME0ReDigiProducer::beginRun() - The geometry has " <<
nLayers <<
" layers, but the readout of "
339 <<
layerReadout.size() <<
" were specified with the layerReadout parameter.";
342 LogDebug(
"ME0ReDigiProducer") <<
"Building temporary geometry:" << std::endl;
344 LogDebug(
"ME0ReDigiProducer") <<
"Done building temporary geometry!" << std::endl;
348 <<
"ME0ReDigiProducer::beginRun() - The geometry has " <<
tempGeo->
numLayers()
349 <<
" layers, but the readout of " <<
layerReadout.size()
350 <<
" were specified with the layerReadout parameter.";
356 CLHEP::HepRandomEngine* engine = &rng->
getEngine(
e.streamID());
359 e.getByToken(
token, input_digis);
375 CLHEP::HepRandomEngine* engine) {
390 LogDebug(
"ME0ReDigiProducer::buildDigis") <<
"Begin building digis." << std::endl;
392 for (me0dgIt = input_digis.begin(); me0dgIt != input_digis.end(); ++me0dgIt) {
393 const auto& me0Id = (*me0dgIt).first;
394 LogTrace(
"ME0ReDigiProducer::buildDigis") <<
"Starting with roll: " << me0Id << std::endl;
402 LogTrace(
"ME0ReDigiProducer::buildDigis") << std::endl
403 <<
"(" << digi->x() <<
"," << digi->y() <<
"," << digi->tof() <<
","
404 << digi->pdgid() <<
"," << digi->prompt() <<
")-> ";
423 int mapPartIDX = me0Id.roll() - 1;
434 const int bxIdx = std::round(tof /
bxWidth);
435 LogTrace(
"ME0ReDigiProducer::buildDigis") << tof <<
"(" << bxIdx <<
") ";
447 LogTrace(
"ME0ReDigiProducer::buildDigis") <<
"(" << bxIdx <<
"," << mapPartIDX <<
"," <<
strip <<
") ";
449 int matchIDX =
fillDigiMap(chDigiMap, bxIdx, mapPartIDX,
strip, newDigiIdx);
463 digiLocalPoint.
x(), digiLocalPoint.
y(),
sigmaX,
sigmaY, corrCoef, tof, digi->pdgid(), digi->prompt());
464 output_digis.insertDigi(me0Id, out_digi);
470 LogTrace(
"ME0ReDigiProducer::buildDigis") <<
"(" << digiLocalPoint.
x() <<
"," << digiLocalPoint.
y() <<
","
479 const auto* mainChamber =
geometry->chambers().front();
480 const unsigned int nLayers = mainChamber->nLayers();
484 LogDebug(
"ME0ReDigiProducer::fillCentralTOFs()") <<
"TOF numbers [layer][partition]: ";
485 for (
unsigned int iL = 0; iL <
nLayers; ++iL) {
486 const auto* layer = mainChamber->layers()[iL];
487 const unsigned int mapLayIDX = layer->id().layer() - 1;
488 const unsigned int nPartitions = layer->nEtaPartitions();
490 throw cms::Exception(
"Setup") <<
"ME0ReDigiProducer::fillCentralTOFs() - ME0Layer has no partitions.";
491 tofs[mapLayIDX].resize(nPartitions);
492 for (
unsigned int iP = 0; iP < nPartitions; ++iP) {
493 const unsigned int mapPartIDX = layer->etaPartitions()[iP]->id().roll() - 1;
494 const GlobalPoint centralGP(layer->etaPartitions()[iP]->position());
495 tofs[mapLayIDX][mapPartIDX] = (centralGP.mag() / (CLHEP::c_light / CLHEP::cm));
496 LogDebug(
"ME0ReDigiProducer::fillCentralTOFs()")
497 <<
"[" << mapLayIDX <<
"][" << mapPartIDX <<
"]=" <<
tofs[mapLayIDX][mapPartIDX] <<
" " << std::endl;
519 const LocalPoint partLocalPoint(inDigi->
x(), inDigi->
y() - partCenter, 0.);
520 strip = topo->channel(partLocalPoint);
524 LocalPoint digiPartLocalPoint = topo->localPosition(stripF);
525 digiLocalError = topo->localError(
530 digiLocalPoint =
LocalPoint(digiPartLocalPoint.
x(), digiPartLocalPoint.
y() + partCenter, 0.0);
548 const LocalPoint partLocalPoint(inDigi->
x(), inDigi->
y(), 0.);
549 strip = topo.channel(partLocalPoint);
553 digiLocalPoint = topo.localPosition(stripF);
554 digiLocalError = topo.localError(stripF, 1. /
sqrt(12.));
560 auto it1 = chDigiMap.find(newIDX);
561 if (it1 == chDigiMap.end()) {
562 chDigiMap[newIDX] = currentIDX;