musrfit 1.10.0
addRun.cpp
Go to the documentation of this file.
1/***************************************************************************
2
3 addRun.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 <cstdio>
35#include <cstdlib>
36#include <cstring>
37#include <string>
38
39#include <iostream>
40#include <fstream>
41#include <memory>
42
43#include <boost/algorithm/string.hpp>
44#include <boost/filesystem.hpp>
45
46#include <TString.h>
47
48#ifdef HAVE_GIT_REV_H
49#include "git-revision.h"
50#endif
51
52#include "PMusr.h"
53#include "PStartupHandler.h"
54#include "PRunDataHandler.h"
55#include "PFindRun.h"
56
58 std::string fPathFileName{""};
60 std::string fFileFormat{""};
61};
62
63
64//--------------------------------------------------------------------------
69{
70 std::cout << std::endl;
71 std::cout << "usage0: addRun [--help | -h] | [--version | -v]" << std::endl;
72 std::cout << "usage1: addRun <options1> -rl <runList>" << std::endl;
73 std::cout << "usage2: addRun <options2> -in <inputFile>" << std::endl;
74 std::cout << std::endl;
75 std::cout << " <options1>:" << std::endl;
76 std::cout << " -t0 <ival>: <ival> is a comma separted list of global t0-bin's, or" << std::endl;
77 std::cout << " <ival> is a comma separted list of '-1', then it is assumed that there is a prompt peak." << std::endl;
78 std::cout << " Under this condition the t0-bin will be determined automatically by" << std::endl;
79 std::cout << " the position of the max-value of the corresponing histograms." << std::endl;
80 std::cout << " If t0's are not provided, t0-bin will be taken from the file." << std::endl;
81 std::cout << " -f <format>: <format> is the output file format to be used." << std::endl;
82 std::cout << " For supported formats see below." << std::endl;
83 std::cout << " -y <year> : the year at which runs were measured. Format yyyy." << std::endl;
84 std::cout << " If not provided, the current year is used." << std::endl;
85 std::cout << " -i <instrument> : <instrument> is one of gps, ltf, flame, gpd, hifi, dolly, lem" << std::endl;
86 std::cout << " -m <dev> : <dev> is pta or tdc (only needed for bulk). Default: tdc" << std::endl;
87 std::cout << " -o <fln> : output file name." << std::endl;
88 std::cout << " -rl <runList> can be:" << std::endl ;
89 std::cout << " (i) <run0> <run1> <run2> ... <runN> : run numbers, e.g. 123 124" << std::endl;
90 std::cout << " (ii) <run0>-<runN> : a range, e.g. 123-125 -> 123 124 125" << std::endl;
91 std::cout << " (iii) <run0>:<runN>:<step> : a sequence, e.g. 123:127:2 -> 123 125 127" << std::endl;
92 std::cout << " <step> will give the step width and has to be a positive number!" << std::endl;
93 std::cout << " a <runList> can also combine (i)-(iii), e.g. 123 128-130 133, etc." << std::endl;
94 std::cout << std::endl;
95 std::cout << " <options2>:" << std::endl;
96 std::cout << " -f <format>: <format> is file format of the output-file to be used." << std::endl;
97 std::cout << " -o <fln> : output file name." << std::endl;
98 std::cout << " -in <inputFile>: the file name of the file containing the necessary run information" << std::endl;
99 std::cout << " to add runs with various t0's, fgb's, lgb's, different years, etc." << std::endl;
100 std::cout << " The structure of the <inputFile> is:" << std::endl;
101 std::cout << " Lines starting with a '%' and empty lines are ignored." << std::endl;
102 std::cout << " A single run needs to provide the following information:" << std::endl;
103 std::cout << " file <path-name>: needs to be a full path name" << std::endl;
104 std::cout << " t0 <t0-bin> : needs to be the t0 bin or " << std::endl;
105 std::cout << " 0 to take the t0 bin from the file, or" << std::endl;
106 std::cout << " -1 for automatic determination via prompt peak (see above)." << std::endl;
107 std::cout << " Example:" << std::endl;
108 std::cout << " % file 1. 6 histos present, hence 6 t0-bins" << std::endl;
109 std::cout << " file /home/test/data/deltat_tdc_gps_4324.bin" << std::endl;
110 std::cout << " t0 401, 400, 399, 400, 358, 400" << std::endl;
111 std::cout << " % file 2, take t0-bins from the file" << std::endl;
112 std::cout << " file /home/test/data/deltat_tdc_gps_4325.bin" << std::endl;
113 std::cout << " % file 3, deduce to t0-bin's from the prompt peak" << std::endl;
114 std::cout << " file /home/test/data/deltat_tdc_gps_4325.bin" << std::endl;
115 std::cout << " t0 -1, -1, -1, -1, -1, -1" << std::endl;
116 std::cout << std::endl;
117 std::cout << " Supported uSR file formats:" << std::endl;
118 std::cout << " MusrRoot, PSI-BIN, PSI-MDU, MUD, NeXus" << std::endl;
119 std::cout << std::endl;
120}
121
122//--------------------------------------------------------------------------
130bool addRun_checkFormat(std::string &format) {
131 bool result = false;
132 boost::to_lower(format);
133
134 if (format == "psi-bin")
135 format = "psibin";
136 if (format == "psi-mud")
137 format = "psimdu";
138
139 if (format == "musrroot") {
140 result = true;
141 } else if (format == "psibin") {
142 result = true;
143 } else if (format == "psimdu") {
144 result = true;
145 } else if (format == "mud") {
146 result = true;
147 } else if (format == "nexus") {
148 result = true;
149 } else if (format == "root") {
150 result = true;
151 }
152
153 return result;
154}
155
156//--------------------------------------------------------------------------
163bool addRun_readInputFiles(const std::string fileName, std::vector<PAddRunInfo> &infoVec)
164{
165 PAddRunInfo info;
166 char str[256];
167 std::ifstream fin(fileName.c_str(), std::ifstream::in);
168 std::string line;
169 char *tok{nullptr};
170 int status, ival;
171 bool lastWasFile{false};
172 memset(str, '\0', sizeof(str));
173 // read into a std::string: a fixed size line buffer silently drops the rest of
174 // the input file as soon as one line (e.g. a long data-file path) exceeds it.
175 while (std::getline(fin, line)) {
176 boost::trim_left(line);
177 if (line.empty())
178 continue;
179 if (line[0] == '%')
180 continue;
181 tok = strtok(line.data(), " "); // strtok tokenises in place, line stays the owner
182 if (!strcmp(tok, "file")) {
183 if (lastWasFile) {
184 infoVec.push_back(info);
185 info.fPathFileName = "";
186 info.fT0.clear();
187 }
188 tok = strtok(NULL, " ");
189 if (tok == NULL) {
190 std::cerr << std::endl;
191 std::cerr << "**ERROR** found label 'file' without argument." << std::endl;
192 std::cerr << std::endl;
193 fin.close();
194 return false;
195 }
196 info.fPathFileName = tok;
197 lastWasFile = true;
198 } else if (!strcmp(tok, "t0")) {
199 while ((tok = strtok(NULL, ",")) != NULL) {
200 status = sscanf(tok, "%d%255s", &ival, str);
201 if (status != 1) {
202 std::cerr << std::endl;
203 std::cerr << "**ERROR** found t0 argument '" << tok << "' which is not a number." << std::endl;
204 std::cerr << std::endl;
205 fin.close();
206 return false;
207 }
208 info.fT0.push_back(ival);
209 }
210 } else {
211 std::cerr << std::endl;
212 std::cerr << "**ERROR** found unrecognized token '" << tok << "'." << std::endl;
213 std::cerr << std::endl;
214 fin.close();
215 return false;
216 }
217 }
218 infoVec.push_back(info);
219
220 fin.close();
221
222 // checks
223 for (int i=0; i<infoVec.size(); i++) {
224 if (infoVec[i].fPathFileName.empty()) {
225 std::cerr << std::endl;
226 std::cerr << "**ERROR** something is wrong with the inputFile. Found empty pathName." << std::endl;
227 std::cerr << std::endl;
228 return false;
229 }
230 }
231
232 return true;
233}
234
235//--------------------------------------------------------------------------
244{
245 UInt_t pos=0;
246
247 if (vec == nullptr)
248 return pos;
249
250 Double_t max=vec->at(0);
251
252 for (UInt_t i=0; i<vec->size(); i++) {
253 if (max < vec->at(i)) {
254 max = vec->at(i);
255 pos = i;
256 }
257 }
258
259 return pos;
260}
261
262//--------------------------------------------------------------------------
274bool addRun_filter_t0(int argc, char *argv[], int &idx, PIntVector &t0)
275{
276 int pos{idx}, status, ival;
277 PIntVector tt0;
278 // collect run list string from input
279 for (int i=idx; i<argc; i++) {
280 pos = i;
281 if ((argv[i][0] == '-') && isalpha(argv[i][1])) { // next command
282 pos = i-1;
283 break;
284 } else {
285 status = sscanf(argv[i], "%d", &ival);
286 if (status != 1) {
287 std::cerr << std::endl;
288 std::cerr << "**ERROR** found t0 value '" << argv[i] << "' which is not an integer." << std::endl;
289 std::cerr << std::endl;
290 return false;
291 }
292 tt0.push_back(ival);
293 }
294 }
295
296 // make sure that t0's > -2
297 for (int i=0; i<tt0.size(); i++) {
298 if (tt0[i] <= -2) {
299 std::cerr << std::endl;
300 std::cerr << "**ERROR** found t0 value '" << tt0[i] << "' which is out-of-range." << std::endl;
301 std::cerr << std::endl;
302 return false;
303 }
304 }
305
306 idx = pos;
307 t0 = tt0;
308
309 return true;
310}
311
312//--------------------------------------------------------------------------
324bool addRun_filter_runList(int argc, char *argv[], int &idx, PUIntVector &runList)
325{
326 int pos{idx};
327 std::string runStr{""};
328 // collect run list string from input
329 for (int i=idx; i<argc; i++) {
330 pos = i;
331 if ((argv[i][0] == '-') && isalpha(argv[i][1])) { // next command
332 pos = i-1;
333 break;
334 } else {
335 runStr += argv[i];
336 runStr += " ";
337 }
338 }
339 // extract run list from string
340 PStringNumberList rl(runStr);
341 std::string errMsg{""};
342 if (!rl.Parse(errMsg)) {
343 std::cerr << "**ERROR** in run list: -rl " << runStr << std::endl;
344 std::cerr << errMsg << std::endl;
345 return false;
346 }
347 runList = rl.GetList();
348
349 idx = pos;
350
351 return true;
352}
353
354//--------------------------------------------------------------------------
363int main(int argc, char *argv[])
364{
365 // check for --help or --version
366 if (argc == 2) {
367 if (!strncmp(argv[1], "--help", 128) || !strncmp(argv[1], "-h", 128)) {
369 return PMUSR_SUCCESS;
370 } else if (!strncmp(argv[1], "--version", 128) || !strncmp(argv[1], "-v", 128)) {
371#ifdef HAVE_CONFIG_H
372#ifdef HAVE_GIT_REV_H
373 std::cout << std::endl << "addRun version: " << PACKAGE_VERSION << ", git-branch: " << GIT_BRANCH << ", git-rev: " << GIT_CURRENT_SHA1 << " (" << BUILD_TYPE << "), ROOT version: " << ROOT_VERSION_USED << std::endl << std::endl;
374#else
375 std::cout << std::endl << "addRun version: " << PACKAGE_VERSION << " (" << BUILD_TYPE << "), ROOT version: " << ROOT_VERSION_USED << std::endl << std::endl;
376#endif
377#else
378#ifdef HAVE_GIT_REV_H
379 std::cout << std::endl << "addRun git-branch: " << GIT_BRANCH << ", git-rev: " << GIT_CURRENT_SHA1 << std::endl << std::endl;
380#else
381 std::cout << std::endl << "addRun version: unkown." << std::endl << std::endl;
382#endif
383#endif
384 return PMUSR_SUCCESS;
385 } else {
386 std::cerr << std::endl;
387 std::cerr << "**ERROR** missing required input." << std::endl;
388 std::cerr << std::endl;
390 return -1;
391 }
392 }
393
394 // filter arguments
395 PIntVector t0;
396 Int_t ival;
397 UInt_t yearNum{0};
398 std::string flnOut{""};
399 std::string format{""}, year{""}, instrument{""}, dev{"tdc"};
400 PUIntVector runList;
401 std::string inputFln{""};
402 int status;
403 std::vector<PAddRunInfo> addRunInfo;
404
405 for (int i=1; i<argc; i++) {
406 if (!strcmp(argv[i], "-t0")) {
407 if (i+1 >= argc) {
408 std::cerr << std::endl;
409 std::cerr << "**ERROR** found -t0 without value." << std::endl;
410 std::cerr << std::endl;
411 return -1;
412 }
413 // deal with run-list here
414 int idx=i+1;
415 if (!addRun_filter_t0(argc, argv, idx, t0)) {
416 return -2;
417 }
418 i=idx;
419 } else if (!strcmp(argv[i], "-f")) {
420 if (i+1 >= argc) {
421 std::cerr << std::endl;
422 std::cerr << "**ERROR** found -f without argument." << std::endl;
423 std::cerr << std::endl;
424 return -1;
425 }
426 format = argv[i+1];
427 if (!addRun_checkFormat(format)) {
428 format = "";
429 std::cerr << std::endl;
430 std::cerr << "**ERROR** found -f with unsupported format: '" << format << "'" << std::endl;
431 std::cerr << std::endl;
432 return -2;
433 }
434 i++;
435 } else if (!strcmp(argv[i], "-y")) {
436 if (i+1 >= argc) {
437 std::cerr << std::endl;
438 std::cerr << "**ERROR** found -y without value." << std::endl;
439 std::cerr << std::endl;
440 return -1;
441 }
442 status = sscanf(argv[i+1], "%d", &ival);
443 if (status != 1) {
444 std::cerr << std::endl;
445 std::cerr << "**ERROR** found invalid -y value: " << argv[i+1] << "." << std::endl;
446 std::cerr << std::endl;
447 return -2;
448 }
449 if (1900 - ival > 0) {
450 std::cerr << std::endl;
451 std::cerr << "**ERROR** found invalid -y value: " << argv[i+1] << "." << std::endl;
452 std::cerr << " Format has to be YYYY." << std::endl;
453 std::cerr << std::endl;
454 return -2;
455 }
456 yearNum = ival;
457 year = argv[i+1];
458 i++;
459 } else if (!strcmp(argv[i], "-i")) {
460 if (i+1 >= argc) {
461 std::cerr << std::endl;
462 std::cerr << "**ERROR** found -i without argument." << std::endl;
463 std::cerr << std::endl;
464 return -1;
465 }
466 instrument = argv[i+1];
467 boost::to_lower(instrument);
468 i++;
469 } else if (!strcmp(argv[i], "-m")) {
470 if (i+1 >= argc) {
471 std::cerr << std::endl;
472 std::cerr << "**ERROR** found -m without argument." << std::endl;
473 std::cerr << std::endl;
474 return -1;
475 }
476 std::string str(argv[i+1]);
477 boost::to_lower(str);
478 if ((str != "pta") && (str != "tdc")) {
479 std::cerr << std::endl;
480 std::cerr << "**ERROR** found -m with unsupported argument '" << argv[i+1] << "'. Possible arguments are 'pta' or 'tdc'." << std::endl;
481 std::cerr << std::endl;
482 return -2;
483 }
484 dev = str;
485 i++;
486 } else if (!strcmp(argv[i], "-o")) {
487 if (i+1 >= argc) {
488 std::cerr << std::endl;
489 std::cerr << "**ERROR** found -o without argument." << std::endl;
490 std::cerr << std::endl;
491 return -1;
492 }
493 flnOut = argv[i+1];
494 i++;
495 } else if (!strcmp(argv[i], "-rl")) {
496 if (i+1 >= argc) {
497 std::cerr << std::endl;
498 std::cerr << "**ERROR** found -rl without argument." << std::endl;
499 std::cerr << std::endl;
500 return -1;
501 }
502 // deal with run-list here
503 int idx=i+1;
504 if (!addRun_filter_runList(argc, argv, idx, runList)) {
505 return -2;
506 }
507 i=idx;
508 } else if (!strcmp(argv[i], "-in")) {
509 if (i+1 >= argc) {
510 std::cerr << std::endl;
511 std::cerr << "**ERROR** found -in without argument." << std::endl;
512 std::cerr << std::endl;
513 return -1;
514 }
515 inputFln = argv[i+1];
516 i++;
517 } else { // error
518 std::cerr << std::endl;
519 std::cerr << "**ERROR** found unexpected command line element '" << argv[i] << "'" << std::endl;
520 std::cerr << std::endl;
522 return -1;
523 }
524 }
525
526 // test for usage1 or usage2
527 if (inputFln.empty() && (runList.size() == 0)) {
528 std::cerr << std::endl;
529 std::cerr << "**ERROR** essential input for usage1 and usage2 is missing." << std::endl;
530 std::cerr << std::endl;
532 return -3;
533 }
534 if (!inputFln.empty() && (runList.size() > 0)) {
535 std::cerr << std::endl;
536 std::cerr << "**ERROR** cannot decide if usage1 or usage2." << std::endl;
537 std::cerr << std::endl;
539 return -3;
540 }
541
542 // read startup file
543 std::string startup_path_name{};
544 std::unique_ptr<TSAXParser> saxParser = std::make_unique<TSAXParser>();
545 std::unique_ptr<PStartupHandler> startupHandler = std::make_unique<PStartupHandler>();
546 if (!startupHandler->StartupFileFound()) {
547 std::cerr << std::endl << ">> addRun **WARNING** couldn't find " << startupHandler->GetStartupFilePath().Data();
548 std::cerr << std::endl;
549 } else {
550 startup_path_name = startupHandler->GetStartupFilePath().Data();
551 saxParser->ConnectToHandler("PStartupHandler", startupHandler.get());
552 //status = saxParser->ParseFile(startup_path_name);
553 // parsing the file as above seems to lead to problems in certain environments;
554 // use the parseXmlFile function instead (see PStartupHandler.cpp for the definition)
555 status = parseXmlFile(saxParser.get(), startup_path_name.c_str());
556 // check for parse errors
557 if (status) { // error
558 std::cerr << std::endl << ">> addRun **WARNING** Reading/parsing musrfit_startup.xml failed.";
559 std::cerr << std::endl;
560 } else {
561 startupHandler->CheckLists();
562 }
563 }
564
565 // additional tests needed for usage1 (currently for PSI use only)
566 if (runList.size() > 0) {
567 if (t0.empty()) {
568 std::cout << ">> t0 not provided.";
569 } else {
570 std::cout << ">> t0: ";
571 for (int i=0; i<t0.size(); i++)
572 std::cout << t0[i] << ", ";
573 }
574 std::cout << std::endl;
575 std::cout << ">> format: " << format << std::endl;
576 std::cout << ">> year: " << year << std::endl;
577 std::cout << ">> instrument: " << instrument << std::endl;
578 std::cout << ">> fln out: " << flnOut << std::endl;
579 std::cout << ">> runList: ";
580 for (int i=0; i<runList.size(); i++)
581 std::cout << runList[i] << ", ";
582 std::cout << std::endl;
583
584 PAddRunInfo addRun;
585 addRun.fT0 = t0;
586 addRun.fFileFormat = format;
587 // construct file names
588 for (int i=0; i<runList.size(); i++) {
589 PFindRun findRun(startupHandler->GetDataPathList(), startupHandler->GetRunNameTemplateList(), instrument, yearNum, runList[i]);
590 if (findRun.FoundPathName()) {
591 std::cout << ">> found path name: " << findRun.GetPathName() << std::endl;
592 addRun.fPathFileName = findRun.GetPathName();
593 addRunInfo.push_back(addRun);
594 } else {
595 std::cout << "**WARNING** run: " << runList[i] << " for instrument '" << instrument << "' and year '" << year << "' not found" << std::endl;
596 }
597 }
598 }
599
600 // additional tests needed for usage2
601 if (!inputFln.empty()) {
602 // check if file exists
603 if (!boost::filesystem::exists(inputFln)) {
604 std::cerr << std::endl;
605 std::cerr << "**ERROR** file '" << inputFln << "' seems not to exist." << std::endl;
606 std::cerr << std::endl;
607 return -1;
608 }
609 // read input-file and data sets
610 if (!addRun_readInputFiles(inputFln, addRunInfo)) {
611 return -2;
612 }
613 }
614
615 for (int i=0; i<addRunInfo.size(); i++) {
616 std::cout << ">> run " << i+1 << ": " << std::endl;
617 std::cout << ">> fln : " << addRunInfo[i].fPathFileName << std::endl;
618 if (addRunInfo[i].fT0.empty()) {
619 std::cout << ">> t0 not provided.";
620 } else {
621 std::cout << ">> t0: ";
622 for (int j=0; j<addRunInfo[i].fT0.size(); j++) {
623 std::cout << addRunInfo[i].fT0[j] << ", ";
624 }
625 }
626 std::cout << std::endl;
627 }
628
629 // load the files
630 std::vector< std::unique_ptr<PRunDataHandler> > runDataHandler;
631 runDataHandler.resize(addRunInfo.size());
632 Bool_t isGood{true};
633 for (UInt_t i=0; i<runDataHandler.size(); i++) {
634 if (startupHandler != nullptr) {
635 runDataHandler[i] = std::make_unique<PRunDataHandler>(addRunInfo[i].fPathFileName, addRunInfo[i].fFileFormat, startupHandler->GetDataPathList());
636 runDataHandler[i]->ReadData();
637 if (!runDataHandler[i]->IsAllDataAvailable()) {
638 isGood = false;
639 std::cerr << std::endl;
640 std::cerr << "**ERROR** couldn't read data for PRunDataHandler (i=" << i << ")." << std::endl;
641 std::cerr << std::endl;
642 break;
643 }
644 } else {
645 runDataHandler[i] = std::make_unique<PRunDataHandler>(addRunInfo[i].fPathFileName, addRunInfo[i].fFileFormat);
646 runDataHandler[i]->ReadData();
647 if (!runDataHandler[i]->IsAllDataAvailable()) {
648 isGood = false;
649 std::cerr << std::endl;
650 std::cerr << "**ERROR** couldn't read data for PRunDataHandler (i=" << i << ")." << std::endl;
651 std::cerr << std::endl;
652 break;
653 }
654 }
655 }
656
657 // make sure that the number of provided t0's are matching the number of histos from the run-file
658
659 // 1st make sure all the runs have the same number run data (==1 here)
660 std::unique_ptr<PAny2ManyInfo> info;
661 std::unique_ptr<PRunDataHandler> dataOut;
662 if (isGood) {
663 for (UInt_t i=1; i<runDataHandler.size(); i++) {
664 if (runDataHandler[0]->GetNoOfRunData() != runDataHandler[i]->GetNoOfRunData()) {
665 isGood = false;
666 std::cerr << std::endl;
667 std::cerr << "**ERROR** can only handle same number of run data per run handler." << std::endl;
668 std::cerr << std::endl;
669 break;
670 }
671 }
672 info = std::make_unique<PAny2ManyInfo>();
673 }
674
675 if (isGood) {
676 // prepare for the new added run data sets
677 info->outFormat = format;
678 info->year = year;
679 info->outFileName = flnOut;
680 dataOut = std::make_unique<PRunDataHandler>(info.get());
681 }
682
683 if (isGood) {
684 // check that all runs have the same number of histograms
685 for (UInt_t i=1; i<runDataHandler.size(); i++) {
686 if (runDataHandler[0]->GetRunData()->GetNoOfHistos() != runDataHandler[i]->GetRunData()->GetNoOfHistos()) {
687 std::cerr << std::endl;
688 std::cerr << "**ERROR** can only add runs with the same number of histograms." << std::endl;
689 std::cerr << std::endl;
690 isGood = false;
691 }
692 }
693 }
694
695 if (isGood) {
696 // add all the runs
697 // take first run as the reference for the data
698 std::vector<PDoubleVector*> addedHistos;
699 addedHistos.resize(runDataHandler[0]->GetRunData()->GetNoOfHistos());
700 for (UInt_t i=0; i<runDataHandler[0]->GetRunData()->GetNoOfHistos(); i++) {
701 addedHistos[i] = runDataHandler[0]->GetRunData()->GetDataSet(i, false)->GetData();
702 }
703 // get the t0's for all the reference histos
704 PIntVector t0Vec;
705 t0Vec.resize(runDataHandler[0]->GetRunData()->GetNoOfHistos());
706 if (addRunInfo[0].fT0.empty()) { // i.e. take t0's from data file
707 for (UInt_t i=0; i<runDataHandler[0]->GetRunData()->GetNoOfHistos(); i++) {
708 t0Vec[i] = runDataHandler[0]->GetRunData()->GetT0Bin(i+1);
709 }
710 addRunInfo[0].fT0 = t0Vec;
711 } else { // t0 vector present
712 // make sure that the number of t0's fit the number of histos
713 if (addRunInfo[0].fT0.size() < runDataHandler[0]->GetRunData()->GetNoOfHistos()) {
714 UInt_t counts=runDataHandler[0]->GetRunData()->GetNoOfHistos()-addRunInfo[0].fT0.size();
715 for (UInt_t i=0; i<counts; i++)
716 addRunInfo[0].fT0.push_back(0);
717 }
718 // check t0 data
719 for (UInt_t i=0; i<addRunInfo[0].fT0.size(); i++) {
720 if (addRunInfo[0].fT0[i] == 0) { // get t0 from file
721 addRunInfo[0].fT0[i] = runDataHandler[0]->GetRunData()->GetT0Bin(i+1);
722 } else if (addRunInfo[0].fT0[i] == -1) { // get t0 from prompt peak
723 addRunInfo[0].fT0[i] = addRun_getPromptPeakPos(runDataHandler[0]->GetRunData()->GetDataSet(i, false)->GetData());
724 }
725 }
726 }
727
728 // loop over the remaining runs, determine t0's if needed and add the data
729 for (int i=1; i<runDataHandler.size(); i++) {
730 // get the t0's for all the histos of a run to be added
731 PIntVector t0Vec;
732 t0Vec.resize(runDataHandler[i]->GetRunData()->GetNoOfHistos());
733 if (addRunInfo[i].fT0.empty()) { // i.e. take t0's from data file
734 for (UInt_t j=0; j<runDataHandler[i]->GetRunData()->GetNoOfHistos(); j++) {
735 t0Vec[j] = runDataHandler[i]->GetRunData()->GetT0Bin(j+1);
736 }
737 addRunInfo[i].fT0 = t0Vec;
738 } else { // t0 vector present
739 // make sure that the number of t0's fit the number of histos
740 if (addRunInfo[i].fT0.size() < runDataHandler[i]->GetRunData()->GetNoOfHistos()) {
741 UInt_t counts=runDataHandler[i]->GetRunData()->GetNoOfHistos()-addRunInfo[i].fT0.size();
742 for (UInt_t j=0; j<counts; j++)
743 addRunInfo[i].fT0.push_back(0);
744 }
745 // check t0 data
746 for (UInt_t j=0; j<addRunInfo[i].fT0.size(); j++) {
747 if (addRunInfo[i].fT0[j] == 0) { // get t0 from file
748 addRunInfo[i].fT0[j] = runDataHandler[i]->GetRunData()->GetT0Bin(j+1);
749 } else if (addRunInfo[i].fT0[j] == -1) { // get t0 from prompt peak
750 addRunInfo[i].fT0[j] = addRun_getPromptPeakPos(runDataHandler[i]->GetRunData()->GetDataSet(j, false)->GetData());
751 }
752 }
753 }
754
755 // calculate the offset due to potential differences in t0's between runs
756 PIntVector diff;
757 diff.resize(addRunInfo[i].fT0.size());
758 for (UInt_t j=0; j<diff.size(); j++) {
759 diff[j] = addRunInfo[i].fT0[j] - addRunInfo[0].fT0[j];
760 }
761
762 // add all the to be added histos of all remaining runs
763 PDoubleVector *addData{nullptr};
764 Int_t idx;
765 for (int j=0; j<runDataHandler[i]->GetRunData()->GetNoOfHistos(); j++) { // loop over all histos
766 addData = runDataHandler[i]->GetRunData()->GetDataSet(j, false)->GetData();
767 for (int k=0; k<addedHistos[j]->size(); k++) { // loop over all elements of a histo
768 idx = k + diff[j];
769 if ((idx >= 0) && (idx < addData->size())) {
770 addedHistos[j]->at(k) += addData->at(idx);
771 }
772 }
773 }
774 }
775
776 // feed all the necessary information for the data file
777 PRawRunData *rawRunData = nullptr;
778 rawRunData = runDataHandler[0]->GetRunData(); // copy all
779 if (rawRunData == nullptr) {
780 std::cerr << ">> addRun: **ERROR** couldn't obtain PRawRunData object." << std::endl;
782 }
783 rawRunData->SetGenerator("addRun");
784 // overwrite the t0 values with the new ones
785 for (UInt_t i=0; i<rawRunData->GetNoOfHistos(); i++) {
786 rawRunData->GetDataSet(i, false)->SetTimeZeroBin(addRunInfo[0].fT0[i]);
787 }
788 // write histos
789 for (UInt_t i=0; i<rawRunData->GetNoOfHistos(); i++) {
790 rawRunData->GetDataSet(i, false)->SetData(*addedHistos[i]);
791 }
792
793 // feed run data handler with new data
794 if (dataOut->SetRunData(rawRunData)) {
795 // write output file
796 dataOut->WriteData();
797 }
798 }
799
800 return PMUSR_SUCCESS;
801}
std::vector< UInt_t > PUIntVector
Definition PMusr.h:375
#define PMUSR_SUCCESS
Successful operation completion.
Definition PMusr.h:58
std::vector< Int_t > PIntVector
Definition PMusr.h:381
#define PMUSR_MSR_ALLOCATION_ERROR
Memory allocation error while processing MSR file.
Definition PMusr.h:66
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().
int main(int argc, char *argv[])
Definition addRun.cpp:363
bool addRun_readInputFiles(const std::string fileName, std::vector< PAddRunInfo > &infoVec)
Definition addRun.cpp:163
UInt_t addRun_getPromptPeakPos(PDoubleVector *vec)
Definition addRun.cpp:243
bool addRun_filter_t0(int argc, char *argv[], int &idx, PIntVector &t0)
Definition addRun.cpp:274
bool addRun_checkFormat(std::string &format)
Definition addRun.cpp:130
void addRun_syntax()
Definition addRun.cpp:68
bool addRun_filter_runList(int argc, char *argv[], int &idx, PUIntVector &runList)
Definition addRun.cpp:324
PFindRun - Locates muSR data files using template-based path resolution.
Definition PFindRun.h:68
Bool_t FoundPathName()
Searches for the run file using configured templates and paths.
Definition PFindRun.cpp:133
TString GetPathName()
Returns the full path to the found run file.
Definition PFindRun.h:128
virtual void SetData(PDoubleVector data)
Definition PMusr.h:702
virtual void SetTimeZeroBin(Double_t tzb)
Definition PMusr.h:684
virtual PRawRunDataSet * GetDataSet(const UInt_t idx, Bool_t wantHistoNo=true)
Definition PMusr.cpp:750
virtual void SetGenerator(const TString &str)
Definition PMusr.h:902
virtual const UInt_t GetNoOfHistos()
Definition PMusr.h:893
virtual PUIntVector GetList()
Definition PMusr.h:1440
virtual bool Parse(std::string &errorMsg, bool ignoreFirstToken=false)
Definition PMusr.cpp:2041
#define NULL
Definition mud.h:167
PIntVector fT0
Definition addRun.cpp:59
std::string fPathFileName
Definition addRun.cpp:58
std::string fFileFormat
Definition addRun.cpp:60