ROOTPWA
TFitBin.cc
Go to the documentation of this file.
1 
2 //
3 // Copyright 2009 Sebastian Neubert
4 //
5 // This file is part of rootpwa
6 //
7 // rootpwa is free software: you can redistribute it and/or modify
8 // it under the terms of the GNU General Public License as published by
9 // the Free Software Foundation, either version 3 of the License, or
10 // (at your option) any later version.
11 //
12 // rootpwa is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 // GNU General Public License for more details.
16 //
17 // You should have received a copy of the GNU General Public License
18 // along with rootpwa. If not, see <http://www.gnu.org/licenses/>.
19 //
21 //-----------------------------------------------------------
22 // File and Version Information:
23 // $Id$
24 //
25 // Description:
26 // Data storage class for PWA fit result of one mass bin
27 //
28 // Environment:
29 // Software developed for the COMPASS experiment at CERN
30 //
31 // Author List:
32 // Sebastian Neubert TUM (original author)
33 //
34 //
35 //-----------------------------------------------------------
36 
37 
38 #include <algorithm>
39 
40 // PWA2000 classes
41 #include "integral.h"
42 
43 #include "reportingUtils.hpp"
44 #include "TFitBin.h"
45 
46 
47 using namespace std;
48 
49 
51 
52 
54  : _hasErrors(true)
55 { }
56 
57 
59 {
60  Reset();
61 }
62 
63 
64 void
66 {
67  _amps.clear();
68  _wavenames.clear();
69 }
70 
71 
72 void
73 TFitBin::fill(const std::vector<TComplex>& prodAmps,
74  const std::vector<std::pair<int, int> >& indices,
75  const std::vector<TString>& prodAmpNames,
76  const int nevt,
77  const unsigned int nmbEvents,
78  const double massBinCenter,
79  const TCMatrix& normIntegral,
80  const TMatrixD& fitParCovMatrix,
81  const double logLikelihood,
82  const int rank)
83 {
84 // !!! add some consistency checks
85  _int.ResizeTo (normIntegral.nrows(), normIntegral.ncols());
86  _errm.ResizeTo(fitParCovMatrix.GetNrows(), fitParCovMatrix.GetNcols());
87  _amps = prodAmps;
88  _indices = indices;
90  _nevt = nevt;
94  if (_errm.GetNrows() == 0) // check whether there really is an error matrix
95  _hasErrors = false;
98  _rank = rank;
99  buildWaveMap();
100 }
101 
102 
103 void
105  int n=_wavenames.size();
106  for(int i=0;i<n;++i){
107  // strip rank
108  TString title=wavetitle(i);
109  //cout << "title=="<<title<<endl;
110  if(find(_wavetitles.begin(),_wavetitles.end(),title)==_wavetitles.end()){
111  //cout<<"Wave: "<<title<<endl;
112  _wavetitles.push_back(title);
113  }
114 
115  // look for index of first occurence
116  int j;
117  for(j=0;j<n;++j){
118  if(_wavenames[j].Contains(title))break;
119  }
120  _wavemap[i]=j;
121  }
122 }
123 
124 // take care of flat wave which has no integral!
125 TComplex
126 TFitBin::getInt(int i, int j) const {
127  // TODO: idea - prestore index of flat wave!
128  bool flat1=_wavenames[i].Contains("flat");
129  bool flat2=_wavenames[j].Contains("flat");
130  if(flat1 && flat2) return 1;
131  else if(flat1 || flat2) return 0;
132  else {
133  map<int, int>::const_iterator indexA = _wavemap.find(i);
134  map<int, int>::const_iterator indexB = _wavemap.find(j);
135  if ((indexA == _wavemap.end()) || (indexB == _wavemap.end())) {
136  printWarn << "Amplitude index " << i << " or " << j << " is out of bound." << endl;
137  return 0;
138  }
139  return _int(indexA->second, indexB->second);
140  }
141 }
142 
143 Int_t
144 TFitBin::rankofwave(int i) const {
145  if(!_wavenames[i].Contains("flat")){
146  return TString(_wavenames[i](1,1)).Atoi();
147  }
148  else return -1;
149 }
150 
151 // OBSERVABLES CALCULATIONS:
152 
153 double
154 TFitBin::intens() const { // total intensity
155  return intens("");
156 }
157 
158 double
159 TFitBin::intens(const char* tag) const {
160  return norm(tag)*_nevt;
161 }
162 
163 double
164 TFitBin::norm(const char* tag) const // added intensity of waves containing tag
165 {
166  TComplex c(0,0);
167  int n=_wavenames.size();
168  // loop over rank:
169  for(int r=-1; r<_rank; ++r){
170  // double loop
171  for(int i=0;i<n;++i){// outer loop
172  if(!(_wavenames[i].Contains(tag) && rankofwave(i)==r))continue;
173  for(int j=0;j<n;++j){
174  if(!(_wavenames[j].Contains(tag) && rankofwave(j)==r))continue;
175  c+=_amps[i]*TComplex::Conjugate(_amps[j])*getInt(i,j);
176  //cout<< _wavenames[i] << " | " << _wavenames[j] << endl;
177  }
178  }
179  }
180  return c.Re();
181 }
182 
183 double
184 TFitBin::getParameter(const char* name) const {
185  // check if real or imag
186  TString na(name);
187  bool re=false;
188  if(na.Contains("flat")){
189  na="flat";
190  re=true;
191  }
192  else re=na.Contains("RE");
193  // find wave -> remove _IM/_RE
194  if(re)na.ReplaceAll("_RE","");
195  else na.ReplaceAll("_IM","");
196  unsigned int n=_wavenames.size();
197  for(unsigned int i=0;i<n;++i){// outer loop
198  if(na==_wavenames[i]){
199  if(re)return _amps[i].Re();
200  else return _amps[i].Im();
201  }
202  }
203  // not found -> return standard
204  return 0;
205 }
206 
207 
208 double
209 TFitBin::intens(int i) const {
210  //cout<<wavename(i)<<" r="<<rankofwave(i)<<endl;
211  //cout<<wavetitle(i)<<endl;
212  return norm(wavetitle(i).Data())*_nevt;
213 }
214 
215 TComplex
216 TFitBin::spinDens(int i, int j) const {
217  // account for find all waves with same title
218  TString w1=wavetitle(i);
219  TString w2=wavetitle(j);
220  int n=_wavenames.size();
221  TComplex result(0,0); // list for ranks
222  TComplex a1(0,0);
223  TComplex a2(0,0);
224  for(int r=0; r<_rank; ++r){
225  for(int k=0;k<n;++k){
226  if(rankofwave(k)!=r)continue;
227  if(_wavenames[k].Contains(w1))a1=_amps[k];
228  if(_wavenames[k].Contains(w2))a2=_amps[k];
229  }
230  result+=a1*TComplex::Conjugate(a2);
231  }
232 
233  return result;
234 }
235 
236 
237 double
238 TFitBin::err(const char* tag) const {
239  if(!_hasErrors)return 0;
240 
241  // double loop
242  TMatrixD C;
243  vector<int> cpar;
244  getCov(tag,C,cpar);
245  if(cpar.size()==0)return 0;
246  //C.Print();
247 
248  // Now build jacobian of intensity
249  TMatrixD J(2,cpar.size()*2);
250  // number of sub-jacobians
251  int nsub=cpar.size();
252  for(int i=0;i<nsub;++i){//loop over subjacobians
253  TMatrixD Ji(2,2);Ji[0][0]=0;Ji[0][1]=0;Ji[1][0]=0;Ji[1][1]=0;
254  // which rank am I in?
255  int currentrank=rankofwave(cpar[i]);
256  //cout << "current rank ="<<currentrank<<endl;
257  for(int j=0;j<nsub;++j){ // loop over j
258  // only consider same rank contributions
259  if(rankofwave(cpar[j])!=currentrank){
260  //cout << " exclude this rank from Ji" << endl;
261  continue;
262  }
263  //cout << "vpsi"<<cpar[j]<<" , "<<cpar[i]<<endl;
264  TComplex vpsi=_amps[cpar[j]]*getInt(j,i);
265  Ji[0][0]+=vpsi.Re();
266  Ji[0][1]+=vpsi.Im();
267  }
268  // set submatrix
269  J.SetSub(0,2*i,Ji);
270 
271  }// end loop over subjacobians
272  //J.Print();
273  J*=2;
274  TMatrixD JT(TMatrixD::kTransposed,J);
275  TMatrixD CJT=C*JT;
276  TMatrixD x=J*CJT;
277  return _nevt*TMath::Sqrt(x[0][0]);
278 }
279 
280 double
281 TFitBin::err(int i) const {
282  //cout<<_wavenames[i]<<endl;
283  return err(wavetitle(i).Data());
284 }
285 
286 
287 double
288 TFitBin::phase(int i, int j) const // phase difference between wave i and j
289 {
290  return spinDens(i,j).Theta()/TMath::Pi()*180.;
291 }
292 
293 double
294 TFitBin::phaseErr(int i, int j) const
295 {
296  if(!_hasErrors)return 0;
297  TMatrixD C=spinDensErr(i,j);
298  TComplex rho=spinDens(i,j);
299  TMatrixD J(1,2);
300  J[0][0]=1./(rho.Re()+rho.Im()*rho.Im()/rho.Re());
301  J[0][1]=-rho.Im()/(rho.Re()*rho.Re()+rho.Im()*rho.Im());
302  TMatrixD JT(TMatrixD::kTransposed,J);
303  TMatrixD CJT=C*JT;
304  TMatrixD x=J*CJT;
305  return sqrt(x[0][0])/TMath::Pi()*180.;
306 }
307 
308 TMatrixD
309 TFitBin::spinDensErr(int i, int j) const {
310  TMatrixD C;
311  getCov(i,j,C);
312  TMatrixD J(2,4);
313  TMatrixD Ji=M(TComplex::Conjugate(_amps[j]));
314  J.SetSub(0,0,Ji);
315  Ji=M(_amps[i]);
316  TMatrixD Jc(2,2);Jc[0][0]=1;Jc[0][1]=0;Jc[1][0]=0;Jc[1][1]=-1;
317  Ji*=Jc;
318  J.SetSub(0,2,Ji);
319  TMatrixD JT(TMatrixD::kTransposed,J);
320  TMatrixD CJT=C*JT;
321  TMatrixD x=J*CJT;
322  return x;
323 }
324 
325 TMatrixD
326 TFitBin::M(const TComplex& c) const {
327  TMatrixD m(2,2);
328  m[0][0]=c.Re();
329  m[0][1]=-c.Im();
330  m[1][0]=c.Im();
331  m[1][1]=c.Re();
332  return m;
333 }
334 
335 
336 double
337 TFitBin::coh(int i, int j) const // coherence between wave i and j
338 { return 0;}
339 
340 
341 void
343  for(unsigned int i=0; i<_wavenames.size();++i)cout<<i<<" "<<_wavenames[i]<<endl;
344 }
345 
346 
347 TMatrixD
348 TFitBin::getErr(pair<int,int> k) const {
349  TMatrixD m(2,2);
350  m[0][0]=_errm[k.first][k.first];
351  m[0][1]=_errm[k.first][k.second];
352  m[1][0]=_errm[k.second][k.first];
353  m[1][1]=_errm[k.second][k.second];
354  return m;
355 }
356 
357 
358 void
359 TFitBin::getCov(const char* tag, TMatrixD& C, vector<int>& cpar) const {
360  // loop over wavenames to get list of paramters
361  cpar.clear();
362  int n=_wavenames.size();
363  vector<int> par; // vector of (real parameters)
364  for(int i=0;i<n;++i){// outer loop
365  if(_wavenames[i].Contains(tag)){
366  par.push_back(_indices[i].first);
367  par.push_back(_indices[i].second);
368  cpar.push_back(i); // vector of complex parameter indices
369  //cout << _wavenames[i] << endl;
370  }
371  }
372  // now build up matrix:
373  int n2=par.size();
374  C.ResizeTo(n2,n2);
375  for(int i=0;i<n2;++i){
376  for(int j=0;j<n2;++j){
377  //cout<<"par="<<par[i]<<" "<<par[j]<<endl;
378  if(par[i]<0 || par[j]<0)C[i][j]=0;
379  else C[i][j]=_errm[par[i]][par[j]];
380  }
381  }
382 }
383 
384 
385 void
386 TFitBin::getCov(int i, int j, TMatrixD& C) const {
387  // now build up matrix:
388  int n2=4;
389  C.ResizeTo(n2,n2);
390  vector<int> par; // vector of (real parameters)
391  par.push_back(_indices[i].first);
392  par.push_back(_indices[i].second);
393  par.push_back(_indices[j].first);
394  par.push_back(_indices[j].second);
395  for(int i=0;i<n2;++i){
396  for(int j=0;j<n2;++j){
397  //cout<<"par="<<par[i]<<" "<<par[j]<<endl;
398  if(par[i]<0 || par[j]<0)C[i][j]=0;
399  else C[i][j]=_errm[par[i]][par[j]];
400  }
401  }
402 }
403 
404 
405 void
407  for(unsigned int i=0;i<_amps.size();++i){
408  cout << _wavenames[i] << " " << _amps[i] << " +- ("
409  << sqrt( _errm[_indices[i].first][_indices[i].first] )
410  << "," ;
411  if(_indices[i].second>=0){
412  cout << sqrt( _errm[_indices[i].second][_indices[i].second] )
413  << ")" << endl;
414  }
415  else {
416  cout << "0)" << endl;
417  }
418  }
419 
420 }
421 
422 void
423 TFitBin::printAmpsGenPW(ostream& s) const {
424  for(unsigned int i=0;i<_amps.size();++i){
425  s << _wavenames[i] << " "
426  << _amps[i].Re() << " "
427  << _amps[i].Im() << endl;
428  }
429 }
430 
431 
432 
433 
434 void
435 TFitBin::getParameters(double* par) const {
436  unsigned int c=0;
437  for(unsigned int i=0;i<_amps.size();++i){
438  par[c++]=_amps[i].Re();
439  if(_indices[i].second>=0){ // check if this one exists
440  par[c++]=_amps[i].Im();
441  }
442  }
443 }