15 #include <CLHEP/Random/RandFlat.h>
16 #include <CLHEP/Random/RandGaussQ.h>
56 debug = conf_.getUntrackedParameter<
bool>(
"debug");
59 LogPrint(
"DTDigitizer") <<
"Creating a DTDigitizer" << endl;
64 produces<DTDigiCollection>();
66 produces<DTDigiSimLinkCollection>();
71 onlyMuHits = conf_.getParameter<
bool>(
"onlyMuHits");
74 interpolate = conf_.getParameter<
bool>(
"interpolate");
80 vPropWire = conf_.getParameter<
double>(
"vPropWire");
83 deadTime = conf_.getParameter<
double>(
"deadTime");
86 smearing = conf_.getParameter<
double>(
"Smearing");
90 IdealModel = conf_.getParameter<
bool>(
"IdealModel");
94 if (conf_.getParameter<
bool>(
"phase2Digis"))
101 theConstVDrift = conf_.getParameter<
double>(
"IdealModelConstantDriftVelocity");
103 theConstVDrift = 55.;
108 throw cms::Exception(
"Configuration") <<
"RandomNumberGeneratorService for DTDigitizer missing in cfg file";
112 MultipleLinks = conf_.getParameter<
bool>(
"MultipleLinks");
115 LinksTimeWindow = conf_.getParameter<
double>(
"LinksTimeWindow");
118 mix_ = conf_.getParameter<
std::string>(
"mixLabel");
119 collection_for_XF = conf_.getParameter<
std::string>(
"InputCollection");
120 cf_token = consumes<CrossingFrame<PSimHit>>(
edm::InputTag(mix_, collection_for_XF));
121 magnField_token = esConsumes<MagneticField, IdealMagneticFieldRecord>();
125 geometryType = conf_.getParameter<
std::string>(
"GeometryType");
126 muonGeom_token = esConsumes<DTGeometry, MuonGeometryRecord>(
edm::ESInputTag(
"", geometryType));
135 LogPrint(
"DTDigitizer") <<
"--- Run: " << iEvent.
id().
run() <<
" Event: " << iEvent.
id().
event() << endl;
168 DTWireId wireId((*simHit).detUnitId());
170 wireMap[wireId].push_back(&(*simHit));
173 pair<float, bool> time(0.,
false);
179 const vector<const PSimHit *> &vhit = (*wire).second;
191 for (vector<const PSimHit *>::const_iterator
hit = vhit.begin();
hit != vhit.end();
hit++) {
201 tdCont.push_back(make_pair((*
hit), time.first));
204 LogPrint(
"DTDigitizer") <<
"hit discarded" << endl;
214 storeDigis(wireId, tdCont, *output, *outputLinks);
229 CLHEP::HepRandomEngine *engine) {
239 LogPrint(
"DTDigitizer") <<
"Hit local entry point: " << entryP << endl <<
"Hit local exit point: " << exitP << endl;
242 float xEntry = entryP.
x() - xwire;
243 float xExit = exitP.
x() - xwire;
246 LogPrint(
"DTDigitizer") <<
"wire position: " << xwire <<
" x entry in cell rf: " << xEntry
247 <<
" x exit in cell rf: " << xExit << endl;
253 dumpHit(hit, xEntry, xExit, topo);
256 pair<float, bool> driftTime(0.,
false);
264 LogPrint(
"DTDigitizer") <<
" e- hit in gas; discarding " << endl;
277 float cosAlpha = hHat.
dot(pHat);
278 float sinAlpha =
sqrt(1. - cosAlpha * cosAlpha);
279 float radius_P = (d.
mag()) / (2. * cosAlpha);
280 float sagitta_P = radius_P * (1. - sinAlpha);
284 float halfd = d.
mag() / 2.;
285 float BMag = BLoc.
mag();
287 float radius_B = (pT.
mag() / (0.3 * BMag)) * 100.;
289 if (radius_B > halfd) {
290 sagitta_B = radius_B -
sqrt(radius_B * radius_B - halfd * halfd);
292 sagitta_B = radius_B;
299 LogPrint(
"DTDigitizer") <<
" delta = " << delta << endl
300 <<
" cosAlpha = " << cosAlpha << endl
301 <<
" sinAlpha = " << sinAlpha << endl
302 <<
" pMag = " << pT.
mag() << endl
303 <<
" bMag = " << BMag << endl
304 <<
" pT = " << pT << endl
305 <<
" halfd = " << halfd << endl
306 <<
" radius_P (cm) = " << radius_P << endl
307 <<
" sagitta_P (um) = " << sagitta_P * 10000. << endl
308 <<
" radius_B (cm) = " << radius_B << endl
309 <<
" sagitta_B (um) = " << sagitta_B * 10000. << endl;
313 || (entrySide == exitSide)
321 && (noParametrisation ==
false)) {
323 LogPrint(
"DTDigitizer") <<
"*** WARNING: hit is not straight, type = " << partType << endl;
328 if (!noParametrisation) {
331 float theta = atan(dir.
x() / -dir.
z()) * 180 /
M_PI;
342 if (fabs(pt.
z()) < 0.002) {
346 x = xEntry - (entryP.
z() * (xExit - xEntry)) / (exitP.
z() - entryP.
z());
350 return make_pair(fabs(x) / theConstVDrift,
true);
355 if ((driftTime.second) ==
false) {
363 if (driftTime.second) {
372 float x,
float theta,
float By,
float Bz, CLHEP::HepRandomEngine *engine)
const {
380 LogPrint(
"DTDigitizer") <<
"*** WARNING: parametrisation: x out of range = " << x <<
", skipping" << endl;
381 return pair<float, bool>(0.f,
false);
389 float theta_par =
theta;
393 if (fabs(theta_par) > 45.) {
395 LogPrint(
"DTDigitizer") <<
"*** WARNING: extrapolating theta > 45: " << theta << endl;
398 if (fabs(By_par) > 0.75) {
400 LogPrint(
"DTDigitizer") <<
"*** WARNING: extrapolating Bnorm > 0.75: " << By_par << endl;
403 if (fabs(Bz_par) > 0.4) {
405 LogPrint(
"DTDigitizer") <<
"*** WARNING: extrapolating Bwire >0.4: " << Bz_par << endl;
411 unsigned short flag = par.
MB_DT_drift_time(x, theta_par, By_par, Bz_par, 0, &DT, interpolate);
414 LogPrint(
"DTDigitizer") <<
" Parametrisation: x, theta, Bnorm, Bwire = " << x <<
" " << theta_par <<
" "
415 << By_par <<
" " << Bz_par << endl
419 LogPrint(
"DTDigitizer") <<
"*** WARNING: call to parametrisation failed" << endl;
420 return pair<float, bool>(0.f,
false);
428 time =
max(time, 0.
f);
434 double u = CLHEP::RandGaussQ::shoot(engine, 0., smearing);
438 LogPrint(
"DTDigitizer") <<
" drift time = " << time << endl;
440 return pair<float, bool>(time,
true);
446 CLHEP::HepRandomEngine *engine)
const {
447 double f = sigmaLeft / (sigmaLeft + sigmaRight);
450 if (CLHEP::RandFlat::shoot(engine) <=
f) {
451 t = CLHEP::RandGaussQ::shoot(engine, mean, sigmaLeft);
452 t = mean - fabs(t - mean);
454 t = CLHEP::RandGaussQ::shoot(engine, mean, sigmaRight);
455 t = mean + fabs(t - mean);
457 return static_cast<float>(
t);
463 LogPrint(
"DTDigitizer") <<
" TimeMap " << endl;
464 return pair<float, bool>(0.,
false);
474 float propgL = halfL - wireCoord;
479 float tof = hit->
tof();
483 double sync =
theSync->digitizerOffset(&wireId, layer);
486 LogPrint(
"DTDigitizer") <<
" propDelay =" << propDelay <<
"; TOF=" << tof <<
"; sync= " << sync << endl;
489 return propDelay + tof + sync;
501 sort(hits.begin(), hits.end(),
hitLessT());
505 float wakeTime = -999999.0;
506 float resolTime = -999999.0;
511 for (TDContainer::const_iterator
hit = hits.begin();
hit != hits.end();
hit++) {
512 if (onlyMuHits &&
abs((*hit).first->particleType()) != 13)
517 float time = (*hit).second;
518 if (time > wakeTime) {
520 int wireN = wireId.
wire();
525 unsigned int SimTrackId = (*hit).first->trackId();
530 LogPrint(
"DTDigitizer") << endl <<
"---- DTDigitizer ----" << endl;
531 LogPrint(
"DTDigitizer") <<
"wireId: " << wireId << endl;
532 LogPrint(
"DTDigitizer") <<
"sim. time = " << time << endl;
533 LogPrint(
"DTDigitizer") <<
"digi number = " << digi.
number() <<
", digi time = " << digi.
time()
534 <<
", linked to SimTrack Id = " << SimTrackId << endl;
539 output.insertDigi(layerID, digi);
544 int wireN = wireId.
wire();
545 unsigned int SimTrackId = (*hit).first->trackId();
552 LogPrint(
"DTDigitizer") <<
"\nAdded multiple link: \n"
553 <<
"digi number = " << digi.
number() <<
", digi time = " << digi.
time()
554 <<
" (sim. time = " << time <<
")"
555 <<
", linked to SimTrack Id = " << SimTrackId << endl;
570 <<
"------- SimHit: " << endl
572 <<
" process type = " << hit->
processType() << endl
576 <<
" trackId = " << hit->
trackId()
579 <<
" |p| = " << hit->
pabs() << endl
588 <<
" Entry point = " << entryP <<
" cell x = " << xEntry << endl
589 <<
" Exit point = " << exitP <<
" cell x = " << xExit << endl
590 <<
" DR = = " << (exitP - entryP).
mag() << endl
591 <<
" Dx = = " << (exitP - entryP).
x() << endl
594 <<
" DY entry from edge = " << topo.
cellLenght() / 2. - fabs(entryP.
y())
595 <<
" DY exit from edge = " << topo.
cellLenght() / 2. - fabs(exitP.
y())
596 <<
" entrySide = " << (
int)entrySide <<
" ; exitSide = " << (int)exitSide << endl;
std::pair< float, bool > computeTime(const DTLayer *layer, const DTWireId &wireId, const PSimHit *hit, const LocalVector &BLoc, CLHEP::HepRandomEngine *)
GlobalPoint toGlobal(const Point2DBase< Scalar, LocalTag > lp) const
EventNumber_t event() const
void dumpHit(const PSimHit *hit, float xEntry, float xExit, const DTTopology &topo)
float wirePosition(int wireNumber) const
Returns the x position in the layer of a given wire number.
Vector3DBase< typename PreciseFloatType< T, U >::Type, FrameTag > cross(const Vector3DBase< U, FrameTag > &v) const
OrphanHandle< PROD > put(std::unique_ptr< PROD > product)
Put a new product.
float tof() const
deprecated name for timeOfFlight()
Side onWhichBorder(float x, float y, float z) const
LocalVector momentumAtEntry() const
The momentum of the track that produced the hit, at entry point.
bool getByToken(EDGetToken token, Handle< PROD > &result) const
T mag() const
The vector magnitude. Equivalent to sqrt(vec.mag2())
Geom::Theta< T > theta() const
float cellWidth() const
Returns the cell width.
PreciseFloatType< T, U >::Type dot(const Vector3DBase< U, FrameTag > &v) const
void insertDigi(const IndexType &index, const DigiType &digi)
insert a digi for a given DetUnit
virtual CLHEP::HepRandomEngine & getEngine(StreamID const &)=0
Use this engine in event methods.
const Plane & surface() const
The nominal surface of the GeomDet.
constexpr std::array< uint8_t, layerIndexSize > layer
const DTTopology & specificTopology() const
double time() const
Get time in ns.
Local3DPoint exitPoint() const
Exit point in the local Det frame.
void storeDigis(DTWireId &wireId, TDContainer &hits, DTDigiCollection &output, DTDigiSimLinkCollection &outputLinks)
edm::ESGetToken< MagneticField, IdealMagneticFieldRecord > magnField_token
Local3DPoint localPosition() const
LocalPoint toLocal(const GlobalPoint &gp) const
Abs< T >::type abs(const T &t)
edm::EDGetTokenT< CrossingFrame< PSimHit > > cf_token
DTDigitizer(const edm::ParameterSet &)
float cellHeight() const
Returns the cell height.
float pabs() const
fast and more accurate access to momentumAtEntry().mag()
DTWireIdMap::const_iterator DTWireIdMapConstIter
Log< level::Warning, true > LogPrint
std::unique_ptr< DTDigiSyncBase > theSync
LocalVector localDirection() const
Obsolete. Same as momentumAtEntry().unit(), for backward compatibility.
int wire() const
Return the wire number.
Vector3DBase unit() const
unsigned short MB_DT_drift_time(double x, double alpha, double by, double bz, short ifl, drift_time *DT, short interpolate) const
Calculate drift time and spread.
std::pair< float, bool > driftTimeFromParametrization(float x, float alpha, float By, float Bz, CLHEP::HepRandomEngine *) const
T const * product() const
T getParameter(std::string const &) const
unsigned short processType() const
std::vector< hitAndT > TDContainer
Structure used to return output values.
void produce(edm::Event &, const edm::EventSetup &) override
DTLayerId layerId() const
Return the corresponding LayerId.
float energyLoss() const
The energy deposit in the PSimHit, in ???.
MuonDigiCollection< DTLayerId, DTDigi > DTDigiCollection
int number() const
Identifies different digis within the same cell.
StreamID streamID() const
unsigned int trackId() const
float externalDelays(const DTLayer *layer, const DTWireId &wireId, const PSimHit *hit) const
ESHandle< T > getHandle(const ESGetToken< T, R > &iToken) const
MuonDigiCollection< DTLayerId, DTDigiSimLink > DTDigiSimLinkCollection
edm::ESGetToken< DTGeometry, MuonGeometryRecord > muonGeom_token
std::map< DTWireId, std::vector< const PSimHit * > > DTWireIdMap
std::pair< float, bool > driftTimeFromTimeMap() const
Local3DPoint entryPoint() const
Entry point in the local Det frame.
float asymGausSmear(double mean, double sigmaLeft, double sigmaRight, CLHEP::HepRandomEngine *) const
A container for a generic type of digis indexed by some index, implemented with a map<IndexType...