Diana Software
MDownSampling.cc
Go to the documentation of this file.
1 #include "MDownSampling.hh"
2 #include "QEventAssembler.hh"
3 #include "QRawEvent.hh"
4 #include "QBaseType.hh"
5 #include "QRunDataHandle.hh"
6 #include "QPulse.hh"
7 #include "QVector.hh"
8 #include <cmath>
9 #include "QFir.hh"
10 
11 
12 
13 
15 
16 using namespace Diana;
17 using namespace std;
18 
20 {
21 
22 
23  fCutOffFrequency = GetDouble("CutOffFrequency",300000);
24  fAttenuation = GetDouble("AttenuationDB",60);
25  fPulseLabel = GetString("PulseLabel","DAQ@Pulse",false);
26  fOverWritePulse = GetBool("OverwritePulse",true);
27  fDownSampling = GetDouble("DownSampling",1.,false);
28  if(fDownSampling < 1.) Panic("Downsampling factor (%f) must be >= 1",fDownSampling);
29 
30 
31  QEvent& ev = eva.GetEvent();
32  ev.Require<QHeader>("DAQ","Header");
33  ev.Require<QPulseInfo>("DAQ","PulseInfo");
34  ev.RequireByLabel<QPulse>(fPulseLabel);
35 
36  if(!fOverWritePulse) {
37  ev.Add<QPulse>(fPulseLabel.name);
38  ev.Add<QPulseInfo>("PulseInfo");
39  }
40 
41  Info("Cutoff set to %f",fCutOffFrequency);
42  return ACT_NEXTEV;
43 }
44 
46 {
47  QEvent& ev = eva.GetEvent();
48  QPulseInfo& pi = eva.Get<QPulseInfo>("DAQ","PulseInfo");
49  const int channel = pi.GetChannelId();
50 
51  if(fFilters.find(channel) == fFilters.end()) {
52  const QHeader& header = ev.Get<QHeader>("DAQ","Header");
53  QRunDataHandle rHandle(header.GetRun());
54  GlobalData().Get("DAQ",&rHandle,"");
55  const QRunData& runData = rHandle.Get();
56  const QChannelRunData& channelRunData = runData.GetChannelRunData(channel);
57  const double samplFreq = channelRunData.fSamplingFrequency;
58  const double ADC2mV = channelRunData.fADC2mV;
59  double fracFreq = fCutOffFrequency/samplFreq;
60 
61  int M = fAttenuation * 0.025/fracFreq;
62  if(M%2 == 0) M++;
63  QCFirData configuration;
64  configuration.fM = M;
65  configuration.fCutoff = fracFreq;
66  configuration.fAttDB = fAttenuation;
67  configuration.fMethod = QCFirData::KayserBessel;
68  QFir* fir = new QFir(configuration);
69  size_t trigPos = pi.GetMasterSample().GetSampleIndex();
70  if(fir->GetFilterReduction() > trigPos/2) {
71  Panic("Filter reduction (%d) is greater than triggerPosition/2 (%d), try a lower attenuation or a higher cutoff frequency (Size of filter scales linearly with them)",fir->GetFilterReduction(),trigPos/2);
72  }
73 
74  if(!fir) Panic("Cannot create FIR for channel %d", channel);
75 
76 
77  ChannelInfo info;
78  info.fir = fir;
79  info.numberOfSamples = channelRunData.fNumberOfSamples - fir->GetFilterReduction();
80 
81  //undersampling
82  info.R = fDownSampling;//samplFreq/(fCutOffFrequency*2)/4;//??????????
83  //if(info.R == 0) Panic("Undersampling failed. Cutoff frequency (%f) must be lower than (sampling frequency/8)= %f",fCutOffFrequency,samplFreq/8);
84 
85  //info.numberOfSamples /= (info.R);
86  info.numberOfSamples /= fDownSampling;
87  //if(info.numberOfSamples %2 != 0) info.numberOfSamples++;
88 
89  fFilters[channel] = info;
90  GlobalHandle<QCFirData> cfh("FirData");
91  cfh.SetChannel(channel);
92  cfh.SetRun(header.GetRun());
93  cfh.Set(configuration);
94  GlobalData().Set(&cfh,"CurrentWriter");
95 
96  if(fOverWritePulse) {
97  // overwrite rundata
98  void* rdv = (void*)&channelRunData;
99  QChannelRunData* rd = (QChannelRunData*)rdv;
101  rd->fADC2mV = ADC2mV;
102  rd->fSamplingFrequency /= info.R;
103  GlobalData().Set(&rHandle,"CurrentWriter");
104 
105  }
106 
107  }
108 
109 
110  QPulse& oldPulse = eva.Get<QPulse>(fPulseLabel.owner.c_str(),fPulseLabel.name.c_str());
111  const QVector& input = oldPulse.GetSamples();
112 
113  const ChannelInfo& info = fFilters[channel];
114  fOutput.Clear();
115  info.fir->Filter(input,fOutput);
116 
117  //cout<<"Input Event: "<<input.Size()<<"\t Output Event: "<<fOutput.Size()<<"\t FIR Reduction: "<<info.fir->GetFilterReduction()<<endl;
118  int samps = 0;
119  for(size_t i = 0; i < info.numberOfSamples; i++) {
120  if(i*info.R<fOutput.Size()){
121  samps++;
122  fOutput[i] = fOutput[i*info.R];
123  }
124  }
125 
126  fOutput.Resize(samps);
127 
128  int ms = pi.GetMasterSample().GetSampleIndex()-info.fir->GetFilterReduction();
129 
130  ms /= info.R;
131 
132  if(fOverWritePulse) {
134  oldPulse.SetSamplesADC(fOutput);
135  } else {
136  ev.Get<QPulseInfo>("PulseInfo") = pi;
137  ev.Get<QPulseInfo>("PulseInfo").GetMasterSample().SetSampleIndex(ms);
138  QPulse& filteredPulse = ev.Get<QPulse>(fPulseLabel.name.c_str());
139  filteredPulse.SetSamplesADC(fOutput);
140  }
141 
142  //MV FIXME: add other sampleInfo
143 
144 
145  return ACT_NEXTEV;
146 }
147 
149 {
150  return ACT_NEXTEV;
151 }
152 
QRunDataHandle rHandle(753)
const int channel
#define REGISTER_MODULE(clazz)
Definition: QDriver.hh:133
QDriver::Action Init(Diana::QEventAssembler &eva)
Init method.
QDriver::Action Do(Diana::QEventAssembler &eva)
Do method. Declare and implement only one of the two versions.
QDriver::Action Done()
Done method.
Data class for QFir (Ported from Calder)
Definition: QCFirData.hh:14
Method fMethod
Definition: QCFirData.hh:34
double fCutoff
Definition: QCFirData.hh:36
@ KayserBessel
Definition: QCFirData.hh:18
double fAttDB
Definition: QCFirData.hh:37
basic channel and run based info. Used in the QRunData object.
double fSamplingFrequency
sampling frequency in Hz
int fNumberOfSamples
number of samples in ADC window
double fADC2mV
conversion: mV = ADC * fADC2mV
class to store ActionId and fEventNumber (in case fActionId=ACT_GOTOEV)
Definition: QDriver.hh:59
Visitor class of QEvent that provides full handling of QEvent.
QEvent & GetEvent()
Get the QEvent.
void Get(const char *owner, WriteHandle< Q > &handle)
Get QObject from the event in write mode. This method has to be called in the event loop,...
diana event
Definition: QEvent.hh:46
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
QFir FIR low pass filter (Ported from Calder)
Definition: QFir.hh:17
QError Filter(const Diana::QVector &input, Diana::QVector &output) const
Definition: QFir.cc:63
size_t GetFilterReduction() const
Definition: QFir.hh:25
Raw event: basic information like run number and time.
Definition: QHeader.hh:16
int GetRun() const
destructor
Definition: QHeader.hh:22
Raw event: bolometer channel, trigger positions and types.
Definition: QPulseInfo.hh:18
const QSampleInfo & GetMasterSample() const
Get MasterSample.
Definition: QPulseInfo.hh:26
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
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
void SetSampleIndex(Int_t index)
Set SampleIndex.
Definition: QSampleInfo.hh:79
the Diana namespace is needed because sometimes we use Qt libraries, that use same class names of our...