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