musrfit 1.12.1
musrFT.cpp
Go to the documentation of this file.
1/***************************************************************************
2
3 musrFT.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#ifdef HAVE_CONFIG_H
31#include "config.h"
32#endif
33
34#include <omp.h>
35
36#include <sys/time.h>
37
38#include <iostream>
39#include <fstream>
40#include <vector>
41#include <string>
42#include <memory>
43
44#include <TApplication.h>
45#include <TROOT.h>
46#include <TString.h>
47#include <TSAXParser.h>
48
49#ifdef HAVE_GIT_REV_H
50#include "git-revision.h"
51#endif
52
53#include "PMusr.h"
54#include "PStringUtils.h"
55#include "PStartupHandler.h"
56#include "PMsrHandler.h"
57#include "PRunDataHandler.h"
58#include "PPrepFourier.h"
59#include "PFourier.h"
60#include "PFourierCanvas.h"
61
62//----------------------------------------------------------------------------
91
92//-------------------------------------------------------------------------
97{
98 std::cout << std::endl << "usage: musrFT [Options] [<msr-files> | -df, --data-file <data-file>]";
99 std::cout << std::endl << " <msr-files> : msr-file name(s). These msr-files are used for the Fourier transform.";
100 std::cout << std::endl << " It can be a list of msr-files, e.g. musrFT 3110.msr 3111.msr";
101 std::cout << std::endl << " For the syntax of the msr-file check the user manual of musrfit.";
102 std::cout << std::endl << " -df, --data-file <data-file> : This allows to feed only muSR data file(s) to";
103 std::cout << std::endl << " perform the Fourier transform. Since the extended <msr-file> information";
104 std::cout << std::endl << " are missing, they will need to be provided by to options, or musrFT";
105 std::cout << std::endl << " tries to guess, based on musrfit_startup.xml settings.";
106 std::cout << std::endl << " Options: ";
107 std::cout << std::endl << " --help : display this help and exit";
108 std::cout << std::endl << " --version : output version information and exit";
109 std::cout << std::endl << " -g, --graphic-format <graphic-format-extension> : ";
110 std::cout << std::endl << " will produce a graphic-output-file without starting a root session.";
111 std::cout << std::endl << " the name is based either on the <msr-file> or the <data-file>,";
112 std::cout << std::endl << " e.g. 3310.msr -> 3310_0.png.";
113 std::cout << std::endl << " Supported graphic-format-extension: eps, pdf, gif, jpg, png, svg, xpm, root";
114 std::cout << std::endl << " --dump <fln> : rather than starting a root session and showing Fourier graphs of the data,";
115 std::cout << std::endl << " it will output the Fourier data in an ascii file <fln>.";
116 std::cout << std::endl << " -br, --background-range <start> <end>: background interval used to estimate the background to be";
117 std::cout << std::endl << " subtracted before the Fourier transform. <start>, <end> to be given in bins.";
118 std::cout << std::endl << " -bg, --background <list> : gives the background explicit for each histogram.";
119 std::cout << std::endl << " -fo, --fourier-option <fopt>: <fopt> can be 'real', 'imag', 'real+imag', 'power', 'phase', or 'phaseOptReal'.";
120 std::cout << std::endl << " If this is not defined (neither on the command line nor in the musrfit_startup.xml),";
121 std::cout << std::endl << " default will be 'power'.";
122 std::cout << std::endl << " -ap, --apodization <val> : <val> can be either 'none', 'weak', 'medium', 'strong'.";
123 std::cout << std::endl << " Default will be 'none'.";
124 std::cout << std::endl << " -fp, --fourier-power <N> : <N> being the Fourier power, i.e. 2^<N> used for zero padding.";
125 std::cout << std::endl << " Default is -1, i.e. no zero padding will be performed.";
126 std::cout << std::endl << " -u, --units <units> : <units> is used to define the x-axis of the Fourier transform.";
127 std::cout << std::endl << " One may choose between the fields (Gauss) or (Tesla), the frequency (MHz),";
128 std::cout << std::endl << " and the angular-frequency domain (Mc/s).";
129 std::cout << std::endl << " Default will be 'MHz'.";
130 std::cout << std::endl << " -ph, --phase <val> : defines the initial phase <val>. This only is of concern for 'real',";
131 std::cout << std::endl << " '<imag>', and 'real+imag'.";
132 std::cout << std::endl << " Default will be 0.0.";
133 std::cout << std::endl << " -fr, --fourier-range <start> <end> : Fourier range. <start>, <end> are interpreted in the units given.";
134 std::cout << std::endl << " Default will be -1.0 for both which means, take the full Fourier range.";
135 std::cout << std::endl << " -tr, --time-range <start> <end> : time domain range to be used for Fourier transform.";
136 std::cout << std::endl << " <start>, <end> are to be given in (us). If nothing is given, the full time range";
137 std::cout << std::endl << " found in the data file(s) will be used.";
138 std::cout << std::endl << " --histo <list> : give the <list> of histograms to be used for the Fourier transform.";
139 std::cout << std::endl << " E.g. musrFT -df lem15_his_01234.root --histo 1 3, will only be needed together with";
140 std::cout << std::endl << " the option --data-file. If multiple data file are given, <list> will apply";
141 std::cout << std::endl << " to all data-files given. If --histo is not given, all histos of a data file will be used.";
142 std::cout << std::endl << " <list> can be anything like: 2 3 6, or 2-17, or 1-6 9, etc.";
143 std::cout << std::endl << " -a, --average : show the average of ALL Fourier transformed data.";
144 std::cout << std::endl << " -ad, --average-per-data-set : show the average of the Fourier transformed data per data set.";
145 std::cout << std::endl << " --t0 <list> : A list of t0's can be provided. This in conjunction with --data-file and";
146 std::cout << std::endl << " --fourier-option real allows to get the proper initial phase if t0's are known.";
147 std::cout << std::endl << " If a single t0 for multiple histos is given, it is assume, that this t0 is common";
148 std::cout << std::endl << " to all histos.";
149 std::cout << std::endl << " Example: musrFT -df lem15_his_01234.root -fo real --t0 2750 --histo 1 3";
150 std::cout << std::endl << " -pa, --packing <N> : if <N> (an integer), the time domain data will first be packed/rebinned by <N>.";
151 std::cout << std::endl << " --title <title> : give a global title for the plot.";
152 std::cout << std::endl << " --create-msr-file <fln> : creates a msr-file based on the command line options";
153 std::cout << std::endl << " provided. This will help on the way to a full fitting model.";
154 std::cout << std::endl << " -lc, --lifetimecorrection <fudge>: try to eliminate muon life time decay. Only makes sense for low";
155 std::cout << std::endl << " transverse fields. <fudge> is a tweaking factor and should be kept around 1.0.";
156 std::cout << std::endl << " --timeout <timeout> : <timeout> given in seconds after which musrFT terminates.";
157 std::cout << std::endl << " If <timeout> <= 0, no timeout will take place. Default <timeout> is 3600.";
158 std::cout << std::endl << std::endl;
159}
160
161//-------------------------------------------------------------------------
168{
169 startupParam.graphicFormat = TString("");
170 startupParam.dumpFln = TString("");
171 startupParam.msrFlnOut = TString("");
172 startupParam.bkg_range[0] = -1;
173 startupParam.bkg_range[1] = -1;
174 startupParam.fourierOpt = TString("??");
175 startupParam.apodization = TString("none");
176 startupParam.fourierPower = -1;
177 startupParam.fourierUnits = TString("??");
178 startupParam.initialPhase = 0.0;
179 startupParam.fourierRange[0] = -1.0;
180 startupParam.fourierRange[1] = -1.0;
181 startupParam.timeRange[0] = -1.0;
182 startupParam.timeRange[1] = -1.0;
183 startupParam.showAverage = false;
184 startupParam.showAveragePerDataSet = false;
185 startupParam.packing = 1;
186 startupParam.title = TString("");
187 startupParam.lifetimecorrection = 0.0;
188 startupParam.timeout = 3600;
189}
190
191//-------------------------------------------------------------------------
207Bool_t musrFT_filter_histo(Int_t &i, Int_t argc, Char_t *argv[], musrFT_startup_param &startupParam)
208{
209 Int_t start = i+1, end = 0;
210
211 // find last element of histo option
212 while (++i < argc) {
213 if (argv[i][0] == '-') {
214 if (!isdigit(argv[i][1]) || (argv[i][1] == '-'))
215 break;
216 }
217 }
218 end = i;
219 --i;
220 if (end < start) {
221 std::cerr << std::endl << ">> musrFT **ERROR** something is wrong with the --histo arguments." << std::endl;
222 startupParam.histo.clear();
223 return false;
224 }
225
226 // handle histo arguments
227 TString tstr("");
228 for (Int_t j=start; j<end; j++) {
229 tstr = argv[j];
230 if (!tstr.Contains("-")) { // likely to be a single number
231 if (tstr.IsDigit()) {
232 startupParam.histo.push_back(tstr.Atoi());
233 } else { // not a number -> error
234 std::cerr << std::endl << ">> musrFT **ERROR** found --histo argument '" << tstr << "' which is not a number." << std::endl;
235 startupParam.histo.clear();
236 return false;
237 }
238 } else { // should be something like h0-hN with h0, hN numbers
239 std::vector<std::string> tok = PStringUtils::Split(tstr.Data(), "-");
240 if (tok.size() != 2) {
241 std::cerr << std::endl << ">> musrFT **ERROR** found --histo argument '" << tstr << "' which is not of the form <h0>-<hN>." << std::endl;
242 startupParam.histo.clear();
243 return false;
244 }
245 TString sstr("");
246 Int_t first=0, last=0;
247 sstr = tok[0];
248 if (sstr.IsDigit()) {
249 first = sstr.Atoi();
250 } else {
251 std::cerr << std::endl << ">> musrFT **ERROR** found --histo argument '" << tstr << "' which is of the form <h0>-<hN>,";
252 std::cerr << std::endl << " but <h0>='" << sstr << "' is not a number." << std::endl;
253 startupParam.histo.clear();
254 return false;
255 }
256 sstr = tok[1];
257 if (sstr.IsDigit()) {
258 last = sstr.Atoi();
259 } else {
260 std::cerr << std::endl << ">> musrFT **ERROR** found --histo argument '" << tstr << "' which is of the form <h0>-<hN>,";
261 std::cerr << std::endl << " but <hN>='" << sstr << "' is not a number." << std::endl;
262 startupParam.histo.clear();
263 return false;
264 }
265
266 if (first > last) {
267 std::cerr << std::endl << ">> musrFT **ERROR** found --histo argument of the form <h0>-<hN> with h0=" << first << " > hN=" << last << "." << std::endl;
268 startupParam.histo.clear();
269 return false;
270 }
271
272 for (Int_t k=first; k<=last; k++) {
273 startupParam.histo.push_back(k);
274 }
275 }
276 }
277
278 return true;
279}
280
281//-------------------------------------------------------------------------
291Int_t musrFT_parse_options(Int_t argc, Char_t *argv[], musrFT_startup_param &startupParam)
292{
293 TString tstr("");
294
295 for (Int_t i=1; i<argc; i++) {
296 tstr = argv[i];
297 if (tstr.BeginsWith("--version")) {
298#ifdef HAVE_CONFIG_H
299#ifdef HAVE_GIT_REV_H
300 std::cout << std::endl << "musrFT version: " << PACKAGE_VERSION << ", git-branch: " << GIT_BRANCH << ", git-rev: " << GIT_CURRENT_SHA1 << " (" << BUILD_TYPE << "), ROOT version: " << ROOT_VERSION_USED << std::endl << std::endl;
301#else
302 std::cout << std::endl << "musrFT version: " << PACKAGE_VERSION << " (" << BUILD_TYPE << "), ROOT version: " << ROOT_VERSION_USED << std::endl << std::endl;
303#endif
304#else
305#ifdef HAVE_GIT_REV_H
306 std::cout << std::endl << "musrFT git-branch: " << GIT_BRANCH << ", git-rev: " << GIT_CURRENT_SHA1 << std::endl << std::endl;
307#else
308 std::cout << std::endl << "musrFT version: unknown." << std::endl << std::endl;
309#endif
310#endif
311 return 1;
312 } else if (tstr.BeginsWith("--help")) {
314 return 1;
315 } else if (tstr.BeginsWith("-g") || tstr.BeginsWith("--graphic-format")) {
316 if (i+1 >= argc) { // something is wrong since there needs to be an argument here
317 std::cerr << std::endl << ">> musrFT **ERROR** found option --graphic-format without argument!" << std::endl;
318 return 2;
319 }
320 TString topt(argv[i+1]);
321 if (!topt.BeginsWith("eps") && !topt.BeginsWith("pdf") && !topt.BeginsWith("gif") && !topt.BeginsWith("jpg") &&
322 !topt.BeginsWith("png") && !topt.BeginsWith("svg") && !topt.BeginsWith("xpm") && !topt.BeginsWith("root")) {
323 std::cerr << std::endl << ">> musrFT **ERROR** found unrecogniced graphic format '" << topt << "'!" << std::endl;
324 return 2;
325 }
326 startupParam.graphicFormat = topt;
327 i++;
328 } else if (tstr.BeginsWith("--dump")) {
329 if (i+1 >= argc) { // something is wrong since there needs to be an argument here
330 std::cerr << std::endl << ">> musrFT **ERROR** found option --dump without argument!" << std::endl;
331 return 2;
332 }
333 startupParam.dumpFln = argv[i+1];
334 i++;
335 } else if (tstr.Contains("-br") || tstr.Contains("--background-range")) {
336 if (i+2 >= argc) { // something is wrong since there needs to be two arguments here
337 std::cerr << std::endl << ">> musrFT **ERROR** found option --background-range with wrong number of arguments." << std::endl;
338 return 2;
339 }
340 TString bkgRange[2];
341 bkgRange[0] = argv[i+1];
342 bkgRange[1] = argv[i+2];
343 if (!bkgRange[0].IsDigit()) {
344 std::cerr << std::endl << ">> musrFT **ERROR** <start> bin of option --background-range is NOT an int-number! ('" << bkgRange[0] << "')." << std::endl;
345 return 2;
346 }
347 if (!bkgRange[1].IsDigit()) {
348 std::cerr << std::endl << ">> musrFT **ERROR** <end> bin of option --background-range is NOT an int-number! ('" << bkgRange[1] << "')." << std::endl;
349 return 2;
350 }
351 startupParam.bkg_range[0] = bkgRange[0].Atoi();
352 startupParam.bkg_range[1] = bkgRange[1].Atoi();
353 i += 2;
354 } else if (tstr.BeginsWith("-bg") || !tstr.CompareTo("--background")) {
355 TString topt("");
356 while (++i < argc) {
357 if (argv[i][0] == '-') {
358 --i;
359 break;
360 } else {
361 topt = argv[i];
362 if (!topt.IsFloat()) {
363 std::cerr << std::endl << ">> musrFT **ERROR** found option --background='" << topt << "' which is not a float" << std::endl;
364 return 2;
365 }
366 startupParam.bkg.push_back(topt.Atoi());
367 }
368 }
369 if (startupParam.bkg.size() == 0) { // something is wrong since there needs to be an argument here
370 std::cerr << std::endl << ">> musrFT **ERROR** found option --background without argument!" << std::endl;
371 return 2;
372 }
373 } else if (tstr.BeginsWith("-fo") || tstr.BeginsWith("--fourier-option")) {
374 if (i+1 >= argc) { // something is wrong since there needs to be two arguments here
375 std::cerr << std::endl << ">> musrFT **ERROR** found option --fourier-option without arguments." << std::endl;
376 return 2;
377 }
378 TString topt(argv[i+1]);
379 if (!topt.BeginsWith("real") && !topt.BeginsWith("imag") && !topt.BeginsWith("power") &&
380 !topt.BeginsWith("phase") && !topt.BeginsWith("phaseOptReal")) {
381 std::cerr << std::endl << ">> musrFT **ERROR** found option --fourier-option with unrecognized argument '" << topt << "'." << std::endl;
382 return 2;
383 }
384 startupParam.fourierOpt = topt;
385 i++;
386 } else if (tstr.BeginsWith("-ap") || tstr.BeginsWith("--apodization")) {
387 if (i+1 >= argc) { // something is wrong since there needs to be two arguments here
388 std::cerr << std::endl << ">> musrFT **ERROR** found option --apodization without arguments." << std::endl;
389 return 2;
390 }
391 TString topt(argv[i+1]);
392 if (!topt.BeginsWith("none") && !topt.BeginsWith("weak") && !topt.BeginsWith("medium") && !topt.BeginsWith("strong")) {
393 std::cerr << std::endl << ">> musrFT **ERROR** found option --apodization with unrecognized argument '" << topt << "'." << std::endl;
394 return 2;
395 }
396 startupParam.apodization = topt;
397 i++;
398 } else if (tstr.BeginsWith("-fp") || tstr.BeginsWith("--fourier-power")) {
399 if (i+1 >= argc) { // something is wrong since there needs to be two arguments here
400 std::cerr << std::endl << ">> musrFT **ERROR** found option --fourier-power without arguments." << std::endl;
401 return 2;
402 }
403 TString fourierPower(argv[i+1]);
404 if (!fourierPower.IsDigit()) {
405 std::cerr << std::endl << ">> musrFT **ERROR** found option --fourier-power with a power which is not an integer '" << fourierPower << "'." << std::endl;
406 return 2;
407 }
408 startupParam.fourierPower = fourierPower.Atoi();
409 if ((startupParam.fourierPower < 1) || (startupParam.fourierPower > 20)) {
410 std::cerr << std::endl << ">> musrFT **ERROR** found Fourier power '" << fourierPower << "', which is out of range [1..20]" << std::endl;
411 return 2;
412 }
413 i++;
414 } else if (tstr.BeginsWith("-u") || tstr.BeginsWith("--units")) {
415 if (i+1 >= argc) { // something is wrong since there needs to be two arguments here
416 std::cerr << std::endl << ">> musrFT **ERROR** found option --units without arguments." << std::endl;
417 return 2;
418 }
419 TString topt(argv[i+1]);
420 if (!topt.BeginsWith("MHz", TString::kIgnoreCase) && !topt.BeginsWith("Gauss", TString::kIgnoreCase) &&
421 !topt.BeginsWith("Tesla", TString::kIgnoreCase) && !topt.BeginsWith("Mc/s", TString::kIgnoreCase)) {
422 std::cerr << std::endl << ">> musrFT **ERROR** found option --fourier-option with unrecognized argument '" << topt << "'." << std::endl;
423 return 2;
424 }
425 startupParam.fourierUnits = topt;
426 i++;
427 } else if (tstr.BeginsWith("-ph") || tstr.BeginsWith("--phase")) {
428 if (i+1 >= argc) { // something is wrong since there needs to be an argument here
429 std::cerr << std::endl << ">> musrFT **ERROR** found option --phase without argument!" << std::endl;
430 return 2;
431 }
432 TString phase(argv[i+1]);
433 if (!phase.IsFloat()) {
434 std::cerr << std::endl << ">> musrFT **ERROR** found --phase argument '" << phase << "' which is not a number." << std::endl;
435 return 2;
436 }
437 startupParam.initialPhase = phase.Atof();
438 i++;
439 } else if (tstr.BeginsWith("-fr") || tstr.BeginsWith("--fourier-range")) {
440 if (i+2 >= argc) { // something is wrong since there needs to be an argument here
441 std::cerr << std::endl << ">> musrFT **ERROR** found option --fourier-range with wrong number of arguments!" << std::endl;
442 return 2;
443 }
444 TString fourierRange[2] = {argv[i+1], argv[i+2]};
445 if (!fourierRange[0].IsFloat() || !fourierRange[1].IsFloat()) {
446 std::cerr << std::endl << ">> musrFT **ERROR** found invalid --fourier-range arguments '" << fourierRange[0] << "' and/or '" << fourierRange[1] << "'." << std::endl;
447 return 2;
448 }
449 startupParam.fourierRange[0] = fourierRange[0].Atof();
450 startupParam.fourierRange[1] = fourierRange[1].Atof();
451 i += 2;
452 } else if (tstr.BeginsWith("-tr") || tstr.BeginsWith("--time-range")) {
453 if (i+2 >= argc) { // something is wrong since there needs to be an argument here
454 std::cerr << std::endl << ">> musrFT **ERROR** found option --time-range with wrong number of arguments!" << std::endl;
455 return 2;
456 }
457 TString timeRange[2] = {argv[i+1], argv[i+2]};
458 if (!timeRange[0].IsFloat() || !timeRange[1].IsFloat()) {
459 std::cerr << std::endl << ">> musrFT **ERROR** found invalid --time-range arguments '" << timeRange[0] << "' and/or '" << timeRange[1] << "'." << std::endl;
460 return 2;
461 }
462 startupParam.timeRange[0] = timeRange[0].Atof();
463 startupParam.timeRange[1] = timeRange[1].Atof();
464 i += 2;
465 } else if (!tstr.CompareTo("-a") || !tstr.CompareTo("--average")) {
466 startupParam.showAverage = true;
467 } else if (!tstr.CompareTo("-ad") || !tstr.CompareTo("--average-per-data-set")) {
468 startupParam.showAveragePerDataSet = true;
469 } else if (tstr.BeginsWith("--histo")) {
470 if (!musrFT_filter_histo(i, argc, argv, startupParam))
471 return 2;
472 } else if (tstr.BeginsWith("--t0")) {
473 TString topt("");
474 while (++i < argc) {
475 if (argv[i][0] == '-') {
476 --i;
477 break;
478 } else {
479 topt = argv[i];
480 if (!topt.IsDigit()) {
481 std::cerr << std::endl << ">> musrFT **ERROR** found option t0='" << topt << "' which is not a number" << std::endl;
482 return 2;
483 }
484 startupParam.t0.push_back(topt.Atoi());
485 }
486 }
487 if (startupParam.t0.size() == 0) { // something is wrong since there needs to be an argument here
488 std::cerr << std::endl << ">> musrFT **ERROR** found option --t0 without argument!" << std::endl;
489 return 2;
490 }
491 } else if (tstr.BeginsWith("--title")) {
492 if (i+1 >= argc) { // something is wrong since there needs to be an argument here
493 std::cerr << std::endl << ">> musrFT **ERROR** found option --title without argument!" << std::endl;
494 return 2;
495 }
496 ++i;
497 startupParam.title = argv[i];
498 } else if (tstr.BeginsWith("-pa") || tstr.BeginsWith("--packing")) {
499 if (i+1 >= argc) { // something is wrong since there needs to be an argument here
500 std::cerr << std::endl << ">> musrFT **ERROR** found option --packing without argument!" << std::endl;
501 return 2;
502 }
503 ++i;
504 TString pack = TString(argv[i]);
505 if (!pack.IsDigit()) {
506 std::cerr << std::endl << ">> musrFT **ERROR** found option --packing with argument '" << pack << "' which is NOT an integer!" << std::endl;
507 return 2;
508 }
509 startupParam.packing = pack.Atoi();
510 } else if (tstr.BeginsWith("--create-msr-file")) {
511 if (i+1 >= argc) { // something is wrong since there needs to be an argument here
512 std::cerr << std::endl << ">> musrFT **ERROR** found option --create-msr-file without argument!" << std::endl;
513 return 2;
514 }
515 ++i;
516 startupParam.msrFlnOut = TString(argv[i]);
517 } else if (tstr.BeginsWith("-lc") || tstr.BeginsWith("--lifetimecorrection")) {
518 if (i+1 >= argc) { // something is wrong since there needs to be an argument here
519 std::cerr << std::endl << ">> musrFT **ERROR** found option --lifetimecorrection without argument!" << std::endl;
520 return 2;
521 }
522 ++i;
523 TString fudge(argv[i]);
524 if (!fudge.IsFloat()) {
525 std::cerr << std::endl << ">> musrFT **ERROR** found option --lifetimecorrection with a fudge which is not a double '" << fudge << "'." << std::endl;
526 return 2;
527 }
528 startupParam.lifetimecorrection = fudge.Atof();
529 } else if (tstr.BeginsWith("--timeout")) {
530 if (i+1 >= argc) { // something is wrong since there needs to be an argument here
531 std::cerr << std::endl << ">> musrFT **ERROR** found option --timeout without argument!" << std::endl;
532 return 2;
533 }
534 ++i;
535 TString tt(argv[i]);
536 if (!tt.IsDigit()) {
537 std::cerr << std::endl << ">> musrFT **ERROR** found option --timeout with a <timeout> which is not an integer '" << tt << "'." << std::endl;
538 return 2;
539 }
540 startupParam.timeout = tt.Atoi();
541 } else if (tstr.BeginsWith("-df") || tstr.BeginsWith("--data-file")) {
542 while (++i < argc) {
543 if (argv[i][0] == '-') {
544 --i;
545 break;
546 } else {
547 startupParam.dataFln.push_back(argv[i]);
548 TString fln(argv[i]);
549 TString fileFormat("??");
550 if (fln.Contains(".root", TString::kIgnoreCase))
551 fileFormat = "MusrRoot";
552 else if (fln.Contains(".bin", TString::kIgnoreCase))
553 fileFormat = "PsiBin";
554 else if (fln.Contains(".mdu", TString::kIgnoreCase))
555 fileFormat = "PsiMdu";
556 else if (fln.Contains(".nxs", TString::kIgnoreCase))
557 fileFormat = "NeXus";
558 else if (fln.Contains(".msr", TString::kIgnoreCase))
559 fileFormat = "Mud";
560
561 if (fileFormat == "??") {
562 std::cerr << std::endl << ">> musrFT **ERROR** found data file name with unrecognized data file format ('" << fln << "')." << std::endl;
563 return 2;
564 } else {
565 startupParam.dataFileFormat.push_back(fileFormat);
566 }
567 }
568 }
569 if (startupParam.dataFln.size() == 0) { // something is wrong since there needs to be an argument here
570 std::cerr << std::endl << ">> musrFT **ERROR** found option --data-file without argument!" << std::endl;
571 return 2;
572 }
573 } else if (tstr.Contains(".msr")) {
574 startupParam.msrFln.push_back(tstr);
575 } else {
576 std::cerr << std::endl << ">> musrFT **ERROR** unrecognized option '" << tstr << "' found." << std::endl;
577 return 2;
578 }
579 }
580
581 // consistency checks
582 if ((startupParam.msrFln.size() == 0) && (startupParam.dataFln.size() == 0)) {
583 std::cerr << std::endl << ">> musrFT **ERROR** neither <msr-file> nor <data-file> defined." << std::endl;
584 return 2;
585 }
586 if (startupParam.bkg_range[0] > startupParam.bkg_range[1]) {
587 std::cerr << std::endl << ">> musrFT **WARNING** in --background-range, start=" << startupParam.bkg_range[0] << " > end=" << startupParam.bkg_range[1] << ", will swap them." << std::endl;
588 Double_t swap = startupParam.bkg_range[0];
589 startupParam.bkg_range[0] = startupParam.bkg_range[1];
590 startupParam.bkg_range[1] = swap;
591 }
592 if (startupParam.fourierRange[0] > startupParam.fourierRange[1]) {
593 std::cerr << std::endl << ">> musrFT **WARNING** in --fourier-range, start=" << startupParam.fourierRange[0] << " > end=" << startupParam.fourierRange[1] << ", will swap them." << std::endl;
594 Double_t swap = startupParam.fourierRange[0];
595 startupParam.fourierRange[0] = startupParam.fourierRange[1];
596 startupParam.fourierRange[1] = swap;
597 }
598 if (startupParam.showAverage && startupParam.showAveragePerDataSet) {
599 std::cerr << std::endl << ">> musrFT **WARNING** Options: --average and --average-per-data-set exclude each other, will choose the latter." << std::endl;
600 startupParam.showAverage = false;
601 }
602
603 return 0;
604}
605
606//----------------------------------------------------------------------------------------
614void musrFT_getMetaInfo(const TString fln, PRawRunData *rawRunData, TString &metaInfo)
615{
616 Double_t dval;
617 TString str = fln;
618 // file name
619 // trunc it in case a path-name is given
620 size_t idx = str.Last('/');
621 if (idx > 0)
622 str.Remove(0, idx+1);
623 metaInfo = str;
624 metaInfo += ",";
625 // temperature
626 for (UInt_t i=0; i<rawRunData->GetNoOfTemperatures(); i++) {
627 metaInfo += TString::Format("T%d=%0.2fK,", i, rawRunData->GetTemperature(i));
628 }
629 // magnetic field
630 dval = rawRunData->GetField();
631 if (dval == PMUSR_UNDEFINED)
632 metaInfo += TString("B=??,");
633 else if (dval < 5000.0)
634 metaInfo += TString::Format("B=%0.1fG,", dval);
635 else
636 metaInfo += TString::Format("B=%0.1fT,", dval/1.0e4);
637 // implantation energy
638 dval = rawRunData->GetEnergy();
639 if (dval == PMUSR_UNDEFINED)
640 metaInfo += TString("E=??;");
641 else if (dval < 1000.0)
642 metaInfo += TString::Format("E=%0.1fkeV;", dval);
643 else
644 metaInfo += TString::Format("E=%0.1fMeV;", dval/1.0e3);
645
646 metaInfo += *rawRunData->GetCryoName();
647 metaInfo += ";";
648 metaInfo += *rawRunData->GetSample();
649}
650
651//-------------------------------------------------------------------------
660{
661 std::cout << std::endl << ">> musrFT **WARNING** try to estimate t0 from maximum in the data set";
662 std::cout << std::endl << " '" << rd.info << "'";
663 std::cout << std::endl << " NO warranty this is sensible!" << std::endl;
664
665 UInt_t idx = 0;
666 Double_t max = rd.rawData[0];
667 for (UInt_t i=1; i<rd.rawData.size(); i++) {
668 if (rd.rawData[i] > max) {
669 max = rd.rawData[i];
670 idx = (Int_t)i;
671 }
672 }
673 std::cout << std::endl << ">> musrFT_estimateT0: estimated t0=" << idx << std::endl;
674 rd.t0 = idx;
675}
676
677//-------------------------------------------------------------------------
683void musrFT_cleanup(TH1F *h)
684{
685 if (h) {
686 delete h;
687 h = 0;
688 }
689}
690
691//-------------------------------------------------------------------------
700Int_t musrFT_dumpData(TString fln, std::vector<PFourier*> &fourierData, Double_t start, Double_t end)
701{
702 std::vector<PDoubleVector> data;
703 PDoubleVector freq;
704 PDoubleVector re;
705 PDoubleVector im;
706 PDoubleVector pwr;
707 TH1F *hRe=nullptr, *hIm=nullptr;
708 Double_t dval;
709
710 // make sure start/end are given, otherwise take the minimum/maximum off all data
711 hRe = fourierData[0]->GetRealFourier();
712 if (start == -1.0) {
713 start = hRe->GetBinCenter(1);
714 if (end == -1.0)
715 end = hRe->GetBinCenter(hRe->GetNbinsX());
716 }
717
718 UInt_t minSize = hRe->GetNbinsX()-1;
719 musrFT_cleanup(hRe);
720 for (UInt_t i=1; i<fourierData.size(); i++) {
721 hRe = fourierData[i]->GetRealFourier();
722 if (hRe->GetNbinsX()-1 < (Int_t)minSize)
723 minSize = hRe->GetNbinsX()-1;
724 musrFT_cleanup(hRe);
725 }
726
727 for (UInt_t i=0; i<fourierData.size(); i++) {
728 hRe = fourierData[i]->GetRealFourier();
729 hIm = fourierData[i]->GetImaginaryFourier();
730 for (Int_t j=1; j<(Int_t)minSize; j++) {
731 dval = hRe->GetBinCenter(j);
732 if ((dval >= start) && (dval <= end)) {
733 freq.push_back(dval);
734 re.push_back(hRe->GetBinContent(j));
735 im.push_back(hIm->GetBinContent(j));
736 pwr.push_back(hRe->GetBinContent(j)*hRe->GetBinContent(j)+hIm->GetBinContent(j)*hIm->GetBinContent(j));
737 }
738 }
739 data.push_back(freq);
740 data.push_back(re);
741 data.push_back(im);
742 data.push_back(pwr);
743 // cleanup
744 freq.clear();
745 re.clear();
746 im.clear();
747 pwr.clear();
748 musrFT_cleanup(hRe);
749 musrFT_cleanup(hIm);
750 }
751
752 std::ofstream fout(fln, std::ofstream::out);
753
754 // write header
755 fout << "% ";
756 for (UInt_t i=0; i<fourierData.size()-1; i++)
757 fout << "freq" << i << ", Re[d" << i << "], Im[d" << i << "], Pwr[d" << i << "], ";
758 fout << "freq" << fourierData.size()-1 << ", Re[d" << fourierData.size()-1 << "], Im[d" << fourierData.size()-1 << "], Pwr[d" << fourierData.size()-1 << "]" << std::endl;
759
760 // write data
761 for (UInt_t j=0; j<data[0].size(); j++) {
762 for (UInt_t i=0; i<data.size()-1; i++) {
763 fout << data[i][j] << ", ";
764 }
765 fout << data[data.size()-1][j] << std::endl;
766 }
767 fout.close();
768
769 return 0;
770}
771
772//-------------------------------------------------------------------------
783{
784 // get proper raw run data set
785 TString runName = *(run.GetRunName());
786 PRawRunData *rawRunData = runDataHandler->GetRunData(runName);
787 if (rawRunData == nullptr) {
788 std::cerr << std::endl << ">> musrFT_groupHistos **ERROR** Couldn't get raw run data for run '" << runName << "'." << std::endl;
789 return 1;
790 }
791
792 // keep histo list
793 PIntVector histoList;
794 for (UInt_t i=0; i<run.GetForwardHistoNoSize(); i++) {
795 histoList.push_back(run.GetForwardHistoNo(i));
796 }
797
798 // check if t0's are found and that #t0 == #histos
799 PDoubleVector t0;
800 t0.resize(histoList.size());
801 // init t0 vector
802 for (UInt_t i=0; i<t0.size(); i++)
803 t0[i] = -1.0;
804 // 1st: check in the global block
805 for (UInt_t i=0; i<global->GetT0BinSize(); i++) {
806 if (i >= t0.size()) { // something is VERY strange
807 std::cerr << std::endl << ">> musrFT_groupHistos **WARNING** found #t0's in GLOBAL block > #histos!";
808 std::cerr << std::endl << ">> This should NEVER happen. Will ignore these entries.";
809 std::cerr << std::endl << ">> Please check your msr-file!!" << std::endl;
810 } else {
811 t0[i] = global->GetT0Bin(i);
812 }
813 }
814 // 2nd: check in the run block
815 for (UInt_t i=0; i<run.GetT0BinSize(); i++) {
816 if (i >= t0.size()) { // something is VERY strange
817 std::cerr << std::endl << ">> musrFT_groupHistos **WARNING** found #t0's in RUN block > #histos!";
818 std::cerr << std::endl << ">> This should NEVER happen. Will ignore these entries.";
819 std::cerr << std::endl << ">> Please check your msr-file!!" << std::endl;
820 } else {
821 t0[i] = run.GetT0Bin(i);
822 }
823 }
824 // if still some t0's are == -1, estimate t0
825 UInt_t idx;
826 Double_t max;
827 for (UInt_t i=0; i<t0.size(); i++) {
828 if (t0[i] == -1.0) {
829 std::cout << std::endl << ">> musrFT_groupHistos **WARNING** try to estimate t0 from maximum in the data set";
830 std::cout << std::endl << ">> '" << runName << "', histo " << histoList[i] << ". NO warranty this is sensible!";
831 idx = 0;
832 max = rawRunData->GetDataBin(histoList[i])->at(0);
833 for (UInt_t j=1; j<rawRunData->GetDataBin(histoList[i])->size(); j++) {
834 if (rawRunData->GetDataBin(histoList[i])->at(j) > max) {
835 max = rawRunData->GetDataBin(histoList[i])->at(j);
836 idx = j;
837 }
838 }
839 std::cout << std::endl << ">> estimated t0=" << idx << std::endl;
840 t0[i] = idx;
841 }
842 }
843
844 // group histos
845 PDoubleVector data = *(rawRunData->GetDataBin(histoList[0]));
846 for (UInt_t i=1; i<histoList.size(); i++) {
847 for (UInt_t j=0; j<data.size(); j++) {
848 if ((j+t0[i]-t0[0] >= 0) && (j+t0[i]-t0[0] < rawRunData->GetDataBin(histoList[i])->size())) {
849 data[j] += rawRunData->GetDataBin(histoList[i])->at(j);
850 }
851 }
852 }
853
854 rd.rawData.clear();
855 rd.rawData = data;
856 rd.t0 = static_cast<Int_t>(t0[0]);
857
858 return 0;
859}
860
861//-------------------------------------------------------------------------
872{
873 std::ofstream fout(param.msrFlnOut.Data(), std::ofstream::out);
874
875 // write title
876 if (param.title.Length() == 0) { // create title if not given
877 if (param.dataFln.size() != 0) {
878 param.title = param.dataFln[0];
879 } else {
880 param.title = param.msrFlnOut;
881 }
882 }
883 fout << param.title << std::endl;
884 fout << "###############################################################" << std::endl;
885
886 // write GLOBAL block
887 fout << "GLOBAL" << std::endl;
888 fout << "fittype 0 (single histogram fit)" << std::endl;
889 if (param.t0.size() == 1) { // only a single t0 value given, hence assume it is valid for ALL histos
890 fout << "t0 " << param.t0[0] << std::endl;
891 }
892 if ((param.timeRange[0] != -1.0) && (param.timeRange[1] != -1.0)) {
893 fout << "fit " << param.timeRange[0] << " " << param.timeRange[1] << std::endl;
894 }
895 fout << "packing " << param.packing << std::endl;
896 fout << std::endl;
897 fout << "###############################################################" << std::endl;
898
899 // write RUN block
900 // get extension of the data file
901 TString fileFormat("MUSR-ROOT");
902 for (UInt_t i=0; i<param.dataFln.size(); i++) {
903 if (param.dataFileFormat[i].BeginsWith("PsiBin"))
904 fileFormat = TString("PSI-BIN");
905 else if (param.dataFileFormat[i].BeginsWith("PsiMdu"))
906 fileFormat = TString("PSI-MDU");
907 else if (param.dataFileFormat[i].BeginsWith("NeXus"))
908 fileFormat = TString("NEXUS");
909 else if (param.dataFileFormat[i].BeginsWith("Mud"))
910 fileFormat = TString("MUD");
911 for (UInt_t j=0; j<param.histo.size(); j++) {
912 fout << "RUN " << param.dataFln[i] << " BXXX IXX " << fileFormat << " (name beamline institute data-file-format)" << std::endl;
913 fout << "forward " << param.histo[j] << std::endl;
914 if ((param.t0.size() > 1) && (j < param.t0.size())) {
915 fout << "t0 " << param.t0[j] << std::endl;
916 }
917 if ((param.bkg_range[0] > -1) && (param.bkg_range[1] > -1))
918 fout << "background " << param.bkg_range[0] << " " << param.bkg_range[1] << std::endl;
919 fout << "#--------------------------------------------------------------" << std::endl;
920 }
921 }
922 fout << std::endl;
923 fout << "###############################################################" << std::endl;
924
925 // write PLOT block
926 fout << "PLOT 0 (single histo plot)" << std::endl;
927 if (param.histo.size() == 0) {
928 fout << "runs 1" << std::endl;
929 } else {
930 fout << "runs ";
931 for (UInt_t i=0; i<param.histo.size(); i++)
932 fout << i+1 << " ";
933 fout << std::endl;
934 }
935 if ((param.timeRange[0] == -1.0) && (param.timeRange[1] == -1.0)) {
936 fout << "range 0 10" << std::endl;
937 } else {
938 fout << "range " << param.timeRange[0] << " " << param.timeRange[1] << std::endl;
939 }
940 fout << std::endl;
941 fout << "###############################################################" << std::endl;
942
943 // write FOURIER block
944 fout << "FOURIER" << std::endl;
945 if (param.fourierUnits.BeginsWith("??")) { // Fourier units not given, hence choose MHz
946 fout << "units MHz # units either 'Gauss', 'MHz', or 'Mc/s'" << std::endl;
947 } else {
948 fout << "units " << param.fourierUnits << " # units either 'Gauss', 'MHz', or 'Mc/s'" << std::endl;
949 }
950 if (param.fourierOpt.BeginsWith("??")) { // Fourier plot option not given, hence choose POWER
951 fout << "plot POWER # REAL, IMAG, REAL_AND_IMAG, POWER, PHASE, PHASE_OPT_REAL" << std::endl;
952 } else {
953 fout << "plot " << param.fourierOpt << " # REAL, IMAG, REAL_AND_IMAG, POWER, PHASE, PHASE_OPT_REAL" << std::endl;
954 }
955 if (param.fourierPower > 1) {
956 fout << "fourier_power " << param.fourierPower << std::endl;
957 }
958 fout << "apodization " << param.apodization << " # NONE, WEAK, MEDIUM, STRONG" << std::endl;
959 if ((param.fourierRange[0] > -1.0) && (param.fourierRange[1] > -1.0)) {
960 fout << "range " << param.fourierRange[0] << " " << param.fourierRange[1] << std::endl;
961 }
962
963 fout.close();
964}
965
966//-------------------------------------------------------------------------
972Double_t millitime()
973{
974 struct timeval now;
975 gettimeofday(&now, 0);
976
977 return (static_cast<Double_t>(now.tv_sec) * 1.0e6 + static_cast<Double_t>(now.tv_usec))/1.0e3;
978}
979
980//-------------------------------------------------------------------------
991Int_t main(Int_t argc, Char_t *argv[])
992{
993 Int_t unitTag = FOURIER_UNIT_NOT_GIVEN;
994 Int_t apodTag = F_APODIZATION_NONE;
995 Int_t fourierPlotTag = FOURIER_PLOT_NOT_GIVEN;
996
997 // only program name alone
998 if (argc == 1) {
1000 return PMUSR_SUCCESS;
1001 }
1002
1003 musrFT_startup_param startupParam;
1004 // init startupParam
1005 musrFT_init(startupParam);
1006
1007 // parse command line options
1008 Int_t status = musrFT_parse_options(argc, argv, startupParam);
1009 if (status != 0) {
1010 Int_t retVal = PMUSR_SUCCESS;
1011 if (status == 2) {
1012 musrFT_syntax();
1014 }
1015 return retVal;
1016 }
1017
1018 // dump msr-file
1019 if (startupParam.msrFlnOut.Length() > 0) {
1020 musrFT_dumpMsrFile(startupParam);
1021 return PMUSR_SUCCESS;
1022 }
1023
1024 // read startup file
1025 std::string startup_path_name{};
1026 PStartupOptions startup_options;
1027 startup_options.writeExpectedChisq = false;
1028 startup_options.estimateN0 = true;
1029 std::unique_ptr<TSAXParser> saxParser = std::make_unique<TSAXParser>();
1030 std::unique_ptr<PStartupHandler> startupHandler = std::make_unique<PStartupHandler>();
1031 if (!startupHandler->StartupFileFound()) {
1032 std::cerr << std::endl << ">> musrFT **WARNING** couldn't find " << startupHandler->GetStartupFilePath().Data();
1033 std::cerr << std::endl;
1034 } else {
1035 startup_path_name = startupHandler->GetStartupFilePath().Data();
1036 saxParser->ConnectToHandler("PStartupHandler", startupHandler.get());
1037 //status = saxParser->ParseFile(startup_path_name);
1038 // parsing the file as above seems to lead to problems in certain environments;
1039 // use the parseXmlFile function instead (see PStartupHandler.cpp for the definition)
1040 status = parseXmlFile(saxParser.get(), startup_path_name.c_str());
1041 // check for parse errors
1042 if (status) { // error
1043 std::cerr << std::endl << ">> musrFT **WARNING** Reading/parsing musrfit_startup.xml failed.";
1044 std::cerr << std::endl;
1045 }
1046 }
1047
1048 // defines the raw time-domain data vector
1049 PPrepFourier data(startupParam.packing, startupParam.bkg_range, startupParam.bkg);
1050
1051 // load msr-file(s)
1052 std::vector< std::unique_ptr<PMsrHandler> > msrHandler;
1053 msrHandler.resize(startupParam.msrFln.size());
1054 for (UInt_t i=0; i<startupParam.msrFln.size(); i++) {
1055 msrHandler[i] = std::make_unique<PMsrHandler>(startupParam.msrFln[i].Data(), &startup_options, true);
1056 status = msrHandler[i]->ReadMsrFile();
1057 if (status != PMUSR_SUCCESS) {
1058 switch (status) {
1060 std::cout << std::endl << ">> musrFT **ERROR** couldn't find " << startupParam.msrFln[i] << std::endl << std::endl;
1061 break;
1063 std::cout << std::endl << ">> musrFT **SYNTAX ERROR** in file " << startupParam.msrFln[i] << ", full stop here." << std::endl << std::endl;
1064 break;
1065 default:
1066 std::cout << std::endl << ">> musrFT **UNKOWN ERROR** when trying to read the msr-file" << std::endl << std::endl;
1067 break;
1068 }
1069 return status;
1070 }
1071 }
1072
1073 // check for ascii-, db- or dat-files in msr-file RUN block
1074 TString ffstr("");
1075 for (UInt_t i=0; i<msrHandler.size(); i++) {
1076 PMsrRunList *runList = msrHandler[i]->GetMsrRunList();
1077 for (UInt_t j=0; j<runList->at(i).GetFileFormatSize(); j++) {
1078 ffstr = *(runList->at(i).GetFileFormat(j));
1079 if (!ffstr.CompareTo("ascii", TString::kIgnoreCase) || !ffstr.CompareTo("dat", TString::kIgnoreCase) || !ffstr.CompareTo("db", TString::kIgnoreCase)) {
1080 std::cout << std::endl;
1081 std::cout << "**ERROR** Currently file format's 'ASCII', 'DAT', nor 'DB' are NOT supported." << std::endl;
1082 std::cout << std::endl;
1084 }
1085 }
1086 }
1087
1088 std::vector< std::unique_ptr<PRunDataHandler> > runDataHandler;
1089 runDataHandler.resize(startupParam.msrFln.size()+startupParam.dataFln.size()); // resize to the total number of run data provided
1090 // load data-file(s) related to msr-file
1091 for (UInt_t i=0; i<msrHandler.size(); i++) {
1092 // create run data handler
1093 if (startupHandler)
1094 runDataHandler[i] = std::make_unique<PRunDataHandler>(msrHandler[i].get(), startupHandler->GetDataPathList());
1095 else
1096 runDataHandler[i] = std::make_unique<PRunDataHandler>(msrHandler[i].get());
1097 if (runDataHandler[i] == nullptr) {
1098 std::cerr << ">> musrFT: **ERROR** couldn't allocate PRunDataHandler object." << std::endl;
1100 }
1101 }
1102
1103 // load data-file(s) provided directly
1104 for (UInt_t i=msrHandler.size(); i<msrHandler.size()+startupParam.dataFln.size(); i++) {
1105 // create run data handler
1106 if (startupHandler)
1107 runDataHandler[i] = std::make_unique<PRunDataHandler>(startupParam.dataFln[i-msrHandler.size()], startupParam.dataFileFormat[i-msrHandler.size()], startupHandler->GetDataPathList());
1108 else
1109 runDataHandler[i] = std::make_unique<PRunDataHandler>(startupParam.dataFln[i-msrHandler.size()], startupParam.dataFileFormat[i-msrHandler.size()]);
1110 if (runDataHandler[i] == nullptr) {
1111 std::cerr << ">> musrFT: **ERROR** couldn't allocate PRunDataHandler object." << std::endl;
1113 }
1114 }
1115
1116 // read all the data files
1117 musrFT_data rd;
1118 rd.dataSetTag = -1;
1119 Int_t dataSetTagCounter = 0;
1120 TString prevDataSetPathName("");
1121 TString str(""), fln("");
1122 UInt_t idx=0;
1123
1124 for (UInt_t i=0; i<runDataHandler.size(); i++) {
1125 runDataHandler[i]->ReadData();
1126
1127 if (!runDataHandler[i]->IsAllDataAvailable()) {
1128 if (i < msrHandler.size()) {
1129 std::cerr << std::endl << ">> musrFT **ERROR** couldn't read data from msr-file '" << startupParam.msrFln[i] << "'." << std::endl;
1130 } else {
1131 std::cerr << std::endl << ">> musrFT **ERROR** couldn't read data-file '" << startupParam.dataFln[i] << "'." << std::endl;
1132 }
1134 }
1135
1136 // dig out all the necessary time domain data
1137 PRawRunData *rawRunData = runDataHandler[i]->GetRunData();
1138 if (rawRunData == nullptr) {
1139 if (i < msrHandler.size()) {
1140 std::cerr << std::endl << ">> musrFT **ERROR** couldn't obtain the raw run data set from msr-file " << startupParam.msrFln[i] << std::endl;
1141 } else {
1142 std::cerr << std::endl << ">> musrFT **ERROR** couldn't obtain the raw run data set for " << startupParam.dataFln[i-msrHandler.size()] << std::endl;
1143 }
1145 }
1146
1147 // first check of histo list makes sense
1148 if (i >= msrHandler.size()) { // only check if originating from data-files (not msr-files)
1149 for (UInt_t j=0; j<startupParam.histo.size(); j++) {
1150 if ((UInt_t)startupParam.histo[j] > rawRunData->GetNoOfHistos()) {
1151 std::cerr << std::endl << ">> musrFT **ERROR** found histo no " << startupParam.histo[j] << " > # of histo in the file (";
1152 std::cerr << startupParam.dataFln[i] << " // # histo: " << rawRunData->GetNoOfHistos() << ")." << std::endl;
1154 }
1155 }
1156 if (startupParam.histo.size() == 0) { // no histo list given
1157 // set histo list to ALL available histos for the data file
1158 for (UInt_t j=0; j<rawRunData->GetNoOfHistos(); j++)
1159 startupParam.histo.push_back(j+1);
1160 }
1161 }
1162
1163 // get meta info, time resolution, time range, raw data sets
1164 if (i < msrHandler.size()) { // obtain info from msr-files
1165 // keep title if not overwritten by the command line
1166 if (startupParam.title.Length() == 0)
1167 startupParam.title = *(msrHandler[0]->GetMsrTitle());
1168 // keep PLOT block info
1169 PMsrPlotList *plot = msrHandler[i]->GetMsrPlotList();
1170 if (plot == nullptr) {
1171 std::cerr << std::endl << ">> musrFT **ERROR** couldn't obtain PLOT block from msr-handler." << std::endl;
1173 }
1174 // keep RUN block(s) info
1175 PMsrRunList *runs = msrHandler[i]->GetMsrRunList();
1176 if (runs == nullptr) {
1177 std::cerr << std::endl << ">> musrFT **ERROR** couldn't obtain RUN block(s) from msr-handler." << std::endl;
1179 }
1180 // keep GLOBAL block info
1181 PMsrGlobalBlock *global = msrHandler[i]->GetMsrGlobal();
1182 if (global == nullptr) {
1183 std::cerr << std::endl << ">> musrFT **ERROR** couldn't obtain GLOBAL block from msr-handler." << std::endl;
1185 }
1186 // keep FOURIER block info
1187 PMsrFourierStructure *fourierBlock = msrHandler[i]->GetMsrFourierList();
1188 if (fourierBlock == nullptr) {
1189 std::cerr << std::endl << ">> msrFT **WARNING** couldn't obtain FOURIER block from msr-handler." << std::endl;
1191 } else { // filter out all necessary info
1192 if (fourierBlock->fFourierBlockPresent) {
1193 // get units
1194 unitTag = fourierBlock->fUnits;
1195 if (startupParam.fourierUnits.BeginsWith("??")) {
1196 switch (unitTag) {
1197 case FOURIER_UNIT_GAUSS:
1198 startupParam.fourierUnits = TString("Gauss");
1199 break;
1200 case FOURIER_UNIT_TESLA:
1201 startupParam.fourierUnits = TString("Tesla");
1202 break;
1203 case FOURIER_UNIT_FREQ:
1204 startupParam.fourierUnits = TString("MHz");
1205 break;
1207 startupParam.fourierUnits = TString("Mc/s");
1208 break;
1209 default:
1210 break;
1211 }
1212 }
1213 // get fourier power
1214 if (startupParam.fourierPower == -1) { // no Fourier power given from the command line, hence check FOURIER block
1215 if (fourierBlock->fFourierPower > 1)
1216 startupParam.fourierPower = fourierBlock->fFourierPower;
1217 }
1218 // get apodization tag
1219 switch (fourierBlock->fApodization) {
1220 case FOURIER_APOD_WEAK:
1221 startupParam.apodization = "weak";
1222 break;
1224 startupParam.apodization = "medium";
1225 break;
1227 startupParam.apodization = "strong";
1228 break;
1229 default:
1230 startupParam.apodization = "none";
1231 break;
1232 }
1233 // get range
1234 if ((startupParam.fourierRange[0] == -1) && (startupParam.fourierRange[1] == -1)) { // no Fourier range given from the command line
1235 startupParam.fourierRange[0] = fourierBlock->fPlotRange[0];
1236 startupParam.fourierRange[1] = fourierBlock->fPlotRange[1];
1237 }
1238 // get Fourier plot option, i.e. real, imag, power, phase
1239 if (startupParam.fourierOpt.BeginsWith("??")) { // only do something if not overwritten by the command line
1240 fourierPlotTag = fourierBlock->fPlotTag;
1241 }
1242 }
1243 }
1244
1245 // get the run information from the msr-file PLOT block 'runs'
1246 PIntVector runList = plot->at(0).fRuns;
1247
1248 // loop over all runs listed in the msr-file PLOT block
1249 for (UInt_t j=0; j<runList.size(); j++) {
1250
1251 // check if the data set name has changed
1252 str = *(runs->at(runList[j]-1).GetRunName()); // get the name from the msr-file RUN block
1253 if (prevDataSetPathName.CompareTo(str)) { // i.e. data set name changed
1254 rd.dataSetTag = dataSetTagCounter++;
1255 prevDataSetPathName = str;
1256 }
1257
1258 // keep forward histo list
1259 PIntVector histoList;
1260 for (UInt_t k=0; k<runs->at(runList[j]-1).GetForwardHistoNoSize(); k++) {
1261 histoList.push_back(runs->at(runList[j]-1).GetForwardHistoNo(k));
1262 }
1263
1264 // handle meta information
1265 fln = *(runs->at(runList[j]-1).GetRunName()); // get the name from the msr-file RUN block
1266 musrFT_getMetaInfo(fln, rawRunData, str);
1267 TString hh("");
1268 hh = TString::Format("h%d", histoList[0]);
1269 for (UInt_t k=1; k<histoList.size(); k++)
1270 hh += TString::Format("/%d", histoList[k]);
1271 hh += ":";
1272 rd.info = hh;
1273 rd.info += str;
1274
1275 // handle time resolution
1276 rd.timeResolution = rawRunData->GetTimeResolution() / 1.0e3; // time resolution in (us)
1277
1278 // handle time range
1279 // take it from msr-file PLOT block 'range' if not overwritten from the command line
1280 if ((startupParam.timeRange[0] != -1) && (startupParam.timeRange[1] != -1)) {
1281 rd.timeRange[0] = startupParam.timeRange[0];
1282 rd.timeRange[1] = startupParam.timeRange[1];
1283 } else {
1284 if (plot->at(0).fTmin.size() > 0) {
1285 rd.timeRange[0] = plot->at(0).fTmin[0];
1286 rd.timeRange[1] = plot->at(0).fTmax[0];
1287 }
1288 }
1289
1290 // handle data set(s)
1291 // group forward histos
1292 if (musrFT_groupHistos(runDataHandler[i].get(), global, runs->at(runList[j]-1), rd)) {
1294 }
1295 // keep data set
1296 data.AddData(rd);
1297
1298 // get packing
1299 Int_t pack = 1;
1300 if (global->GetPacking() != -1) {
1301 pack = global->GetPacking();
1302 }
1303 if (runs->at(runList[j]-1).GetPacking() != -1) {
1304 pack = runs->at(runList[j]-1).GetPacking();
1305 }
1306 if (startupParam.packing > 1)
1307 pack = startupParam.packing;
1308 data.SetPacking(pack);
1309
1310 // get background range
1311 Int_t bkgStart=-1, bkgEnd=-1;
1312 bkgStart = runs->at(runList[j]-1).GetBkgRange(0);
1313 bkgEnd = runs->at(runList[j]-1).GetBkgRange(1);
1314 if ((startupParam.bkg_range[0] == -1) && (bkgStart != -1))
1315 startupParam.bkg_range[0] = bkgStart;
1316 if ((startupParam.bkg_range[1] == -1) && (bkgEnd != -1))
1317 startupParam.bkg_range[1] = bkgEnd;
1318 data.SetBkgRange(startupParam.bkg_range);
1319 }
1320 } else { // obtain info from command line options for direct data-file read
1321 // check if the data set name has changed
1322 // since data-files are given, each PRunDataHandler object contains only a SINGLE data file.
1323 str = *(runDataHandler[i]->GetRunData()->GetFileName()); // get the data set name
1324 if (prevDataSetPathName.CompareTo(str)) { // i.e. data set name changed
1325 rd.dataSetTag = dataSetTagCounter++;
1326 prevDataSetPathName = str;
1327 }
1328
1329 musrFT_getMetaInfo(startupParam.dataFln[i-msrHandler.size()], rawRunData, str);
1330 for (UInt_t j=0; j<startupParam.histo.size(); j++) {
1331 idx = startupParam.histo[j];
1332
1333 // handle meta information
1334 rd.info = TString::Format("h%d:", idx);
1335 rd.info += str;
1336
1337 // handle time resolution
1338 rd.timeResolution = rawRunData->GetTimeResolution() / 1.0e3; // time resolution in (us)
1339
1340 // handle time range
1341 rd.timeRange[0] = startupParam.timeRange[0]; // in (us)
1342 rd.timeRange[1] = startupParam.timeRange[1]; // in (us)
1343
1344 // handle data set
1345 rd.rawData.clear();
1346 rd.rawData = *(rawRunData->GetDataBin(idx));
1347
1348 // handle t0's
1349 rd.t0 = -1;
1350 if (startupParam.t0.size() == 1)
1351 rd.t0 = startupParam.t0[0];
1352 else if (j < startupParam.t0.size())
1353 rd.t0 = startupParam.t0[j];
1354 if (rd.t0 == -1) { // no t0 given, try to estimate it
1356 }
1357
1358 data.AddData(rd);
1359 }
1360 }
1361 }
1362
1363 // generate data set label vector
1364 PIntVector dataSetTag;
1365 for (UInt_t i=0; i<data.GetNoOfData(); i++) {
1366 dataSetTag.push_back(data.GetDataSetTag(i));
1367 }
1368
1369 // make sure Fourier plot tag is set
1370 if (fourierPlotTag == FOURIER_PLOT_NOT_GIVEN) {
1371 if (!startupParam.fourierOpt.CompareTo("real", TString::kIgnoreCase))
1372 fourierPlotTag = FOURIER_PLOT_REAL;
1373 else if (!startupParam.fourierOpt.CompareTo("imag", TString::kIgnoreCase))
1374 fourierPlotTag = FOURIER_PLOT_IMAG;
1375 else if (!startupParam.fourierOpt.CompareTo("real+imag", TString::kIgnoreCase))
1376 fourierPlotTag = FOURIER_PLOT_REAL_AND_IMAG;
1377 else if (!startupParam.fourierOpt.CompareTo("power", TString::kIgnoreCase))
1378 fourierPlotTag = FOURIER_PLOT_POWER;
1379 else if (!startupParam.fourierOpt.CompareTo("phase", TString::kIgnoreCase))
1380 fourierPlotTag = FOURIER_PLOT_PHASE;
1381 else if (!startupParam.fourierOpt.CompareTo("phaseoptreal", TString::kIgnoreCase))
1382 fourierPlotTag = FOURIER_PLOT_PHASE_OPT_REAL;
1383 else
1384 fourierPlotTag = FOURIER_PLOT_POWER;
1385 }
1386
1387 // calculate background levels and subtract them from the data
1388 data.DoBkgCorrection();
1389
1390 // do lifetime correction
1391 if (startupParam.lifetimecorrection != 0.0)
1392 data.DoLifeTimeCorrection(startupParam.lifetimecorrection);
1393
1394 // do packing
1395 data.DoPacking();
1396
1397 // get all the corrected data
1398 std::vector<TH1F*> histo = data.GetData();
1399
1400 // prepare Fourier
1401 if (startupParam.fourierUnits.BeginsWith("gauss", TString::kIgnoreCase))
1402 unitTag = FOURIER_UNIT_GAUSS;
1403 else if (startupParam.fourierUnits.BeginsWith("tesla", TString::kIgnoreCase))
1404 unitTag = FOURIER_UNIT_TESLA;
1405 else if (startupParam.fourierUnits.BeginsWith("mhz", TString::kIgnoreCase))
1406 unitTag = FOURIER_UNIT_FREQ;
1407 else if (startupParam.fourierUnits.BeginsWith("mc/s", TString::kIgnoreCase))
1408 unitTag = FOURIER_UNIT_CYCLES;
1409 else if (startupParam.fourierUnits.BeginsWith("??", TString::kIgnoreCase) && (unitTag == FOURIER_UNIT_NOT_GIVEN))
1410 unitTag = FOURIER_UNIT_FREQ;
1411
1412 std::vector<PFourier*> fourier;
1413 fourier.resize(histo.size());
1414 for (UInt_t i=0; i<fourier.size(); i++) {
1415 fourier[i] = new PFourier(histo[i], unitTag, 0.0, 0.0, true, startupParam.fourierPower);
1416 if (fourier[i] == nullptr) {
1417 std::cerr << ">> musrFT: **ERROR** couldn't invoke PFourier object" << std::endl;
1419 }
1420 }
1421
1422 // Fourier transform data
1423 if (startupParam.apodization.BeginsWith("weak", TString::kIgnoreCase))
1424 apodTag = F_APODIZATION_WEAK;
1425 else if (startupParam.apodization.BeginsWith("medium", TString::kIgnoreCase))
1426 apodTag = F_APODIZATION_MEDIUM;
1427 else if (startupParam.apodization.BeginsWith("strong", TString::kIgnoreCase))
1428 apodTag = F_APODIZATION_STRONG;
1429
1430 Double_t start = millitime();
1431 Int_t noOfFourier = static_cast<Int_t>(fourier.size());
1432 #ifdef HAVE_GOMP
1433 Int_t chunk = noOfFourier/omp_get_num_procs();
1434 if (chunk < 1)
1435 chunk = 1;
1436 #pragma omp parallel for default(shared) schedule(dynamic,chunk)
1437 #endif
1438 for (Int_t i=0; i<noOfFourier; i++) {
1439 fourier[i]->Transform(apodTag);
1440 }
1441 Double_t end = millitime();
1442 std::cout << std::endl << "info> after FFT. calculation time: " << (end-start)/1.0e3 << " (sec)." << std::endl;
1443
1444 // make sure that a Fourier range is provided, if not calculate one
1445 if ((startupParam.fourierRange[0] == -1.0) && (startupParam.fourierRange[1] == -1.0)) {
1446 startupParam.fourierRange[0] = 0.0;
1447 startupParam.fourierRange[1] = fourier[0]->GetMaxFreq();
1448 }
1449
1450 std::unique_ptr<PFourierCanvas> fourierCanvas;
1451
1452 Int_t result = PMUSR_SUCCESS;
1453
1454 // if Fourier dumped if whished do it now
1455 if (startupParam.dumpFln.Length() > 0) {
1456 musrFT_dumpData(startupParam.dumpFln, fourier, startupParam.fourierRange[0], startupParam.fourierRange[1]);
1457 } else { // do Canvas
1458
1459 // if Fourier graphical export is wished, switch to batch mode
1460 Bool_t batch = false;
1461 // create list of essential arguments to pass to the ROOT application
1462 std::vector<char*> args;
1463 args.push_back(argv[0]); // program name
1464 if (startupParam.graphicFormat.Length() != 0) {
1465 batch = true;
1466 args.push_back((char*)"-b"); // batch mode flag
1467 }
1468 int cc = args.size();
1469 // plot the Fourier transform
1470 TApplication app("App", &cc, args.data());
1471
1472 if (startupHandler) {
1473 fourierCanvas = std::unique_ptr<PFourierCanvas>(new PFourierCanvas(fourier, dataSetTag, startupParam.title.Data(),
1474 startupParam.showAverage, startupParam.showAveragePerDataSet,
1475 fourierPlotTag, startupParam.fourierRange, startupParam.initialPhase,
1476 10, 10, 800, 800,
1477 startupHandler->GetMarkerList(),
1478 startupHandler->GetColorList(),
1479 batch));
1480 } else {
1481 fourierCanvas = std::unique_ptr<PFourierCanvas>(new PFourierCanvas(fourier, dataSetTag, startupParam.title.Data(),
1482 startupParam.showAverage, startupParam.showAveragePerDataSet,
1483 fourierPlotTag, startupParam.fourierRange, startupParam.initialPhase,
1484 10, 10, 800, 800,
1485 batch));
1486 }
1487 if (fourierCanvas == nullptr) {
1488 std::cerr << ">> musrFT: **ERROR** couldn't invoke PFourierCanvas object." << std::endl;
1490 }
1491
1492 fourierCanvas->UpdateFourierPad();
1493 fourierCanvas->UpdateInfoPad();
1494
1495 Bool_t ok = true;
1496 if (!fourierCanvas->IsValid()) {
1497 std::cerr << std::endl << ">> musrFT **SEVERE ERROR** Couldn't invoke all necessary objects, will quit.";
1498 std::cerr << std::endl;
1499 ok = false;
1500 result = PMUSR_MSR_RUN_ERROR;
1501 } else {
1502 // connect signal/slot
1503 TQObject::Connect("TCanvas", "Closed()", "PFourierCanvas", fourierCanvas.get(), "LastCanvasClosed()");
1504
1505 fourierCanvas->SetTimeout(startupParam.timeout);
1506
1507 fourierCanvas->Connect("Done(Int_t)", "TApplication", &app, "Terminate(Int_t)");
1508
1509 if (startupParam.graphicFormat.Length() != 0) {
1510 TString fileName("");
1511 // create output filename based on the msr- or raw-data-filename
1512 if (startupParam.dataFln.size() > 0) {
1513 fileName = startupParam.dataFln[0];
1514 }
1515 if (startupParam.msrFln.size() > 0) {
1516 fileName = startupParam.msrFln[0];
1517 }
1518 Ssiz_t idx = fileName.Last('.');
1519 fileName.Remove(idx, fileName.Length());
1520 fileName += ".";
1521 fileName += startupParam.graphicFormat;
1522 fourierCanvas->SaveGraphicsAndQuit(fileName.Data());
1523 }
1524 }
1525 // check that everything is ok
1526 if (ok)
1527 app.Run();
1528 }
1529
1530 return result;
1531}
#define F_APODIZATION_WEAK
Weak apodization (gentle roll-off at edges).
Definition PFourier.h:55
#define F_APODIZATION_STRONG
Strong apodization (heavy roll-off for best frequency resolution).
Definition PFourier.h:59
#define F_APODIZATION_NONE
No apodization (rectangular window).
Definition PFourier.h:53
#define F_APODIZATION_MEDIUM
Medium apodization (moderate roll-off).
Definition PFourier.h:57
#define PMUSR_DATA_FILE_READ_ERROR
Error reading data file (ROOT, NeXus, MUD, etc.).
Definition PMusr.h:76
#define PMUSR_MSR_RUN_ERROR
Error during run processing or fitting.
Definition PMusr.h:78
#define FOURIER_UNIT_FREQ
Frequency in MHz.
Definition PMusr.h:290
#define FOURIER_PLOT_REAL_AND_IMAG
Plot both real and imaginary components (default).
Definition PMusr.h:328
#define PMUSR_SUCCESS
Successful operation completion.
Definition PMusr.h:58
std::vector< PMsrRunBlock > PMsrRunList
Definition PMusr.h:1263
#define FOURIER_UNIT_GAUSS
Magnetic field in Gauss (G).
Definition PMusr.h:286
#define PMUSR_UNSUPPORTED_FEATURE
Requested feature is not yet supported.
Definition PMusr.h:80
#define FOURIER_PLOT_NOT_GIVEN
Plot type not specified.
Definition PMusr.h:322
#define FOURIER_PLOT_POWER
Plot power spectrum |F(ω)|²
Definition PMusr.h:330
#define PMUSR_UNDEFINED
Definition PMusr.h:177
#define PMUSR_MSR_FILE_NOT_FOUND
MSR file could not be found at specified path.
Definition PMusr.h:64
#define FOURIER_PLOT_REAL
Plot real component only.
Definition PMusr.h:324
#define FOURIER_PLOT_PHASE_OPT_REAL
Plot phase-optimized real component.
Definition PMusr.h:334
#define FOURIER_APOD_WEAK
Weak apodization (gentle windowing).
Definition PMusr.h:308
std::vector< PMsrPlotStructure > PMsrPlotList
Definition PMusr.h:1330
#define PMUSR_MSR_SYNTAX_ERROR
Syntax error detected in MSR file content.
Definition PMusr.h:68
#define FOURIER_UNIT_CYCLES
Angular frequency in Mc/s (Mega-cycles per second).
Definition PMusr.h:292
#define FOURIER_APOD_STRONG
Strong apodization (heavy windowing for best frequency resolution).
Definition PMusr.h:312
std::vector< Int_t > PIntVector
Definition PMusr.h:381
#define FOURIER_PLOT_IMAG
Plot imaginary component only.
Definition PMusr.h:326
#define FOURIER_APOD_MEDIUM
Medium apodization (moderate windowing).
Definition PMusr.h:310
#define FOURIER_PLOT_PHASE
Plot phase spectrum arg(F(ω)).
Definition PMusr.h:332
#define FOURIER_UNIT_NOT_GIVEN
Units not specified.
Definition PMusr.h:284
#define PMUSR_MSR_ALLOCATION_ERROR
Memory allocation error while processing MSR file.
Definition PMusr.h:66
#define FOURIER_UNIT_TESLA
Magnetic field in Tesla (T).
Definition PMusr.h:288
#define PMUSR_WRONG_STARTUP_SYNTAX
Incorrect startup command syntax provided.
Definition PMusr.h:62
std::vector< TString > PStringVector
Definition PMusr.h:417
std::vector< Double_t > PDoubleVector
Definition PMusr.h:399
const char * startup_path_name
return status
int parseXmlFile(TSAXParser *, const char *)
Replacement function for TSAXParser::ParseFile().
virtual UInt_t GetT0BinSize()
Definition PMusr.h:1068
virtual Int_t GetPacking()
Definition PMusr.h:1076
virtual Double_t GetT0Bin(UInt_t idx=0)
Definition PMusr.cpp:1038
virtual UInt_t GetForwardHistoNoSize()
Definition PMusr.h:1158
virtual TString * GetRunName(UInt_t idx=0)
Definition PMusr.cpp:1335
virtual UInt_t GetT0BinSize()
Definition PMusr.h:1166
virtual Int_t GetForwardHistoNo(UInt_t idx=0)
Definition PMusr.cpp:1503
virtual Double_t GetT0Bin(UInt_t idx=0)
Definition PMusr.cpp:1798
Prepares time-domain μSR data for Fourier transformation.
virtual void DoLifeTimeCorrection(Double_t fudge)
Applies muon lifetime correction for theory-free analysis.
virtual void SetPacking(const Int_t packing)
Sets rebinning/packing factor for data reduction.
UInt_t GetNoOfData()
Returns number of stored data sets.
Int_t GetDataSetTag(const UInt_t idx)
Returns data set tag identifier.
virtual void AddData(musrFT_data &data)
Adds a time-domain data set for processing.
std::vector< TH1F * > GetData()
Creates ROOT histograms for all processed data sets.
virtual void DoBkgCorrection()
Applies background correction to all data sets.
virtual void SetBkgRange(const Int_t *bkgRange)
Sets background range for automatic background calculation.
virtual void DoPacking()
Applies rebinning/packing to reduce data points.
virtual const PDoubleVector * GetDataBin(const UInt_t histoNo)
Definition PMusr.h:896
virtual const Double_t GetTimeResolution()
Definition PMusr.h:882
virtual const TString * GetSample()
Definition PMusr.h:870
virtual const UInt_t GetNoOfTemperatures()
Definition PMusr.h:874
virtual const Double_t GetField()
Definition PMusr.h:873
virtual const Double_t GetEnergy()
Definition PMusr.h:878
virtual const UInt_t GetNoOfHistos()
Definition PMusr.h:893
virtual const TString * GetCryoName()
Definition PMusr.h:869
virtual const PDoublePairVector * GetTemperature() const
Definition PMusr.h:875
Raw data file reader and format converter for μSR data.
virtual PRawRunData * GetRunData(const TString &runName)
Retrieves run data by run name.
static std::vector< std::string > Split(const std::string &str, const std::string &delimiters)
Int_t musrFT_dumpData(TString fln, std::vector< PFourier * > &fourierData, Double_t start, Double_t end)
Definition musrFT.cpp:700
void musrFT_init(musrFT_startup_param &startupParam)
Definition musrFT.cpp:167
Int_t musrFT_groupHistos(PRunDataHandler *runDataHandler, PMsrGlobalBlock *global, PMsrRunBlock &run, musrFT_data &rd)
Definition musrFT.cpp:782
void musrFT_dumpMsrFile(musrFT_startup_param &param)
Definition musrFT.cpp:871
Bool_t musrFT_filter_histo(Int_t &i, Int_t argc, Char_t *argv[], musrFT_startup_param &startupParam)
Definition musrFT.cpp:207
void musrFT_syntax()
Definition musrFT.cpp:96
void musrFT_estimateT0(musrFT_data &rd)
Definition musrFT.cpp:659
Int_t main(Int_t argc, Char_t *argv[])
Definition musrFT.cpp:991
Int_t musrFT_parse_options(Int_t argc, Char_t *argv[], musrFT_startup_param &startupParam)
Definition musrFT.cpp:291
void musrFT_cleanup(TH1F *h)
Definition musrFT.cpp:683
Double_t millitime()
Definition musrFT.cpp:972
void musrFT_getMetaInfo(const TString fln, PRawRunData *rawRunData, TString &metaInfo)
Definition musrFT.cpp:614
Int_t fPlotTag
tag used for initial plot. 0=real, 1=imaginary, 2=real & imaginary (default), 3=power,...
Definition PMusr.h:1284
Bool_t fFourierBlockPresent
flag indicating if a Fourier block is present in the msr-file
Definition PMusr.h:1279
Double_t fPlotRange[2]
field/frequency plot range
Definition PMusr.h:1289
Int_t fFourierPower
i.e. zero padding up to 2^fFourierPower, default = 0 which means NO zero padding
Definition PMusr.h:1282
Int_t fUnits
flag used to indicate the units. 1=field units (G); 2=field units (T); 3=frequency units (MHz); 4=Mc/...
Definition PMusr.h:1280
Int_t fApodization
tag indicating the kind of apodization wished, 0=no appodization (default), 1=weak,...
Definition PMusr.h:1283
Bool_t writeExpectedChisq
if set to true, expected chisq and chisq per block will be written
Definition PMusr.h:1397
Bool_t estimateN0
if set to true, for single histogram fits N0 will be estimated
Definition PMusr.h:1398
Data structure holding raw time-domain μSR data with metadata.
PDoubleVector rawData
Raw time-domain data vector (bin counts).
Double_t timeResolution
Time resolution in microseconds (μs).
Double_t timeRange[2]
Time range to process: [0]=start, [1]=end in microseconds (μs).
Int_t dataSetTag
Data set identifier tag (needed for average-per-data-set operations).
TString info
Metadata string (run name, histogram info, etc.).
Int_t t0
Time zero bin number (start of valid data).
Bool_t showAveragePerDataSet
flag indicating if initially the Fourier average over the given histos shall be plotted,...
Definition musrFT.cpp:84
TString apodization
apodization setting: none, weak, medium, strong
Definition musrFT.cpp:76
TString fourierUnits
wished Fourier units: Gauss, Tesla, MHz, Mc/s
Definition musrFT.cpp:78
Double_t fourierRange[2]
Fourier range to be plotted. Given in the choosen units.
Definition musrFT.cpp:80
Double_t lifetimecorrection
is == 0.0 for NO life time correction, otherwise it holds the fudge factor
Definition musrFT.cpp:88
PDoubleVector bkg
background value
Definition musrFT.cpp:74
Int_t packing
packing for rebinning the time histograms before Fourier transform.
Definition musrFT.cpp:86
Int_t bkg_range[2]
background range
Definition musrFT.cpp:73
TString graphicFormat
format for the graphical output dump
Definition musrFT.cpp:70
TString msrFlnOut
dump file name for msr-file generation
Definition musrFT.cpp:72
Int_t fourierPower
Fourier power for zero padding, i.e. 2^fourierPower points.
Definition musrFT.cpp:77
Bool_t showAverage
flag indicating if initially the Fourier average over the given histos shall be plotted,...
Definition musrFT.cpp:83
PStringVector dataFileFormat
file format guess
Definition musrFT.cpp:69
Int_t timeout
timeout in (sec) after which musrFT will terminate. if <= 0, no automatic termination will take place...
Definition musrFT.cpp:89
TString title
title to be shown for the Fourier plot.
Definition musrFT.cpp:87
Double_t initialPhase
inital Fourier phase for Real/Imag
Definition musrFT.cpp:79
PStringVector dataFln
raw-data-file names to be used.
Definition musrFT.cpp:68
PIntVector histo
selection of the histos used from at data file for Fourier
Definition musrFT.cpp:82
Double_t timeRange[2]
time range used for the Fourier
Definition musrFT.cpp:81
PIntVector t0
t0 vector for the histos. If not given t0's will be estimated.
Definition musrFT.cpp:85
TString fourierOpt
Fourier options, i.e. real, imag, power, phase, phaseOptReal.
Definition musrFT.cpp:75
PStringVector msrFln
msr-file names to be used.
Definition musrFT.cpp:67
TString dumpFln
dump file name for Fourier data output
Definition musrFT.cpp:71