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");
125 collection_for_XF = conf_.
getParameter<std::string>(
"InputCollection");
128 geometryType = conf_.
getParameter<std::string>(
"GeometryType");
133 delete theGaussianDistribution;
134 delete theFlatDistribution;
141 <<
" Event: " << iEvent.
id().
event() << endl;
150 iEvent.
getByLabel(
"mix",collection_for_XF,xFrame);
152 auto_ptr<MixCollection<PSimHit> >
175 simHit != simHits->end(); simHit++){
179 DTWireId wireId( (*simHit).detUnitId() );
181 wireMap[wireId].push_back(&(*simHit));
184 pair<float,bool>
time(0.,
false);
190 const vector<const PSimHit*> & vhit = (*wire).second;
201 for (vector<const PSimHit*>::const_iterator
hit=vhit.begin();
202 hit != vhit.end();
hit++){
208 time = computeTime(layer, wireId, *
hit, BLoc);
212 tdCont.push_back(make_pair((*
hit),time.first));
214 if (
debug)
cout <<
"hit discarded" << endl;
223 storeDigis(wireId,tdCont,*output,*outputLinks);
232 iEvent.
put(outputLinks);
247 if(
debug)
cout<<
"Hit local entry point: "<<entryP<<endl
248 <<
"Hit local exit point: "<<exitP<<endl;
251 float xEntry = entryP.
x() - xwire;
252 float xExit = exitP.
x() - xwire;
255 <<
" x entry in cell rf: "<<xEntry
256 <<
" x exit in cell rf: "<<xExit<<endl;
261 if (
debug) dumpHit(hit, xEntry, xExit,topo);
264 pair<float,bool> driftTime(0.,
false);
271 if (
debug)
cout <<
" e- hit in gas; discarding " << endl;
284 float cosAlpha = hHat.
dot(pHat);
285 float sinAlpha =
sqrt(1.-cosAlpha*cosAlpha);
286 float radius_P = (d.
mag())/(2.*cosAlpha);
287 float sagitta_P = radius_P*(1.-sinAlpha);
291 float halfd = d.
mag()/2.;
292 float BMag = BLoc.
mag();
294 float radius_B = (pT.
mag()/(0.3*BMag))*100.;
296 if (radius_B > halfd) {
297 sagitta_B = radius_B -
sqrt(radius_B*radius_B - halfd*halfd);
299 sagitta_B = radius_B;
305 if (
debug)
cout <<
" 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;
318 bool noParametrisation =
320 || (entrySide == exitSide)
328 && (noParametrisation ==
false)) {
329 if (
debug)
cout <<
"*** WARNING: hit is not straight, type = " << partType << endl;
334 if (!noParametrisation) {
347 if(fabs(pt.
z()) < 0.002) {
351 x = xEntry - (entryP.
z()*(xExit-xEntry))/(exitP.
z()-entryP.
z());
354 if(IdealModel)
return make_pair(fabs(x)/theConstVDrift,
true);
355 else driftTime = driftTimeFromParametrization(x, theta, By, Bz);
360 if ((driftTime.second)==
false) {
362 driftTime = driftTimeFromTimeMap();
368 if (driftTime.second) {
369 driftTime.first += externalDelays(layer,wireId,hit);
384 if (
debug)
cout <<
"*** WARNING: parametrisation: x out of range = "
385 << x <<
", skipping" << endl;
386 return pair<float,bool>(0.f,
false);
394 float theta_par =
theta;
398 if (fabs(theta_par)>45.) {
399 if (
debug)
cout <<
"*** WARNING: extrapolating theta > 45: "
403 if (fabs(By_par)>0.75) {
404 if (
debug)
cout <<
"*** WARNING: extrapolating Bnorm > 0.75: "
408 if (fabs(Bz_par)>0.4) {
409 if (
debug)
cout <<
"*** WARNING: extrapolating Bwire >0.4: "
419 cout <<
" Parametrisation: x, theta, Bnorm, Bwire = "
420 << x <<
" " << theta_par <<
" " << By_par <<
" " << Bz_par << endl
425 cout <<
"*** WARNING: call to parametrisation failed" << endl;
426 return pair<float,bool>(0.f,
false);
434 time =
max(time,0.
f);
439 double u = theGaussianDistribution->fire(0.,smearing);
442 if (
debug)
cout <<
" drift time = " << time << endl;
444 return pair<float,bool>(
time,
true);
449 double f = sigmaLeft/(sigmaLeft+sigmaRight);
452 if (theFlatDistribution->fire() <=
f) {
453 t = theGaussianDistribution->fire(mean,sigmaLeft);
454 t = mean - fabs(t - mean);
456 t = theGaussianDistribution->fire(mean,sigmaRight);
457 t = mean + fabs(t - mean);
459 return static_cast<float>(
t);
465 return pair<float,bool>(0.,
false);
478 float propgL = halfL - wireCoord;
480 float propDelay = propgL/vPropWire;
483 float tof = hit->
tof();
487 double sync= theSync->digitizerOffset(&wireId,layer);
491 cout <<
" propDelay =" << propDelay
493 <<
"; sync= " << sync
497 return propDelay + tof + sync;
514 float wakeTime = -999999.0;
515 float resolTime = -999999.0;
520 for ( TDContainer::const_iterator
hit = hits.begin() ;
hit != hits.end() ;
523 if (onlyMuHits &&
abs((*hit).first->particleType())!=13)
continue;
527 float time = (*hit).second;
528 if ( time > wakeTime ) {
530 int wireN = wireId.
wire();
532 digi =
DTDigi(wireN, time, digiN);
535 unsigned int SimTrackId = (*hit).first->trackId();
537 DTDigiSimLink digisimLink(wireN, digiN, time, SimTrackId, evId);
540 cout<<endl<<
"---- DTDigitizer ----"<<endl;
541 cout<<
"wireId: "<<wireId<<endl;
542 cout<<
"sim. time = "<<time<<endl;
543 cout<<
"digi number = "<< digi.
number()<<
", digi time = "<<digi.
time()
544 <<
", linked to SimTrack Id = "<<SimTrackId<<endl;
550 output.insertDigi(layerID, digi);
552 wakeTime = time + deadTime;
553 resolTime = time + LinksTimeWindow;
559 else if (MultipleLinks && time < resolTime){
560 int wireN = wireId.
wire();
561 unsigned int SimTrackId = (*hit).first->trackId();
563 DTDigiSimLink digisimLink(wireN, digiN, time, SimTrackId, evId);
568 cout<<
"\nAdded multiple link: \n"
569 <<
"digi number = "<<digi.
number()<<
", digi time = "<<digi.
time()<<
" (sim. time = "<<time<<
")"
570 <<
", linked to SimTrack Id = "<<SimTrackId<<endl;
578 float xEntry,
float xExit,
589 <<
"------- SimHit: " << endl
591 <<
" process type = " << hit->
processType() << endl
592 <<
" process type = " << hit->
processType() << endl
594 <<
" trackId = " << hit->
trackId() << endl
596 <<
" |p| = " << hit->
pabs() << endl
597 <<
" Energy loss = " << hit->
energyLoss() << endl
602 <<
" Entry point = " << entryP <<
" cell x = " << xEntry << endl
603 <<
" Exit point = " << exitP <<
" cell x = " << xExit << endl
604 <<
" DR = = " << (exitP-entryP).
mag() << endl
605 <<
" Dx = = " << (exitP-entryP).
x() << endl
608 <<
" , " << topo.
cellLenght() <<
") cm" << endl
609 <<
" DY entry from edge = " << topo.
cellLenght()/2.-fabs(entryP.
y())
610 <<
" DY exit from edge = " << topo.
cellLenght()/2.-fabs(exitP.
y())
611 <<
" entrySide = " << (
int)entrySide
612 <<
" ; 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
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 ???.
const BoundPlane & surface() const
The nominal surface of the GeomDet.
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...