CMS 3D CMS Logo

ZdcSimpleRecAlgo.cc
Go to the documentation of this file.
4 #include <algorithm> // for "max"
5 #include <iostream>
6 #include <cmath>
7 
8 
9 
10 constexpr double MaximumFractionalError = 0.0005; // 0.05% error allowed from this source
11 
12 ZdcSimpleRecAlgo::ZdcSimpleRecAlgo(bool correctForTimeslew, bool correctForPulse, float phaseNS, int recoMethod, int lowGainOffset, double lowGainFrac) :
13  recoMethod_(recoMethod),
14  correctForTimeslew_(correctForTimeslew),
15  correctForPulse_(correctForPulse),
16  phaseNS_(phaseNS),
17  lowGainOffset_(lowGainOffset),
18  lowGainFrac_(lowGainFrac)
19  {
20 }
21 
23  recoMethod_(recoMethod),
25 }
26 
27 void ZdcSimpleRecAlgo::initPulseCorr(int toadd, const HcalTimeSlew* hcalTimeSlew_delay) {
28  if (correctForPulse_) {
29  pulseCorr_ = std::make_unique<HcalPulseContainmentCorrection>(toadd,phaseNS_,MaximumFractionalError, hcalTimeSlew_delay);
30  }
31 }
32 //static float timeshift_ns_zdc(float wpksamp);
33 
35  template<class Digi, class RecHit>
36  inline RecHit reco1(const Digi& digi, const HcalCoder& coder, const HcalCalibrations& calibs,
37  const std::vector<unsigned int>& myNoiseTS, const std::vector<unsigned int>& mySignalTS, int lowGainOffset, double lowGainFrac, bool slewCorrect, const HcalPulseContainmentCorrection* corr, HcalTimeSlew::BiasSetting slewFlavor) {
38  CaloSamples tool;
39  coder.adc2fC(digi,tool);
40  int ifirst = mySignalTS[0];
41  int n = mySignalTS.size();
42  double ampl=0; int maxI = -1; double maxA = -1e10; double ta=0;
43  double fc_ampl=0;
44  double lowGEnergy=0; double lowGfc_ampl=0; double TempLGAmp=0;
45 // TS increment for regular energy to lowGainEnergy
46 // Signal in higher TS (effective "low Gain") has a fraction of the whole signal
47 // This constant for fC --> GeV is dervied from 2010 PbPb analysis of single neutrons
48 // assumed similar fraction for EM and HAD sections
49 // this variable converts from current assumed TestBeam values for fC--> GeV
50 // to the lowGain TS region fraction value (based on 1N Had, assume EM same response)
51 // regular energy
52  for (int i=ifirst; i<tool.size() && i<n+ifirst; i++) {
53  int capid=digi[i].capid();
54  ta = (tool[i]-calibs.pedestal(capid)); // pedestal subtraction
55  fc_ampl+=ta;
56  ta*= calibs.respcorrgain(capid) ; // fC --> GeV
57  ampl+=ta;
58  if(ta>maxA){
59  maxA=ta;
60  maxI=i;
61  }
62  }
63 // calculate low Gain Energy (in 2010 PbPb, signal TS 4,5,6, lowGain TS: 6,7,8)
64  int topLowGain=10;
65  if((n+ifirst+lowGainOffset)<=10){
66  topLowGain=n+ifirst+lowGainOffset;
67  } else {
68  topLowGain=10;
69  }
70  for (int iLG=(ifirst+lowGainOffset); iLG<tool.size() && iLG<topLowGain; iLG++) {
71  int capid=digi[iLG].capid();
72  TempLGAmp = (tool[iLG]-calibs.pedestal(capid)); // pedestal subtraction
73  lowGfc_ampl+=TempLGAmp;
74  TempLGAmp*= calibs.respcorrgain(capid) ; // fC --> GeV
75  TempLGAmp*= lowGainFrac ; // TS (signalRegion) --> TS (lowGainRegion)
76  lowGEnergy+=TempLGAmp;
77  }
78  double time=-9999;
79  // Time based on regular energy (lowGainEnergy signal assumed to happen at same Time)
81  if(maxI==0 || maxI==(tool.size()-1)) {
82  LogDebug("HCAL Pulse") << "ZdcSimpleRecAlgo::reco1 :"
83  << " Invalid max amplitude position, "
84  << " max Amplitude: "<< maxI
85  << " first: "<<ifirst
86  << " last: "<<(tool.size()-1)
87  << std::endl;
88  } else {
89  int capid=digi[maxI-1].capid();
90  double Energy0 = ((tool[maxI-1])*calibs.respcorrgain(capid) );
91 // if any of the energies used in the weight are negative, make them 0 instead
92 // these are actually QIE values, not energy
93  if(Energy0<0){Energy0=0.;}
94  capid=digi[maxI].capid();
95  double Energy1 = ((tool[maxI])*calibs.respcorrgain(capid) ) ;
96  if(Energy1<0){Energy1=0.;}
97  capid=digi[maxI+1].capid();
98  double Energy2 = ((tool[maxI+1])*calibs.respcorrgain(capid) );
99  if(Energy2<0){Energy2=0.;}
100 //
101  double TSWeightEnergy = ((maxI-1)*Energy0 + maxI*Energy1 + (maxI+1)*Energy2);
102  double EnergySum=Energy0+Energy1+Energy2;
103  double AvgTSPos=0.;
104  if (EnergySum!=0) AvgTSPos=TSWeightEnergy/ EnergySum;
105 // If time is zero, set it to the "nonsensical" -99
106 // Time should be between 75ns and 175ns (Timeslices 3-7)
107  if(AvgTSPos==0){
108  time=-99;
109  } else {
110  time = (AvgTSPos*25.0);
111  }
112  if (corr!=nullptr) {
113  // Apply phase-based amplitude correction:
114  ampl *= corr->getCorrection(fc_ampl);
115  }
116  }
117  return RecHit(digi.id(),ampl,time,lowGEnergy);
118  }
119 }
120 
121 namespace ZdcSimpleRecAlgoImpl {
122  template<class Digi, class RecHit>
123  inline RecHit reco2(const Digi& digi, const HcalCoder& coder, const HcalCalibrations& calibs,
124  const std::vector<unsigned int>& myNoiseTS, const std::vector<unsigned int>& mySignalTS, int lowGainOffset, double lowGainFrac, bool slewCorrect, const HcalPulseContainmentCorrection* corr, HcalTimeSlew::BiasSetting slewFlavor) {
125  CaloSamples tool;
126  coder.adc2fC(digi,tool);
127  // Reads noiseTS and signalTS from database
128  int ifirst = mySignalTS[0];
129 // int n = mySignalTS.size();
130  double ampl=0; int maxI = -1; double maxA = -1e10; double ta=0;
131  double fc_ampl=0;
132  double lowGEnergy=0; double lowGfc_ampl=0; double TempLGAmp=0;
133 // TS increment for regular energy to lowGainEnergy
134 // Signal in higher TS (effective "low Gain") has a fraction of the whole signal
135 // This constant for fC --> GeV is dervied from 2010 PbPb analysis of single neutrons
136 // assumed similar fraction for EM and HAD sections
137 // this variable converts from current assumed TestBeam values for fC--> GeV
138 // to the lowGain TS region fraction value (based on 1N Had, assume EM same response)
139  double Allnoise = 0;
140  int noiseslices = 0;
141  int CurrentTS = 0;
142  double noise = 0;
143 // regular energy (both use same noise)
144  for(unsigned int iv = 0; iv<myNoiseTS.size(); ++iv)
145  {
146  CurrentTS = myNoiseTS[iv];
147  Allnoise += tool[CurrentTS];
148  noiseslices++;
149  }
150  if(noiseslices != 0) {
151  noise = (Allnoise)/double(noiseslices);
152  } else {
153  noise = 0;
154  }
155  for(unsigned int ivs = 0; ivs<mySignalTS.size(); ++ivs)
156  {
157  CurrentTS = mySignalTS[ivs];
158  int capid=digi[CurrentTS].capid();
159 // if(noise<0){
160 // // flag hit as having negative noise, and don't subtract anything, because
161 // // it will falsely increase the energy
162 // noisefactor=0.;
163 // }
164  ta = tool[CurrentTS]-noise;
165  fc_ampl+=ta;
166  ta*= calibs.respcorrgain(capid) ; // fC --> GeV
167  ampl+=ta;
168  if(ta>maxA){
169  maxA=ta;
170  maxI=CurrentTS;
171  }
172  }
173 // calculate low Gain Energy (in 2010 PbPb, signal TS 4,5,6, lowGain TS: 6,7,8)
174  for(unsigned int iLGvs = 0; iLGvs<mySignalTS.size(); ++iLGvs)
175  {
176  CurrentTS = mySignalTS[iLGvs]+lowGainOffset;
177  int capid=digi[CurrentTS].capid();
178  TempLGAmp = tool[CurrentTS]-noise;
179  lowGfc_ampl+=TempLGAmp;
180  TempLGAmp*= calibs.respcorrgain(capid) ; // fC --> GeV
181  TempLGAmp*= lowGainFrac ; // TS (signalRegion) --> TS (lowGainRegion)
182  lowGEnergy+=TempLGAmp;
183  }
184 // if(ta<0){
185 // // flag hits that have negative energy
186 // }
187 
188  double time=-9999;
189  // Time based on regular energy (lowGainEnergy signal assumed to happen at same Time)
191  if(maxI==0 || maxI==(tool.size()-1)) {
192  LogDebug("HCAL Pulse") << "ZdcSimpleRecAlgo::reco2 :"
193  << " Invalid max amplitude position, "
194  << " max Amplitude: "<< maxI
195  << " first: "<<ifirst
196  << " last: "<<(tool.size()-1)
197  << std::endl;
198  } else {
199  int capid=digi[maxI-1].capid();
200  double Energy0 = ((tool[maxI-1])*calibs.respcorrgain(capid) );
201 // if any of the energies used in the weight are negative, make them 0 instead
202 // these are actually QIE values, not energy
203  if(Energy0<0){Energy0=0.;}
204  capid=digi[maxI].capid();
205  double Energy1 = ((tool[maxI])*calibs.respcorrgain(capid) ) ;
206  if(Energy1<0){Energy1=0.;}
207  capid=digi[maxI+1].capid();
208  double Energy2 = ((tool[maxI+1])*calibs.respcorrgain(capid) );
209  if(Energy2<0){Energy2=0.;}
210 //
211  double TSWeightEnergy = ((maxI-1)*Energy0 + maxI*Energy1 + (maxI+1)*Energy2);
212  double EnergySum=Energy0+Energy1+Energy2;
213  double AvgTSPos=0.;
214  if (EnergySum!=0) AvgTSPos=TSWeightEnergy/ EnergySum;
215 // If time is zero, set it to the "nonsensical" -99
216 // Time should be between 75ns and 175ns (Timeslices 3-7)
217  if(AvgTSPos==0){
218  time=-99;
219  } else {
220  time = (AvgTSPos*25.0);
221  }
222  if (corr!=nullptr) {
223  // Apply phase-based amplitude correction:
224  ampl *= corr->getCorrection(fc_ampl);
225  }
226  }
227  return RecHit(digi.id(),ampl,time,lowGEnergy);
228  }
229 }
230 
231 ZDCRecHit ZdcSimpleRecAlgo::reconstruct(const ZDCDataFrame& digi, const std::vector<unsigned int>& myNoiseTS, const std::vector<unsigned int>& mySignalTS, const HcalCoder& coder, const HcalCalibrations& calibs) const {
232 
233  if(recoMethod_ == 1)
234  return ZdcSimpleRecAlgoImpl::reco1<ZDCDataFrame,ZDCRecHit>(digi,coder,calibs,
235  myNoiseTS,mySignalTS,lowGainOffset_,lowGainFrac_,false,
236  nullptr,
238  if(recoMethod_ == 2)
239  return ZdcSimpleRecAlgoImpl::reco2<ZDCDataFrame,ZDCRecHit>(digi,coder,calibs,
240  myNoiseTS,mySignalTS,lowGainOffset_,lowGainFrac_,false,
241  nullptr,HcalTimeSlew::Fast);
242 
243  edm::LogError("ZDCSimpleRecAlgoImpl::reconstruct, recoMethod was not declared");
244  throw cms::Exception("ZDCSimpleRecoAlgos::exiting process");
245 
246 }
#define LogDebug(id)
RecHit reco1(const Digi &digi, const HcalCoder &coder, const HcalCalibrations &calibs, const std::vector< unsigned int > &myNoiseTS, const std::vector< unsigned int > &mySignalTS, int lowGainOffset, double lowGainFrac, bool slewCorrect, const HcalPulseContainmentCorrection *corr, HcalTimeSlew::BiasSetting slewFlavor)
double respcorrgain(int fCapId) const
get response corrected gain for capid=0..3
void initPulseCorr(int toadd, const HcalTimeSlew *hcalTimeSlew_delay)
double getCorrection(double fc_ampl) const
double pedestal(int fCapId) const
get pedestal for capid=0..3
std::tuple< unsigned int, int, int, DigiType, int, int, int, float > Digi
Definition: GenericDigi.h:30
#define constexpr
ZDCRecHit reconstruct(const ZDCDataFrame &digi, const std::vector< unsigned int > &myNoiseTS, const std::vector< unsigned int > &mySignalTS, const HcalCoder &coder, const HcalCalibrations &calibs) const
ZdcSimpleRecAlgo(bool correctForTimeslew, bool correctForContainment, float fixedPhaseNs, int recoMethod, int lowGainOffset, double lowGainFrac)
double MaximumFractionalError
JetCorrectorParameters corr
Definition: classes.h:5
virtual void adc2fC(const HBHEDataFrame &df, CaloSamples &lf) const =0
std::unique_ptr< HcalPulseContainmentCorrection > pulseCorr_
int size() const
get the size
Definition: CaloSamples.h:24
RecHit reco2(const Digi &digi, const HcalCoder &coder, const HcalCalibrations &calibs, const std::vector< unsigned int > &myNoiseTS, const std::vector< unsigned int > &mySignalTS, int lowGainOffset, double lowGainFrac, bool slewCorrect, const HcalPulseContainmentCorrection *corr, HcalTimeSlew::BiasSetting slewFlavor)