15 #include <CLHEP/Random/RandGaussQ.h>
16 #include <CLHEP/Random/RandFlat.h>
62 if (
debug)
LogPrint(
"DTDigitizer")<<
"Creating a DTDigitizer"<<endl;
66 produces<DTDigiCollection>();
68 produces<DTDigiSimLinkCollection>();
100 theConstVDrift = conf_.
getParameter<
double>(
"IdealModelConstantDriftVelocity");
101 else theConstVDrift = 55.;
107 <<
"RandomNumberGeneratorService for DTDigitizer missing in cfg file";
111 MultipleLinks = conf_.
getParameter<
bool>(
"MultipleLinks");
114 LinksTimeWindow = conf_.
getParameter<
double>(
"LinksTimeWindow");
119 cf_token = consumes<CrossingFrame<PSimHit> >(
edm::InputTag(mix_, collection_for_XF) );
134 <<
" Event: " << iEvent.
id().
event() << endl;
145 unique_ptr<MixCollection<PSimHit> >
168 simHit != simHits->end(); simHit++){
172 DTWireId wireId( (*simHit).detUnitId() );
174 wireMap[wireId].push_back(&(*simHit));
177 pair<float,bool> time(0.,
false);
183 const vector<const PSimHit*> & vhit = (*wire).second;
194 for (vector<const PSimHit*>::const_iterator
hit=vhit.begin();
195 hit != vhit.end();
hit++){
201 time = computeTime(layer, wireId, *
hit, BLoc, engine);
205 tdCont.push_back(make_pair((*
hit),time.first));
207 if (
debug)
LogPrint(
"DTDigitizer") <<
"hit discarded" << endl;
216 storeDigis(wireId,tdCont,*output,*outputLinks);
231 CLHEP::HepRandomEngine* engine){
241 if(
debug)
LogPrint(
"DTDigitizer")<<
"Hit local entry point: "<<entryP<<endl
242 <<
"Hit local exit point: "<<exitP<<endl;
245 float xEntry = entryP.
x() - xwire;
246 float xExit = exitP.
x() - xwire;
249 <<
" x entry in cell rf: "<<xEntry
250 <<
" x exit in cell rf: "<<xExit<<endl;
255 if (
debug) dumpHit(hit, xEntry, xExit,topo);
258 pair<float,bool> driftTime(0.,
false);
265 if (
debug)
LogPrint(
"DTDigitizer") <<
" e- hit in gas; discarding " << endl;
278 float cosAlpha = hHat.
dot(pHat);
279 float sinAlpha =
sqrt(1.-cosAlpha*cosAlpha);
280 float radius_P = (d.
mag())/(2.*cosAlpha);
281 float sagitta_P = radius_P*(1.-sinAlpha);
285 float halfd = d.
mag()/2.;
286 float BMag = BLoc.
mag();
288 float radius_B = (pT.
mag()/(0.3*BMag))*100.;
290 if (radius_B > halfd) {
291 sagitta_B = radius_B -
sqrt(radius_B*radius_B - halfd*halfd);
293 sagitta_B = radius_B;
299 if (
debug)
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;
312 bool noParametrisation =
314 || (entrySide == exitSide)
322 && (noParametrisation ==
false)) {
323 if (
debug)
LogPrint(
"DTDigitizer") <<
"*** WARNING: hit is not straight, type = " << partType << endl;
328 if (!noParametrisation) {
341 if(fabs(pt.
z()) < 0.002) {
345 x = xEntry - (entryP.
z()*(xExit-xEntry))/(exitP.
z()-entryP.
z());
348 if(IdealModel)
return make_pair(fabs(x)/theConstVDrift,
true);
349 else driftTime = driftTimeFromParametrization(x, theta, By, Bz, engine);
354 if ((driftTime.second)==
false) {
356 driftTime = driftTimeFromTimeMap();
362 if (driftTime.second) {
363 driftTime.first += externalDelays(layer,wireId,hit);
371 CLHEP::HepRandomEngine* engine)
const {
379 if (
debug)
LogPrint(
"DTDigitizer") <<
"*** WARNING: parametrisation: x out of range = "
380 << x <<
", skipping" << endl;
381 return pair<float,bool>(0.f,
false);
389 float theta_par =
theta;
393 if (fabs(theta_par)>45.) {
394 if (
debug)
LogPrint(
"DTDigitizer") <<
"*** WARNING: extrapolating theta > 45: "
398 if (fabs(By_par)>0.75) {
399 if (
debug)
LogPrint(
"DTDigitizer") <<
"*** WARNING: extrapolating Bnorm > 0.75: "
403 if (fabs(Bz_par)>0.4) {
404 if (
debug)
LogPrint(
"DTDigitizer") <<
"*** WARNING: extrapolating Bwire >0.4: "
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 = "
415 << x <<
" " << theta_par <<
" " << By_par <<
" " << Bz_par << endl
420 LogPrint(
"DTDigitizer") <<
"*** WARNING: call to parametrisation failed" << endl;
421 return pair<float,bool>(0.f,
false);
429 time =
max(time,0.
f);
434 double u = CLHEP::RandGaussQ::shoot(engine, 0., smearing);
437 if (
debug)
LogPrint(
"DTDigitizer") <<
" drift time = " << time << endl;
439 return pair<float,bool>(time,
true);
443 CLHEP::HepRandomEngine* engine)
const {
445 double f = sigmaLeft/(sigmaLeft+sigmaRight);
448 if (CLHEP::RandFlat::shoot(engine) <=
f) {
449 t = CLHEP::RandGaussQ::shoot(engine, mean, sigmaLeft);
450 t = mean - fabs(t - mean);
452 t = CLHEP::RandGaussQ::shoot(engine, mean, sigmaRight);
453 t = mean + fabs(t - mean);
455 return static_cast<float>(
t);
461 return pair<float,bool>(0.,
false);
474 float propgL = halfL - wireCoord;
476 float propDelay = propgL/vPropWire;
479 float tof = hit->
tof();
483 double sync= theSync->digitizerOffset(&wireId,layer);
487 LogPrint(
"DTDigitizer") <<
" propDelay =" << propDelay
489 <<
"; sync= " << sync
493 return propDelay + tof + sync;
506 sort(hits.begin(),hits.end(),
hitLessT());
510 float wakeTime = -999999.0;
511 float resolTime = -999999.0;
516 for ( TDContainer::const_iterator
hit = hits.begin() ;
hit != hits.end() ;
519 if (onlyMuHits &&
abs((*hit).first->particleType())!=13)
continue;
523 float time = (*hit).second;
524 if ( time > wakeTime ) {
526 int wireN = wireId.
wire();
528 digi =
DTDigi(wireN, time, digiN);
531 unsigned int SimTrackId = (*hit).first->trackId();
533 DTDigiSimLink digisimLink(wireN, digiN, time, SimTrackId, evId);
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;
546 output.insertDigi(layerID, digi);
548 wakeTime = time + deadTime;
549 resolTime = time + LinksTimeWindow;
555 else if (MultipleLinks && time < resolTime){
556 int wireN = wireId.
wire();
557 unsigned int SimTrackId = (*hit).first->trackId();
559 DTDigiSimLink digisimLink(wireN, digiN, time, SimTrackId, evId);
564 LogPrint(
"DTDigitizer")<<
"\nAdded multiple link: \n"
565 <<
"digi number = "<<digi.
number()<<
", digi time = "<<digi.
time()<<
" (sim. time = "<<time<<
")"
566 <<
", linked to SimTrack Id = "<<SimTrackId<<endl;
574 float xEntry,
float xExit,
585 <<
"------- SimHit: " << endl
587 <<
" process type = " << hit->
processType() << endl
588 <<
" process type = " << hit->
processType() << endl
590 <<
" trackId = " << hit->
trackId() << endl
592 <<
" |p| = " << hit->
pabs() << endl
593 <<
" Energy loss = " << hit->
energyLoss() << endl
598 <<
" Entry point = " << entryP <<
" cell x = " << xEntry << endl
599 <<
" Exit point = " << exitP <<
" cell x = " << xExit << endl
600 <<
" DR = = " << (exitP-entryP).
mag() << endl
601 <<
" Dx = = " << (exitP-entryP).
x() << endl
604 <<
" , " << topo.
cellLenght() <<
") cm" << endl
605 <<
" DY entry from edge = " << topo.
cellLenght()/2.-fabs(entryP.
y())
606 <<
" DY exit from edge = " << topo.
cellLenght()/2.-fabs(exitP.
y())
607 <<
" entrySide = " << (
int)entrySide
608 <<
" ; 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
T getUntrackedParameter(std::string const &, T const &) 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.
OrphanHandle< PROD > put(std::unique_ptr< PROD > product)
Put a new product.
float tof() const
deprecated name for timeOfFlight()
edm::Service< edm::RandomNumberGenerator > rng
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.
T x() const
Cartesian x coordinate.
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
Vector3DBase< typename PreciseFloatType< T, U >::Type, FrameTag > cross(const Vector3DBase< U, FrameTag > &v) const
Abs< T >::type abs(const T &t)
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
uint32_t countsTDC() const
Get raw TDC count.
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.
virtual 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.
StreamID streamID() const
unsigned int trackId() const
float externalDelays(const DTLayer *layer, const DTWireId &wireId, const PSimHit *hit) const
MuonDigiCollection< DTLayerId, DTDigiSimLink > DTDigiSimLinkCollection
std::pair< float, bool > driftTimeFromTimeMap() const
Local3DPoint entryPoint() const
Entry point in the local Det frame.
std::map< DTWireId, std::vector< const PSimHit * > > DTWireIdMap
Power< A, B >::type pow(const A &a, const B &b)
float asymGausSmear(double mean, double sigmaLeft, double sigmaRight, CLHEP::HepRandomEngine *) const
T get(const Candidate &c)
EventID const & max(EventID const &lh, EventID const &rh)