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  if ( CurrentTS >= digi.size() ) continue;
148  Allnoise += tool[CurrentTS];
149  noiseslices++;
150  }
151  if(noiseslices != 0) {
152  noise = (Allnoise)/double(noiseslices);
153  } else {
154  noise = 0;
155  }
156  for(unsigned int ivs = 0; ivs<mySignalTS.size(); ++ivs)
157  {
158  CurrentTS = mySignalTS[ivs];
159  if ( CurrentTS >= digi.size() ) continue;
160  int capid=digi[CurrentTS].capid();
161 // if(noise<0){
162 // // flag hit as having negative noise, and don't subtract anything, because
163 // // it will falsely increase the energy
164 // noisefactor=0.;
165 // }
166  ta = tool[CurrentTS]-noise;
167  fc_ampl+=ta;
168  ta*= calibs.respcorrgain(capid) ; // fC --> GeV
169  ampl+=ta;
170  if(ta>maxA){
171  maxA=ta;
172  maxI=CurrentTS;
173  }
174  }
175 // calculate low Gain Energy (in 2010 PbPb, signal TS 4,5,6, lowGain TS: 6,7,8)
176  for(unsigned int iLGvs = 0; iLGvs<mySignalTS.size(); ++iLGvs)
177  {
178  CurrentTS = mySignalTS[iLGvs]+lowGainOffset;
179  if ( CurrentTS >= digi.size() ) continue;
180  int capid=digi[CurrentTS].capid();
181  TempLGAmp = tool[CurrentTS]-noise;
182  lowGfc_ampl+=TempLGAmp;
183  TempLGAmp*= calibs.respcorrgain(capid) ; // fC --> GeV
184  TempLGAmp*= lowGainFrac ; // TS (signalRegion) --> TS (lowGainRegion)
185  lowGEnergy+=TempLGAmp;
186  }
187 // if(ta<0){
188 // // flag hits that have negative energy
189 // }
190 
191  double time=-9999;
192  // Time based on regular energy (lowGainEnergy signal assumed to happen at same Time)
194  if(maxI==0 || maxI==(tool.size()-1)) {
195  LogDebug("HCAL Pulse") << "ZdcSimpleRecAlgo::reco2 :"
196  << " Invalid max amplitude position, "
197  << " max Amplitude: "<< maxI
198  << " first: "<<ifirst
199  << " last: "<<(tool.size()-1)
200  << std::endl;
201  } else {
202  int capid=digi[maxI-1].capid();
203  double Energy0 = ((tool[maxI-1])*calibs.respcorrgain(capid) );
204 // if any of the energies used in the weight are negative, make them 0 instead
205 // these are actually QIE values, not energy
206  if(Energy0<0){Energy0=0.;}
207  capid=digi[maxI].capid();
208  double Energy1 = ((tool[maxI])*calibs.respcorrgain(capid) ) ;
209  if(Energy1<0){Energy1=0.;}
210  capid=digi[maxI+1].capid();
211  double Energy2 = ((tool[maxI+1])*calibs.respcorrgain(capid) );
212  if(Energy2<0){Energy2=0.;}
213 //
214  double TSWeightEnergy = ((maxI-1)*Energy0 + maxI*Energy1 + (maxI+1)*Energy2);
215  double EnergySum=Energy0+Energy1+Energy2;
216  double AvgTSPos=0.;
217  if (EnergySum!=0) AvgTSPos=TSWeightEnergy/ EnergySum;
218 // If time is zero, set it to the "nonsensical" -99
219 // Time should be between 75ns and 175ns (Timeslices 3-7)
220  if(AvgTSPos==0){
221  time=-99;
222  } else {
223  time = (AvgTSPos*25.0);
224  }
225  if (corr!=nullptr) {
226  // Apply phase-based amplitude correction:
227  ampl *= corr->getCorrection(fc_ampl);
228  }
229  }
230  return RecHit(digi.id(),ampl,time,lowGEnergy);
231  }
232 }
233 
234 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 {
235 
236  if(recoMethod_ == 1)
237  return ZdcSimpleRecAlgoImpl::reco1<ZDCDataFrame,ZDCRecHit>(digi,coder,calibs,
238  myNoiseTS,mySignalTS,lowGainOffset_,lowGainFrac_,false,
239  nullptr,
241  if(recoMethod_ == 2)
242  return ZdcSimpleRecAlgoImpl::reco2<ZDCDataFrame,ZDCRecHit>(digi,coder,calibs,
243  myNoiseTS,mySignalTS,lowGainOffset_,lowGainFrac_,false,
244  nullptr,HcalTimeSlew::Fast);
245 
246  edm::LogError("ZDCSimpleRecAlgoImpl::reconstruct, recoMethod was not declared");
247  throw cms::Exception("ZDCSimpleRecoAlgos::exiting process");
248 
249 }
#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)
void initPulseCorr(int toadd, const HcalTimeSlew *hcalTimeSlew_delay)
double getCorrection(double fc_ampl) const
std::tuple< unsigned int, int, int, DigiType, int, int, int, float > Digi
Definition: GenericDigi.h:40
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
constexpr double pedestal(int fCapId) const
get pedestal for capid=0..3
std::unique_ptr< HcalPulseContainmentCorrection > pulseCorr_
int size() const
get the size
Definition: CaloSamples.h:24
constexpr double respcorrgain(int fCapId) const
get response corrected gain for capid=0..3
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)
#define constexpr