16 #include <CLHEP/Random/RandGaussQ.h>
17 #include <CLHEP/Random/RandFlat.h>
68 if (
debug)
cout<<
"Creating a DTDigitizer"<<endl;
72 produces<DTDigiCollection>();
74 produces<DTDigiSimLinkCollection>();
106 theConstVDrift = conf_.
getParameter<
double>(
"IdealModelConstantDriftVelocity");
107 else theConstVDrift = 55.;
113 <<
"RandomNumberGeneratorService for DTDigitizer missing in cfg file";
115 theGaussianDistribution =
new CLHEP::RandGaussQ(rng->
getEngine());
116 theFlatDistribution =
new CLHEP::RandFlat(rng->
getEngine(), 0, 1);
119 MultipleLinks = conf_.
getParameter<
bool>(
"MultipleLinks");
122 LinksTimeWindow = conf_.
getParameter<
double>(
"LinksTimeWindow");
134 delete theGaussianDistribution;
135 delete theFlatDistribution;
142 <<
" Event: " << iEvent.
id().
event() << endl;
151 iEvent.
getByLabel(mix_,collection_for_XF,xFrame);
153 auto_ptr<MixCollection<PSimHit> >
176 simHit != simHits->end(); simHit++){
180 DTWireId wireId( (*simHit).detUnitId() );
182 wireMap[wireId].push_back(&(*simHit));
185 pair<float,bool>
time(0.,
false);
191 const vector<const PSimHit*> & vhit = (*wire).second;
202 for (vector<const PSimHit*>::const_iterator
hit=vhit.begin();
203 hit != vhit.end();
hit++){
209 time = computeTime(layer, wireId, *
hit, BLoc);
213 tdCont.push_back(make_pair((*
hit),time.first));
215 if (
debug)
cout <<
"hit discarded" << endl;
224 storeDigis(wireId,tdCont,*output,*outputLinks);
233 iEvent.
put(outputLinks);
248 if(
debug)
cout<<
"Hit local entry point: "<<entryP<<endl
249 <<
"Hit local exit point: "<<exitP<<endl;
252 float xEntry = entryP.
x() - xwire;
253 float xExit = exitP.
x() - xwire;
256 <<
" x entry in cell rf: "<<xEntry
257 <<
" x exit in cell rf: "<<xExit<<endl;
262 if (
debug) dumpHit(hit, xEntry, xExit,topo);
265 pair<float,bool> driftTime(0.,
false);
272 if (
debug)
cout <<
" e- hit in gas; discarding " << endl;
285 float cosAlpha = hHat.
dot(pHat);
286 float sinAlpha =
sqrt(1.-cosAlpha*cosAlpha);
287 float radius_P = (d.
mag())/(2.*cosAlpha);
288 float sagitta_P = radius_P*(1.-sinAlpha);
292 float halfd = d.
mag()/2.;
293 float BMag = BLoc.
mag();
295 float radius_B = (pT.
mag()/(0.3*BMag))*100.;
297 if (radius_B > halfd) {
298 sagitta_B = radius_B -
sqrt(radius_B*radius_B - halfd*halfd);
300 sagitta_B = radius_B;
306 if (
debug)
cout <<
" delta = " << delta << endl
307 <<
" cosAlpha = " << cosAlpha << endl
308 <<
" sinAlpha = " << sinAlpha << endl
309 <<
" pMag = " << pT.
mag() << endl
310 <<
" bMag = " << BMag << endl
311 <<
" pT = " << pT << endl
312 <<
" halfd = " << halfd << endl
313 <<
" radius_P (cm) = " << radius_P << endl
314 <<
" sagitta_P (um) = " << sagitta_P*10000. << endl
315 <<
" radius_B (cm) = " << radius_B << endl
316 <<
" sagitta_B (um) = " << sagitta_B*10000. << endl;
319 bool noParametrisation =
321 || (entrySide == exitSide)
329 && (noParametrisation ==
false)) {
330 if (
debug)
cout <<
"*** WARNING: hit is not straight, type = " << partType << endl;
335 if (!noParametrisation) {
348 if(fabs(pt.
z()) < 0.002) {
352 x = xEntry - (entryP.
z()*(xExit-xEntry))/(exitP.
z()-entryP.
z());
355 if(IdealModel)
return make_pair(fabs(x)/theConstVDrift,
true);
356 else driftTime = driftTimeFromParametrization(x, theta, By, Bz);
361 if ((driftTime.second)==
false) {
363 driftTime = driftTimeFromTimeMap();
369 if (driftTime.second) {
370 driftTime.first += externalDelays(layer,wireId,hit);
385 if (
debug)
cout <<
"*** WARNING: parametrisation: x out of range = "
386 << x <<
", skipping" << endl;
387 return pair<float,bool>(0.f,
false);
395 float theta_par =
theta;
399 if (fabs(theta_par)>45.) {
400 if (
debug)
cout <<
"*** WARNING: extrapolating theta > 45: "
404 if (fabs(By_par)>0.75) {
405 if (
debug)
cout <<
"*** WARNING: extrapolating Bnorm > 0.75: "
409 if (fabs(Bz_par)>0.4) {
410 if (
debug)
cout <<
"*** WARNING: extrapolating Bwire >0.4: "
420 cout <<
" Parametrisation: x, theta, Bnorm, Bwire = "
421 << x <<
" " << theta_par <<
" " << By_par <<
" " << Bz_par << endl
426 cout <<
"*** WARNING: call to parametrisation failed" << endl;
427 return pair<float,bool>(0.f,
false);
435 time =
max(time,0.
f);
440 double u = theGaussianDistribution->fire(0.,smearing);
443 if (
debug)
cout <<
" drift time = " << time << endl;
445 return pair<float,bool>(
time,
true);
450 double f = sigmaLeft/(sigmaLeft+sigmaRight);
453 if (theFlatDistribution->fire() <=
f) {
454 t = theGaussianDistribution->fire(mean,sigmaLeft);
455 t = mean - fabs(t - mean);
457 t = theGaussianDistribution->fire(mean,sigmaRight);
458 t = mean + fabs(t - mean);
460 return static_cast<float>(
t);
466 return pair<float,bool>(0.,
false);
479 float propgL = halfL - wireCoord;
481 float propDelay = propgL/vPropWire;
484 float tof = hit->
tof();
488 double sync= theSync->digitizerOffset(&wireId,layer);
492 cout <<
" propDelay =" << propDelay
494 <<
"; sync= " << sync
498 return propDelay + tof + sync;
515 float wakeTime = -999999.0;
516 float resolTime = -999999.0;
521 for ( TDContainer::const_iterator
hit = hits.begin() ;
hit != hits.end() ;
524 if (onlyMuHits &&
abs((*hit).first->particleType())!=13)
continue;
528 float time = (*hit).second;
529 if ( time > wakeTime ) {
531 int wireN = wireId.
wire();
533 digi =
DTDigi(wireN, time, digiN);
536 unsigned int SimTrackId = (*hit).first->trackId();
538 DTDigiSimLink digisimLink(wireN, digiN, time, SimTrackId, evId);
541 cout<<endl<<
"---- DTDigitizer ----"<<endl;
542 cout<<
"wireId: "<<wireId<<endl;
543 cout<<
"sim. time = "<<time<<endl;
544 cout<<
"digi number = "<< digi.
number()<<
", digi time = "<<digi.
time()
545 <<
", linked to SimTrack Id = "<<SimTrackId<<endl;
551 output.insertDigi(layerID, digi);
553 wakeTime = time + deadTime;
554 resolTime = time + LinksTimeWindow;
560 else if (MultipleLinks && time < resolTime){
561 int wireN = wireId.
wire();
562 unsigned int SimTrackId = (*hit).first->trackId();
564 DTDigiSimLink digisimLink(wireN, digiN, time, SimTrackId, evId);
569 cout<<
"\nAdded multiple link: \n"
570 <<
"digi number = "<<digi.
number()<<
", digi time = "<<digi.
time()<<
" (sim. time = "<<time<<
")"
571 <<
", linked to SimTrack Id = "<<SimTrackId<<endl;
579 float xEntry,
float xExit,
590 <<
"------- SimHit: " << endl
592 <<
" process type = " << hit->
processType() << endl
593 <<
" process type = " << hit->
processType() << endl
595 <<
" trackId = " << hit->
trackId() << endl
597 <<
" |p| = " << hit->
pabs() << endl
598 <<
" Energy loss = " << hit->
energyLoss() << endl
603 <<
" Entry point = " << entryP <<
" cell x = " << xEntry << endl
604 <<
" Exit point = " << exitP <<
" cell x = " << xExit << endl
605 <<
" DR = = " << (exitP-entryP).
mag() << endl
606 <<
" Dx = = " << (exitP-entryP).
x() << endl
609 <<
" , " << topo.
cellLenght() <<
") cm" << endl
610 <<
" DY entry from edge = " << topo.
cellLenght()/2.-fabs(entryP.
y())
611 <<
" DY exit from edge = " << topo.
cellLenght()/2.-fabs(exitP.
y())
612 <<
" entrySide = " << (
int)entrySide
613 <<
" ; exitSide = " << (int)exitSide << endl;
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.
std::pair< float, bool > computeTime(const DTLayer *layer, const DTWireId &wireId, const PSimHit *hit, const LocalVector &BLoc)
float tof() const
deprecated name for timeOfFlight()
float asymGausSmear(double mean, double sigmaLeft, double sigmaRight) const
Side onWhichBorder(float x, float y, float z) const
LocalVector momentumAtEntry() const
The momentum of the track that produced the hit, at entry point.
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.
std::pair< float, bool > driftTimeFromParametrization(float x, float alpha, float By, float Bz) const
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
DTDigitizer(const edm::ParameterSet &)
virtual CLHEP::HepRandomEngine & getEngine() const =0
Use this to get the random number engine, this is the only function most users should call...
float cellHeight() const
Returns the cell height.
float pabs() const
fast and more accurate access to momentumAtEntry().mag()
DTWireIdMap::const_iterator DTWireIdMapConstIter
bool getByLabel(InputTag const &tag, Handle< PROD > &result) const
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.
T const * product() const
unsigned short processType() const
std::vector< hitAndT > TDContainer
Structure used to return output values.
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.
unsigned int trackId() const
float externalDelays(const DTLayer *layer, const DTWireId &wireId, const PSimHit *hit) const
virtual void produce(edm::Event &, const edm::EventSetup &)
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)
T get(const Candidate &c)
EventID const & max(EventID const &lh, EventID const &rh)
A container for a generic type of digis indexed by some index, implemented with a map<IndexType...