15 #include <CLHEP/Random/RandFlat.h> 16 #include <CLHEP/Random/RandGaussQ.h> 62 debug = conf_.getUntrackedParameter<
bool>(
"debug");
65 LogPrint(
"DTDigitizer") <<
"Creating a DTDigitizer" << endl;
70 produces<DTDigiCollection>();
72 produces<DTDigiSimLinkCollection>();
77 onlyMuHits = conf_.getParameter<
bool>(
"onlyMuHits");
80 interpolate = conf_.getParameter<
bool>(
"interpolate");
86 vPropWire = conf_.getParameter<
double>(
"vPropWire");
89 deadTime = conf_.getParameter<
double>(
"deadTime");
92 smearing = conf_.getParameter<
double>(
"Smearing");
96 IdealModel = conf_.getParameter<
bool>(
"IdealModel");
100 if (conf_.getParameter<
bool>(
"phase2Digis"))
107 theConstVDrift = conf_.getParameter<
double>(
"IdealModelConstantDriftVelocity");
114 throw cms::Exception(
"Configuration") <<
"RandomNumberGeneratorService for DTDigitizer missing in cfg file";
139 LogPrint(
"DTDigitizer") <<
"--- Run: " << iEvent.
id().
run() <<
" Event: " << iEvent.
id().
event() << endl;
174 DTWireId wireId((*simHit).detUnitId());
176 wireMap[wireId].push_back(&(*
simHit));
179 pair<float, bool>
time(0.,
false);
185 const vector<const PSimHit *> &vhit = (*wire).second;
197 for (vector<const PSimHit *>::const_iterator
hit = vhit.begin();
hit != vhit.end();
hit++) {
207 tdCont.push_back(make_pair((*
hit), time.first));
210 LogPrint(
"DTDigitizer") <<
"hit discarded" << endl;
220 storeDigis(wireId, tdCont, *output, *outputLinks);
235 CLHEP::HepRandomEngine *engine) {
245 LogPrint(
"DTDigitizer") <<
"Hit local entry point: " << entryP << endl <<
"Hit local exit point: " << exitP << endl;
248 float xEntry = entryP.
x() - xwire;
249 float xExit = exitP.
x() - xwire;
252 LogPrint(
"DTDigitizer") <<
"wire position: " << xwire <<
" x entry in cell rf: " << xEntry
253 <<
" x exit in cell rf: " << xExit << endl;
259 dumpHit(hit, xEntry, xExit, topo);
262 pair<float, bool> driftTime(0.,
false);
270 LogPrint(
"DTDigitizer") <<
" e- hit in gas; discarding " << endl;
283 float cosAlpha = hHat.
dot(pHat);
284 float sinAlpha =
sqrt(1. - cosAlpha * cosAlpha);
285 float radius_P = (d.
mag()) / (2. * cosAlpha);
286 float sagitta_P = radius_P * (1. - sinAlpha);
290 float halfd = d.
mag() / 2.;
291 float BMag = BLoc.
mag();
293 float radius_B = (pT.
mag() / (0.3 * BMag)) * 100.;
295 if (radius_B > halfd) {
296 sagitta_B = radius_B -
sqrt(radius_B * radius_B - halfd * halfd);
298 sagitta_B = radius_B;
305 LogPrint(
"DTDigitizer") <<
" delta = " << delta << endl
306 <<
" cosAlpha = " << cosAlpha << endl
307 <<
" sinAlpha = " << sinAlpha << endl
308 <<
" pMag = " << pT.
mag() << endl
309 <<
" bMag = " << BMag << endl
310 <<
" pT = " << pT << endl
311 <<
" halfd = " << halfd << endl
312 <<
" radius_P (cm) = " << radius_P << endl
313 <<
" sagitta_P (um) = " << sagitta_P * 10000. << endl
314 <<
" radius_B (cm) = " << radius_B << endl
315 <<
" sagitta_B (um) = " << sagitta_B * 10000. << endl;
319 || (entrySide == exitSide)
327 && (noParametrisation ==
false)) {
329 LogPrint(
"DTDigitizer") <<
"*** WARNING: hit is not straight, type = " << partType << endl;
334 if (!noParametrisation) {
337 float theta = atan(dir.
x() / -dir.
z()) * 180 /
M_PI;
348 if (fabs(pt.
z()) < 0.002) {
352 x = xEntry - (entryP.
z() * (xExit - xEntry)) / (exitP.
z() - entryP.
z());
361 if ((driftTime.second) ==
false) {
369 if (driftTime.second) {
378 float x,
float theta,
float By,
float Bz, CLHEP::HepRandomEngine *engine)
const {
386 LogPrint(
"DTDigitizer") <<
"*** WARNING: parametrisation: x out of range = " << x <<
", skipping" << endl;
387 return pair<float, bool>(0.f,
false);
395 float theta_par =
theta;
399 if (fabs(theta_par) > 45.) {
401 LogPrint(
"DTDigitizer") <<
"*** WARNING: extrapolating theta > 45: " << theta << endl;
404 if (fabs(By_par) > 0.75) {
406 LogPrint(
"DTDigitizer") <<
"*** WARNING: extrapolating Bnorm > 0.75: " << By_par << endl;
409 if (fabs(Bz_par) > 0.4) {
411 LogPrint(
"DTDigitizer") <<
"*** WARNING: extrapolating Bwire >0.4: " << Bz_par << endl;
420 LogPrint(
"DTDigitizer") <<
" Parametrisation: x, theta, Bnorm, Bwire = " << x <<
" " << theta_par <<
" " 421 << By_par <<
" " << Bz_par << endl
425 LogPrint(
"DTDigitizer") <<
"*** WARNING: call to parametrisation failed" << endl;
426 return pair<float, bool>(0.f,
false);
434 time =
max(time, 0.
f);
440 double u = CLHEP::RandGaussQ::shoot(engine, 0.,
smearing);
444 LogPrint(
"DTDigitizer") <<
" drift time = " << time << endl;
446 return pair<float, bool>(
time,
true);
452 CLHEP::HepRandomEngine *engine)
const {
453 double f = sigmaLeft / (sigmaLeft + sigmaRight);
456 if (CLHEP::RandFlat::shoot(engine) <=
f) {
457 t = CLHEP::RandGaussQ::shoot(engine, mean, sigmaLeft);
458 t = mean - fabs(t - mean);
460 t = CLHEP::RandGaussQ::shoot(engine, mean, sigmaRight);
461 t = mean + fabs(t - mean);
463 return static_cast<float>(
t);
469 LogPrint(
"DTDigitizer") <<
" TimeMap " << endl;
470 return pair<float, bool>(0.,
false);
480 float propgL = halfL - wireCoord;
485 float tof = hit->
tof();
489 double sync =
theSync->digitizerOffset(&wireId, layer);
492 LogPrint(
"DTDigitizer") <<
" propDelay =" << propDelay <<
"; TOF=" << tof <<
"; sync= " << sync << endl;
495 return propDelay + tof + sync;
507 sort(hits.begin(), hits.end(),
hitLessT());
511 float wakeTime = -999999.0;
512 float resolTime = -999999.0;
517 for (TDContainer::const_iterator
hit = hits.begin();
hit != hits.end();
hit++) {
523 float time = (*hit).second;
524 if (time > wakeTime) {
526 int wireN = wireId.
wire();
531 unsigned int SimTrackId = (*hit).first->trackId();
536 LogPrint(
"DTDigitizer") << endl <<
"---- DTDigitizer ----" << endl;
537 LogPrint(
"DTDigitizer") <<
"wireId: " << wireId << endl;
538 LogPrint(
"DTDigitizer") <<
"sim. time = " << time << endl;
539 LogPrint(
"DTDigitizer") <<
"digi number = " << digi.
number() <<
", digi time = " << digi.
time()
540 <<
", linked to SimTrack Id = " << SimTrackId << endl;
545 output.insertDigi(layerID, digi);
550 int wireN = wireId.
wire();
551 unsigned int SimTrackId = (*hit).first->trackId();
558 LogPrint(
"DTDigitizer") <<
"\nAdded multiple link: \n" 559 <<
"digi number = " << digi.
number() <<
", digi time = " << digi.
time()
560 <<
" (sim. time = " << time <<
")" 561 <<
", linked to SimTrack Id = " << SimTrackId << endl;
576 <<
"------- SimHit: " << endl
578 <<
" process type = " << hit->
processType() << endl
582 <<
" trackId = " << hit->
trackId()
585 <<
" |p| = " << hit->
pabs() << endl
594 <<
" Entry point = " << entryP <<
" cell x = " << xEntry << endl
595 <<
" Exit point = " << exitP <<
" cell x = " << xExit << endl
596 <<
" DR = = " << (exitP - entryP).
mag() << endl
597 <<
" Dx = = " << (exitP - entryP).
x() << endl
600 <<
" DY entry from edge = " << topo.
cellLenght() / 2. - fabs(entryP.
y())
601 <<
" DY exit from edge = " << topo.
cellLenght() / 2. - fabs(exitP.
y())
602 <<
" 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
T getParameter(std::string const &) 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.
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)
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
virtual GlobalVector inTesla(const GlobalPoint &gp) const =0
Field value ad specified global point, in Tesla.
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
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
const DTLayer * layer(const DTLayerId &id) const
Return a layer given its id.
MuonDigiCollection< DTLayerId, DTDigiSimLink > DTDigiSimLinkCollection
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
std::string collection_for_XF
A container for a generic type of digis indexed by some index, implemented with a map<IndexType...