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 auto_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);
225 iEvent.
put(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;
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.
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
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
OrphanHandle< PROD > put(std::auto_ptr< PROD > product)
Put a new product.
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
virtual CLHEP::HepRandomEngine & getEngine(StreamID const &) const =0
Use this engine in event methods.
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)