14 #include <CLHEP/Random/RandGaussQ.h>
15 #include <CLHEP/Random/RandFlat.h>
66 if (
debug)
cout<<
"Creating a DTDigitizer"<<endl;
70 produces<DTDigiCollection>();
72 produces<DTDigiSimLinkCollection>();
104 theConstVDrift = conf_.
getParameter<
double>(
"IdealModelConstantDriftVelocity");
105 else theConstVDrift = 55.;
111 <<
"RandomNumberGeneratorService for DTDigitizer missing in cfg file";
113 theGaussianDistribution =
new CLHEP::RandGaussQ(rng->
getEngine());
114 theFlatDistribution =
new CLHEP::RandFlat(rng->
getEngine(), 0, 1);
117 MultipleLinks = conf_.
getParameter<
bool>(
"MultipleLinks");
120 LinksTimeWindow = conf_.
getParameter<
double>(
"LinksTimeWindow");
132 delete theGaussianDistribution;
133 delete theFlatDistribution;
140 <<
" Event: " << iEvent.
id().
event() << endl;
149 iEvent.
getByLabel(mix_,collection_for_XF,xFrame);
151 auto_ptr<MixCollection<PSimHit> >
174 simHit != simHits->end(); simHit++){
178 DTWireId wireId( (*simHit).detUnitId() );
180 wireMap[wireId].push_back(&(*simHit));
183 pair<float,bool>
time(0.,
false);
189 const vector<const PSimHit*> & vhit = (*wire).second;
200 for (vector<const PSimHit*>::const_iterator
hit=vhit.begin();
201 hit != vhit.end();
hit++){
207 time = computeTime(layer, wireId, *
hit, BLoc);
211 tdCont.push_back(make_pair((*
hit),time.first));
213 if (
debug)
cout <<
"hit discarded" << endl;
222 storeDigis(wireId,tdCont,*output,*outputLinks);
231 iEvent.
put(outputLinks);
246 if(
debug)
cout<<
"Hit local entry point: "<<entryP<<endl
247 <<
"Hit local exit point: "<<exitP<<endl;
250 float xEntry = entryP.
x() - xwire;
251 float xExit = exitP.
x() - xwire;
254 <<
" x entry in cell rf: "<<xEntry
255 <<
" x exit in cell rf: "<<xExit<<endl;
260 if (
debug) dumpHit(hit, xEntry, xExit,topo);
263 pair<float,bool> driftTime(0.,
false);
270 if (
debug)
cout <<
" 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;
304 if (
debug)
cout <<
" delta = " << delta << endl
305 <<
" cosAlpha = " << cosAlpha << endl
306 <<
" sinAlpha = " << sinAlpha << endl
307 <<
" pMag = " << pT.
mag() << endl
308 <<
" bMag = " << BMag << endl
309 <<
" pT = " << pT << endl
310 <<
" halfd = " << halfd << endl
311 <<
" radius_P (cm) = " << radius_P << endl
312 <<
" sagitta_P (um) = " << sagitta_P*10000. << endl
313 <<
" radius_B (cm) = " << radius_B << endl
314 <<
" sagitta_B (um) = " << sagitta_B*10000. << endl;
317 bool noParametrisation =
319 || (entrySide == exitSide)
327 && (noParametrisation ==
false)) {
328 if (
debug)
cout <<
"*** WARNING: hit is not straight, type = " << partType << endl;
333 if (!noParametrisation) {
346 if(fabs(pt.
z()) < 0.002) {
350 x = xEntry - (entryP.
z()*(xExit-xEntry))/(exitP.
z()-entryP.
z());
353 if(IdealModel)
return make_pair(fabs(x)/theConstVDrift,
true);
354 else driftTime = driftTimeFromParametrization(x, theta, By, Bz);
359 if ((driftTime.second)==
false) {
361 driftTime = driftTimeFromTimeMap();
367 if (driftTime.second) {
368 driftTime.first += externalDelays(layer,wireId,hit);
383 if (
debug)
cout <<
"*** WARNING: parametrisation: x out of range = "
384 << x <<
", skipping" << endl;
385 return pair<float,bool>(0.f,
false);
393 float theta_par =
theta;
397 if (fabs(theta_par)>45.) {
398 if (
debug)
cout <<
"*** WARNING: extrapolating theta > 45: "
402 if (fabs(By_par)>0.75) {
403 if (
debug)
cout <<
"*** WARNING: extrapolating Bnorm > 0.75: "
407 if (fabs(Bz_par)>0.4) {
408 if (
debug)
cout <<
"*** WARNING: extrapolating Bwire >0.4: "
415 unsigned short flag = par.
MB_DT_drift_time (x, theta_par, By_par, Bz_par, 0, &DT, interpolate);
418 cout <<
" Parametrisation: x, theta, Bnorm, Bwire = "
419 << x <<
" " << theta_par <<
" " << By_par <<
" " << Bz_par << endl
424 cout <<
"*** WARNING: call to parametrisation failed" << endl;
425 return pair<float,bool>(0.f,
false);
433 time =
max(time,0.
f);
438 double u = theGaussianDistribution->fire(0.,smearing);
441 if (
debug)
cout <<
" drift time = " << time << endl;
443 return pair<float,bool>(
time,
true);
448 double f = sigmaLeft/(sigmaLeft+sigmaRight);
451 if (theFlatDistribution->fire() <=
f) {
452 t = theGaussianDistribution->fire(mean,sigmaLeft);
453 t = mean - fabs(t - mean);
455 t = theGaussianDistribution->fire(mean,sigmaRight);
456 t = mean + fabs(t - mean);
458 return static_cast<float>(
t);
464 return pair<float,bool>(0.,
false);
477 float propgL = halfL - wireCoord;
479 float propDelay = propgL/vPropWire;
482 float tof = hit->
tof();
486 double sync= theSync->digitizerOffset(&wireId,layer);
490 cout <<
" propDelay =" << propDelay
492 <<
"; sync= " << sync
496 return propDelay + tof + sync;
513 float wakeTime = -999999.0;
514 float resolTime = -999999.0;
519 for ( TDContainer::const_iterator
hit = hits.begin() ;
hit != hits.end() ;
522 if (onlyMuHits &&
abs((*hit).first->particleType())!=13)
continue;
526 float time = (*hit).second;
527 if ( time > wakeTime ) {
529 int wireN = wireId.
wire();
531 digi =
DTDigi(wireN, time, digiN);
534 unsigned int SimTrackId = (*hit).first->trackId();
536 DTDigiSimLink digisimLink(wireN, digiN, time, SimTrackId, evId);
539 cout<<endl<<
"---- DTDigitizer ----"<<endl;
540 cout<<
"wireId: "<<wireId<<endl;
541 cout<<
"sim. time = "<<time<<endl;
542 cout<<
"digi number = "<< digi.
number()<<
", digi time = "<<digi.
time()
543 <<
", linked to SimTrack Id = "<<SimTrackId<<endl;
549 output.insertDigi(layerID, digi);
551 wakeTime = time + deadTime;
552 resolTime = time + LinksTimeWindow;
558 else if (MultipleLinks && time < resolTime){
559 int wireN = wireId.
wire();
560 unsigned int SimTrackId = (*hit).first->trackId();
562 DTDigiSimLink digisimLink(wireN, digiN, time, SimTrackId, evId);
567 cout<<
"\nAdded multiple link: \n"
568 <<
"digi number = "<<digi.
number()<<
", digi time = "<<digi.
time()<<
" (sim. time = "<<time<<
")"
569 <<
", linked to SimTrack Id = "<<SimTrackId<<endl;
577 float xEntry,
float xExit,
588 <<
"------- SimHit: " << endl
590 <<
" process type = " << hit->
processType() << endl
591 <<
" process type = " << hit->
processType() << endl
593 <<
" trackId = " << hit->
trackId() << endl
595 <<
" |p| = " << hit->
pabs() << endl
596 <<
" Energy loss = " << hit->
energyLoss() << endl
601 <<
" Entry point = " << entryP <<
" cell x = " << xEntry << endl
602 <<
" Exit point = " << exitP <<
" cell x = " << xExit << endl
603 <<
" DR = = " << (exitP-entryP).
mag() << endl
604 <<
" Dx = = " << (exitP-entryP).
x() << endl
607 <<
" , " << topo.
cellLenght() <<
") cm" << endl
608 <<
" DY entry from edge = " << topo.
cellLenght()/2.-fabs(entryP.
y())
609 <<
" DY exit from edge = " << topo.
cellLenght()/2.-fabs(exitP.
y())
610 <<
" entrySide = " << (
int)entrySide
611 <<
" ; 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
Abs< T >::type abs(const T &t)
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)