musrfit 1.10.0
PRunNonMusr.cpp
Go to the documentation of this file.
1/***************************************************************************
2
3 PRunNonMusr.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 "PRunNonMusr.h"
33
34//--------------------------------------------------------------------------
35// Constructor
36//--------------------------------------------------------------------------
55{
56 fNoOfFitBins = 0;
57 fPacking = 1;
58 fStartTimeBin = 0;
59 fEndTimeBin = 0;
60
62
63 fRawRunData = nullptr;
64}
65
66//--------------------------------------------------------------------------
67// Constructor
68//--------------------------------------------------------------------------
113PRunNonMusr::PRunNonMusr(PMsrHandler *msrInfo, PRunDataHandler *rawData, UInt_t runNo, EPMusrHandleTag tag, Bool_t theoAsData) :
114 PRunBase(msrInfo, rawData, runNo, tag), fTheoAsData(theoAsData)
115{
116 // get the proper run
117 fRawRunData = fRawData->GetRunData(*(fRunInfo->GetRunName()));
118 if (!fRawRunData) { // couldn't get run
119 std::cerr << std::endl << "PRunNonMusr::PRunNonMusr(): **ERROR** Couldn't get raw run data!";
120 std::cerr << std::endl;
121 fValid = false;
122 }
123
124 // calculate fData
125 if (!PrepareData())
126 fValid = false;
127}
128
129//--------------------------------------------------------------------------
130// Destructor
131//--------------------------------------------------------------------------
146
147//--------------------------------------------------------------------------
148// CalcChiSquare
149//--------------------------------------------------------------------------
189Double_t PRunNonMusr::CalcChiSquare(const std::vector<Double_t>& par)
190{
191 Double_t chisq = 0.0;
192 Double_t diff = 0.0;
193
194 // calculate functions
195 for (Int_t i=0; i<fMsrInfo->GetNoOfFuncs(); i++) {
196 fFuncValues[i] = fMsrInfo->EvalFunc(fMsrInfo->GetFuncNo(i), *fRunInfo->GetMap(), par, fMetaData);
197 }
198
199 // calculate chi square
200 Double_t x(1.0);
201 for (UInt_t i=fStartTimeBin; i<=fEndTimeBin; i++) {
202 x = fData.GetX()->at(i);
203 diff = fData.GetValue()->at(i) - fTheory->Func(x, par, fFuncValues);
204 chisq += diff*diff / (fData.GetError()->at(i)*fData.GetError()->at(i));
205 }
206
207 return chisq;
208}
209
210//--------------------------------------------------------------------------
211// CalcChiSquareExpected (public)
212//--------------------------------------------------------------------------
235Double_t PRunNonMusr::CalcChiSquareExpected(const std::vector<Double_t>& par)
236{
237 std::cout << std::endl << "PRunNonMusr::CalcChiSquareExpected(): not implemented yet ..." << std::endl;
238
239 return 0.0;
240}
241
242//--------------------------------------------------------------------------
243// CalcMaxLikelihood
244//--------------------------------------------------------------------------
273Double_t PRunNonMusr::CalcMaxLikelihood(const std::vector<Double_t>& par)
274{
275 std::cout << std::endl << "PRunNonMusr::CalcMaxLikelihood(): not implemented yet ..." << std::endl;
276
277 return 1.0;
278}
279
280//--------------------------------------------------------------------------
281// CalcTheory
282//--------------------------------------------------------------------------
300{
301}
302
303//--------------------------------------------------------------------------
304// GetNoOfFitBins (public)
305//--------------------------------------------------------------------------
331{
332 fNoOfFitBins=0;
333 Double_t x;
334 for (UInt_t i=0; i<fData.GetValue()->size(); i++) {
335 x = fData.GetX()->at(i);
336 if ((x >= fFitStartTime) && (x <= fFitEndTime))
337 fNoOfFitBins++;
338 }
339
340 return fNoOfFitBins;
341}
342
343//--------------------------------------------------------------------------
344// PrepareData
345//--------------------------------------------------------------------------
354{
355 Bool_t success = true;
356
357 if (!fValid)
358 return false;
359
360 if (fRunInfo->GetRunNameSize() > 1) { // ADDRUN present which is not supported for NonMusr
361 std::cerr << std::endl << ">> PRunNonMusr::PrepareData(): **WARNING** ADDRUN NOT SUPPORTED FOR THIS FIT TYPE, WILL IGNORE IT." << std::endl;
362 }
363
364 // get packing info
365 fPacking = fRunInfo->GetPacking();
366 if (fPacking == -1) { // packing not present in the RUN block, will try the GLOBAL block
367 fPacking = fMsrInfo->GetMsrGlobal()->GetPacking();
368 }
369 if (fPacking == -1) { // packing NOT present, in neither the RUN block, nor in the GLOBAL block
370 std::cerr << std::endl << ">> PRunNonMusr::PrepareData(): **ERROR** couldn't find any packing information." << std::endl;
371 return false;
372 }
373
374 // get fit start/end time
375 fFitStartTime = fRunInfo->GetFitRange(0);
376 fFitEndTime = fRunInfo->GetFitRange(1);
377 if (fFitStartTime == PMUSR_UNDEFINED) { // not present in the RUN block, will try GLOBAL block
378 fFitStartTime = fMsrInfo->GetMsrGlobal()->GetFitRange(0);
379 fFitEndTime = fMsrInfo->GetMsrGlobal()->GetFitRange(1);
380 }
381
382 if (fHandleTag == kFit)
383 success = PrepareFitData();
384 else if (fHandleTag == kView)
385 success = PrepareViewData();
386 else
387 success = false;
388
389 return success;
390}
391
392//--------------------------------------------------------------------------
393// PrepareFitData
394//--------------------------------------------------------------------------
403{
404 Bool_t success = true;
405
406 // get x-, y-index
407 UInt_t xIndex = GetXIndex();
408 UInt_t yIndex = GetYIndex();
409
410 // pack the raw data
411 Double_t value = 0.0;
412 Double_t err = 0.0;
413 for (UInt_t i=0; i<fRawRunData->fDataNonMusr.GetData()->at(xIndex).size(); i++) {
414 if (fPacking == 1) {
415 fData.AppendXValue(fRawRunData->fDataNonMusr.GetData()->at(xIndex).at(i));
416 fData.AppendValue(fRawRunData->fDataNonMusr.GetData()->at(yIndex).at(i));
417 fData.AppendErrorValue(fRawRunData->fDataNonMusr.GetErrData()->at(yIndex).at(i));
418 } else { // packed data, i.e. fPacking > 1
419 if ((i % fPacking == 0) && (i != 0)) { // fill data
420 fData.AppendXValue(fRawRunData->fDataNonMusr.GetData()->at(xIndex).at(i)-(fRawRunData->fDataNonMusr.GetData()->at(xIndex).at(i)-fRawRunData->fDataNonMusr.GetData()->at(xIndex).at(i-fPacking))/2.0);
421 fData.AppendValue(value);
422 fData.AppendErrorValue(TMath::Sqrt(err));
423 value = 0.0;
424 err = 0.0;
425 }
426 // sum raw data values
427 value += fRawRunData->fDataNonMusr.GetData()->at(yIndex).at(i);
428 err += fRawRunData->fDataNonMusr.GetErrData()->at(yIndex).at(i)*fRawRunData->fDataNonMusr.GetErrData()->at(yIndex).at(i);
429 }
430 }
431
432 // count the number of bins to be fitted
433 fNoOfFitBins=0;
434 Double_t x;
435 for (UInt_t i=0; i<fData.GetValue()->size(); i++) {
436 x = fData.GetX()->at(i);
437 if ((x >= fFitStartTime) && (x <= fFitEndTime))
438 fNoOfFitBins++;
439 }
440
441 // get start/end bin
442 const PDoubleVector *xx = fData.GetX();
443 fStartTimeBin = 0;
444 fEndTimeBin = xx->size()-1;
445 for (UInt_t i=0; i<xx->size(); i++) {
446 if (xx->at(i) < fFitStartTime)
447 fStartTimeBin = i;
448 if (xx->at(i) < fFitEndTime)
449 fEndTimeBin = i;
450 }
451
452 return success;
453}
454
455//--------------------------------------------------------------------------
456// PrepareViewData
457//--------------------------------------------------------------------------
466{
467 Bool_t success = true;
468
469 // get x-, y-index
470 UInt_t xIndex = GetXIndex();
471 UInt_t yIndex = GetYIndex();
472
473 // fill data histo
474 // pack the raw data
475 Double_t value = 0.0;
476 Double_t err = 0.0;
477 for (UInt_t i=0; i<fRawRunData->fDataNonMusr.GetData()->at(xIndex).size(); i++) {
478 if (fPacking == 1) {
479 fData.AppendXValue(fRawRunData->fDataNonMusr.GetData()->at(xIndex).at(i));
480 fData.AppendValue(fRawRunData->fDataNonMusr.GetData()->at(yIndex).at(i));
481 fData.AppendErrorValue(fRawRunData->fDataNonMusr.GetErrData()->at(yIndex).at(i));
482 } else { // packed data, i.e. fPacking > 1
483 if ((i % fPacking == 0) && (i != 0)) { // fill data
484 fData.AppendXValue(fRawRunData->fDataNonMusr.GetData()->at(xIndex).at(i)-(fRawRunData->fDataNonMusr.GetData()->at(xIndex).at(i)-fRawRunData->fDataNonMusr.GetData()->at(xIndex).at(i-fPacking))/2.0);
485 fData.AppendValue(value);
486 fData.AppendErrorValue(TMath::Sqrt(err));
487 value = 0.0;
488 err = 0.0;
489 }
490 // sum raw data values
491 value += fRawRunData->fDataNonMusr.GetData()->at(yIndex).at(i);
492 err += fRawRunData->fDataNonMusr.GetErrData()->at(yIndex).at(i)*fRawRunData->fDataNonMusr.GetErrData()->at(yIndex).at(i);
493 }
494 }
495
496 // count the number of bins to be fitted
497 fNoOfFitBins = fData.GetValue()->size();
498
499 // fill theory histo
500 // feed the parameter vector
501 std::vector<Double_t> par;
502 PMsrParamList *paramList = fMsrInfo->GetMsrParamList();
503 for (UInt_t i=0; i<paramList->size(); i++)
504 par.push_back((*paramList)[i].fValue);
505 // calculate functions
506 for (Int_t i=0; i<fMsrInfo->GetNoOfFuncs(); i++) {
507 fFuncValues[i] = fMsrInfo->EvalFunc(fMsrInfo->GetFuncNo(i), *fRunInfo->GetMap(), par, fMetaData);
508 }
509
510 // get plot range
511 PMsrPlotList *plotList;
512 PMsrPlotStructure plotBlock;
513 plotList = fMsrInfo->GetMsrPlotList();
514 // find the proper plot block
515 // Here a small complication to be handled: there are potentially multiple
516 // run blocks and the run might be present in various of these run blocks. In
517 // order to get a nice resolution on the theory the following procedure will be
518 // followed: the smallest x-interval found will be used to for the fXTheory resolution
519 // which is 1000 function points. The function will be calculated from the smallest
520 // xmin found up to the largest xmax found.
521 Double_t xMin = 0.0, xMax = 0.0;
522
523 // init xMin/xMax, xAbsMin/xAbsMax
524 plotBlock = plotList->at(0);
525 if (plotBlock.fTmin.size() == 0) { // check if no range information is present
526 PMsrRunList *runList = fMsrInfo->GetMsrRunList();
527 xMin = runList->at(0).GetFitRange(0);
528 xMax = runList->at(0).GetFitRange(1);
529 for (UInt_t i=1; i<runList->size(); i++) {
530 if (runList->at(i).GetFitRange(0) < xMin)
531 xMin = runList->at(i).GetFitRange(0);
532 if (runList->at(i).GetFitRange(1) > xMax)
533 xMax = runList->at(i).GetFitRange(1);
534 }
535 } else if (plotBlock.fTmin.size() == 1) { // check if 'range' information is present
536 xMin = plotBlock.fTmin[0];
537 xMax = plotBlock.fTmax[0];
538 } else if (plotBlock.fTmin.size() > 1) { // check if 'sub_ranges' information is present
539 xMin = plotBlock.fTmin[0];
540 xMax = plotBlock.fTmax[0];
541 for (UInt_t i=1; i<plotBlock.fTmin.size(); i++) {
542 if (plotBlock.fTmin[i] < xMin)
543 xMin = plotBlock.fTmin[i];
544 if (plotBlock.fTmax[i] > xMax)
545 xMax = plotBlock.fTmax[i];
546 }
547 }
548
549 if (plotBlock.fUseFitRanges) { // check if 'use_fit_ranges' information is present
550 PMsrRunList *runList = fMsrInfo->GetMsrRunList();
551 xMin = runList->at(0).GetFitRange(0);
552 xMax = runList->at(0).GetFitRange(1);
553 for (UInt_t i=1; i<runList->size(); i++) {
554 if (runList->at(i).GetFitRange(0) < xMin)
555 xMin = runList->at(i).GetFitRange(0);
556 if (runList->at(i).GetFitRange(1) > xMax)
557 xMax = runList->at(i).GetFitRange(1);
558 }
559 }
560
561 for (UInt_t i=1; i<plotList->size(); i++) { // go through all the plot blocks
562 plotBlock = plotList->at(i);
563
564 if (plotBlock.fTmin.size() == 0) { // check if no range information is present
565 PMsrRunList *runList = fMsrInfo->GetMsrRunList();
566 for (UInt_t i=0; i<runList->size(); i++) {
567 if (runList->at(i).GetFitRange(0) < xMin)
568 xMin = runList->at(i).GetFitRange(0);
569 if (runList->at(i).GetFitRange(1) > xMax)
570 xMax = runList->at(i).GetFitRange(1);
571 }
572 } else if (plotBlock.fTmin.size() == 1) { // check if 'range' information is present
573 if (plotBlock.fTmin[0] < xMin)
574 xMin = plotBlock.fTmin[0];
575 if (plotBlock.fTmax[0] > xMax)
576 xMax = plotBlock.fTmax[0];
577 } else if (plotBlock.fTmin.size() > 1) { // check if 'sub_ranges' information is present
578 for (UInt_t i=0; i<plotBlock.fTmin.size(); i++) {
579 if (plotBlock.fTmin[i] < xMin)
580 xMin = plotBlock.fTmin[i];
581 if (plotBlock.fTmax[i] > xMax)
582 xMax = plotBlock.fTmax[i];
583 }
584 }
585
586 if (plotBlock.fUseFitRanges) { // check if 'use_fit_ranges' information is present
587 PMsrRunList *runList = fMsrInfo->GetMsrRunList();
588 for (UInt_t i=0; i<runList->size(); i++) {
589 if (runList->at(i).GetFitRange(0) < xMin)
590 xMin = runList->at(i).GetFitRange(0);
591 if (runList->at(i).GetFitRange(1) > xMax)
592 xMax = runList->at(i).GetFitRange(1);
593 }
594 }
595 }
596
597 // typically take 1000 points to calculate the theory, except if there are more data points, than take that number
598 Double_t xStep;
599 if (fData.GetX()->size() > 1000.0)
600 xStep = (xMax-xMin)/fData.GetX()->size();
601 else
602 xStep = (xMax-xMin)/1000.0;
603
604 if (fTheoAsData) {
605 Double_t xx;
606 for (UInt_t i=0; i<fRawRunData->fDataNonMusr.GetData()->at(xIndex).size(); i++) {
607 // fill x-vector
608 xx = fRawRunData->fDataNonMusr.GetData()->at(xIndex).at(i);
609 fData.AppendXTheoryValue(xx);
610 // fill y-vector
611 fData.AppendTheoryValue(fTheory->Func(xx, par, fFuncValues));
612 }
613 } else {
614 Double_t xx = xMin;
615 do {
616 // fill x-vector
617 fData.AppendXTheoryValue(xx);
618 // fill y-vector
619 fData.AppendTheoryValue(fTheory->Func(xx, par, fFuncValues));
620 // calculate next xx
621 xx += xStep;
622 } while (xx < xMax);
623 }
624
625 // clean up
626 par.clear();
627
628 return success;
629}
630
631//--------------------------------------------------------------------------
632// GetXIndex
633//--------------------------------------------------------------------------
641{
642 UInt_t index = 0;
643 Bool_t found = false;
644
645 if (fRawRunData->fDataNonMusr.FromAscii()) { // ascii-file format
646 index = 0;
647 found = true;
648 } else { // db-file format
649 if (fRunInfo->GetXDataIndex() > 0) { // xy-data already indices
650 index = fRunInfo->GetXDataIndex()-1; // since xy-data start with 1 ...
651 found = true;
652 } else { // xy-data data tags which needs to be converted to an index
653 for (UInt_t i=0; i<fRawRunData->fDataNonMusr.GetDataTags()->size(); i++) {
654 if (fRawRunData->fDataNonMusr.GetDataTags()->at(i).CompareTo(*fRunInfo->GetXDataLabel()) == 0) {
655 index = i;
656 found = true;
657 break;
658 }
659 }
660 }
661 }
662
663 if (!found) {
664 std::cerr << std::endl << "PRunNonMusr::GetXIndex(): **ERROR** Couldn't obtain x-data index!";
665 std::cerr << std::endl;
666 assert(0);
667 }
668
669 return index;
670}
671
672//--------------------------------------------------------------------------
673// GetYIndex
674//--------------------------------------------------------------------------
682{
683 UInt_t index = 0;
684 Bool_t found = false;
685
686 if (fRawRunData->fDataNonMusr.FromAscii()) { // ascii-file format
687 index = 1;
688 found = true;
689 } else { // db-file format
690 if (fRunInfo->GetYDataIndex() > 0) { // xy-data already indices
691 index = fRunInfo->GetYDataIndex()-1; // since xy-data start with 1 ...
692 found = true;
693 } else { // xy-data data tags which needs to be converted to an index
694 for (UInt_t i=0; i<fRawRunData->fDataNonMusr.GetDataTags()->size(); i++) {
695 if (fRawRunData->fDataNonMusr.GetDataTags()->at(i).CompareTo(*fRunInfo->GetYDataLabel()) == 0) {
696 index = i;
697 found = true;
698 break;
699 }
700 }
701 }
702 }
703
704 if (!found) {
705 std::cerr << std::endl << "PRunNonMusr::GetYIndex(): **ERROR** Couldn't obtain y-data index!";
706 std::cerr << std::endl;
707 assert(0);
708 }
709
710 return index;
711}
EPMusrHandleTag
Definition PMusr.h:413
@ kEmpty
No operation active.
Definition PMusr.h:414
@ kFit
Fitting mode - perform least-squares fit to data.
Definition PMusr.h:415
@ kView
Viewing mode - display data and theory without fitting.
Definition PMusr.h:416
std::vector< PMsrRunBlock > PMsrRunList
Definition PMusr.h:1245
#define PMUSR_UNDEFINED
Definition PMusr.h:172
std::vector< PMsrPlotStructure > PMsrPlotList
Definition PMusr.h:1312
std::vector< PMsrParamStructure > PMsrParamList
Definition PMusr.h:1022
std::vector< Double_t > PDoubleVector
Definition PMusr.h:385
if(xmlFile.is_open())
MSR file parser and manager for the musrfit framework.
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
PMsrHandler * fMsrInfo
Pointer to MSR file handler (owned externally, not deleted here)
Definition PRunBase.h:271
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
EPMusrHandleTag fHandleTag
Operation mode: kFit (fitting), kView (display only), kEmpty (uninitialized)
Definition PRunBase.h:268
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
PRunBase()
Default constructor.
Definition PRunBase.cpp:54
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
Raw data file reader and format converter for μSR data.
Int_t fStartTimeBin
Index of first data point in fit range.
virtual ~PRunNonMusr()
Virtual destructor (no cleanup needed for this class).
virtual UInt_t GetNoOfFitBins()
Returns the number of x-y points within the fit range.
PRawRunData * fRawRunData
Pointer to raw run data handler (not owned).
virtual Bool_t PrepareData()
Main data preparation orchestrator for non-μSR data.
Bool_t fTheoAsData
Theory calculation mode flag.
Int_t fPacking
Data point averaging/grouping factor.
PRunNonMusr()
Default constructor creating an empty, invalid non-μSR run object.
virtual Double_t CalcChiSquareExpected(const std::vector< Double_t > &par)
Calculates expected χ² (NOT IMPLEMENTED for non-μSR).
Int_t fEndTimeBin
Index of last data point in fit range (inclusive).
virtual Double_t CalcChiSquare(const std::vector< Double_t > &par)
Calculates χ² between non-μSR data and theory.
virtual void CalcTheory()
Evaluates theory function (empty implementation for non-μSR).
virtual Bool_t PrepareViewData()
Prepares x-y data for viewing/plotting.
virtual UInt_t GetXIndex()
Returns the x-axis column index from MSR file specification.
virtual Double_t CalcMaxLikelihood(const std::vector< Double_t > &par)
Calculates maximum likelihood (NOT IMPLEMENTED for non-μSR).
virtual UInt_t GetYIndex()
Returns the y-axis column index from MSR file specification.
UInt_t fNoOfFitBins
Number of x-y points within fit range (fFitStartTime ≤ x ≤ fFitEndTime)
virtual Bool_t PrepareFitData()
Prepares x-y data for fitting.
Bool_t fUseFitRanges
yes -> use the fit ranges to plot the data, no (default) -> use range information if present
Definition PMusr.h:1292
PDoubleVector fTmax
time maximum
Definition PMusr.h:1298
PDoubleVector fTmin
time minimum
Definition PMusr.h:1297