musrfit  1.9.2
PPrepFourier.cpp
Go to the documentation of this file.
1 /***************************************************************************
2 
3  PPrepFourier.cpp
4 
5  Author: Andreas Suter
6  e-mail: andreas.suter@psi.ch
7 
8 ***************************************************************************/
9 
10 /***************************************************************************
11  * Copyright (C) 2007-2023 by Andreas Suter *
12  * andreas.suter@psi.ch *
13  * *
14  * This program is free software; you can redistribute it and/or modify *
15  * it under the terms of the GNU General Public License as published by *
16  * the Free Software Foundation; either version 2 of the License, or *
17  * (at your option) any later version. *
18  * *
19  * This program is distributed in the hope that it will be useful, *
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
22  * GNU General Public License for more details. *
23  * *
24  * You should have received a copy of the GNU General Public License *
25  * along with this program; if not, write to the *
26  * Free Software Foundation, Inc., *
27  * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
28  ***************************************************************************/
29 
30 #include <cmath>
31 
32 #include "PPrepFourier.h"
33 
34 //--------------------------------------------------------------------------
35 // Constructor
36 //--------------------------------------------------------------------------
41 {
42  fBkgRange[0] = -1;
43  fBkgRange[1] = -1;
44  fPacking = 1;
45 }
46 
47 //--------------------------------------------------------------------------
48 // Constructor
49 //--------------------------------------------------------------------------
53 PPrepFourier::PPrepFourier(const Int_t packing, const Int_t *bkgRange, PDoubleVector bkg) :
54  fPacking(packing)
55 {
56  SetBkgRange(bkgRange);
57  SetBkg(bkg);
58 }
59 
60 //--------------------------------------------------------------------------
61 // Destructor
62 //--------------------------------------------------------------------------
67 {
68  fRawData.clear();
69  fData.clear();
70 }
71 
72 //--------------------------------------------------------------------------
73 // SetBkgRange
74 //--------------------------------------------------------------------------
80 void PPrepFourier::SetBkgRange(const Int_t *bkgRange)
81 {
82  Int_t err=0;
83  if (bkgRange[0] >= -1) {
84  fBkgRange[0] = bkgRange[0];
85  } else {
86  err = 1;
87  }
88  if (bkgRange[1] >= -1) {
89  fBkgRange[1] = bkgRange[1];
90  } else {
91  if (err == 0)
92  err = 2;
93  else
94  err = 3;
95  }
96 
97  TString errMsg("");
98  switch (err) {
99  case 1:
100  errMsg = TString::Format("start bkg range < 0 (given: %d), will ignore it.", bkgRange[0]);
101  break;
102  case 2:
103  errMsg = TString::Format("end bkg range < 0 (given: %d), will ignore it.", bkgRange[1]);
104  break;
105  case 3:
106  errMsg = TString::Format("start/end bkg range < 0 (given: %d/%d), will ignore it.", bkgRange[0], bkgRange[1]);
107  break;
108  default:
109  errMsg = TString("??");
110  break;
111  }
112 
113  if (err != 0) {
114  std::cerr << std::endl << ">> PPrepFourier::SetBkgRange: **WARNING** " << errMsg << std::endl;
115  }
116 }
117 
118 //--------------------------------------------------------------------------
119 // SetBkgRange
120 //--------------------------------------------------------------------------
127 {
128  for (UInt_t i=0; i<bkg.size(); i++)
129  fBkg.push_back(bkg[i]);
130 }
131 
132 //--------------------------------------------------------------------------
133 // SetPacking
134 //--------------------------------------------------------------------------
140 void PPrepFourier::SetPacking(const Int_t packing)
141 {
142  if (packing > 0) {
143  fPacking = packing;
144  } else {
145  std::cerr << std::endl << ">> PPrepFourier::SetPacking: **WARNING** found packing=" << packing << " < 0, will ignore it." << std::endl;
146  }
147 }
148 
149 //--------------------------------------------------------------------------
150 // AddData
151 //--------------------------------------------------------------------------
159 {
160  fRawData.push_back(data);
161 }
162 
163 //--------------------------------------------------------------------------
164 // DoBkgCorrection
165 //--------------------------------------------------------------------------
170 {
171  // make sure fData are already present, and if not create the necessary data sets
172  if (fData.size() != fRawData.size()) {
173  InitData();
174  }
175 
176  // if no bkg-range is given, nothing needs to be done
177  if ((fBkgRange[0] == -1) && (fBkgRange[1] == -1) && (fBkg.size() == 0)) {
178  return;
179  }
180 
181  if ((fBkgRange[0] != -1) && (fBkgRange[1] != -1)) { // background range is given
182  // make sure that the bkg range is ok
183  for (UInt_t i=0; i<fRawData.size(); i++) {
184  if ((fBkgRange[0] >= static_cast<Int_t>(fRawData[i].rawData.size())) || (fBkgRange[1] >= static_cast<Int_t>(fRawData[i].rawData.size()))) {
185  std::cerr << std::endl << "PPrepFourier::DoBkgCorrection() **ERROR** bkg-range out of data-range!";
186  return;
187  }
188  }
189 
190  Double_t bkg=0.0;
191  for (UInt_t i=0; i<fRawData.size(); i++) {
192  // calculate the bkg for the given range
193  for (Int_t j=fBkgRange[0]; j<=fBkgRange[1]; j++) {
194  bkg += fRawData[i].rawData[j];
195  }
196  bkg /= (fBkgRange[1]-fBkgRange[0]+1);
197  std::cout << "info> background " << i << ": " << bkg << std::endl;
198 
199  // correct data
200  for (UInt_t j=0; j<fData[i].size(); j++)
201  fData[i][j] -= bkg;
202  }
203  } else { // there might be an explicit background list
204  // check if there is a background list
205  if (fBkg.size() == 0)
206  return;
207 
208  // check if there are as many background values than data values
209  if (fBkg.size() != fData.size()) {
210  std::cerr << std::endl << "PPrepFourier::DoBkgCorrection() **ERROR** #bkg values != #histos. Will do nothing here." << std::endl;
211  return;
212  }
213 
214  for (UInt_t i=0; i<fData.size(); i++)
215  for (UInt_t j=0; j<fData[i].size(); j++)
216  fData[i][j] -= fBkg[i];
217  }
218 }
219 
220 //--------------------------------------------------------------------------
221 // DoPacking
222 //--------------------------------------------------------------------------
227 {
228  // make sure fData are already present, and if not create the necessary data sets
229  if (fData.size() != fRawData.size()) {
230  InitData();
231  }
232 
233  if (fPacking == 1) // nothing to be done
234  return;
235 
236  PDoubleVector tmpData;
237  Double_t dval = 0.0;
238  for (UInt_t i=0; i<fData.size(); i++) {
239  tmpData.clear();
240  dval = 0.0;
241  for (UInt_t j=0; j<fData[i].size(); j++) {
242  if ((j % fPacking == 0) && (j != 0)) {
243  tmpData.push_back(dval);
244  dval = 0.0;
245  } else {
246  dval += fData[i][j];
247  }
248  }
249  // change the original data set with the packed one
250  fData[i].clear();
251  fData[i] = tmpData;
252  }
253 }
254 
255 //--------------------------------------------------------------------------
256 // DoLifeTimeCorrection
257 //--------------------------------------------------------------------------
266 {
267  // make sure fData are already present, and if not create the necessary data sets
268  if (fData.size() != fRawData.size()) {
269  InitData();
270  }
271 
272  // calc exp(+t/tau)*N(t), where N(t) is already background corrected
273  Double_t scale;
274  for (UInt_t i=0; i<fData.size(); i++) {
275  scale = fRawData[i].timeResolution / PMUON_LIFETIME;
276  for (UInt_t j=0; j<fData[i].size(); j++) {
277  fData[i][j] *= exp(j*scale);
278  }
279  }
280 
281  // calc N0
282  Double_t dval;
283  Double_t N0;
284  for (UInt_t i=0; i<fData.size(); i++) {
285  dval = 0.0;
286  for (UInt_t j=0; j<fData[i].size(); j++) {
287  dval += fData[i][j];
288  }
289  N0 = dval/fData[i].size();
290  N0 *= fudge;
291  for (UInt_t j=0; j<fData[i].size(); j++) {
292  fData[i][j] -= N0;
293  fData[i][j] /= N0;
294  }
295  }
296 }
297 
298 //--------------------------------------------------------------------------
299 // GetInfo
300 //--------------------------------------------------------------------------
306 TString PPrepFourier::GetInfo(const UInt_t idx)
307 {
308  TString info("");
309 
310  if (idx < fRawData.size())
311  info = fRawData[idx].info;
312 
313  return info;
314 }
315 
316 //--------------------------------------------------------------------------
317 // GetDataSetTag
318 //--------------------------------------------------------------------------
324 Int_t PPrepFourier::GetDataSetTag(const UInt_t idx)
325 {
326  Int_t result = -1;
327 
328  if (idx < fRawData.size())
329  result = fRawData[idx].dataSetTag;
330 
331  return result;
332 }
333 
334 //--------------------------------------------------------------------------
335 // GetData
336 //--------------------------------------------------------------------------
341 std::vector<TH1F*> PPrepFourier::GetData()
342 {
343  std::vector<TH1F*> data;
344  data.resize(fData.size());
345 
346  // if not data are present, just return an empty vector
347  if (fData.size() == 0)
348  return data;
349 
350  TString name("");
351  Double_t dt=0.0;
352  Double_t start=0.0;
353  Double_t end=0.0;
354  UInt_t size;
355  UInt_t startIdx;
356  UInt_t endIdx;
357 
358  for (UInt_t i=0; i<fData.size(); i++) {
359  name = TString::Format("histo%2d", i);
360  dt = fRawData[i].timeResolution*fPacking;
361  start = fRawData[i].timeRange[0];
362  end = fRawData[i].timeRange[1];
363 
364  // init size and start/end indices
365  size = fData[i].size();
366  startIdx = 1;
367  endIdx = size;
368 
369  // time range given, hence calculate the proper size
370  if (start != -1.0) {
371  size = static_cast<UInt_t>((end-start)/dt);
372  if (start >= 0.0) {
373  startIdx = static_cast<UInt_t>(start/dt)+1;
374  endIdx = static_cast<UInt_t>(end/dt)+1;
375  } else {
376  std::cerr << std::endl << ">> PPrepFourier::GetData **WARNING** found start time < 0.0, will set it to 0.0" << std::endl;
377  endIdx = static_cast<UInt_t>(end/dt)+1;
378  }
379  }
380 
381  if (start == -1.0) { // no time range given, hence start == 0.0 - dt/2
382  start = -dt/2.0;
383  } else { // time range given
384  start -= dt/2.0;
385  }
386 
387  if (end == -1.0) { // no time range given, hence end == (fData[idx].size()-1)*dt + dt/2
388  end = (fData[i].size()-1)*dt+dt/2.0;
389  } else { // time range given
390  end += dt/2.0;
391  }
392 
393  data[i] = new TH1F(name.Data(), fRawData[i].info.Data(), size, start, end);
394  for (UInt_t j=startIdx; j<endIdx; j++)
395  data[i]->SetBinContent(j-startIdx+1, fData[i][j]);
396  }
397 
398  return data;
399 }
400 
401 //--------------------------------------------------------------------------
402 // GetData
403 //--------------------------------------------------------------------------
410 TH1F *PPrepFourier::GetData(const UInt_t idx)
411 {
412  if (fData.size() == 0) // no data present
413  return nullptr;
414 
415  if (idx > fData.size()) // requested index out of range
416  return nullptr;
417 
418  TString name = TString::Format("histo%2d", idx);
419  Double_t dt = fRawData[idx].timeResolution*fPacking;
420  Double_t start = fRawData[idx].timeRange[0];
421  Double_t end = fRawData[idx].timeRange[1];
422  UInt_t size = fData[idx].size();
423  UInt_t startIdx = 1;
424  UInt_t endIdx = size;
425 
426  // time range given, hence calculate the proper size
427  if (start != -1.0) {
428  size = static_cast<UInt_t>((end-start)/dt);
429  if (start >= 0.0) {
430  startIdx = static_cast<UInt_t>(start/dt)+1;
431  endIdx = static_cast<UInt_t>(end/dt)+1;
432  } else {
433  std::cerr << std::endl << ">> PPrepFourier::GetData **WARNING** found start time < 0.0, will set it to 0.0" << std::endl;
434  endIdx = static_cast<UInt_t>(end/dt)+1;
435  }
436  }
437 
438  if (start == -1.0) { // no time range given, hence start == 0.0 - dt/2
439  start = -dt/2.0;
440  } else { // time range given
441  start -= dt/2.0;
442  }
443 
444  if (end == -1.0) { // no time range given, hence end == (fData[idx].size()-1)*dt + dt/2
445  end = (fData[idx].size()-1)*dt+dt/2.0;
446  } else { // time range given
447  end += dt/2.0;
448  }
449 
450  TH1F *data = new TH1F(name.Data(), fRawData[idx].info.Data(), size, start, end);
451  for (UInt_t i=startIdx; i<endIdx; i++)
452  data->SetBinContent(i-startIdx+1, fData[idx][i]);
453 
454  return data;
455 }
456 
457 //--------------------------------------------------------------------------
458 // InitData (private)
459 //--------------------------------------------------------------------------
464 {
465  fData.resize(fRawData.size());
466  UInt_t t0;
467  for (UInt_t i=0; i<fRawData.size(); i++) {
468  if (fRawData[i].t0 >= 0)
469  t0 = fRawData[i].t0;
470  else
471  t0 = 0;
472  for (UInt_t j=t0; j<fRawData[i].rawData.size(); j++) {
473  fData[i].push_back(fRawData[i].rawData[j]);
474  }
475  }
476 }
TString GetInfo(const UInt_t idx)
virtual void DoPacking()
#define PMUON_LIFETIME
Definition: PMusr.h:68
virtual void DoBkgCorrection()
std::vector< TH1F * > GetData()
std::vector< musrFT_data > fRawData
Definition: PPrepFourier.h:81
virtual void SetPacking(const Int_t packing)
virtual ~PPrepFourier()
PDoubleVector fBkg
Definition: PPrepFourier.h:84
Int_t fBkgRange[2]
Definition: PPrepFourier.h:83
virtual void InitData()
std::vector< Double_t > PDoubleVector
Definition: PMusr.h:196
virtual void SetBkgRange(const Int_t *bkgRange)
std::vector< PDoubleVector > fData
Definition: PPrepFourier.h:82
Int_t GetDataSetTag(const UInt_t idx)
virtual void DoLifeTimeCorrection(Double_t fudge)
virtual void SetBkg(PDoubleVector bkg)
Int_t fPacking
Definition: PPrepFourier.h:85
virtual void AddData(musrFT_data &data)