CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
HcalTDC.cc
Go to the documentation of this file.
5 
6 HcalTDC::HcalTDC(unsigned int thresholdDAC) : theTDCParameters(),
7  theDbService(0),
8  theDAC(thresholdDAC),
9  lsb(3.74),
10  theRandGaussQ(0) {}
11 
13  if (theRandGaussQ) delete theRandGaussQ;
14 }
15 
16 void HcalTDC::timing(const CaloSamples& lf, HcalUpgradeDataFrame& digi) const {
17 
18  float const TDC_Threshold(getThreshold(digi.id()));
19  float const TDC_Threshold_hyst(TDC_Threshold);
20  bool risingReady(true), fallingReady(false);
21  int tdcBins = theTDCParameters.nbins();
22  // start with a loop over 10 samples
23  bool hasTDCValues=true;
24  if (lf.preciseSize()==0 ) hasTDCValues=false;
25 
26  // "AC" hysteresis from Tom: There cannot be a second transition
27  // within the QIE within 3ns
28  int const rising_ac_hysteresis(5);
29  int lastRisingEdge(0);
30 
31  // if (hasTDCValues)
32  // std::cout << digi.id()
33  // << " threshold: " << TDC_Threshold
34  // << '\n';
35  for (int ibin = 0; ibin < lf.size(); ++ibin) {
36  /*
37  If in a given 25ns bunch/time sample, the pulse is above
38  TDC_Thresh already, then TDC_RisingEdge=0 if it was low in the
39  last precision bin on the previous bunch crossing, otherwise,
40  TDC_RisingEdge=63 if the pulse never crosses the threshold
41  having started off, then the special code is 62 and then
42  one can still have a TDC_FallingEdge that is valid. If the pulse
43  never falls below threshold having started above threshold (or
44  goes above threshold in the bunch crossing and doesn't come down),
45  then TDC_FallingEdge=. If the pulse never went above
46  threshold, then TDC_RisingEdge=63 and
47  TDC_FallingEdge=62.
48  */
49  // special codes
50  int TDC_RisingEdge = (risingReady) ?
53  int TDC_FallingEdge = (fallingReady) ?
56  int preciseBegin = ibin * tdcBins;
57  int preciseEnd = preciseBegin + tdcBins;
58  if ( hasTDCValues) {
59  // std::cout << " alreadyOn: " << alreadyOn << '\n';
60  for(int i = preciseBegin; i < preciseEnd; ++i) {
61  // std::cout << " preciseBin: " << i
62  // << " preciseAt(i): " << lf.preciseAt(i);
63  if( (fallingReady) && (i%3 == 0) && (lf.preciseAt(i) < TDC_Threshold)) {
64  fallingReady = false;
65  TDC_FallingEdge = i-preciseBegin;
66  // std::cout << " falling ";
67  }
68  if ((risingReady) && (lf.preciseAt(i) > TDC_Threshold)) {
69  risingReady = false;
70  TDC_RisingEdge = i-preciseBegin;
71  lastRisingEdge = 0;
72  // std::cout << " rising ";
73  }
74  // std::cout << '\n';
75 
76  //This is the place for hysteresis code. Need to to arm the
77  //tdc by setting the risingReady or fallingReady to true.
78 
79  if ((!fallingReady) && (lf.preciseAt(i) > TDC_Threshold)) {
80  fallingReady = true;
81  if (TDC_FallingEdge == theTDCParameters.alreadyTransitionCode())
82  TDC_FallingEdge = theTDCParameters.noTransitionCode();
83  }
84  if ((!risingReady) && (lastRisingEdge > rising_ac_hysteresis) &&
85  (lf.preciseAt(i) < TDC_Threshold_hyst)) {
86  risingReady = true;
87  if (TDC_RisingEdge == theTDCParameters.alreadyTransitionCode())
88  TDC_RisingEdge = theTDCParameters.noTransitionCode();
89  }
90  ++lastRisingEdge;
91  }
92  }
93  // change packing to allow for special codes
94  int packedTDC = TDC_RisingEdge + (tdcBins*2) * TDC_FallingEdge;
95  digi.setSample(ibin, digi.adc(ibin), packedTDC, true);
96  // if ( hasTDCValues) {
97  // std::cout << " sample: " << ibin
98  // << " adc: " << digi.adc(ibin)
99  // << " fC: " << digi[ibin].nominal_fC()
100  // << " risingEdge: " << TDC_RisingEdge
101  // << " fallingEdge: " << TDC_FallingEdge
102  // << " packedTDC: " << packedTDC
103  // << std::endl;
104  // }
105  } // loop over bunch crossing bins
106 }
107 
108 double HcalTDC::getThreshold(const HcalGenericDetId & detId) const {
109  // subtract off pedestal and noise once
110  double pedestal = theDbService->getHcalCalibrations(detId).pedestal(0);
111  double pedestalWidth = theDbService->getHcalCalibrationWidths(detId).pedestal(0);
112  // here the TDCthreshold_ is a multiple of the least significant bit
113  // for the TDC portion of the QIE. The nominal reference is 40 uA which is
114  // divided by an 8 bit DAC. This means the least significant bit is 0.135 uA
115  // in the TDC circuit or 3.74 uA at the input current.
116 
117  // the pedestal is assumed to be evenly distributed in time with some
118  // random variation.
119 
120  return lsb*theDAC - theRandGaussQ->shoot(pedestal, pedestalWidth)/theTDCParameters.deltaT()/theTDCParameters.nbins();
121 }
122 
123 double HcalTDC::getHysteresisThreshold(double nominal) const {
124  // the TDC will "re-arm" when it crosses the threshold minus 2.5 mV.
125  // the lsb is 44kOhm * (3.74 uA / 24) = 6.86 mV. 2.5 mV is 0.36 lsb.
126  // with the this means that the hysteresis it isn't far from the nominal
127  // threshold
128 
129  return nominal - 0.365*lsb;
130 }
131 
132 void HcalTDC::setRandomEngine(CLHEP::HepRandomEngine & engine) {
133  theRandGaussQ = new CLHEP::RandGaussQ(engine);
134 }
135 
136 void HcalTDC::setDbService(const HcalDbService * service) {
137  theDbService = service;
138 }
double getThreshold(const HcalGenericDetId &detId) const
Definition: HcalTDC.cc:108
int i
Definition: DBlmapReader.cc:9
float deltaT() const
void setRandomEngine(CLHEP::HepRandomEngine &engine)
Definition: HcalTDC.cc:132
unsigned int theDAC
Definition: HcalTDC.h:35
const HcalDbService * theDbService
Definition: HcalTDC.h:33
double pedestal(int fCapId) const
get pedestal for capid=0..3
int preciseSize() const
get the size
Definition: CaloSamples.h:62
float preciseAt(int i) const
const function to access precise samples
Definition: CaloSamples.h:33
double getHysteresisThreshold(double nominal) const
Definition: HcalTDC.cc:123
double pedestal(int fCapId) const
get pedestal width for capid=0..3
CLHEP::RandGaussQ * theRandGaussQ
Definition: HcalTDC.h:39
int noTransitionCode() const
int alreadyTransitionCode() const
const HcalCalibrationWidths & getHcalCalibrationWidths(const HcalGenericDetId &fId) const
void timing(const CaloSamples &lf, HcalUpgradeDataFrame &digi) const
adds timing information to the digi
Definition: HcalTDC.cc:16
void setSample(int iSample, uint16_t adc, uint16_t tdc, bool dv)
int size() const
get the size
Definition: CaloSamples.h:24
const HcalDetId & id() const
double const lsb
Definition: HcalTDC.h:37
~HcalTDC()
Definition: HcalTDC.cc:12
uint16_t adc(int iSample=0) const
const HcalCalibrations & getHcalCalibrations(const HcalGenericDetId &fId) const
HcalTDC(unsigned int thresholdDAC=12)
Definition: HcalTDC.cc:6
void setDbService(const HcalDbService *service)
the Producer will probably update this every event
Definition: HcalTDC.cc:136
HcalTDCParameters theTDCParameters
Definition: HcalTDC.h:32