Diana Software
MDecorrelator.cc
Go to the documentation of this file.
1 #include "MDecorrelator.hh"
2 #include "QEvent.hh"
3 #include "QEventList.hh"
4 #include "QPulse.hh"
5 #include "QVectorView.hh"
6 #include "QPulseInfo.hh"
7 #include "QRealComplexFFT.hh"
8 #include "QCountPulsesData.hh"
9 #include "QBaselineData.hh"
10 #include "QBool.hh"
11 #include "QBaseType.hh"
12 #include "QStdVector.hh"
13 #include "QHeader.hh"
15 #include "QAveragePulseHandle.hh"
16 #include "QRunDataHandle.hh"
17 #include <algorithm>
18 
19 using namespace Diana;
20 using namespace std;
21 
22 
24 
25 
26 void MDecorrelator::Init(QEvent& ev)
27 {
28  ev.Add<QPulse>("Pulse").SetWrite(GetBool("SaveSamples",true));
29  ev.Add<QBool>("Decorrelated");
30  ev.Require<QPulseInfo>("DAQ","PulseInfo");
31  ev.Require<QHeader>("DAQ","Header");
32  ev.Require<QPulse>("DAQ","Pulse");
33  fFirstCall = true;
34  fUseOF = GetBool("UseOF",false);
35  if(fUseOF) {
36  ev.Add<QDouble>("OFAmplitude");
37  ev.Add<QDouble>("OFMaximumPosition");
38  }
39 }
40 
41 void MDecorrelator::Do(QEvent& ev, const QEventList& neighbours)
42 {
43  const QPulseInfo& pi = ev.Get<QPulseInfo>("DAQ","PulseInfo");
44  const int channel = pi.GetChannelId();
45  const int run = ev.Get<QHeader>("DAQ","Header").GetRun();
46  if(fFirstCall) {
47  std::string corrInput = GetString("CovarianceInput",Q_STRING_DEFAULT);
48 
49  GlobalHandle<QInt> dataset("Dataset");
50  GlobalData().Get("",&dataset,"");
51  GlobalHandle<QChannelCovariance> CovGetter("Covariance");
52  CovGetter.SetDataset(dataset.Get());
53  GlobalData().Get("NoiseCrossPowerSpectrum",&CovGetter,corrInput);
54  if(!CovGetter.IsValid()) {
55  CovGetter.SetDataset(Q_INT_DEFAULT);
56  CovGetter.SetRun(run);
57  GlobalData().Get("NoiseCrossPowerSpectrum",&CovGetter,corrInput);
58  }
59 
60  fCovariance = CovGetter.Get();
61  fFirstCall = false;
62  }
63 
64 
65  if(fDecorrelators.find(channel) == fDecorrelators.end()) {
66  QMultiChannelDecorrelator* newdeco = 0;
67  bool pDeco=false,pOF=false,pOFMultiDim=false;
68  if(fUseOF) {
69  pOF = true;
70  std::string apInput = GetString("AveragePulseInput",Q_STRING_DEFAULT);
71  std::string apOwner = GetString("AveragePulseOwner","AveragePulses",false);
72  std::string relativesInput = GetString("RelativeChannelsInput","",false);
73  std::vector<QVector> averagePulses;
74  std::vector<int> relatives;
75 
76  GlobalHandle<QStdVector<int> > relativesHandle("RelativeChannels");
77  relativesHandle.SetChannel(channel);
78  GlobalData().Get("User",&relativesHandle,relativesInput);
79  if(relativesHandle.IsValid() && !relativesHandle.Get().empty()) {
80  relatives = relativesHandle.Get();
81  }
82  if(!relatives.empty()) {
83  pOF = false;
84  pOFMultiDim = true;
85  }
86  relatives.insert(relatives.begin(),channel);
87  for(size_t i =0; i < relatives.size(); i++) {
88  const int rchan = relatives[i];
89  QVector ap;
90  if(apOwner == "Old") {
91  GlobalHandle<QVector> apHandle("Average");
92  apHandle.SetChannel(rchan);
93  GlobalData().Get(apOwner,&apHandle,apInput);
94  ap = apHandle.Get();
95  } else {
96  QAveragePulseHandle apHandle(rchan);
97  GlobalHandle<QInt> dataset("Dataset");
98  GlobalData().Get("",&dataset,"");
99  apHandle.SetDataset(dataset.Get());
100  GlobalData().Get(apOwner,&apHandle,apInput);
101  ap = apHandle.Get();
102  }
103  averagePulses.push_back(ap);
104  }
105  newdeco = new QMultiChannelDecorrelatorOF(relatives,&fCovariance,averagePulses);
106 
107  }
108  std::string sideInput = GetString("SideChannelsInput",Q_STRING_DEFAULT);
109  GlobalHandle<QStdVector<int> > sidesHandle("CorrelatedChannels");
110  sidesHandle.SetChannel(channel);
111  GlobalData().Get("User",&sidesHandle,sideInput);
112  if(sidesHandle.IsValid()) {
113  pDeco = true;
114  if(!pOF && !pOFMultiDim) newdeco = new QMultiChannelDecorrelator(channel,&fCovariance);
115  newdeco->SetSideChannels(sidesHandle.Get());
116  }
117 
118  if(GetBool("ConvertTomV",false,false)) {
119  QRunDataHandle rHandle(run);
120  GlobalData().Get("",&rHandle,"");
121  double ADC2mV = rHandle.Get().GetChannelRunData(channel).fADC2mV;
122  if(newdeco) {
123  newdeco->SetScale(ADC2mV);
124  // forse re-initialization
125  newdeco->SetSideChannels(newdeco->GetSideChannels());
126  }
127  }
128  string msg;
129  if(newdeco) {
130 
131  stringstream msgstr;
132  msgstr<<", OrigRMS="<<newdeco->GetOriginalResolution();
133  msgstr<<", FiltRMS="<<newdeco->GetFilteredResolution();
134  msg = msgstr.str();
135  }
136 
137  fDecorrelators[channel].fDecorrelator = newdeco;
138  fDecorrelators[channel].fUsed = false;
139 
140  Info("Channel %04d: Deco %d, OF1D %d, OFMD %d%s",channel,pDeco,pOF,pOFMultiDim,msg.c_str());
141 
142  }
143 
144  QMultiChannelDecorrelator* deco = fDecorrelators[channel].fDecorrelator;
145  QVector decoPulse;
146  QPulse& decorrelated_pulse = ev.Get<QPulse>("Pulse");
147  const QPulse& pulse = ev.Get<QPulse>("DAQ","Pulse");
148 
149 
150  ev.Get<QBool>("Decorrelated") = false;
151 
152  if(deco != 0) {
153  std::vector<const QVector*> sideSamples;
154  const std::vector<int>& sideChannels = deco->GetSideChannels();
155  for(size_t ich = 0; ich < sideChannels.size(); ich++) {
156  const QVector& sideSample = GetNeighbourSamples(sideChannels[ich],neighbours);
157  if(sideSample.Size() > 0) {
158  sideSamples.push_back(&sideSample);
159  }
160  }
161  if(sideSamples.size() != sideChannels.size()) {
162  decoPulse = pulse.GetSamples();
163  decorrelated_pulse.SetSamplesADC(decoPulse);
164  return;
165  }
166  std::vector<const QVector*> samples;
167  samples.push_back(&pulse.GetSamples());
168  const std::vector<int>& channels = deco->GetChannels();
169  for(size_t ich = 1; ich < channels.size(); ich++) {
170  const QVector& sample = GetNeighbourSamples(channels[ich],neighbours);
171  if(sample.Size() > 0) {
172  samples.push_back(&sample);
173  }
174  }
175  if(samples.size() != channels.size()) {
176  decoPulse = pulse.GetSamples();
177  decorrelated_pulse.SetSamplesADC(decoPulse);
178  return;
179  }
180 
181  deco->Filter(samples,sideSamples,decoPulse);
182  if(fUseOF) {
183  double amp = Q_DOUBLE_DEFAULT;
184  double maxpos = Q_DOUBLE_DEFAULT;
185  if(pi.GetIsNoise()) {
186  amp = decoPulse[pi.GetMasterSample().GetSampleIndex()];
188  } else {
189  amp = decoPulse.GetMax();
190  maxpos = decoPulse.GetMaxIndex();
191  }
192  ev.Get<QDouble>("OFAmplitude") = amp;
193  ev.Get<QDouble>("OFMaximumPosition") = maxpos;
194  }
195  fDecorrelators[channel].fUsed = true;
196  ev.Get<QBool>("Decorrelated") = true;
197  decorrelated_pulse.SetSamplesADC(decoPulse);
198  } else {
199  decoPulse = pulse.GetSamples();
200  decorrelated_pulse.SetSamplesADC(decoPulse);
201  return;
202  }
203 
204  //decorrelated_pulse.SetSamplesADC(decoPulse);
205  return;
206 }
207 
209 {
210  std::map<int,ChannelInfo>::const_iterator iter = fDecorrelators.begin();
211  while(iter != fDecorrelators.end()) {
212  if(iter->second.fDecorrelator && !iter->second.fUsed) Warn("Channel %d was never decorrelated because the expected neighbours were not present",iter->first);
213  iter++;
214  }
215 }
216 
217 const QVector& MDecorrelator::GetNeighbourSamples(const int channel, const QEventList& neighbours)
218 {
219  for(size_t i = 0; i < neighbours.Size(); i++) {
220  const QPulseInfo& pi = neighbours[i].Get<QPulseInfo>("DAQ","PulseInfo");
221  if(pi.GetChannelId() == channel) {
222  const QPulse& pulse = neighbours[i].Get<QPulse>("DAQ","Pulse");
223  return pulse.GetSamples();
224  }
225  }
226  return fEmpty;
227 }
int maxpos
Definition: CheckOFShape.C:59
ap
Definition: CheckOFShape.C:47
double amp
Definition: CheckOF.C:32
QRunDataHandle rHandle(753)
const int channel
#define Q_DOUBLE_DEFAULT
Definition: QDiana.hh:24
#define Q_STRING_DEFAULT
Definition: QDiana.hh:38
#define Q_INT_DEFAULT
Definition: QDiana.hh:26
#define REGISTER_MODULE(clazz)
Definition: QDriver.hh:133
noise decorrelation using side pulses
const Diana::QVector & GetNeighbourSamples(const int channel, const Diana::QEventList &neighbours)
void Done()
Done method.
void Do(Diana::QEvent &ev, const Diana::QEventList &neighbours)
Do method.
global handle for average pulse
base types wrapped into a QObject. Currently implemented types are QInt QDouble and QFloat....
Definition: QBaseType.hh:17
bool wrapped into a QObject
Definition: QBool.hh:17
list of references to const QEvent (s)
Definition: QEventList.hh:21
size_t Size() const
number of QEvent (s)
Definition: QEventList.hh:36
diana event
Definition: QEvent.hh:46
void Get(const char *owner, ReadHandle< Q > &handle) const
Get a QObject Handle in read mode.
Definition: QEvent.hh:74
Raw event: basic information like run number and time.
Definition: QHeader.hh:16
class to perform multichannel complex decorrelation of single channel waveforms using also optimum fi...
void SetScale(double scale)
scale power spectra and filtered samples
double GetFilteredResolution() const
get filtered resolution
const std::vector< int > & GetChannels() const
get main channels
void SetSideChannels(const std::vector< int > &channels)
chose subset of channels to use for decorrelation
double GetOriginalResolution() const
get original resolution
virtual void Filter(const Diana::QVector &input, const std::vector< const Diana::QVector * > &sideInputs, Diana::QVector &output) const
decorrelate input QVector from this channel using sideInputs QVectors from sideChannels,...
const std::vector< int > & GetSideChannels() const
get subset of channels to use for decorrelation
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
void SetSamplesADC(const Diana::QVectorI &samples)
Set Samples acquired from ADC.
Definition: QPulse.cc:74
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
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...