Diana Software
MOptimumFilter.cc
Go to the documentation of this file.
1 #include "MOptimumFilter.hh"
2 #include "QEvent.hh"
3 #include "QEventList.hh"
4 #include "QRawEvent.hh"
5 #include "QBaseModule.hh"
6 #include "QSampleInfo.hh"
7 #include "QRunDataHandle.hh"
8 #include "QBaseType.hh"
9 #include "QBaselineData.hh"
10 #include "QAveragePulseHandle.hh"
11 #include "QAverageNoiseHandle.hh"
12 #include "QCOFParametersHandle.hh"
13 #include "QOptimumFilter.hh"
14 
16 
17  using namespace Diana;
18 
20 {
21  fAvgNoiseInput = GetString("AvgNoiseInput","");
22  fAvgPulseInput= GetString("AvgPulseInput","");
23  fAvgPulseOwner = GetString("AvgPulseOwner","AveragePulses",false);
24  fAvgNoiseOwner = GetString("AvgNoiseOwner","NoiseAvgPowerSpectrum",false);
25 
26  std::string searchMode = GetString("AmplitudeMode","AbsoluteMaximum");
27  if(searchMode == "AbsoluteMaximum") fJitterMode = QOptimumFilter::J_ABSMAX;
28  else if(searchMode == "NoSearch") fJitterMode = QOptimumFilter::J_NOJITTER;
29  else if(searchMode == "LocalMaximum") fJitterMode = QOptimumFilter::J_LOCMAX;
30  else if(searchMode == "FixedDistance") fJitterMode = QOptimumFilter::J_FIXED;
31  else Panic("AmplitudeMode %s not available",searchMode.c_str());
32 
33  fInterpolationOn = GetBool("InterpolationOn",true,true);
34 
35  double defaultChi2Threshold1 = 0.1;
36  fChi2Threshold1 = GetDouble("Chi2Threshold1",defaultChi2Threshold1,false);
37  if(fChi2Threshold1 < 0 || fChi2Threshold1 > 1) {
38  Error("Chi2Threshold1 value %f must be between 0 and 1, resetting to default %f",fChi2Threshold1, defaultChi2Threshold1);
39  fChi2Threshold1 = defaultChi2Threshold1;
40  }
41 
42 
43  fMaxJitter = GetInt("MaxJitter",-1,false);
44  fParametersOutput = GetString("ParametersOutput","",false);
45  fDifferentiationOn = GetBool("DifferentiationOn",true);
46  fTomV = GetBool("ConvertTomV",true,false);
47 
48  ev.Add<QDouble>("Amplitude");
49  ev.Add<QDouble>("Integral");
50  ev.Add<QDouble>("ChiSquare");
51  ev.Add<QDouble>("HighSNRChiSquare");
52  ev.Add<QDouble>("Jitter");
53  ev.Add<QDouble>("ChiLeft");
54  ev.Add<QDouble>("ChiRight");
55 
56  fSaveSamples = GetBool("SaveSamples",false,false);
57  fShiftFilteredSamples = GetBool("ShiftFilteredSamples",true,false);
58 
59  ev.Add<QVector>("FilteredSamples").SetWrite(fSaveSamples);
60  fPulseLabel = GetString("PulseLabel","DAQ@Pulse",false);
61  ev.RequireByLabel<QPulse>(fPulseLabel);
62  ev.Require<QPulseInfo>("DAQ","PulseInfo");
63  ev.Require<QHeader>("DAQ","Header");
64 
65 }
66 
67 //void MOptimumFilter::Do(QEvent& ev, const QEventList& neighbours)
69 {
70  const QPulseInfo& pulseInfo = ev.Get<QPulseInfo>("DAQ","PulseInfo");
71  const QHeader& header = ev.Get<QHeader>("DAQ","Header");
72  const int chan = pulseInfo.GetChannelId();
73 
74  QRunDataHandle rHandle(header.GetRun());
75  GlobalData().Get("",&rHandle,"");
76 
77  const QRunData& runData = rHandle.Get();
78  const QChannelRunData& channelRunData = runData.GetChannelRunData(chan);
79  double samplingFreq = channelRunData.fSamplingFrequency;
80  double ADC2mV = 1;
81  if(fTomV) ADC2mV = channelRunData.fADC2mV;
82 
83  if(fMap.find(chan) == fMap.end()) {
84 
85  GlobalHandle<QInt> dHandle("Dataset");
86  GlobalData().Get("",&dHandle,"");
87 
88  fMap[chan].BlackSheep = false;
89 
90  QAverageNoiseHandle AVG_Noise_Handle(chan);
91  AVG_Noise_Handle.SetDataset(dHandle.Get());
92  GlobalData().Get(fAvgNoiseOwner,&AVG_Noise_Handle,fAvgNoiseInput);
93  // try with an of run
94  if(!AVG_Noise_Handle.IsValid()) {
95  AVG_Noise_Handle.SetRun(header.GetRun());
96  AVG_Noise_Handle.SetDataset(Q_INT_DEFAULT);
97  GlobalData().Get(fAvgNoiseOwner,&AVG_Noise_Handle,fAvgNoiseInput);
98  }
99  if(!AVG_Noise_Handle.IsValid()) {
100  Warn("%s. Channel %d will not be processed",AVG_Noise_Handle.GetError().GetDescription().c_str(),chan);
101  fMap[chan].BlackSheep = true;
102  }
103  QAveragePulseHandle AVG_Pulse_Handle(chan);
104  AVG_Pulse_Handle.SetDataset(dHandle.Get());
105  GlobalData().Get(fAvgPulseOwner,&AVG_Pulse_Handle,fAvgPulseInput);
106 
107  if(!AVG_Pulse_Handle.IsValid()) {
108  AVG_Pulse_Handle.SetRun(header.GetRun());
109  AVG_Pulse_Handle.SetDataset(Q_INT_DEFAULT);
110  GlobalData().Get(fAvgPulseOwner,&AVG_Pulse_Handle,fAvgPulseInput);
111  }
112 
113  if(!fMap[chan].BlackSheep && !AVG_Pulse_Handle.IsValid()) {
114  Warn("%s. Channel %d will not be processed",AVG_Pulse_Handle.GetError().GetDescription().c_str(),chan);
115  fMap[chan].BlackSheep = true;
116  }
117  if(!fMap[chan].BlackSheep) {
118 
119  fMap[chan].ADC2Time = 1000./samplingFreq; //ms
120 
121  const QVector& avg_noise = AVG_Noise_Handle.Get();
122  const QVector& avg_pulse = AVG_Pulse_Handle.Get();
123 
124  fMap[chan].of = new QOptimumFilter(avg_pulse, avg_noise,fMaxJitter , fDifferentiationOn,false );
125  Info("Channel %d: Maximum Jitter = +/- %d [samples], Cutoff = %.0f [Hz]",chan, fMap[chan].of->GetMaxJitter(), fMap[chan].of->GetCutOffFrequency()*samplingFreq);
126 
127  QCOFData cofData;
128  cofData.fResolutionmV = fMap[chan].of->GetFilteredNoiseRMS()*ADC2mV;
129 
130  QCOFParametersHandle cofhandle;
131  cofhandle.SetChannel(chan);
132  cofhandle.SetDataset(dHandle.Get());
133  cofhandle.Set(cofData);
134 
135  // if fStoreParametersInDB is true call COFhandle
136  if (!fParametersOutput.empty()) {
137  cofhandle.SetAPLabel(AVG_Pulse_Handle.GetLabel());
138  cofhandle.SetAPVersion(AVG_Pulse_Handle.GetVersion());
139  if(AVG_Pulse_Handle.GetDataset()!=Q_INT_DEFAULT){
140  cofhandle.SetAPValidityKind("data_set");
141  }
142  else {
143  cofhandle.SetAPValidityKind("run");
144  }
145  cofhandle.SetNPSLabel(AVG_Noise_Handle.GetLabel());
146  cofhandle.SetNPSVersion(AVG_Noise_Handle.GetVersion());
147  if(AVG_Noise_Handle.GetDataset()!=Q_INT_DEFAULT){
148  cofhandle.SetNPSValidityKind("data_set");
149  }
150  else {
151  cofhandle.SetNPSValidityKind("run");
152  }
153  }
154  GlobalData().Set(&cofhandle,fParametersOutput);
155 
156  }
157  }
158 
159  ChannelInfo& chanInfo = fMap[chan];
160  if (chanInfo.BlackSheep) return;
161 
162  const QPulse& rawPulse = ev.GetByLabel<QPulse>(fPulseLabel);
163  const QVector& Samples = rawPulse.GetSamples();
164  QError err = chanInfo.of->Filter(Samples);
165  if(err!=QERR_SUCCESS) {
166  Debug("Event number %d %s",header.GetEventNumber(),err.GetDescription().c_str());
167  return;
168  }
169 
170  if(pulseInfo.GetIsNoise()) {
172  } else if(fJitterMode == QOptimumFilter::J_LOCMAX) {
174  } else {
175  err = chanInfo.of->SetJitter(fJitterMode);
176 
177  }
178  if(err!=QERR_SUCCESS) {
179  Debug("Event number %d %s",header.GetEventNumber(),err.GetDescription().c_str());
180  return;
181  }
182  if(fShiftFilteredSamples)
183  ev.Get<QVector>("FilteredSamples") = chanInfo.of->GetFilteredShifted();
184  else
185  ev.Get<QVector>("FilteredSamples") = chanInfo.of->GetFiltered();
186 
187  double a1, chi2, integral, jitter,chileft,chiright;
188  if(!fInterpolationOn || pulseInfo.GetIsNoise()) {
189  err = chanInfo.of->Get(jitter,chi2, a1, integral,chileft,chiright);
190  } else {
191  err = chanInfo.of->GetInterpolated(jitter,chi2, a1,integral,chileft,chiright);
192  }
193  if(err!=QERR_SUCCESS) {
194  Debug("Event number %d %s",header.GetEventNumber(),err.GetDescription().c_str());
195  return;
196  }
197 
198 
199  ev.Get<QDouble>("Amplitude") = a1*ADC2mV;
200  ev.Get<QDouble>("Integral") = integral*ADC2mV/samplingFreq;
201 
202  ev.Get<QDouble>("ChiSquare") = chi2;
203  ev.Get<QDouble>("Jitter") = jitter*fMap[chan].ADC2Time;
204 
205 
206  ev.Get<QDouble>("ChiLeft") = chileft;
207  ev.Get<QDouble>("ChiRight") = chiright;
208 
209  double highSNRChi21 = Q_DOUBLE_DEFAULT;
210  err = chanInfo.of->GetHighSNRChi2(fChi2Threshold1,highSNRChi21);
211  if(err != QERR_SUCCESS) {
212  Debug("Event number %d %s",header.GetEventNumber(),err.GetDescription().c_str());
213  return;
214  }
215  ev.Get<QDouble>("HighSNRChiSquare") = highSNRChi21;
216 
217 
218 
219 
220  return;
221 }
222 
223 
225 {
226  /* This method is called at the end of the event loop.
227  * Here you can:
228  *
229  * 1) Operate on the sequence execution parameters(see QBaseModule.hh).
230  *
231  * 2) Read/Write global data.
232  */
233 }
234 
QOptimumFilter of(ap, an,-1, false)
err
Definition: CheckOF.C:114
QRunDataHandle rHandle(753)
#define Q_DOUBLE_DEFAULT
Definition: QDiana.hh:24
#define Q_INT_DEFAULT
Definition: QDiana.hh:26
#define REGISTER_MODULE(clazz)
Definition: QDriver.hh:133
@ QERR_SUCCESS
Definition: QError.hh:27
Optimum Filter.
void Init(Diana::QEvent &ev)
Init method.
void Done()
Done method.
void Do(Diana::QEvent &ev)
Do method. Declare and implement only one of the two versions.
global handle for average noise power spectra
global handle for average pulse
base types wrapped into a QObject. Currently implemented types are QInt QDouble and QFloat....
Definition: QBaseType.hh:17
general quantities about COF
Definition: QCOFData.hh:15
double fResolutionmV
Definition: QCOFData.hh:24
void SetAPLabel(const std::string &apl)
void SetAPVersion(const std::string &apv)
void SetNPSLabel(const std::string &npsl)
void SetAPValidityKind(const std::string &apvk)
void SetNPSVersion(const std::string &npsv)
void SetNPSValidityKind(const std::string &npsvk)
basic channel and run based info. Used in the QRunData object.
double fSamplingFrequency
sampling frequency in Hz
double fADC2mV
conversion: mV = ADC * fADC2mV
error class with error type and description
Definition: QError.hh:115
diana event
Definition: QEvent.hh:46
const Q & GetByLabel(const QEventLabel &label) const
Get a QObject in read mode by label.
Definition: QEvent.hh:135
void RequireByLabel(const QEventLabel &label) const
notify the QEvent that we need a QObject, if not found an exception is thrown
Definition: QEvent.hh:242
void Require(const std::string &owner, const std::string &name) const
notify the QEvent that we need a QObject, if not found an exception is thrown
Definition: QEvent.hh:232
void Get(const char *owner, ReadHandle< Q > &handle) const
Get a QObject Handle in read mode.
Definition: QEvent.hh:74
void Add(WriteHandle< Q > &handle)
Add a QObject to the event.
Definition: QEvent.hh:193
Raw event: basic information like run number and time.
Definition: QHeader.hh:16
Optimum filter implemented with windowing and zeros.
QError GetInterpolated(double &jitter, double &chi2, double &amplitude, double &integral, double &left, double &right) const
get values at interpolated chi^2 minimum. Three points around the minimum are used for a parabolic in...
QError GetHighSNRChi2(const double &threshold, double &chi2) const
get chi^2 (mean 0, variance 1) restricting the DoF to frequencies with SNR > threshold
Diana::QVector GetFilteredShifted() const
get filtered and shifted samples by fMaxPos
QError SetJitter(JitterMode mode, int start=0)
int GetMaxJitter() const
QError Get(double &jitter, double &chi2, double &amplitude, double &integral, double &left, double &right) const
const Diana::QVector & GetFiltered() const
get filtered samples
QError Filter(const Diana::QVector &p)
filter. In case of failure an error is returned.
Raw event: bolometer channel, trigger positions and types.
Definition: QPulseInfo.hh:18
const QSampleInfo & GetMasterSample() const
Get MasterSample.
Definition: QPulseInfo.hh:26
bool GetIsNoise() const
Get IsNoise.
Definition: QPulseInfo.hh:54
const int & GetChannelId() const
Get ChannelId.
Definition: QPulseInfo.hh:22
Raw event: sampled waveform.
Definition: QPulse.hh:22
const Diana::QVector & GetSamples() const
Get Samples casted to double (QVector instead of QVectorI). Use this method in place of GetSamplesADC...
Definition: QPulse.cc:49
global handle for QRunData
Basic run based info.
Definition: QRunData.hh:20
const QChannelRunData & GetChannelRunData(const int channel) const
get channel based run data quantities
Definition: QRunData.cc:339
Int_t GetSampleIndex() const
Get SampleIndex from the beginning of the waveform.
Definition: QSampleInfo.hh:51
the Diana namespace is needed because sometimes we use Qt libraries, that use same class names of our...