Diana Software
QMultiChannelDecorrelator.cc
Go to the documentation of this file.
2 #include <sstream>
3 
4 using namespace Diana;
5 
7 {
8  std::vector<int> channels;
9  channels.push_back(chan);
10  Constructor(channels,cov,false);
11 }
12 
14 {
15  std::vector<int> channels;
16  channels.push_back(chan);
17  Constructor(channels,cov,init);
18 }
19 
20 QMultiChannelDecorrelator::QMultiChannelDecorrelator(const std::vector<int>& channels, const QChannelCovariance* cov, bool init)
21 {
22  Constructor(channels,cov,init);
23 }
24 
25 
26 void QMultiChannelDecorrelator::Constructor(const std::vector<int>& channels, const QChannelCovariance* cov, bool init)
27 {
28  fScale = 1.;
29  fTransformer = 0;
30  fOriginalResolution = Q_DOUBLE_DEFAULT;
31  fFilteredResolution = Q_DOUBLE_DEFAULT;
32  if(cov == 0) {
34  std::stringstream msg;
35  msg<<"Pointer to QChannelCovariance is NULL";
36  err.SetDescription(__FILE__,__LINE__,msg.str());
37  DianaThrow(err);
38  }
39  if(channels.empty()) {
41  std::stringstream msg;
42  msg<<"no channel given";
43  err.SetDescription(__FILE__,__LINE__,msg.str());
44  DianaThrow(err);
45  }
46  fCovarianceMatrix = cov;
47  fTransformer = new QRealComplexFFT(fCovarianceMatrix->GetNFreq());
48  fAvailableSideChannels = fCovarianceMatrix->GetChannels();
49  fChannels.clear();
50  for(size_t i = 0; i < channels.size() ;i++) {
51  const int chan = channels[i];
52  fAvailableSideChannels.erase(FindChannel(fAvailableSideChannels,chan));
53  fChannels.push_back(chan);
54  }
55  if(init) {
56  std::vector<int> empty;
57  SetSideChannels(empty);
58  }
59 }
60 
62 {
63  if(fTransformer) delete fTransformer;
64 }
65 
66 
67 void QMultiChannelDecorrelator::SetSideChannels(const std::vector<int>& channels)
68 {
69  fSideChannels.clear();
70  fWeights.clear();
71  fOriginalPowerSpectrum.Clear();
72  fDecorrelatedPowerSpectrum.Clear();
73 
74  std::vector<int> allChannels;
75  for(size_t i = 0; i < fChannels.size(); i++) {
76  allChannels.push_back(fChannels.at(i));
77  }
78  for(size_t i = 0; i < channels.size(); i++) {
79  const int sideChan = channels[i];
80  FindChannel(fAvailableSideChannels, sideChan);
81  allChannels.push_back(sideChan);
82  fSideChannels.push_back(sideChan);
83  }
84  Init(allChannels);
85 }
86 
87 void QMultiChannelDecorrelator::Init(const std::vector<int>& allChannels)
88 {
89  const int chan = fChannels.at(0);
90  fOriginalPowerSpectrum = fCovarianceMatrix->GetCovariance(chan,chan).GetModulus()*fScale*fScale;
91  fOriginalResolution = ComputeResolution(fOriginalPowerSpectrum);
92 
93  QChannelCovariance reducedCovarianceMatrix = (fCovarianceMatrix->GetSubMatrix(allChannels)).Inverse();
94  QVectorC Cii = reducedCovarianceMatrix.GetCovariance(chan,chan);
95  QVectorC identity(fOriginalPowerSpectrum.Size());
96  identity.Initialize(1,0);
97  fDecorrelatedPowerSpectrum = (identity.Div(Cii)).GetModulus()*fScale*fScale;
98  fFilteredResolution = ComputeResolution(fDecorrelatedPowerSpectrum);
99 
100  fWeights.push_back(identity);
101  for(size_t i = 1; i < allChannels.size(); i++) {
102  QVectorC W = reducedCovarianceMatrix.GetCovariance(chan,allChannels[i]).Div(Cii);
103  W[0].SetIm(0);
104  W[0].SetRe(0);
105  fWeights.push_back(W);
106  }
107 
108 }
109 
110 double QMultiChannelDecorrelator::ComputeResolution(const QVector& ps) const
111 {
112  double resolution = 0;
113  for(size_t i = 1; i < ps.Size(); i++){
114  resolution += ps[i];
115  }
116  resolution = sqrt(resolution);
117  resolution /= ps.Size();
118  return resolution;
119 }
120 
121 void QMultiChannelDecorrelator::Filter(const Diana::QVector& input, const std::vector<const Diana::QVector*>& sideInputs, QVector& output) const
122 {
123  if(fWeights.size() <= 1 || sideInputs.size() != fWeights.size()-1) {
124  output.Clear();
125  return;
126  }
127  QVectorC outFreq(fWeights[0].Size());
128  QVectorC tmp(fWeights[0].Size());
129 
130  fTransformer->TransformToFreq(input,tmp);
131  outFreq = tmp.Mult(fWeights[0]);
132  for(size_t i = 1; i < fWeights.size(); i++) {
133  fTransformer->TransformToFreq(*sideInputs[i-1],tmp);
134  outFreq += tmp.Mult(fWeights[i]);
135  }
136  fTransformer->TransformFromFreq(outFreq,output);
137 }
138 
139 void QMultiChannelDecorrelator::Filter(const std::vector<const Diana::QVector*>& inputs, const std::vector<const Diana::QVector*>& sideInputs, Diana::QVector& output) const
140 {
141  if(inputs.size() != 1) {
143  std::stringstream msg;
144  msg<<"inputs.Size() = "<<inputs.size()<<" differs from 1";
145  err.SetDescription(__FILE__,__LINE__,msg.str());
146  DianaThrow(err);
147  return;
148  }
149  Filter(*inputs[0],sideInputs,output);
150 }
151 
152 std::vector<int>::iterator QMultiChannelDecorrelator::FindChannel(std::vector<int>& channels, const int chan)
153 {
154  std::vector<int>::iterator iter = find(channels.begin(), channels.end(), chan);
155  if(iter == channels.end()) {
157  std::stringstream msg;
158  msg<<"Channel "<<chan<<" is not contained in input covariance matrix ";
159  err.SetDescription(__FILE__,__LINE__,msg.str());
160  DianaThrow(err);
161  }
162  return iter;
163 }
err
Definition: CheckOF.C:114
#define DianaThrow(obj)
Definition: QDianaDebug.hh:26
#define Q_DOUBLE_DEFAULT
Definition: QDiana.hh:24
@ QERR_UNKNOWN_ERR
Definition: QError.hh:108
@ QERR_SIZE_NOT_MATCH
Definition: QError.hh:31
@ QERR_OUT_OF_RANGE
Definition: QError.hh:28
class to perform multichannel complex decorrelation of single channel waveforms
Complex covariance matrix of an array of bolometers.
Diana::QVectorC GetCovariance(int chI, int chJ) const
get covariance between channel I and J
error class with error type and description
Definition: QError.hh:115
double ComputeResolution(const Diana::QVector &powerSpectrum) const
compute resolution
virtual void Init(const std::vector< int > &allChannels)
init weights
std::vector< int >::iterator FindChannel(std::vector< int > &channels, const int chan)
find if chan is contained in channels otherwise throw exception
void Constructor(const std::vector< int > &channels, const QChannelCovariance *cov, bool init)
perform constructor operations
void SetSideChannels(const std::vector< int > &channels)
chose subset of channels to use for decorrelation
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,...
QMultiChannelDecorrelator(const int chan, const QChannelCovariance *cov)
ctor, by default all channels are used to decorrelate
Wrapper for a specific QRealComplexFFT algorithm class.
the Diana namespace is needed because sometimes we use Qt libraries, that use same class names of our...