Diana Software
QChannelCovariance.cc
Go to the documentation of this file.
1 #include "QChannelCovariance.hh"
2 #include <sstream>
3 #include <cmath>
4 
6 
7 bool CompareCorrelations(const std::pair<int,double>& lhs, const std::pair<int,double>& rhs)
8 {
9  return lhs.second > rhs.second;
10 }
11 
12 
14 {
15 }
16 
17 QChannelCovariance::QChannelCovariance(size_t nfreq, const std::vector<int> &channels)
18 {
19  SetNFreq(nfreq);
20  SetChannels(channels);
21 }
22 
23 void QChannelCovariance::SetNFreq(size_t nfreq)
24 {
25  Clear();
26  fCovariance.resize(nfreq);
27 }
28 
29 void QChannelCovariance::SetChannels(const std::vector<int> &channels)
30 {
31  for(size_t f = 0; f < fCovariance.size(); f++) {
32  fCovariance[f].Resize(channels.size(),channels.size());
33  fCovariance[f].Initialize(0,0);
34  }
35  for(size_t i = 0; i < channels.size(); i++) {
36  fChannels[channels[i]]=i;
37  }
38  fNevents.Resize(channels.size(),channels.size());
39  fNevents.Initialize(0);
40 }
41 
42 void QChannelCovariance::SetCovariance(int chI, int chJ,const Diana::QVectorC& cov)
43 {
44  if(cov.Size() != fCovariance.size()) {
46  std::stringstream msg;
47  msg<<"Size of given QVectorC, "
48  <<cov.Size()<<", is wrong; expects" <<fCovariance.size();
49  err.SetDescription(__FILE__,__LINE__,msg.str());
50  DianaThrow(err);
51  return;
52  }
53 
54  int i,j;
55  Channels2Indices(chI,chJ,i,j);
56 
57  for(size_t f = 0; f < fCovariance.size(); f++) {
58  fCovariance[f](i,j) = cov[f];
59  }
60 }
61 
62 void QChannelCovariance::SetNEvents(int chI, int chJ, int nev)
63 {
64  int i,j;
65  Channels2Indices(chI,chJ,i,j);
66  fNevents(i,j) = nev;
67 }
68 
69 std::vector<int> QChannelCovariance::GetChannels() const
70 {
71  std::map<int,int>::const_iterator iter = fChannels.begin();
72  std::vector<int> res(fChannels.size());
73  for(size_t i = 0; iter != fChannels.end(); i++) {
74  res[i]= iter->first;
75  iter++;
76  }
77  return res;
78 }
79 
80 
81 Diana::QVectorC QChannelCovariance::GetCovariance(int chI, int chJ) const
82 {
83  int i,j;
84  Channels2Indices(chI,chJ,i,j);
85 
86  Diana::QVectorC res(fCovariance.size());
87  for(size_t f = 0; f < fCovariance.size(); f++) {
88  res[f] = fCovariance[f](i,j);
89  }
90  return res;
91 }
92 
93 Diana::QVectorC QChannelCovariance::GetCovarianceByIndex(int i, int j) const
94 {
95  Diana::QVectorC res(fCovariance.size());
96  for(size_t f = 0; f < fCovariance.size(); f++) {
97  res[f] = fCovariance[f](i,j);
98  }
99  return res;
100 }
101 
102 
103 
104 int QChannelCovariance::GetNEvents(int chI, int chJ) const
105 {
106  int i,j;
107  Channels2Indices(chI,chJ,i,j);
108  return (int)fNevents(i,j);
109 }
110 
112 {
113  QChannelCovariance res(*this);
114  for(size_t f = 1; f < fCovariance.size(); f++) {
115  res.fCovariance[f].Invert();
116  }
117  return res;
118 }
119 
120 QChannelCovariance QChannelCovariance::GetSubMatrix(const std::vector<int> &channels) const
121 {
122  QChannelCovariance res(fCovariance.size(),channels);
123  for(size_t i = 0; i < channels.size(); i++) {
124  for(size_t j = 0; j < channels.size(); j++) {
125  const int chanI = channels[i];
126  const int chanJ = channels[j];
127  res.SetCovariance(chanI,chanJ,GetCovariance(chanI,chanJ));
128  res.SetNEvents(chanI,chanJ,GetNEvents(chanI,chanJ));
129  }
130  }
131  return res;
132 }
133 
134 
135 
136 
137 Diana::QVectorC QChannelCovariance::GetCorrelation(int chI, int chJ) const
138 {
139  Diana::QVectorC covII, covJJ, covIJ;
140  covII = GetCovariance(chI,chI);
141  covJJ = GetCovariance(chJ,chJ);
142  covIJ = GetCovariance(chI,chJ);
143 
144  Diana::QVectorC res(covII.Size());
145  res[0].SetRe(0);
146  res[0].SetIm(0);
147  for(size_t f = 1; f < covII.Size(); f++) {
148  const double div = sqrt(fabs(covII[f].Re()*covJJ[f].Re()));
149  res[f] = covIJ[f]/div;
150  }
151  return res;
152 }
153 
154 double QChannelCovariance::GetMeanCorrelation(int chI, int chJ, int fmin, int fmax) const
155 {
156  Diana::QVectorC covII = GetCovariance(chI,chI);
157  Diana::QVector rho2 = GetCorrelation(chI,chJ).GetModulusSquare();
158 
159  double num = 0., den = 0.;
160  if(fmin <= 0 || fmin >= (int)rho2.Size()) fmin = 1;
161  if(fmax < 0 || fmax >= (int)rho2.Size()) fmax = -1+rho2.Size();
162 
163  for(int f = fmin; f < fmax; f++) {
164  num += rho2[f]*fabs(covII[f].Re());
165  den += fabs(covII[f].Re());
166  }
167  double res = 0.;
168  if(den != 0) res = sqrt(num/den);
169  return res;
170 }
171 
172 std::vector<int> QChannelCovariance::GetChannelsByCorrelation(int chI, int fmin, int fmax) const
173 {
174  std::vector<std::pair<int,double> > pairs;
175  std::vector<int> ch = GetChannels();
176  for(size_t i = 0; i < ch.size(); i++) {
177  int chJ = ch[i];
178  if(chJ != chI) {
179  double corr = GetMeanCorrelation(chI,chJ,fmin,fmax);
180  std::pair<int,double> p(chJ,corr);
181  pairs.push_back(p);
182  }
183  }
184  std::sort(pairs.begin(),pairs.end(),CompareCorrelations);
185  std::vector<int> res;
186  for(size_t i = 0; i < pairs.size(); i++) {
187  res.push_back(pairs[i].first);
188  }
189  return res;
190 }
191 
192 
193 
194 void QChannelCovariance::Dump(std::ostream& o) const
195 {
196  std::vector<int> ch = GetChannels();
197  o<<"# of chans: "<<ch.size()<<std::endl;
198  o<<"# of freqs: "<<fCovariance.size();
199 
200  if(ch.empty()) return;
201  o<<std::endl;
202  if(ch.size() == 1) {
203  o<<"channel "<<ch[0];
204  if(fCovariance.size()<2) return;
205  o<<": Covariance[f=1] = "<<fCovariance[1](ch[0],ch[0]);
206  o<<", Nevents = "<<fNevents(ch[0],ch[0]);
207  return;
208  } else {
209  o<<"first 2 chans ("<<ch[0]<<","<<ch[1]<<")";
210  if(fCovariance.size()<2) return;
211  o<<": Covariance[f=1] = "<<fCovariance[1](ch[0],ch[1]);
212  o<<", Nevents = "<<fNevents(ch[0],ch[0]);
213  }
214  return;
215 
216 }
217 
218 void QChannelCovariance::DumpMeanCorrelationMatrix(std::ostream& o,const int fmin, const int fmax) const
219 {
220  std::map<int,int>::const_iterator chIIter = fChannels.begin();
221  std::map<int,int>::const_iterator chKIter = fChannels.begin();
222  while(chKIter!=fChannels.end()) {
223  o<<"\t"<<chKIter->first<<" ";
224  chKIter++;
225  }
226  o<<std::endl;
227 
228  while(chIIter != fChannels.end()) {
229  o<<chIIter->first<<"\t";
230  std::map<int,int>::const_iterator chJIter = fChannels.begin();
231  while(chJIter != fChannels.end()) {
232  double corr=GetMeanCorrelation(chIIter->first,chJIter->first,fmin,fmax);
233  o<<corr<<" ";
234  chJIter++;
235  }
236  o<<std::endl;
237  chIIter++;
238  }
239 }
240 
241 
242 void QChannelCovariance::Channels2Indices(const int chI, const int chJ, int& i, int& j) const
243 {
244  i = j = 0;
245  std::map<int,int>::const_iterator chIIter = fChannels.find(chI);
246  std::map<int,int>::const_iterator chJIter = fChannels.find(chJ);
247  if(chIIter == fChannels.end()) {
249  std::stringstream msg;
250  msg<<"Given channel "<<chI<<" not allowed";
251  err.SetDescription(__FILE__,__LINE__,msg.str());
252  DianaThrow(err);
253  return;
254  }
255  if(chJIter == fChannels.end()) {
257  std::stringstream msg;
258  msg<<"Given channel "<<chJ<<" not allowed";
259  err.SetDescription(__FILE__,__LINE__,msg.str());
260  DianaThrow(err);
261  return;
262  }
263  i = chIIter->second;
264  j = chJIter->second;
265 }
err
Definition: CheckOF.C:114
QObjectImp(QChannelCovariance)
bool CompareCorrelations(const std::pair< int, double > &lhs, const std::pair< int, double > &rhs)
double Re(const Diana::QComplex &z)
Function to get the real part.
Definition: QComplex.cc:260
#define DianaThrow(obj)
Definition: QDianaDebug.hh:26
@ QERR_SIZE_NOT_MATCH
Definition: QError.hh:31
Complex covariance matrix of an array of bolometers.
std::map< int, int > fChannels
map real channel number into channel index
void SetNEvents(int chI, int chJ, int nev)
set number of events of the couple I,J
void DumpMeanCorrelationMatrix(std::ostream &o, const int fmin=-1, const int fmax=-1) const
dump mean correlation matrix
void Dump(std::ostream &o) const
dump summary of content
double GetMeanCorrelation(int chI, int chJ, int fmin=-1, int fmax=-1) const
get mean correlation between frequency indices fmin and fmax of the couple (chI,chJ)
Diana::QVectorC GetCorrelation(int chI, int chJ) const
get correlation
void SetChannels(const std::vector< int > &channels)
set channels
QChannelCovariance GetSubMatrix(const std::vector< int > &channels) const
Get sub matrix of channels.
std::vector< int > GetChannels() const
get channels
void Clear()
clear members
QChannelCovariance Inverse() const
get inverse matrix
void SetNFreq(size_t nfreq)
set number of frequencies
Diana::QVectorC GetCovarianceByIndex(int i, int j) const
int GetNEvents(int chI, int chJ) const
get number of events of the couple I,J
Diana::QVectorC GetCovariance(int chI, int chJ) const
get covariance between channel I and J
Diana::QMatrix fNevents
number of events used to build each element of fCovariance
void Channels2Indices(const int chI, const int chJ, int &i, int &j) const
convert channel numbers to indices
std::vector< Diana::QMatrixC > fCovariance
std::vector< int > GetChannelsByCorrelation(int chI, int fmin=-1, int fmax=-1) const
get mean correlation between frequency indices fmin and fmax of the couple (chI,chJ)
void SetCovariance(int chI, int chJ, const Diana::QVectorC &cov)
set covariance (size equal to nfreq) of channels I and J
error class with error type and description
Definition: QError.hh:115