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