musrfit 1.10.0
PRunBase.cpp
Go to the documentation of this file.
1/***************************************************************************
2
3 PRunBase.cpp
4
5 Author: Andreas Suter
6 e-mail: andreas.suter@psi.ch
7
8***************************************************************************/
9
10/***************************************************************************
11 * Copyright (C) 2007-2026 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 <iostream>
31
32#include <TROOT.h>
33#include <TSystem.h>
34#include <TString.h>
35#include <TObjArray.h>
36#include <TObjString.h>
37#include <TFolder.h>
38
39#include "PRunBase.h"
40
41//--------------------------------------------------------------------------
42// Constructor
43//--------------------------------------------------------------------------
55{
56 fRunNo = -1;
57 fRunInfo = nullptr;
58 fRawData = nullptr;
60 fMetaData.fEnergy = PMUSR_UNDEFINED;
61 fTimeResolution = -1.0;
62
65
66 fValid = true;
68}
69
70//--------------------------------------------------------------------------
71// Constructor
72//--------------------------------------------------------------------------
94PRunBase::PRunBase(PMsrHandler *msrInfo, PRunDataHandler *rawData, UInt_t runNo, EPMusrHandleTag tag) :
95 fHandleTag(tag), fMsrInfo(msrInfo), fRawData(rawData)
96{
97 fValid = true;
98
99 fRunNo = static_cast<Int_t>(runNo);
100 if (runNo > fMsrInfo->GetMsrRunList()->size()) {
101 fRunInfo = nullptr;
102 return;
103 }
104
105 // keep the run header info for this run
106 fRunInfo = &(*fMsrInfo->GetMsrRunList())[runNo];
107
108 // check the parameter and map range of the functions
109 if (!fMsrInfo->CheckMapAndParamRange(static_cast<UInt_t>(fRunInfo->GetMap()->size()), fMsrInfo->GetNoOfParams())) {
110 std::cerr << std::endl << "**SEVERE ERROR** PRunBase::PRunBase: map and/or parameter out of range in FUNCTIONS." << std::endl;
111 exit(0);
112 }
113
114 // init private variables
115 fMetaData.fField = PMUSR_UNDEFINED;
116 fMetaData.fEnergy = PMUSR_UNDEFINED;
117 fTimeResolution = -1.0;
118 for (Int_t i=0; i<fMsrInfo->GetNoOfFuncs(); i++)
119 fFuncValues.push_back(0.0);
120
121 // generate theory
122 fTheory = std::make_unique<PTheory>(fMsrInfo, runNo);
123 if (fTheory == nullptr) {
124 std::cerr << std::endl << "**SEVERE ERROR** PRunBase::PRunBase: Couldn't create an instance of PTheory :-(, will quit" << std::endl;
125 exit(0);
126 }
127 if (!fTheory->IsValid()) {
128 std::cerr << std::endl << "**SEVERE ERROR** PRunBase::PRunBase: Theory is not valid :-(, will quit" << std::endl;
129 exit(0);
130 }
131
132 // set fit time ranges
135}
136
137//--------------------------------------------------------------------------
138// Destructor
139//--------------------------------------------------------------------------
153{
154 fT0s.clear();
155 for (UInt_t i=0; i<fAddT0s.size(); i++)
156 fAddT0s[i].clear();
157 fAddT0s.clear();
158
159 fFuncValues.clear();
160}
161
162//--------------------------------------------------------------------------
163// DeadTimeCorrection (protected)
164//--------------------------------------------------------------------------
171void PRunBase::DeadTimeCorrection(std::vector<PDoubleVector> &histos, PUIntVector &histoNo)
172{
173 PRawRunData* runData = fRawData->GetRunData(*fRunInfo->GetRunName());
174
175 if (runData == nullptr) {
176 std::cerr << std::endl << "**WARNING** PRunBase::DeadTimeCorrection: couldn't get data from '" << *fRunInfo->GetRunName() << "'" << std::endl;
177 return;
178 }
179
180 bool checkDeadTime{false};
181 PMsrRunList *rl = fMsrInfo->GetMsrRunList();
182 for (unsigned int i=0; i<rl->size(); i++) {
183 if (!rl->at(i).GetFileFormat()->CompareTo("nexus", TString::kIgnoreCase)) {
184 checkDeadTime = true;
185 break;
186 }
187 }
188
189 if (!runData->DeadTimeCorrectionReady() && checkDeadTime) {
190 std::cerr << std::endl << "**WARNING** PRunBase::DeadTimeCorrection: missing input for dead time correction" << std::endl;
191 return;
192 }
193
194
195 // check if a dead time correction has to be done
196 // first check the global block
197 TString dtcg = fMsrInfo->GetMsrGlobal()->GetDeadTimeCorrection();
198 Int_t dtcg_tag = 0; // 0=no, 1=file, 2=estimate
199 if (dtcg.Contains("file", TString::kIgnoreCase)) {
200 dtcg_tag = 1;
201 } else if (dtcg.Contains("estimate", TString::kIgnoreCase)) {
202 dtcg_tag = 2;
203 }
204 // now check each run
205 TString dtcr{"no"};
206 Bool_t needToCheck{true};
207 for (UInt_t i=0; i<histoNo.size(); i++) {
208 dtcr = fRunInfo->GetDeadTimeCorrection();
209 if (dtcr.Contains("file", TString::kIgnoreCase) || (dtcg_tag != 0)) {
210 if (runData->DeadTimeCorrectionReady()) {
211 needToCheck = false;
212 // Dead time correction: n_true = n_obs / (1 - n_obs * t_dt / (good_frames * dt))
213 Double_t n_true;
214 Int_t gf = runData->GetNumberOfGoodFrames();
215 std::vector<float> t_dt = runData->GetDeadTimeParam();
216 for (UInt_t j=0; j<histos[i].size(); j++) {
217 n_true = histos[i][j] / (1.0 - histos[i][j] * t_dt[histoNo[i]-1] / (gf * fTimeResolution));
218 histos[i][j] = n_true;
219 }
220 }
221 }
222 if ((dtcr.Contains("estimate", TString::kIgnoreCase) || (dtcg_tag != 0)) && needToCheck) {
223 std::cerr << std::endl << "**INFO** deadtime correction estimate not yet implemented." << std::endl;
224 }
225 }
226}
227
228//--------------------------------------------------------------------------
229// SetFitRange (public)
230//--------------------------------------------------------------------------
253{
254 Double_t start=0.0, end=0.0;
255
256 assert(fitRange.size()); // make sure fitRange is not empty
257
258 if (fitRange.size()==1) { // one fit range for all
259 start = fitRange[0].first;
260 end = fitRange[0].second;
261 } else {
262 // check that fRunNo is found within fitRange
263 UInt_t idx=static_cast<UInt_t>(fRunNo);
264 if (idx < fitRange.size()) { // fRunNo present
265 start = fitRange[idx].first;
266 end = fitRange[idx].second;
267 } else { // fRunNo NOT present
268 std::cerr << std::endl << ">> PRunBase::SetFitRange(): **ERROR** msr-file run entry " << fRunNo << " not present in fit range vector.";
269 std::cerr << std::endl << ">> Will not do anything! Please check, this shouldn't happen." << std::endl;
270 return;
271 }
272 }
273
274 // check that start is before end
275 if (start > end) {
276 std::cerr << std::endl << ">> PRunBase::SetFitRange(): **WARNING** start=" << start << " is > as end=" << end;
277 std::cerr << std::endl << ">> Will swap them, since otherwise chisq/logLH == 0.0" << std::endl;
278 fFitStartTime = end;
279 fFitEndTime = start;
280 } else {
281 fFitStartTime = start;
282 fFitEndTime = end;
283 }
284}
285
286//--------------------------------------------------------------------------
287// CleanUp (public)
288//--------------------------------------------------------------------------
299{
300 fTheory.reset();
301}
302
303//--------------------------------------------------------------------------
304// CalculateKaiserFilterCoeff (protected)
305//--------------------------------------------------------------------------
339void PRunBase::CalculateKaiserFilterCoeff(Double_t wc, Double_t A, Double_t dw)
340{
341 Double_t beta;
342 Double_t dt = fData.GetTheoryTimeStep();
343 Int_t m;
344
345 // estimate beta (see reference above, p.574ff)
346 if (A > 50.0) {
347 beta = 0.1102*(A-8.7);
348 } else if ((A >= 21.0) && (A <= 50.0)) {
349 beta = 0.5842*TMath::Power(A-21.0, 0.4) + 0.07886*(A-21.0);
350 } else {
351 beta = 0.0;
352 }
353
354 m = TMath::FloorNint((A-8.0)/(2.285*dw*TMath::Pi()));
355 // make sure m is odd
356 if (m % 2 == 0)
357 m++;
358
359 Double_t alpha = static_cast<Double_t>(m)/2.0;
360 Double_t dval;
361 Double_t dsum = 0.0;
362 for (Int_t i=0; i<=m; i++) {
363 dval = TMath::Sin(wc*(i-alpha)*dt)/(TMath::Pi()*(i-alpha)*dt);
364 dval *= TMath::BesselI0(beta*TMath::Sqrt(1.0-TMath::Power((i-alpha)*dt/alpha, 2.0)))/TMath::BesselI0(beta);
365 dsum += dval;
366 fKaiserFilter.push_back(dval);
367 }
368 for (UInt_t i=0; i<=static_cast<UInt_t>(m); i++) {
369 fKaiserFilter[i] /= dsum;
370 }
371}
372
373//--------------------------------------------------------------------------
374// FilterTheo (protected)
375//--------------------------------------------------------------------------
406{
407 PDoubleVector theoFiltered;
408 Double_t dval = 0.0;
409 const PDoubleVector *theo = fData.GetTheory();
410
411 for (UInt_t i=0; i<theo->size(); i++) {
412 for (UInt_t j=0; j<fKaiserFilter.size(); j++) {
413 if (i<j)
414 dval = 0.0;
415 else
416 dval += fKaiserFilter[j]*theo->at(i-j);
417 }
418 theoFiltered.push_back(dval);
419 dval = 0.0;
420 }
421
422 fData.ReplaceTheory(theoFiltered);
423
424 // shift time start by half the filter length
425 dval = fData.GetTheoryTimeStart() - 0.5*static_cast<Double_t>(fKaiserFilter.size())*fData.GetTheoryTimeStep();
426 fData.SetTheoryTimeStart(dval);
427
428 theoFiltered.clear();
429}
std::vector< UInt_t > PUIntVector
Definition PMusr.h:361
EPMusrHandleTag
Definition PMusr.h:413
@ kEmpty
No operation active.
Definition PMusr.h:414
std::vector< PMsrRunBlock > PMsrRunList
Definition PMusr.h:1245
#define PMUSR_UNDEFINED
Definition PMusr.h:172
std::vector< PDoublePair > PDoublePairVector
Definition PMusr.h:397
std::vector< Double_t > PDoubleVector
Definition PMusr.h:385
if(xmlFile.is_open())
MSR file parser and manager for the musrfit framework.
virtual const Int_t GetNumberOfGoodFrames()
Definition PMusr.h:876
virtual const Bool_t DeadTimeCorrectionReady()
Definition PMusr.cpp:734
virtual const std::vector< float > GetDeadTimeParam()
Definition PMusr.h:877
virtual void CleanUp()
Cleans up internal data structures.
Definition PRunBase.cpp:298
Double_t fTimeResolution
Time resolution of raw histogram data in microseconds (μs), e.g., 0.01953125 μs for PSI GPS.
Definition PRunBase.h:276
virtual ~PRunBase()
Virtual destructor.
Definition PRunBase.cpp:152
Bool_t fValid
Flag indicating if run object initialized successfully; false if any error occurred.
Definition PRunBase.h:266
Double_t fFitEndTime
Fit range end time in microseconds (μs) relative to t0.
Definition PRunBase.h:282
PDoubleVector fFuncValues
Cached values of user-defined functions from FUNCTIONS block, evaluated at current parameters.
Definition PRunBase.h:284
PDoubleVector fKaiserFilter
Kaiser window FIR filter coefficients for smoothing RRF theory curves.
Definition PRunBase.h:287
virtual void SetFitRange(PDoublePairVector fitRange)
Sets the fit time range for this run.
Definition PRunBase.cpp:252
PMsrHandler * fMsrInfo
Pointer to MSR file handler (owned externally, not deleted here)
Definition PRunBase.h:271
virtual void DeadTimeCorrection(std::vector< PDoubleVector > &histos, PUIntVector &histoNo)
carry out dead time correction
Definition PRunBase.cpp:171
PMetaData fMetaData
Experimental metadata extracted from data file header (magnetic field, temperature,...
Definition PRunBase.h:277
std::unique_ptr< PTheory > fTheory
Theory function evaluator (smart pointer, automatically deleted)
Definition PRunBase.h:285
std::vector< PDoubleVector > fAddT0s
Time-zero bin values for additional runs to be added to main run.
Definition PRunBase.h:279
EPMusrHandleTag fHandleTag
Operation mode: kFit (fitting), kView (display only), kEmpty (uninitialized)
Definition PRunBase.h:268
virtual void CalculateKaiserFilterCoeff(Double_t wc, Double_t A, Double_t dw)
Calculates Kaiser window FIR filter coefficients for RRF smoothing.
Definition PRunBase.cpp:339
PRunData fData
Processed data container: background-corrected, packed, with theory values.
Definition PRunBase.h:275
PRunDataHandler * fRawData
Pointer to raw data handler (owned externally, not deleted here)
Definition PRunBase.h:273
PDoubleVector fT0s
Time-zero bin values for all histograms in this run (forward, backward, etc.)
Definition PRunBase.h:278
PRunBase()
Default constructor.
Definition PRunBase.cpp:54
Int_t fRunNo
Run number (0-based index in MSR file RUN blocks)
Definition PRunBase.h:270
PMsrRunBlock * fRunInfo
Pointer to this run's RUN block settings within fMsrInfo.
Definition PRunBase.h:272
Double_t fFitStartTime
Fit range start time in microseconds (μs) relative to t0.
Definition PRunBase.h:281
virtual void FilterTheo()
Applies Kaiser FIR filter to theory values for RRF fits.
Definition PRunBase.cpp:405
Raw data file reader and format converter for μSR data.