musrfit 1.10.0
PRunDataHandler.cpp
Go to the documentation of this file.
1/***************************************************************************
2
3 PRunDataHandler.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/types.h>
35#include <sys/stat.h>
36#include <unistd.h>
37#include <cstdio>
38#include <ctime>
39#include <iostream>
40#include <iomanip>
41#include <fstream>
42#include <string>
43#include <sstream>
44#include <memory>
45
46#include <TROOT.h>
47#include <TSystem.h>
48#include <TString.h>
49#include <TObjArray.h>
50#include <TObjString.h>
51#include <TFile.h>
52#include <TFolder.h>
53#include <TH1F.h>
54#include <TDatime.h>
55#include <TDirectoryFile.h>
56
57#include "TMusrRunHeader.h"
58#include "TLemRunHeader.h"
59#include "MuSR_td_PSI_bin.h"
60#include "mud.h"
61
62#ifdef PNEXUS_ENABLED
63#include "PNeXus.h"
64#endif
65
66#include "PRunDataHandler.h"
67
68#define PRH_MUSR_ROOT 0
69#define PRH_MUSR_ROOT_DIR 1
70#define PRH_LEM_ROOT 2
71
72#define PRH_NPP_OFFSET 0
73#define PRH_PPC_OFFSET 20
74
75#define PHR_INIT_ALL 0
76#define PHR_INIT_MSR 1
77#define PHR_INIT_ANY2MANY 2
78
79//--------------------------------------------------------------------------
80// Constructor
81//--------------------------------------------------------------------------
89
90//--------------------------------------------------------------------------
91// Constructor
92//--------------------------------------------------------------------------
99PRunDataHandler::PRunDataHandler(TString fileName, const TString fileFormat) : fFileFormat(fileFormat)
100{
101 Init();
102
103 FileExistsCheck(fileName);
104}
105
106//--------------------------------------------------------------------------
107// Constructor
108//--------------------------------------------------------------------------
116PRunDataHandler::PRunDataHandler(TString fileName, const TString fileFormat, const PStringVector dataPath) : fDataPath(dataPath), fFileFormat(fileFormat)
117{
118 Init();
119
120 FileExistsCheck(fileName);
121}
122
123//--------------------------------------------------------------------------
124// Constructor
125//--------------------------------------------------------------------------
134PRunDataHandler::PRunDataHandler(TString fileName, const TString fileFormat, const TString dataPath, PRawRunData &runData)
135{
136 Init();
137}
138
139//--------------------------------------------------------------------------
140// Constructor
141//--------------------------------------------------------------------------
151
152//--------------------------------------------------------------------------
153// Constructor
154//--------------------------------------------------------------------------
162 fAny2ManyInfo(any2ManyInfo), fDataPath(dataPath)
163{
165}
166
167//--------------------------------------------------------------------------
168// Constructor
169//--------------------------------------------------------------------------
179
180//--------------------------------------------------------------------------
181// Constructor
182//--------------------------------------------------------------------------
191 fMsrInfo(msrInfo), fDataPath(dataPath)
192{
194}
195
196//--------------------------------------------------------------------------
197// Destructor
198//--------------------------------------------------------------------------
203{
204 fDataPath.clear();
205 fData.clear();
206}
207
208//--------------------------------------------------------------------------
209// GetRunData
210//--------------------------------------------------------------------------
222{
223 UInt_t i;
224
225 for (i=0; i<fData.size(); i++) {
226 if (!fData[i].GetRunName()->CompareTo(runName)) // run found
227 break;
228 }
229
230 if (i == fData.size())
231 return nullptr;
232 else
233 return &fData[i];
234}
235
236//--------------------------------------------------------------------------
237// GetRunData
238//--------------------------------------------------------------------------
249{
250 if (idx >= fData.size())
251 return nullptr;
252 else
253 return &fData[idx];
254}
255
256//--------------------------------------------------------------------------
257// ReadData
258//--------------------------------------------------------------------------
264{
265 if (fMsrInfo) { // i.e. msr-file triggered
266 if (!ReadFilesMsr()) // couldn't read file
267 fAllDataAvailable = false;
268 else
269 fAllDataAvailable = true;
270 } else if (!fRunPathName.IsWhitespace()) { // i.e. file name triggered
271 if (fFileFormat == "") { // try to guess the file format if fromat hasn't been provided
272 TString ext=fRunPathName;
273 Ssiz_t pos=ext.Last('.');
274 ext.Remove(0, pos+1);
275 if (!ext.CompareTo("bin", TString::kIgnoreCase))
276 fFileFormat = "psibin";
277 else if (!ext.CompareTo("root", TString::kIgnoreCase))
278 fFileFormat = "musrroot";
279 else if (!ext.CompareTo("msr", TString::kIgnoreCase))
280 fFileFormat = "mud";
281 else if (!ext.CompareTo("nxs", TString::kIgnoreCase))
282 fFileFormat = "nexus";
283 else if (!ext.CompareTo("mdu", TString::kIgnoreCase))
284 fFileFormat = "psimdu";
285 }
286 if ((fFileFormat == "MusrRoot") || (fFileFormat == "musrroot")) {
288 } else if ((fFileFormat == "NeXus") || (fFileFormat == "nexus")) {
290 } else if ((fFileFormat == "PsiBin") || (fFileFormat == "psibin") ||
291 (fFileFormat == "PsiMdu") || (fFileFormat == "psimdu")) {
293 } else if ((fFileFormat == "Mud") || (fFileFormat == "mud")) {
295 } else if ((fFileFormat == "Wkm") || (fFileFormat == "wkm")) {
297 } else {
298 std::cerr << std::endl << ">> PRunDataHandler::ReadData(): **ERROR** unkown file format \"" << fFileFormat << "\" found." << std::endl;
299 fAllDataAvailable = false;
300 }
301 } else {
302 std::cerr << std::endl << ">> PRunDataHandler::ReadData(): **ERROR** Couldn't read files." << std::endl;
303 fAllDataAvailable = false;
304 }
305}
306
307//--------------------------------------------------------------------------
308// ConvertData
309//--------------------------------------------------------------------------
314{
315 if (!ReadWriteFilesList()) // couldn't read file
316 fAllDataAvailable = false;
317 else
318 fAllDataAvailable = true;
319}
320
321//--------------------------------------------------------------------------
322// SetRunData
323//--------------------------------------------------------------------------
333{
334 if ((idx == 0) && (fData.size() == 0)) {
335 fData.resize(1);
336 }
337 if (idx >= fData.size()) {
338 std::cerr << std::endl << ">>PRunDataHandler::SetRunData(): **ERROR** idx=" << idx << " is out-of-range (0.." << fData.size() << ")." << std::endl;
339 return false;
340 }
341
342 fData[idx] = *data;
343
344 return true;
345}
346
347//--------------------------------------------------------------------------
348// WriteData
349//--------------------------------------------------------------------------
353Bool_t PRunDataHandler::WriteData(TString fileName)
354{
355 if ((fAny2ManyInfo == nullptr) && (fileName="")) {
356 std::cerr << std::endl << ">> PRunDataHandler::WriteData(): **ERROR** insufficient information: no fileName nor fAny2ManyInfo object.";
357 std::cerr << std::endl << " Cannot write data under this conditions." << std::endl;
358 return false;
359 }
360
361 // get output file format tag, first try via fAny2ManyInfo
362 Int_t outTag = A2M_UNDEFINED;
363 if (fAny2ManyInfo != nullptr) {
364 if (!fAny2ManyInfo->outFormat.CompareTo("musrroot", TString::kIgnoreCase))
365 outTag = A2M_MUSR_ROOT;
366 else if (!fAny2ManyInfo->outFormat.CompareTo("musrrootdir", TString::kIgnoreCase))
367 outTag = A2M_MUSR_ROOT_DIR;
368 else if (!fAny2ManyInfo->outFormat.CompareTo("psibin", TString::kIgnoreCase))
369 outTag = A2M_PSIBIN;
370 else if (!fAny2ManyInfo->outFormat.CompareTo("psimdu", TString::kIgnoreCase))
371 outTag = A2M_PSIMDU;
372 else if (!fAny2ManyInfo->outFormat.CompareTo("mud",TString::kIgnoreCase))
373 outTag = A2M_MUD;
374 else if (fAny2ManyInfo->outFormat.BeginsWith("nexus", TString::kIgnoreCase))
375 outTag = A2M_NEXUS;
376 else
377 outTag = A2M_UNDEFINED;
378 } else { // only fileName is given, try to guess from the extension
379 // STILL MISSING
380 }
381
382 if (outTag == A2M_UNDEFINED) {
383 std::cerr << std::endl << ">> PRunDataHandler::WriteData(): **ERROR** no valid output data file format found: '" << fAny2ManyInfo->outFormat.Data() << "'" << std::endl;
384 return false;
385 }
386
387 Bool_t success{true};
388 switch (outTag) {
389 case A2M_MUSR_ROOT:
391 if (fAny2ManyInfo->outFileName.Length() == 0)
392 success = WriteMusrRootFile(outTag, fileName);
393 else
394 success = WriteMusrRootFile(outTag, fAny2ManyInfo->outFileName);
395 break;
396 case A2M_PSIBIN:
397 case A2M_PSIMDU:
398 if (fAny2ManyInfo->outFileName.Length() == 0)
399 success = WritePsiBinFile(fileName);
400 else
401 success = WritePsiBinFile(fAny2ManyInfo->outFileName);
402 break;
403 case A2M_MUD:
404 if (fAny2ManyInfo->outFileName.Length() == 0)
405 success = WriteMudFile(fileName);
406 else
407 success = WriteMudFile(fAny2ManyInfo->outFileName);
408 break;
409 case A2M_NEXUS:
410 if (fAny2ManyInfo->outFileName.Length() == 0)
411 success = WriteNexusFile(fAny2ManyInfo->outFormat, fileName);
412 else
413 success = WriteNexusFile(fAny2ManyInfo->outFormat, fAny2ManyInfo->outFileName);
414 break;
415 default:
416 break;
417 }
418
419 return success;
420}
421
422//--------------------------------------------------------------------------
423// Init (private)
424//--------------------------------------------------------------------------
428void PRunDataHandler::Init(const Int_t tag)
429{
430 if ((tag==PHR_INIT_ALL) || (tag==PHR_INIT_ANY2MANY))
431 fMsrInfo = nullptr;
432 if ((tag==PHR_INIT_ALL) || (tag==PHR_INIT_MSR))
433 fAny2ManyInfo = nullptr;
434 fAllDataAvailable = false;
435 if (tag!=PHR_INIT_ALL)
436 fFileFormat = TString("");
437 fRunName = TString("");
438 fRunPathName = TString("");
439}
440
441//--------------------------------------------------------------------------
442// ReadFilesMsr (private)
443//--------------------------------------------------------------------------
453{
454 Bool_t success = true;
455
456 // loop over the full RUN list to see what needs to be read
457 PMsrRunList *runList = nullptr;
458 runList = fMsrInfo->GetMsrRunList();
459 if (runList == nullptr) {
460 std::cerr << std::endl << ">> PRunDataHandler::ReadFilesMsr(): **ERROR** Couldn't obtain run list from PMsrHandler: something VERY fishy";
461 std::cerr << std::endl;
462 return false;
463 }
464
465 char str[1024], *p_str=nullptr;
466 UInt_t year=0;
467 TString musrRoot("musr-root");
468
469 for (UInt_t i=0; i<runList->size(); i++) {
470 for (UInt_t j=0; j<runList->at(i).GetRunNameSize(); j++) {
471 fRunName = *(runList->at(i).GetRunName(j));
472 // check if file actually exists
473 if (!FileExistsCheck(runList->at(i), j))
474 return false;
475
476 // get year from string if LEM data file
477 strcpy(str, fRunName.Data());
478 p_str = strstr(str, "lem");
479 if (p_str != nullptr)
480 sscanf(p_str, "lem%d_his", &year);
481
482 // check special case for ROOT-NPP/ROOT-PPC (LEM)
483 if (!runList->at(i).GetFileFormat(j)->CompareTo("root-npp")) { // not post pile up corrected histos
484 // if LEM file header is already TMusrRoot, change the data-file-format
485 if (year >= 12)
486 runList->at(i).SetFileFormat(musrRoot, j);
487 // check if forward/backward histoNo are within proper bounds, i.e. < PRH_PPC_OFFSET
488 for (UInt_t k=0; k<runList->at(i).GetForwardHistoNoSize(); k++) {
489 if (runList->at(i).GetForwardHistoNo(k) > PRH_PPC_OFFSET)
490 runList->at(i).SetForwardHistoNo(runList->at(i).GetForwardHistoNo(k)-PRH_PPC_OFFSET, k);
491 }
492 for (UInt_t k=0; k<runList->at(i).GetBackwardHistoNoSize(); k++) {
493 if (runList->at(i).GetBackwardHistoNo(k) > PRH_PPC_OFFSET)
494 runList->at(i).SetBackwardHistoNo(runList->at(i).GetBackwardHistoNo(k)-PRH_PPC_OFFSET, k);
495 }
496 } else if (!runList->at(i).GetFileFormat(j)->CompareTo("root-ppc")) { // post pile up corrected histos
497 // if LEM file header is already TMusrRoot, change the data-file-format
498 if (year >= 12)
499 runList->at(i).SetFileFormat(musrRoot, j);
500 // check if forward/backward histoNo are within proper bounds, i.e. > PRH_PPC_OFFSET
501 for (UInt_t k=0; k<runList->at(i).GetForwardHistoNoSize(); k++) {
502 if (runList->at(i).GetForwardHistoNo(k) < PRH_PPC_OFFSET)
503 runList->at(i).SetForwardHistoNo(runList->at(i).GetForwardHistoNo(k)+PRH_PPC_OFFSET, k);
504 }
505 for (UInt_t k=0; k<runList->at(i).GetBackwardHistoNoSize(); k++) {
506 if (runList->at(i).GetBackwardHistoNo(k) < PRH_PPC_OFFSET)
507 runList->at(i).SetBackwardHistoNo(runList->at(i).GetBackwardHistoNo(k)+PRH_PPC_OFFSET, k);
508 }
509 }
510
511 // check is file is already read
512 if (FileAlreadyRead(*(runList->at(i).GetRunName(j))))
513 continue;
514 // everything looks fine, hence try to read the data file
515 if (!runList->at(i).GetFileFormat(j)->CompareTo("root-npp")) { // not post pile up corrected histos
516 success = ReadRootFile();
517 } else if (!runList->at(i).GetFileFormat(j)->CompareTo("root-ppc")) { // post pile up corrected histos
518 success = ReadRootFile();
519 } else if (!runList->at(i).GetFileFormat(j)->CompareTo("musr-root")) { // MusrRoot style file
520 success = ReadRootFile();
521 } else if (!runList->at(i).GetFileFormat(j)->CompareTo("nexus")) {
522 success = ReadNexusFile();
523 } else if (!runList->at(i).GetFileFormat(j)->CompareTo("psi-bin")) {
524 success = ReadPsiBinFile();
525 } else if (!runList->at(i).GetFileFormat(j)->CompareTo("psi-mdu")) {
526 success = ReadPsiBinFile();
527 } else if (!runList->at(i).GetFileFormat(j)->CompareTo("mud")) {
528 success = ReadMudFile();
529 } else if (!runList->at(i).GetFileFormat(j)->CompareTo("wkm")) {
530 success = ReadWkmFile();
531 } else if (!runList->at(i).GetFileFormat(j)->CompareTo("mdu-ascii")) {
532 success = ReadMduAsciiFile();
533 } else if (!runList->at(i).GetFileFormat(j)->CompareTo("ascii")) {
534 success = ReadAsciiFile();
535 } else if (!runList->at(i).GetFileFormat(j)->CompareTo("db")) {
536 success = ReadDBFile();
537 } else if (!runList->at(i).GetFileFormat(j)->CompareTo("dat")) {
538 success = ReadDatFile();
539 } else {
540 success = false;
541 }
542 }
543 }
544
545 return success;
546}
547
548//--------------------------------------------------------------------------
549// ReadWriteFilesList (private)
550//--------------------------------------------------------------------------
562{
563 if ((fAny2ManyInfo->inFileName.size() == 0) && (fAny2ManyInfo->runList.size() == 0)) {
564 std::cerr << std::endl << ">> PRunDataHandler::ReadWriteFilesList(): **ERROR** Couldn't obtain run list from fAny2ManyInfo: something VERY fishy";
565 std::cerr << std::endl;
566 return false;
567 }
568
569 // get input file format tag
570 Int_t inTag = A2M_UNDEFINED;
571 if (!fAny2ManyInfo->inFormat.CompareTo("root", TString::kIgnoreCase))
572 inTag = A2M_ROOT;
573 else if (!fAny2ManyInfo->inFormat.CompareTo("musrroot", TString::kIgnoreCase))
574 inTag = A2M_MUSR_ROOT;
575 else if (!fAny2ManyInfo->inFormat.CompareTo("psi-bin", TString::kIgnoreCase))
576 inTag = A2M_PSIBIN;
577 else if (!fAny2ManyInfo->inFormat.CompareTo("psi-mdu", TString::kIgnoreCase))
578 inTag = A2M_PSIMDU;
579 else if (!fAny2ManyInfo->inFormat.CompareTo("mud", TString::kIgnoreCase))
580 inTag = A2M_MUD;
581 else if (!fAny2ManyInfo->inFormat.CompareTo("nexus", TString::kIgnoreCase))
582 inTag = A2M_NEXUS;
583 else if (!fAny2ManyInfo->inFormat.CompareTo("wkm", TString::kIgnoreCase))
584 inTag = A2M_WKM;
585 else
586 inTag = A2M_UNDEFINED;
587
588 if (inTag == A2M_UNDEFINED) {
589 std::cerr << std::endl << ">> PRunDataHandler::ReadWriteFilesList(): **ERROR** no valid input data file format found: '" << fAny2ManyInfo->inFormat.Data() << "'" << std::endl;
590 return false;
591 }
592
593 // get output file format tag
594 Int_t outTag = A2M_UNDEFINED;
595 if (!fAny2ManyInfo->outFormat.CompareTo("root", TString::kIgnoreCase))
596 outTag = A2M_ROOT;
597 else if (!fAny2ManyInfo->outFormat.CompareTo("musrroot", TString::kIgnoreCase))
598 outTag = A2M_MUSR_ROOT;
599 else if (!fAny2ManyInfo->outFormat.CompareTo("musrrootdir", TString::kIgnoreCase))
600 outTag = A2M_MUSR_ROOT_DIR;
601 else if (!fAny2ManyInfo->outFormat.CompareTo("psi-bin", TString::kIgnoreCase))
602 outTag = A2M_PSIBIN;
603 else if (!fAny2ManyInfo->outFormat.CompareTo("mud",TString::kIgnoreCase))
604 outTag = A2M_MUD;
605 else if (fAny2ManyInfo->outFormat.BeginsWith("nexus", TString::kIgnoreCase))
606 outTag = A2M_NEXUS;
607 else if (!fAny2ManyInfo->outFormat.CompareTo("wkm", TString::kIgnoreCase))
608 outTag = A2M_WKM;
609 else if (!fAny2ManyInfo->outFormat.CompareTo("ascii", TString::kIgnoreCase))
610 outTag = A2M_ASCII;
611 else
612 outTag = A2M_UNDEFINED;
613
614 if (outTag == A2M_UNDEFINED) {
615 std::cerr << std::endl << ">> PRunDataHandler::ReadWriteFilesList(): **ERROR** no valid output data file format found: '" << fAny2ManyInfo->outFormat.Data() << "'" << std::endl;
616 return false;
617 }
618
619 if (fAny2ManyInfo->inFileName.size() != 0) { // file name list given
620
621 // loop over all runs of the run list
622 for (UInt_t i=0; i<fAny2ManyInfo->inFileName.size(); i++) {
623 if (!FileExistsCheck(true, i)) {
624 std::cerr << std::endl << ">> PRunDataHandler::ReadWriteFilesList(): **ERROR** Couldn't find file " << fAny2ManyInfo->inFileName[i].Data() << std::endl;
625 return false;
626 }
627
628 // read input file
629 Bool_t success = false;
630 switch (inTag) {
631 case A2M_ROOT:
632 case A2M_MUSR_ROOT:
633 success = ReadRootFile();
634 break;
635 case A2M_PSIBIN:
636 case A2M_PSIMDU:
637 success = ReadPsiBinFile();
638 break;
639 case A2M_NEXUS:
640 success = ReadNexusFile();
641 break;
642 case A2M_MUD:
643 success = ReadMudFile();
644 break;
645 case A2M_WKM:
646 success = ReadWkmFile();
647 break;
648 default:
649 break;
650 }
651
652 if (!success) {
653 std::cerr << std::endl << ">> PRunDataHandler::ReadWriteFilesList(): **ERROR** Couldn't read file " << fAny2ManyInfo->inFileName[i].Data() << std::endl;
654 return false;
655 }
656
657 // write 'converted' output data file
658 success = false;
659 switch (outTag) {
660 case A2M_ROOT:
661 if (fAny2ManyInfo->outFileName.Length() == 0)
662 success = WriteRootFile();
663 else
664 success = WriteRootFile(fAny2ManyInfo->outFileName);
665 break;
666 case A2M_MUSR_ROOT:
668 if (fAny2ManyInfo->outFileName.Length() == 0)
669 success = WriteMusrRootFile(outTag);
670 else
671 success = WriteMusrRootFile(outTag, fAny2ManyInfo->outFileName);
672 break;
673 case A2M_PSIBIN:
674 if (fAny2ManyInfo->outFileName.Length() == 0)
675 success = WritePsiBinFile();
676 else
677 success = WritePsiBinFile(fAny2ManyInfo->outFileName);
678 break;
679 case A2M_PSIMDU:
680 if (fAny2ManyInfo->outFileName.Length() == 0)
681 success = WritePsiBinFile();
682 else
683 success = WritePsiBinFile(fAny2ManyInfo->outFileName);
684 break;
685 case A2M_NEXUS:
686 if (fAny2ManyInfo->outFileName.Length() == 0)
687 success = WriteNexusFile(fAny2ManyInfo->outFormat);
688 else
689 success = WriteNexusFile(fAny2ManyInfo->outFormat, fAny2ManyInfo->outFileName);
690 break;
691 case A2M_MUD:
692 if (fAny2ManyInfo->outFileName.Length() == 0)
693 success = WriteMudFile();
694 else
695 success = WriteMudFile(fAny2ManyInfo->outFileName);
696 break;
697 case A2M_WKM:
698 if (fAny2ManyInfo->outFileName.Length() == 0)
699 success = WriteWkmFile();
700 else
701 success = WriteWkmFile(fAny2ManyInfo->outFileName);
702 break;
703 case A2M_ASCII:
704 if (fAny2ManyInfo->outFileName.Length() == 0)
705 success = WriteAsciiFile();
706 else
707 success = WriteAsciiFile(fAny2ManyInfo->outFileName);
708 break;
709 default:
710 break;
711 }
712
713 if (success == false) {
714 std::cerr << std::endl << ">> PRunDataHandler::ReadWriteFilesList(): **ERROR** Couldn't write converted output file." << std::endl;
715 return false;
716 }
717
718 // throw away the current data set
719 fData.clear();
720 }
721 }
722
723 if (fAny2ManyInfo->runList.size() != 0) { // run list given
724
725 // loop over all runs of the run list
726 for (UInt_t i=0; i<fAny2ManyInfo->runList.size(); i++) {
727 if (!FileExistsCheck(false, i)) {
728 std::cerr << std::endl << ">> PRunDataHandler::ReadWriteFilesList(): **ERROR** Couldn't find run " << fAny2ManyInfo->runList[i] << std::endl;
729 return false;
730 }
731
732 // read input file
733 Bool_t success = false;
734 switch (inTag) {
735 case A2M_ROOT:
736 case A2M_MUSR_ROOT:
737 success = ReadRootFile();
738 break;
739 case A2M_PSIBIN:
740 case A2M_PSIMDU:
741 success = ReadPsiBinFile();
742 break;
743 case A2M_NEXUS:
744 success = ReadNexusFile();
745 break;
746 case A2M_MUD:
747 success = ReadMudFile();
748 break;
749 case A2M_WKM:
750 success = ReadWkmFile();
751 break;
752 default:
753 break;
754 }
755
756 if (!success) {
757 std::cerr << std::endl << ">> PRunDataHandler::ReadWriteFilesList(): **ERROR** Couldn't read file " << fRunPathName.Data() << std::endl;
758 return false;
759 }
760
761 TString year("");
762 TDatime dt;
763 year += dt.GetYear();
764 if (fAny2ManyInfo->year.Length() > 0)
765 year = fAny2ManyInfo->year;
766 Bool_t ok;
767 TString fln = FileNameFromTemplate(fAny2ManyInfo->outTemplate, fAny2ManyInfo->runList[i], year, ok);
768 if (!ok) {
769 std::cerr << std::endl << ">> PRunDataHandler::ReadWriteFilesList(): **ERROR** Couldn't create necessary output file name." << std::endl;
770 return false;
771 }
772
773 // write 'converted' output data file
774 success = false;
775 switch (outTag) {
776 case A2M_ROOT:
777 success = WriteRootFile(fln);
778 break;
779 case A2M_MUSR_ROOT:
781 success = WriteMusrRootFile(outTag, fln);
782 break;
783 case A2M_PSIBIN:
784 success = WritePsiBinFile(fln);
785 break;
786 case A2M_PSIMDU:
787 success = WritePsiBinFile(fln);
788 break;
789 case A2M_NEXUS:
790 success = WriteNexusFile(fAny2ManyInfo->outFormat, fln);
791 break;
792 case A2M_MUD:
793 success = WriteMudFile(fln);
794 break;
795 case A2M_WKM:
796 success = WriteWkmFile(fln);
797 break;
798 case A2M_ASCII:
799 success = WriteAsciiFile(fln);
800 break;
801 default:
802 break;
803 }
804
805 if (success == false) {
806 std::cerr << std::endl << ">> PRunDataHandler::ReadWriteFilesList(): **ERROR** Couldn't write converted output file." << std::endl;
807 return false;
808 }
809
810 // throw away the current data set
811 fData.clear();
812 }
813
814 }
815
816 // check if compression is wished
817 if (fAny2ManyInfo->compressionTag > 0) {
818 TString fln = fAny2ManyInfo->outPath + fAny2ManyInfo->compressFileName;
819
820 // currently system call is used, which means this is only running under Linux and Mac OS X but not under Windows
821 char cmd[256];
822 if (fAny2ManyInfo->outPathFileName.size() == 1) {
823 if (fAny2ManyInfo->compressionTag == 1) // gzip
824 fln += TString(".tar.gz");
825 else // bzip2
826 fln += TString(".tar.bz2");
827 if (fAny2ManyInfo->compressionTag == 1) // gzip
828 snprintf(cmd, sizeof(cmd), "tar -zcf %s %s", fln.Data(), fAny2ManyInfo->outPathFileName[0].Data());
829 else // bzip2
830 snprintf(cmd, sizeof(cmd), "tar -jcf %s %s", fln.Data(), fAny2ManyInfo->outPathFileName[0].Data());
831 if (system(cmd) == -1) {
832 std::cerr << "**ERROR** cmd: " << cmd << " failed." << std::endl;
833 }
834 } else {
835 fln += TString(".tar");
836 for (UInt_t i=0; i<fAny2ManyInfo->outPathFileName.size(); i++) {
837 if (i==0) {
838 snprintf(cmd, sizeof(cmd), "tar -cf %s %s", fln.Data(), fAny2ManyInfo->outPathFileName[i].Data());
839 } else {
840 snprintf(cmd, sizeof(cmd), "tar -rf %s %s", fln.Data(), fAny2ManyInfo->outPathFileName[i].Data());
841 }
842 if (system(cmd) == -1) {
843 std::cerr << "**ERROR** cmd: " << cmd << " failed." << std::endl;
844 }
845 }
846 if (fAny2ManyInfo->compressionTag == 1) { // gzip
847 snprintf(cmd, sizeof(cmd), "gzip %s", fln.Data());
848 fln += ".gz";
849 } else {
850 snprintf(cmd, sizeof(cmd), "bzip2 -z %s", fln.Data());
851 fln += ".bz2";
852 }
853 if (system(cmd) == -1) {
854 std::cerr << "**ERROR** cmd: " << cmd << " failed." << std::endl;
855 }
856 }
857
858 // check if the compressed file shall be streamed to the stdout
859 if (fAny2ManyInfo->useStandardOutput) {
860 // stream file to stdout
861 std::ifstream is;
862 int length=1024;
863 char *buffer;
864
865 is.open(fln.Data(), std::ios::binary);
866 if (!is.is_open()) {
867 std::cerr << std::endl << "PRunDataHandler::ReadWriteFilesList(): **ERROR** Couldn't open the file for streaming." << std::endl;
868 remove(fln.Data());
869 return false;
870 }
871
872 // get length of file
873 is.seekg(0, std::ios::end);
874 length = is.tellg();
875 is.seekg(0, std::ios::beg);
876
877 if (length == -1) {
878 std::cerr << std::endl << "PRunDataHandler::ReadWriteFilesList(): **ERROR** Couldn't determine the file size." << std::endl;
879 remove(fln.Data());
880 return false;
881 }
882
883 // allocate memory
884 buffer = new char [length];
885
886 // read data as a block
887 while (!is.eof()) {
888 is.read(buffer, length);
889 std::cout.write(buffer, length);
890 }
891
892 is.close();
893
894 delete [] buffer;
895
896 // delete temporary root file
897 remove(fln.Data());
898 }
899
900 // remove all the converted files
901 for (UInt_t i=0; i<fAny2ManyInfo->outPathFileName.size(); i++)
902 remove(fAny2ManyInfo->outPathFileName[i].Data());
903 }
904
905 return true;
906}
907
908//--------------------------------------------------------------------------
909// FileAlreadyRead (private)
910//--------------------------------------------------------------------------
921Bool_t PRunDataHandler::FileAlreadyRead(TString runName)
922{
923 for (UInt_t i=0; i<fData.size(); i++) {
924 if (!fData[i].GetRunName()->CompareTo(runName)) { // run alread read
925 return true;
926 }
927 }
928
929 return false;
930}
931
932//--------------------------------------------------------------------------
933// TestFileName (private)
934//--------------------------------------------------------------------------
942void PRunDataHandler::TestFileName(TString &runName, const TString &ext)
943{
944 TString tmpStr(runName), tmpExt(ext);
945
946 // check first if the file exists with the default extension which is not given with the run name
947 tmpStr += TString(".") + ext;
948 if (gSystem->AccessPathName(tmpStr.Data()) != true) { // found
949 runName = tmpStr;
950 return;
951 }
952
953 // test if the file exists with the given run name but an only upper-case extension which is not included in the file name
954 tmpStr = runName;
955 tmpExt.ToUpper();
956 tmpStr += TString(".") + tmpExt;
957 if (gSystem->AccessPathName(tmpStr.Data()) != true) { // found
958 runName = tmpStr;
959 return;
960 }
961
962 // test if the file exists with the given run name but an only lower-case extension which is not included in the file name
963 tmpStr = runName;
964 tmpExt.ToLower();
965 tmpStr += TString(".") + tmpExt;
966 if (gSystem->AccessPathName(tmpStr.Data()) != true) { // found
967 runName = tmpStr;
968 return;
969 }
970
971 // test if the file exists with only upper-case letters
972 tmpStr = runName + TString(".") + tmpExt;
973 tmpStr.ToUpper();
974 if (gSystem->AccessPathName(tmpStr.Data()) != true) { // found
975 runName = tmpStr;
976 return;
977 }
978
979 // test if the file exists with only lower-case letters
980 tmpStr.ToLower();
981 if (gSystem->AccessPathName(tmpStr.Data()) != true) { // found
982 runName = tmpStr;
983 return;
984 }
985
986 tmpStr = runName;
987
988 // the extension is already part of the file name, therefore, do not append it
989 if (tmpStr.EndsWith(ext.Data(), TString::kIgnoreCase)) {
990 if (gSystem->AccessPathName(tmpStr.Data()) != true) { // found
991 runName = tmpStr;
992 return;
993 }
994
995 // assume some extension is part of the given file name but the real data file ends with an lower-case extension
996 tmpExt.ToLower();
997 tmpStr = tmpStr.Replace(static_cast<Ssiz_t>(tmpStr.Length()-tmpExt.Length()), tmpExt.Length(), tmpExt);
998 if (gSystem->AccessPathName(tmpStr.Data()) != true) { // found
999 runName = tmpStr;
1000 return;
1001 }
1002
1003 // assume some extension is part of the given file name but the real data file ends with an upper-case extension
1004 tmpExt.ToUpper();
1005 tmpStr = runName;
1006 tmpStr = tmpStr.Replace(static_cast<Ssiz_t>(tmpStr.Length()-tmpExt.Length()), tmpExt.Length(), tmpExt);
1007 if (gSystem->AccessPathName(tmpStr.Data()) != true) { // found
1008 runName = tmpStr;
1009 return;
1010 }
1011
1012 // test if the file exists with only lower-case letters and the extension already included in the file name
1013 tmpStr = runName;
1014 tmpStr.ToLower();
1015 if (gSystem->AccessPathName(tmpStr.Data()) != true) { // found
1016 runName = tmpStr;
1017 return;
1018 }
1019
1020 // test if the file exists with only upper-case letters and the extension already included in the file name
1021 tmpStr = runName;
1022 tmpStr.ToUpper();
1023 if (gSystem->AccessPathName(tmpStr.Data()) != true) { // found
1024 runName = tmpStr;
1025 return;
1026 }
1027 }
1028
1029 // if the file has not been found, set the run name to be empty
1030 runName = "";
1031
1032 return;
1033}
1034
1035//--------------------------------------------------------------------------
1036// FileExistsCheck (private)
1037//--------------------------------------------------------------------------
1048Bool_t PRunDataHandler::FileExistsCheck(PMsrRunBlock &runInfo, const UInt_t idx)
1049{
1050 Bool_t success = true;
1051
1052 // local init
1053 TROOT root("PRunBase", "PRunBase", nullptr);
1054 TString pathName = "???";
1055 TString str, *pstr;
1056 TString ext;
1057
1058 pstr = runInfo.GetBeamline(idx);
1059 if (pstr == nullptr) {
1060 std::cerr << std::endl << ">> PRunDataHandler::FileExistsCheck: **ERROR** Couldn't obtain beamline data." << std::endl;
1061 assert(0);
1062 }
1063 pstr->ToLower();
1064 runInfo.SetBeamline(*pstr, idx);
1065 pstr = runInfo.GetInstitute(idx);
1066 if (pstr == nullptr) {
1067 std::cerr << std::endl << ">> PRunDataHandler::FileExistsCheck: **ERROR** Couldn't obtain institute data." << std::endl;
1068 assert(0);
1069 }
1070 pstr->ToLower();
1071 runInfo.SetInstitute(*pstr, idx);
1072 pstr = runInfo.GetFileFormat(idx);
1073 if (pstr == nullptr) {
1074 std::cerr << std::endl << ">> PRunDataHandler::FileExistsCheck: **ERROR** Couldn't obtain file format data." << std::endl;
1075 assert(0);
1076 }
1077 pstr->ToLower();
1078 runInfo.SetFileFormat(*pstr, idx);
1079
1080 // file extensions for the various formats
1081 if (!runInfo.GetFileFormat(idx)->CompareTo("root-npp")) // not post pile up corrected histos
1082 ext = TString("root");
1083 else if (!runInfo.GetFileFormat(idx)->CompareTo("root-ppc")) // post pile up corrected histos
1084 ext = TString("root");
1085 else if (!runInfo.GetFileFormat(idx)->CompareTo("musr-root")) // post pile up corrected histos
1086 ext = TString("root");
1087 else if (!runInfo.GetFileFormat(idx)->CompareTo("nexus"))
1088 ext = TString("NXS");
1089 else if (!runInfo.GetFileFormat(idx)->CompareTo("psi-bin"))
1090 ext = TString("bin");
1091 else if (!runInfo.GetFileFormat(idx)->CompareTo("psi-mdu"))
1092 ext = TString("mdu");
1093 else if (!runInfo.GetFileFormat(idx)->CompareTo("mud"))
1094 ext = TString("msr");
1095 else if (!runInfo.GetFileFormat(idx)->CompareTo("wkm")) {
1096 if (!runInfo.GetBeamline(idx)->CompareTo("mue4"))
1097 ext = TString("nemu");
1098 else
1099 ext = *runInfo.GetBeamline(idx);
1100 }
1101 else if (!runInfo.GetFileFormat(idx)->CompareTo("mdu-ascii"))
1102 ext = TString("mdua");
1103 else if (!runInfo.GetFileFormat(idx)->CompareTo("ascii"))
1104 ext = TString("dat");
1105 else if (!runInfo.GetFileFormat(idx)->CompareTo("db"))
1106 ext = TString("db");
1107 else if (!runInfo.GetFileFormat(idx)->CompareTo("dat"))
1108 ext = TString("dat");
1109 else
1110 success = false;
1111
1112 // unkown file format found
1113 if (!success) {
1114 pstr = runInfo.GetFileFormat(idx);
1115 if (pstr == nullptr) {
1116 std::cerr << std::endl << ">> PRunDataHandler::FileExistsCheck: **ERROR** Couldn't obtain file format data." << std::endl;
1117 assert(0);
1118 }
1119 pstr->ToUpper();
1120 std::cerr << std::endl << ">> PRunDataHandler::FileExistsCheck: **ERROR** File Format '" << pstr->Data() << "' unsupported.";
1121 std::cerr << std::endl << ">> support file formats are:";
1122 std::cerr << std::endl << ">> ROOT-NPP -> root not post pileup corrected for lem";
1123 std::cerr << std::endl << ">> ROOT-PPC -> root post pileup corrected for lem";
1124 std::cerr << std::endl << ">> MUSR-ROOT -> MusrRoot file format";
1125 std::cerr << std::endl << ">> NEXUS -> nexus file format, HDF4, HDF5, or XML";
1126 std::cerr << std::endl << ">> PSI-BIN -> psi bin file format";
1127 std::cerr << std::endl << ">> PSI-MDU -> psi mdu file format (see also MDU-ASCII)";
1128 std::cerr << std::endl << ">> MUD -> triumf mud file format";
1129 std::cerr << std::endl << ">> WKM -> wkm ascii file format";
1130 std::cerr << std::endl << ">> MDU-ASCII -> psi mdu ascii file format";
1131 std::cerr << std::endl << ">> ASCII -> column like file format";
1132 std::cerr << std::endl << ">> DB -> triumf db file \"format\"";
1133 std::cerr << std::endl << ">> DAT -> csv like file \"format\" as exported by msr2data.";
1134 std::cerr << std::endl;
1135 return success;
1136 }
1137
1138 // check if the file is in the local directory
1139 str = *runInfo.GetRunName(idx);
1140 TestFileName(str, ext);
1141 if (!str.IsNull()) {
1142 pathName = str;
1143 }
1144
1145 // check if the file is found in the <msr-file-directory>
1146 if (pathName.CompareTo("???") == 0) { // not found in local directory search
1147 str = *fMsrInfo->GetMsrFileDirectoryPath() + *runInfo.GetRunName(idx);
1148 TestFileName(str, ext);
1149 if (!str.IsNull()) {
1150 pathName = str;
1151 }
1152 }
1153
1154 // check if the file is found in the directory given in the startup file
1155 if (pathName.CompareTo("???") == 0) { // not found in local directory search and not found in the <msr-file-directory> search
1156 for (UInt_t i=0; i<fDataPath.size(); i++) {
1157 str = fDataPath[i] + TString("/") + *runInfo.GetRunName(idx);
1158 TestFileName(str, ext);
1159 if (!str.IsNull()) {
1160 pathName = str;
1161 break;
1162 }
1163 }
1164 }
1165
1166 // check if the file is found in the directories given by MUSRFULLDATAPATH
1167 const Char_t *musrpath = gSystem->Getenv("MUSRFULLDATAPATH");
1168 if (pathName.CompareTo("???") == 0) { // not found in local directory and xml path
1169 str = TString(musrpath);
1170 // MUSRFULLDATAPATH has the structure: path_1:path_2:...:path_n
1171 TObjArray *tokens = str.Tokenize(":");
1172 TObjString *ostr;
1173 for (Int_t i=0; i<tokens->GetEntries(); i++) {
1174 ostr = dynamic_cast<TObjString*>(tokens->At(i));
1175 str = ostr->GetString() + TString("/") + *runInfo.GetRunName(idx);
1176 TestFileName(str, ext);
1177 if (!str.IsNull()) {
1178 pathName = str;
1179 break;
1180 }
1181 }
1182 // cleanup
1183 if (tokens) {
1184 delete tokens;
1185 tokens = nullptr;
1186 }
1187 }
1188
1189 // check if the file is found in the generated default path
1190 if (pathName.CompareTo("???") == 0) { // not found in MUSRFULLDATAPATH search
1191 str = TString(musrpath);
1192 // MUSRFULLDATAPATH has the structure: path_1:path_2:...:path_n
1193 TObjArray *tokens = str.Tokenize(":");
1194 TObjString *ostr;
1195 pstr = runInfo.GetInstitute(idx);
1196 if (pstr == nullptr) {
1197 std::cerr << std::endl << ">> PRunDataHandler::FileExistsCheck: **ERROR** Couldn't obtain institute data." << std::endl;
1198 assert(0);
1199 }
1200 pstr->ToUpper();
1201 runInfo.SetInstitute(*pstr, idx);
1202 pstr = runInfo.GetBeamline(idx);
1203 if (pstr == nullptr) {
1204 std::cerr << std::endl << ">> PRunDataHandler::FileExistsCheck: **ERROR** Couldn't obtain beamline data." << std::endl;
1205 assert(0);
1206 }
1207 pstr->ToUpper();
1208 runInfo.SetBeamline(*pstr, idx);
1209 for (Int_t i=0; i<tokens->GetEntries(); i++) {
1210 ostr = dynamic_cast<TObjString*>(tokens->At(i));
1211 str = ostr->GetString() + TString("/DATA/") +
1212 *runInfo.GetInstitute(idx) + TString("/") +
1213 *runInfo.GetBeamline(idx) + TString("/") +
1214 *runInfo.GetRunName(idx);
1215 TestFileName(str, ext);
1216 if (!str.IsNull()) { // found
1217 pathName = str;
1218 break;
1219 }
1220 }
1221 // clean up
1222 if (tokens) {
1223 delete tokens;
1224 tokens = nullptr;
1225 }
1226 }
1227
1228 // no proper path name found
1229 if (pathName.CompareTo("???") == 0) {
1230 std::cerr << std::endl << ">> PRunDataHandler::FileExistsCheck(): **ERROR** Couldn't find '" << runInfo.GetRunName(idx)->Data() << "' in any standard path.";
1231 std::cerr << std::endl << ">> standard search pathes are:";
1232 std::cerr << std::endl << ">> 1. the local directory";
1233 std::cerr << std::endl << ">> 2. the data directory given in the startup XML file";
1234 std::cerr << std::endl << ">> 3. the directories listed in MUSRFULLDATAPATH";
1235 std::cerr << std::endl << ">> 4. default path construct which is described in the manual";
1236 return false;
1237 }
1238
1239 fRunPathName = pathName;
1240
1241 return true;
1242}
1243
1244//--------------------------------------------------------------------------
1245// FileExistsCheck (private)
1246//--------------------------------------------------------------------------
1257Bool_t PRunDataHandler::FileExistsCheck(const Bool_t fileName, const Int_t idx)
1258{
1259 TString pathName("???");
1260 TString str("");
1261 TString fln("");
1262
1263 if (fileName) { // single input file name
1264 if (idx >= static_cast<Int_t>(fAny2ManyInfo->inFileName.size())) {
1265 std::cerr << std::endl << ">> PRunDataHandler::FileExistsCheck(): **ERROR** idx=" << idx << " out of range. (inFileName.size()==" << fAny2ManyInfo->inFileName.size() << ")" << std::endl;
1266 return false;
1267 }
1268 fln = fAny2ManyInfo->inFileName[idx];
1269 } else { // run file list entry shall be handled
1270 if (idx >= static_cast<Int_t>(fAny2ManyInfo->runList.size())) {
1271 std::cerr << std::endl << ">> PRunDataHandler::FileExistsCheck(): **ERROR** idx=" << idx << " out of range. (inFileName.size()==" << fAny2ManyInfo->runList.size() << ")" << std::endl;
1272 return false;
1273 }
1274 // check for input/output templates
1275 if ((fAny2ManyInfo->inTemplate.Length() == 0) || (fAny2ManyInfo->outTemplate.Length() == 0)) {
1276 std::cerr << std::endl << ">> PRunDataHandler::FileExistsCheck(): **ERROR** when using run lists, input/output templates are needed as well." << std::endl;
1277 return false;
1278 }
1279 // make the input file name according to the input template
1280 TString year("");
1281 TDatime dt;
1282 year += dt.GetYear();
1283 if (fAny2ManyInfo->year.Length() > 0)
1284 year = fAny2ManyInfo->year;
1285 Bool_t ok;
1286 fln = FileNameFromTemplate(fAny2ManyInfo->inTemplate, fAny2ManyInfo->runList[idx], year, ok);
1287 if (!ok)
1288 return false;
1289 }
1290
1291 // check if the file is in the local directory
1292 if (gSystem->AccessPathName(fln) != true) { // found in the local dir
1293 pathName = fln;
1294 }
1295 // check if the file is found in the directory given in the startup file
1296 if (pathName.CompareTo("???") == 0) { // not found in local directory search
1297 for (UInt_t i=0; i<fDataPath.size(); i++) {
1298 str = fDataPath[i] + TString("/") + fln;
1299 if (gSystem->AccessPathName(str.Data())!=true) { // found
1300 pathName = str;
1301 break;
1302 }
1303 }
1304 }
1305 // check if the file is found in the directories given by MUSRFULLDATAPATH
1306 const Char_t *musrpath = gSystem->Getenv("MUSRFULLDATAPATH");
1307 if (pathName.CompareTo("???") == 0) { // not found in local directory and xml path
1308 str = TString(musrpath);
1309 // MUSRFULLDATAPATH has the structure: path_1:path_2:...:path_n
1310 TObjArray *tokens = str.Tokenize(":");
1311 TObjString *ostr;
1312 for (Int_t i=0; i<tokens->GetEntries(); i++) {
1313 ostr = dynamic_cast<TObjString*>(tokens->At(i));
1314 str = ostr->GetString() + TString("/") + fln;
1315 if (gSystem->AccessPathName(str.Data())!=true) { // found
1316 pathName = str;
1317 break;
1318 }
1319 }
1320 // cleanup
1321 if (tokens) {
1322 delete tokens;
1323 tokens = nullptr;
1324 }
1325 }
1326 // no proper path name found
1327 if (pathName.CompareTo("???") == 0) {
1328 std::cerr << std::endl << ">> PRunDataHandler::FileExistsCheck(): **ERROR** Couldn't find '" << fln.Data() << "' in any standard path.";
1329 std::cerr << std::endl << ">> standard search pathes are:";
1330 std::cerr << std::endl << ">> 1. the local directory";
1331 std::cerr << std::endl << ">> 2. the data directory given in the startup XML file";
1332 std::cerr << std::endl << ">> 3. the directories listed in MUSRFULLDATAPATH";
1333 return false;
1334 }
1335
1336 fRunPathName = pathName;
1337
1338 return true;
1339}
1340
1341//--------------------------------------------------------------------------
1342// FileExistsCheck (private)
1343//--------------------------------------------------------------------------
1353Bool_t PRunDataHandler::FileExistsCheck(const TString fileName)
1354{
1355 TString pathName("???");
1356 TString str("");
1357
1358 // check if the file is in the local directory
1359 if (gSystem->AccessPathName(fileName) != true) { // found in the local dir
1360 pathName = fileName;
1361 }
1362 // check if the file is found in the directory given in the startup file
1363 if (pathName.CompareTo("???") == 0) { // not found in local directory search
1364 for (UInt_t i=0; i<fDataPath.size(); i++) {
1365 str = fDataPath[i] + TString("/") + fileName;
1366 if (gSystem->AccessPathName(str.Data())!=true) { // found
1367 pathName = str;
1368 break;
1369 }
1370 }
1371 }
1372 // check if the file is found in the directories given by MUSRFULLDATAPATH
1373 const Char_t *musrpath = gSystem->Getenv("MUSRFULLDATAPATH");
1374 if (pathName.CompareTo("???") == 0) { // not found in local directory and xml path
1375 str = TString(musrpath);
1376 // MUSRFULLDATAPATH has the structure: path_1:path_2:...:path_n
1377 TObjArray *tokens = str.Tokenize(":");
1378 TObjString *ostr;
1379 for (Int_t i=0; i<tokens->GetEntries(); i++) {
1380 ostr = dynamic_cast<TObjString*>(tokens->At(i));
1381 str = ostr->GetString() + TString("/") + fileName;
1382 if (gSystem->AccessPathName(str.Data())!=true) { // found
1383 pathName = str;
1384 break;
1385 }
1386 }
1387 // cleanup
1388 if (tokens) {
1389 delete tokens;
1390 tokens = nullptr;
1391 }
1392 }
1393 // no proper path name found
1394 if (pathName.CompareTo("???") == 0) {
1395 std::cerr << std::endl << ">> PRunDataHandler::FileExistsCheck(): **ERROR** Couldn't find '" << fileName.Data() << "' in any standard path.";
1396 std::cerr << std::endl << ">> standard search pathes are:";
1397 std::cerr << std::endl << ">> 1. the local directory";
1398 std::cerr << std::endl << ">> 2. the data directory given in the startup XML file";
1399 std::cerr << std::endl << ">> 3. the directories listed in MUSRFULLDATAPATH";
1400 return false;
1401 }
1402
1403 fRunPathName = pathName;
1404
1405 return true;
1406}
1407
1408//--------------------------------------------------------------------------
1409// ReadRootFile (private)
1410//--------------------------------------------------------------------------
1420{
1421 PDoubleVector histoData;
1422 PRawRunData runData;
1423 PRawRunDataSet dataSet;
1424
1425 TFile f(fRunPathName.Data());
1426 if (f.IsZombie()) {
1427 return false;
1428 }
1429
1430 UInt_t fileType = PRH_MUSR_ROOT;
1431
1432 TFolder *folder;
1433 f.GetObject("RunInfo", folder); // try first LEM-ROOT style file (used until 2011).
1434 if (!folder) { // either something is wrong, or it is a MusrRoot file
1435 TObject *obj = f.FindObjectAny("RunHeader");
1436 if (obj == nullptr) { // something is wrong!!
1437 std::cerr << std::endl << ">> PRunDataHandler::ReadRootFile: **ERROR** Couldn't neither obtain RunInfo (LEM),";
1438 std::cerr << std::endl << " nor RunHeader (MusrRoot) from " << fRunPathName.Data() << std::endl;
1439 f.Close();
1440 return false;
1441 }
1442 if (!strcmp(obj->ClassName(), "TFolder"))
1443 fileType = PRH_MUSR_ROOT;
1444 else if (!strcmp(obj->ClassName(), "TDirectoryFile"))
1445 fileType = PRH_MUSR_ROOT_DIR;
1446 else {
1447 std::cerr << std::endl << "PRunDataHandler::ReadRootFile: **ERROR** RunHeader (MusrRoot) from '" << fRunPathName.Data() << "' is neither a TFolder nor a TDirectory. Found: '" << obj->ClassName() << "'" << std::endl;
1448 f.Close();
1449 return false;
1450 }
1451 } else {
1452 fileType = PRH_LEM_ROOT;
1453 }
1454
1455 if (fileType == PRH_LEM_ROOT) {
1456 // read header and check if some missing run info need to be fed
1457 TLemRunHeader *runHeader = dynamic_cast<TLemRunHeader*>(folder->FindObjectAny("TLemRunHeader"));
1458
1459 // check if run header is valid
1460 if (!runHeader) {
1461 std::cerr << std::endl << ">> PRunDataHandler::ReadRootFile: **ERROR** Couldn't obtain run header info from ROOT file " << fRunPathName.Data() << std::endl;
1462 f.Close();
1463 return false;
1464 }
1465
1466 // set laboratory / beamline / instrument
1467 runData.SetLaboratory("PSI");
1468 runData.SetBeamline("muE4");
1469 runData.SetInstrument("LEM");
1470 runData.SetMuonSource("low energy muon source");
1471 runData.SetMuonSpecies("positive muons");
1472
1473 // get run title
1474 TObjString ostr = runHeader->GetRunTitle();
1475 runData.SetRunTitle(ostr.GetString());
1476
1477 // get run number
1478 runData.SetRunNumber(static_cast<Int_t>(runHeader->GetRunNumber()));
1479
1480 // get temperature
1481 runData.ClearTemperature();
1482 runData.SetTemperature(0, runHeader->GetSampleTemperature(), runHeader->GetSampleTemperatureError());
1483
1484 // get field
1485 runData.SetField(runHeader->GetSampleBField());
1486
1487 // get implantation energy
1488 runData.SetEnergy(runHeader->GetImpEnergy());
1489
1490 // get moderator HV
1491 runData.SetTransport(runHeader->GetModeratorHV());
1492
1493 // get setup
1494 runData.SetSetup(runHeader->GetLemSetup().GetString());
1495
1496 // get start time/date
1497 // start date
1498 time_t idt = static_cast<time_t>(runHeader->GetStartTime());
1499 runData.SetStartDateTime(idt);
1500 struct tm *dt = localtime(&idt);
1501 char str[128];
1502 strftime(str, sizeof(str), "%F", dt);
1503 TString stime(str);
1504 runData.SetStartDate(stime);
1505 // start time
1506 memset(str, 0, sizeof(str));
1507 strftime(str, sizeof(str), "%T", dt);
1508 stime = str;
1509 runData.SetStartTime(stime);
1510
1511 // get stop time/date
1512 // stop date
1513 idt = static_cast<time_t>(runHeader->GetStopTime());
1514 runData.SetStopDateTime(idt);
1515 dt = localtime(&idt);
1516 memset(str, 0, sizeof(str));
1517 strftime(str, sizeof(str), "%F", dt);
1518 stime = str;
1519 runData.SetStopDate(stime);
1520 // stop time
1521 memset(str, 0, sizeof(str));
1522 strftime(str, sizeof(str), "%T", dt);
1523 stime = str;
1524 runData.SetStopTime(stime);
1525
1526 // get time resolution
1527 runData.SetTimeResolution(runHeader->GetTimeResolution());
1528
1529 // get number of histogramms
1530 Int_t noOfHistos = runHeader->GetNHist();
1531
1532 // get t0's there will be handled together with the data
1533 Double_t *t0 = runHeader->GetTimeZero();
1534
1535 // read run summary to obtain ring anode HV values
1536 TObjArray *runSummary = dynamic_cast<TObjArray*>(folder->FindObjectAny("RunSummary"));
1537
1538 // check if run summary is valid
1539 if (!runSummary) {
1540 std::cout << std::endl << "**INFO** Couldn't obtain run summary info from ROOT file " << fRunPathName.Data() << std::endl;
1541 // this is not fatal... only RA-HV values are not available
1542 } else { // it follows a (at least) little bit strange extraction of the RA values from Thomas' TObjArray...
1543 //streaming of a ASCII-file would be more easy
1544 TString s;
1545 TObjArrayIter summIter(runSummary);
1546 TObjString *os(dynamic_cast<TObjString*>(summIter.Next()));
1547 TObjArray *oa(nullptr);
1548 TObjString *objTok(nullptr);
1549 while (os != nullptr) {
1550 s = os->GetString();
1551 // will put four parallel if's since it may be that more than one RA-values are on one line
1552 if (s.Contains("RA-L")) {
1553 oa = s.Tokenize(" ");
1554 TObjArrayIter lineIter(oa);
1555 objTok = dynamic_cast<TObjString*>(lineIter.Next());
1556 while (objTok != nullptr) {
1557 if (!objTok->GetString().CompareTo("RA-L")) {
1558 objTok = dynamic_cast<TObjString*>(lineIter.Next()); // "="
1559 if ((objTok != nullptr) && !objTok->GetString().CompareTo("=")) {
1560 objTok = dynamic_cast<TObjString*>(lineIter.Next()); // HV value
1561 runData.SetRingAnode(0, objTok->GetString().Atof()); // fill RA-R value into the runData structure
1562 break;
1563 }
1564 }
1565 objTok = dynamic_cast<TObjString*>(lineIter.Next()); // next token...
1566 }
1567 // clean up
1568 if (oa) {
1569 delete oa;
1570 oa = nullptr;
1571 }
1572 }
1573
1574 if (s.Contains("RA-R")) {
1575 oa = s.Tokenize(" ");
1576 TObjArrayIter lineIter(oa);
1577 objTok = dynamic_cast<TObjString*>(lineIter.Next());
1578 while (objTok != nullptr){
1579 if (!objTok->GetString().CompareTo("RA-R")) {
1580 objTok = dynamic_cast<TObjString*>(lineIter.Next()); // "="
1581 if (objTok != nullptr && !objTok->GetString().CompareTo("=")) {
1582 objTok = dynamic_cast<TObjString*>(lineIter.Next()); // HV value
1583 runData.SetRingAnode(1, objTok->GetString().Atof()); // fill RA-R value into the runData structure
1584 break;
1585 }
1586 }
1587 objTok = dynamic_cast<TObjString*>(lineIter.Next()); // next token...
1588 }
1589 // clean up
1590 if (oa) {
1591 delete oa;
1592 oa = nullptr;
1593 }
1594 }
1595
1596 if (s.Contains("RA-T")) {
1597 oa = s.Tokenize(" ");
1598 TObjArrayIter lineIter(oa);
1599 objTok = dynamic_cast<TObjString*>(lineIter.Next());
1600 while (objTok != nullptr){
1601 if (!objTok->GetString().CompareTo("RA-T")) {
1602 objTok = dynamic_cast<TObjString*>(lineIter.Next()); // "="
1603 if ((objTok != nullptr) && !objTok->GetString().CompareTo("=")) {
1604 objTok = dynamic_cast<TObjString*>(lineIter.Next()); // HV value
1605 runData.SetRingAnode(2, objTok->GetString().Atof()); // fill RA-T value into the runData structure
1606 break;
1607 }
1608 }
1609 objTok = dynamic_cast<TObjString*>(lineIter.Next()); // next token...
1610 }
1611 // clean up
1612 if (oa) {
1613 delete oa;
1614 oa = nullptr;
1615 }
1616 }
1617
1618 if (s.Contains("RA-B")) {
1619 oa = s.Tokenize(" ");
1620 TObjArrayIter lineIter(oa);
1621 objTok = dynamic_cast<TObjString*>(lineIter.Next());
1622 while (objTok != nullptr){
1623 if (!objTok->GetString().CompareTo("RA-B")) {
1624 objTok = dynamic_cast<TObjString*>(lineIter.Next()); // "="
1625 if ((objTok != nullptr) && !objTok->GetString().CompareTo("=")) {
1626 objTok = dynamic_cast<TObjString*>(lineIter.Next()); // HV value
1627 runData.SetRingAnode(3, objTok->GetString().Atof()); // fill RA-B value into the runData structure
1628 break;
1629 }
1630 }
1631 objTok = dynamic_cast<TObjString*>(lineIter.Next()); // next token...
1632 }
1633 // clean up
1634 if (oa) {
1635 delete oa;
1636 oa = nullptr;
1637 }
1638 }
1639
1640 os = dynamic_cast<TObjString*>(summIter.Next()); // next summary line...
1641 }
1642 }
1643
1644 // read data ---------------------------------------------------------
1645
1646 // check if histos folder is found
1647 f.GetObject("histos", folder);
1648 if (!folder) {
1649 std::cerr << std::endl << ">> PRunDataHandler::ReadRootFile: **ERROR** Couldn't obtain histos from " << fRunPathName.Data() << std::endl;
1650 f.Close();
1651 return false;
1652 }
1653
1654 // get all the data
1655 Char_t histoName[32];
1656 for (Int_t i=0; i<noOfHistos; i++) {
1657 snprintf(histoName, sizeof(histoName), "hDecay%02d", i);
1658 TH1F *histo = dynamic_cast<TH1F*>(folder->FindObjectAny(histoName));
1659 if (!histo) {
1660 std::cerr << std::endl << ">> PRunDataHandler::ReadRootFile: **ERROR** Couldn't get histo " << histoName;
1661 std::cerr << std::endl;
1662 f.Close();
1663 return false;
1664 }
1665
1666 // fill data
1667 for (Int_t j=1; j<=histo->GetNbinsX(); j++) {
1668 histoData.push_back(histo->GetBinContent(j));
1669 }
1670
1671 // fill the data set
1672 dataSet.Clear();
1673 dataSet.SetName(histo->GetTitle());
1674 dataSet.SetHistoNo(i+1);
1675 dataSet.SetTimeZeroBin(t0[i]);
1676 dataSet.SetTimeZeroBinEstimated(histo->GetMaximumBin());
1677 dataSet.SetFirstGoodBin(static_cast<Int_t>(t0[i]));
1678 dataSet.SetLastGoodBin(histo->GetNbinsX()-1);
1679 dataSet.SetData(histoData);
1680 runData.SetDataSet(dataSet);
1681
1682 // clear histoData for the next histo
1683 histoData.clear();
1684 }
1685 // check if any post pileup histos are present at all (this is not the case for LEM data 2006 and earlier)
1686 snprintf(histoName, sizeof(histoName), "hDecay%02d", POST_PILEUP_HISTO_OFFSET);
1687 if (!folder->FindObjectAny(histoName)) {
1688 std::cerr << std::endl << ">> PRunDataHandler::ReadRootFile: **WARNING** Couldn't get histo " << histoName;
1689 std::cerr << std::endl << ">> most probably this is an old (2006 or earlier) LEM file without post pileup histos.";
1690 std::cerr << std::endl;
1691 } else {
1692 for (Int_t i=0; i<noOfHistos; i++) {
1693 snprintf(histoName, sizeof(histoName), "hDecay%02d", i+POST_PILEUP_HISTO_OFFSET);
1694 TH1F *histo = dynamic_cast<TH1F*>(folder->FindObjectAny(histoName));
1695 if (!histo) {
1696 std::cerr << std::endl << ">> PRunDataHandler::ReadRootFile: **ERROR** Couldn't get histo " << histoName;
1697 std::cerr << std::endl;
1698 f.Close();
1699 return false;
1700 }
1701
1702 // fill data
1703 for (Int_t j=1; j<=histo->GetNbinsX(); j++)
1704 histoData.push_back(histo->GetBinContent(j));
1705
1706 // fill the data set
1707 dataSet.Clear();
1708 dataSet.SetName(histo->GetTitle());
1710 dataSet.SetTimeZeroBin(t0[i]);
1711 dataSet.SetTimeZeroBinEstimated(histo->GetMaximumBin());
1712 dataSet.SetFirstGoodBin(static_cast<Int_t>(t0[i]));
1713 dataSet.SetLastGoodBin(histo->GetNbinsX()-1);
1714 dataSet.SetData(histoData);
1715 runData.SetDataSet(dataSet);
1716
1717 // clear histoData for the next histo
1718 histoData.clear();
1719 }
1720 }
1721 } else { // MusrRoot file
1722 // invoke the MusrRoot header object
1723 std::unique_ptr<TMusrRunHeader> header = std::make_unique<TMusrRunHeader>(true); // read quiet
1724 if (header == nullptr) {
1725 std::cerr << std::endl << ">> PRunDataHandler::ReadRootFile: **ERROR** Couldn't invoke MusrRoot RunHeader in file:" << fRunPathName;
1726 std::cerr << std::endl;
1727 f.Close();
1728 return false;
1729 }
1730
1731 // check if TFolder or TDirectory is needed
1732 if (fileType == PRH_MUSR_ROOT) { // TFolder
1733 f.GetObject("RunHeader", folder);
1734
1735 // try to populate the MusrRoot header object
1736 if (!header->ExtractAll(folder)) {
1737 std::cerr << std::endl << ">> PRunDataHandler::ReadRootFile: **ERROR** Couldn't invoke MusrRoot RunHeader (TFolder) in file:" << fRunPathName;
1738 std::cerr << std::endl;
1739 f.Close();
1740 return false;
1741 }
1742 } else { // TDirectory
1743 TDirectoryFile *runHeader = nullptr;
1744 f.GetObject("RunHeader", runHeader);
1745
1746 // try to populate the MusrRoot header object
1747 if (!header->ExtractAll(runHeader)) {
1748 std::cerr << std::endl << ">> PRunDataHandler::ReadRootFile: **ERROR** Couldn't invoke MusrRoot RunHeader (TDirectoryFile) in file:" << fRunPathName;
1749 std::cerr << std::endl;
1750 f.Close();
1751 return false;
1752 }
1753 }
1754
1755 // get all the header information
1756 Bool_t ok;
1757 TString str, path, pathName;
1758 Int_t ival, noOfHistos=0;
1759 Double_t dval;
1761 PIntVector ivec, redGreenOffsets;
1762
1763 header->Get("RunInfo/Version", str, ok);
1764 if (ok)
1765 runData.SetVersion(str);
1766
1767 header->Get("RunInfo/Generic Validator URL", str, ok);
1768 if (ok)
1769 runData.SetGenericValidatorUrl(str);
1770
1771 header->Get("RunInfo/Specific Validator URL", str, ok);
1772 if (ok)
1773 runData.SetSpecificValidatorUrl(str);
1774
1775 header->Get("RunInfo/Generator", str, ok);
1776 if (ok)
1777 runData.SetGenerator(str);
1778
1779 header->Get("RunInfo/File Name", str, ok);
1780 if (ok)
1781 runData.SetFileName(str);
1782
1783 header->Get("RunInfo/Run Title", str, ok);
1784 if (ok)
1785 runData.SetRunTitle(str);
1786
1787 header->Get("RunInfo/Run Number", ival, ok);
1788 if (ok)
1789 runData.SetRunNumber(ival);
1790
1791 header->Get("RunInfo/Run Start Time", str, ok);
1792 if (ok) {
1793 Ssiz_t pos = str.Index(' ');
1794 TString substr = str;
1795 substr.Remove(pos, str.Length());
1796 runData.SetStartDate(substr);
1797 substr = str;
1798 substr.Remove(0, pos+1);
1799 runData.SetStartTime(substr);
1800 }
1801
1802 header->Get("RunInfo/Run Stop Time", str, ok);
1803 if (ok) {
1804 Ssiz_t pos = str.Index(' ');
1805 TString substr = str;
1806 substr.Remove(pos, str.Length());
1807 runData.SetStopDate(substr);
1808 substr = str;
1809 substr.Remove(0, pos+1);
1810 runData.SetStopTime(substr);
1811 }
1812
1813 header->Get("RunInfo/Laboratory", str, ok);
1814 if (ok)
1815 runData.SetLaboratory(str);
1816
1817 header->Get("RunInfo/Instrument", str, ok);
1818 if (ok)
1819 runData.SetInstrument(str);
1820
1821 header->Get("RunInfo/Muon Beam Momentum", prop, ok);
1822 if (ok) {
1823 if (!prop.GetUnit().CompareTo("MeV/c"))
1824 runData.SetMuonBeamMomentum(prop.GetValue());
1825 }
1826
1827 header->Get("RunInfo/Muon Species", str, ok);
1828 if (ok)
1829 runData.SetMuonSpecies(str);
1830
1831 header->Get("RunInfo/Muon Source", str, ok);
1832 if (ok)
1833 runData.SetMuonSource(str);
1834
1835 header->Get("RunInfo/Muon Spin Angle", prop, ok);
1836 if (ok) {
1837 runData.SetMuonSpinAngle(prop.GetValue());
1838 }
1839
1840 header->Get("RunInfo/Setup", str, ok);
1841 if (ok)
1842 runData.SetSetup(str);
1843
1844 header->Get("RunInfo/Comment", str, ok);
1845 if (ok)
1846 runData.SetComment(str);
1847
1848 header->Get("RunInfo/Sample Name", str, ok);
1849 if (ok)
1850 runData.SetSample(str);
1851
1852 header->Get("RunInfo/Sample Temperature", prop, ok);
1853 if (ok)
1854 runData.SetTemperature(0, prop.GetValue(), prop.GetError());
1855
1856 header->Get("RunInfo/Sample Magnetic Field", prop, ok);
1857 if (ok) {
1858 dval = MRH_UNDEFINED;
1859 if (!prop.GetUnit().CompareTo("G") || !prop.GetUnit().CompareTo("Gauss"))
1860 dval = prop.GetValue();
1861 else if (!prop.GetUnit().CompareTo("T") || !prop.GetUnit().CompareTo("Tesla"))
1862 dval = prop.GetValue() * 1.0e4;
1863 runData.SetField(dval);
1864 }
1865
1866 header->Get("RunInfo/No of Histos", ival, ok);
1867 if (ok) {
1868 noOfHistos = ival;
1869 }
1870
1871 header->Get("RunInfo/Time Resolution", prop, ok);
1872 if (ok) {
1873 dval = -1.0;
1874 if (!prop.GetUnit().CompareTo("ps") || !prop.GetUnit().CompareTo("picosec"))
1875 dval = prop.GetValue()/1.0e3;
1876 else if (!prop.GetUnit().CompareTo("ns") || !prop.GetUnit().CompareTo("nanosec"))
1877 dval = prop.GetValue();
1878 else if (!prop.GetUnit().CompareTo("us") || !prop.GetUnit().CompareTo("microsec"))
1879 dval = prop.GetValue()*1.0e3;
1880 else
1881 std::cerr << std::endl << ">> PRunDataHandler::ReadRootFile: **ERROR** Found unrecognized Time Resolution unit: " << prop.GetUnit() << std::endl;
1882 runData.SetTimeResolution(dval);
1883 }
1884
1885 header->Get("RunInfo/RedGreen Offsets", ivec, ok);
1886 if (ok) {
1887 // check if any2many is used and a group histo list is defined, if NOT, only take the 0-offset data!
1888 if (fAny2ManyInfo) { // i.e. any2many is called
1889 if (fAny2ManyInfo->groupHistoList.size() == 0) { // NO group list defined -> use only the 0-offset data
1890 redGreenOffsets.push_back(0);
1891 } else { // group list defined
1892 // make sure that the group list elements is a subset of present RedGreen offsets
1893 Bool_t found = false;
1894 for (UInt_t i=0; i<fAny2ManyInfo->groupHistoList.size(); i++) {
1895 found = false;
1896 for (UInt_t j=0; j<ivec.size(); j++) {
1897 if (fAny2ManyInfo->groupHistoList[i] == ivec[j])
1898 found = true;
1899 }
1900 if (!found) {
1901 std::cerr << std::endl << ">> PRunDataHandler::ReadRootFile: **ERROR** requested histo group " << fAny2ManyInfo->groupHistoList[i];
1902 std::cerr << std::endl << ">> which is NOT present in the data file." << std::endl;
1903 return false;
1904 }
1905 }
1906 // found all requested histo groups, hence stuff it to the right places
1907 redGreenOffsets = fAny2ManyInfo->groupHistoList;
1908 runData.SetRedGreenOffset(fAny2ManyInfo->groupHistoList);
1909 }
1910 } else { // not any2many, i.e. musrfit, musrview, ...
1911 redGreenOffsets = ivec;
1912 runData.SetRedGreenOffset(ivec);
1913 }
1914 }
1915
1916 header->Get("RunInfo/Sample Orientation", str, ok);
1917 if (ok)
1918 runData.SetOrientation(str);
1919
1920 // check further for LEM specific stuff in RunInfo
1921
1922 header->Get("RunInfo/Moderator HV", prop, ok);
1923 if (ok)
1924 runData.SetTransport(prop.GetValue());
1925
1926 header->Get("RunInfo/Implantation Energy", prop, ok);
1927 if (ok)
1928 runData.SetEnergy(prop.GetValue());
1929
1930 // read the SampleEnvironmentInfo
1931
1932 header->Get("SampleEnvironmentInfo/Cryo", str, ok);
1933 if (ok)
1934 runData.SetCryoName(str);
1935
1936 // read the MagneticFieldEnvironmentInfo
1937
1938 header->Get("MagneticFieldEnvironmentInfo/Magnet Name", str, ok);
1939 if (ok)
1940 runData.SetMagnetName(str);
1941
1942 // read the BeamlineInfo
1943
1944 header->Get("BeamlineInfo/Name", str, ok);
1945 if (ok)
1946 runData.SetBeamline(str);
1947
1948 // read run summary to obtain ring anode HV values
1949 TObjArray *runSummary = nullptr;
1950 if (fileType == PRH_MUSR_ROOT) // TFolder
1951 runSummary = dynamic_cast<TObjArray*>(folder->FindObjectAny("RunSummary"));
1952 else { // TDirectory
1953 f.GetObject("RunHeader/RunSummary", runSummary);
1954 }
1955
1956 // check if run summary is valid
1957 if (!runSummary) {
1958 std::cout << std::endl << "**INFO** Couldn't obtain run summary info from ROOT file " << fRunPathName.Data() << std::endl;
1959 // this is not fatal... only RA-HV values are not available
1960 } else { // it follows a (at least) little bit strange extraction of the RA values from Thomas' TObjArray...
1961 //streaming of a ASCII-file would be more easy
1962 TString s;
1963 TObjArrayIter summIter(runSummary);
1964 TObjString *os(dynamic_cast<TObjString*>(summIter.Next()));
1965 TObjArray *oa(nullptr);
1966 TObjString *objTok(nullptr);
1967 while (os != nullptr) {
1968 s = os->GetString();
1969 // will put four parallel if's since it may be that more than one RA-values are on one line
1970 if (s.Contains("RA-L")) {
1971 oa = s.Tokenize(" ");
1972 TObjArrayIter lineIter(oa);
1973 objTok = dynamic_cast<TObjString*>(lineIter.Next());
1974 while (objTok != nullptr) {
1975 if (!objTok->GetString().CompareTo("RA-L")) {
1976 objTok = dynamic_cast<TObjString*>(lineIter.Next()); // "="
1977 if ((objTok != nullptr) && !objTok->GetString().CompareTo("=")) {
1978 objTok = dynamic_cast<TObjString*>(lineIter.Next()); // HV value
1979 runData.SetRingAnode(0, objTok->GetString().Atof()); // fill RA-R value into the runData structure
1980 break;
1981 }
1982 }
1983 objTok = dynamic_cast<TObjString*>(lineIter.Next()); // next token...
1984 }
1985 // clean up
1986 if (oa) {
1987 delete oa;
1988 oa = nullptr;
1989 }
1990 }
1991
1992 if (s.Contains("RA-R")) {
1993 oa = s.Tokenize(" ");
1994 TObjArrayIter lineIter(oa);
1995 objTok = dynamic_cast<TObjString*>(lineIter.Next());
1996 while (objTok != nullptr){
1997 if (!objTok->GetString().CompareTo("RA-R")) {
1998 objTok = dynamic_cast<TObjString*>(lineIter.Next()); // "="
1999 if ((objTok != nullptr) && !objTok->GetString().CompareTo("=")) {
2000 objTok = dynamic_cast<TObjString*>(lineIter.Next()); // HV value
2001 runData.SetRingAnode(1, objTok->GetString().Atof()); // fill RA-R value into the runData structure
2002 break;
2003 }
2004 }
2005 objTok = dynamic_cast<TObjString*>(lineIter.Next()); // next token...
2006 }
2007 // clean up
2008 if (oa) {
2009 delete oa;
2010 oa = nullptr;
2011 }
2012 }
2013
2014 if (s.Contains("RA-T")) {
2015 oa = s.Tokenize(" ");
2016 TObjArrayIter lineIter(oa);
2017 objTok = dynamic_cast<TObjString*>(lineIter.Next());
2018 while (objTok != nullptr){
2019 if (!objTok->GetString().CompareTo("RA-T")) {
2020 objTok = dynamic_cast<TObjString*>(lineIter.Next()); // "="
2021 if ((objTok != nullptr) && !objTok->GetString().CompareTo("=")) {
2022 objTok = dynamic_cast<TObjString*>(lineIter.Next()); // HV value
2023 runData.SetRingAnode(2, objTok->GetString().Atof()); // fill RA-T value into the runData structure
2024 break;
2025 }
2026 }
2027 objTok = dynamic_cast<TObjString*>(lineIter.Next()); // next token...
2028 }
2029 // clean up
2030 if (oa) {
2031 delete oa;
2032 oa = nullptr;
2033 }
2034 }
2035
2036 if (s.Contains("RA-B")) {
2037 oa = s.Tokenize(" ");
2038 TObjArrayIter lineIter(oa);
2039 objTok = dynamic_cast<TObjString*>(lineIter.Next());
2040 while (objTok != nullptr){
2041 if (!objTok->GetString().CompareTo("RA-B")) {
2042 objTok = dynamic_cast<TObjString*>(lineIter.Next()); // "="
2043 if ((objTok != nullptr) && !objTok->GetString().CompareTo("=")) {
2044 objTok = dynamic_cast<TObjString*>(lineIter.Next()); // HV value
2045 runData.SetRingAnode(3, objTok->GetString().Atof()); // fill RA-B value into the runData structure
2046 break;
2047 }
2048 }
2049 objTok = dynamic_cast<TObjString*>(lineIter.Next()); // next token...
2050 }
2051 // clean up
2052 if (oa) {
2053 delete oa;
2054 oa = nullptr;
2055 }
2056 }
2057
2058 os = dynamic_cast<TObjString*>(summIter.Next()); // next summary line...
2059 }
2060 }
2061
2062 // read data ---------------------------------------------------------
2063
2064 if (fileType == PRH_MUSR_ROOT) { // TFolder
2065 // check if histos folder is found
2066 f.GetObject("histos", folder);
2067 if (!folder) {
2068 std::cerr << std::endl << ">> PRunDataHandler::ReadRootFile: **ERROR** Couldn't obtain histos from " << fRunPathName.Data() << std::endl;
2069 f.Close();
2070 return false;
2071 }
2072
2073 // get all the data
2074 for (UInt_t i=0; i<redGreenOffsets.size(); i++) {
2075 for (Int_t j=0; j<noOfHistos; j++) {
2076 str.Form("hDecay%03d", redGreenOffsets[i]+j+1);
2077 TH1F *histo = dynamic_cast<TH1F*>(folder->FindObjectAny(str.Data()));
2078 if (!histo) {
2079 std::cerr << std::endl << ">> PRunDataHandler::ReadRootFile: **ERROR** Couldn't get histo " << str;
2080 std::cerr << std::endl;
2081 f.Close();
2082 return false;
2083 }
2084
2085 dataSet.Clear();
2086 dataSet.SetTitle(histo->GetTitle());
2087 dataSet.SetHistoNo(redGreenOffsets[i]+j+1);
2088
2089 // get detector info
2090 path.Form("DetectorInfo/Detector%03d/", redGreenOffsets[i]+j+1);
2091 pathName = path + "Name";
2092 header->Get(pathName, str, ok);
2093 if (ok)
2094 dataSet.SetName(str);
2095 pathName = path + "Time Zero Bin";
2096 header->Get(pathName, dval, ok);
2097 if (ok)
2098 dataSet.SetTimeZeroBin(dval);
2099 pathName = path + "First Good Bin";
2100 header->Get(pathName, ival, ok);
2101 if (ok)
2102 dataSet.SetFirstGoodBin(ival);
2103 pathName = path + "Last Good Bin";
2104 header->Get(pathName, ival, ok);
2105 if (ok)
2106 dataSet.SetLastGoodBin(ival);
2107 dataSet.SetTimeZeroBinEstimated(histo->GetMaximumBin());
2108
2109 // fill data
2110 for (Int_t j=1; j<=histo->GetNbinsX(); j++) {
2111 histoData.push_back(histo->GetBinContent(j));
2112 }
2113 dataSet.SetData(histoData);
2114 runData.SetDataSet(dataSet);
2115
2116 // clear histoData for the next histo
2117 histoData.clear();
2118 }
2119 }
2120 } else { // TDirectory
2121 // get all the data
2122 TH1F *histo;
2123 for (UInt_t i=0; i<redGreenOffsets.size(); i++) {
2124 for (Int_t j=0; j<noOfHistos; j++) {
2125 str.Form("histos/DecayAnaModule/hDecay%03d", redGreenOffsets[i]+j+1);
2126 f.GetObject(str, histo);
2127 if (!histo) {
2128 std::cerr << std::endl << ">> PRunDataHandler::ReadRootFile: **ERROR** Couldn't get histo " << str;
2129 std::cerr << std::endl;
2130 f.Close();
2131 return false;
2132 }
2133
2134 dataSet.Clear();
2135 dataSet.SetTitle(histo->GetTitle());
2136 dataSet.SetHistoNo(redGreenOffsets[i]+j+1);
2137
2138 // get detector info
2139 path.Form("DetectorInfo/Detector%03d/", redGreenOffsets[i]+j+1);
2140 pathName = path + "Name";
2141 header->Get(pathName, str, ok);
2142 if (ok)
2143 dataSet.SetName(str);
2144 pathName = path + "Time Zero Bin";
2145 header->Get(pathName, dval, ok);
2146 if (ok)
2147 dataSet.SetTimeZeroBin(dval);
2148 pathName = path + "First Good Bin";
2149 header->Get(pathName, ival, ok);
2150 if (ok)
2151 dataSet.SetFirstGoodBin(ival);
2152 pathName = path + "Last Good Bin";
2153 header->Get(pathName, ival, ok);
2154 if (ok)
2155 dataSet.SetLastGoodBin(ival);
2156 dataSet.SetTimeZeroBinEstimated(histo->GetMaximumBin());
2157
2158 // fill data
2159 for (Int_t j=1; j<=histo->GetNbinsX(); j++) {
2160 histoData.push_back(histo->GetBinContent(j));
2161 }
2162 dataSet.SetData(histoData);
2163 runData.SetDataSet(dataSet);
2164
2165 // clear histoData for the next histo
2166 histoData.clear();
2167 }
2168 }
2169 }
2170 }
2171
2172 f.Close();
2173
2174 // keep run name
2175 runData.SetRunName(fRunName);
2176
2177 // add run to the run list
2178 fData.push_back(runData);
2179
2180 return true;
2181}
2182
2183//--------------------------------------------------------------------------
2184// ReadNexusFile (private)
2185//--------------------------------------------------------------------------
2194{
2195#ifdef PNEXUS_ENABLED
2196 std::cout << std::endl << ">> PRunDataHandler::ReadNexusFile(): Will read nexus file " << fRunPathName.Data() << " ...";
2197
2199
2200 // check for type errors, missing enabled HDF4
2201 switch (type) {
2202 case nxs::HDFType::HDF4:
2203 std::cout << std::endl << ">> PRunDataHandler::ReadNexusFile(): HDF4 file." << std::endl;
2204#ifndef HAVE_HDF4
2205 std::cerr << std::endl << ">> PRunDataHandler::ReadNexusFile(): **ERROR**, HDF4 is not enabled." << std::endl;
2206 return false;
2207#endif
2208 break;
2209 case nxs::HDFType::HDF5:
2210 std::cout << std::endl << ">> PRunDataHandler::ReadNexusFile(): HDF5 file." << std::endl;
2211 break;
2213 std::cerr << std::endl << ">> PRunDataHandler::ReadNexusFile(): Not a valid NeXus file." << std::endl;
2214 return false;
2215 }
2216
2217 PDoubleVector histoData;
2218 PRawRunData runData;
2219 PRawRunDataSet dataSet;
2220 TString str;
2221 std::string sstr;
2222 Int_t ival, idf{-1};
2223 Double_t dval, factor;
2224 bool ok;
2225
2226 if (type == nxs::HDFType::HDF4) {
2227#ifdef HAVE_HDF4
2228 std::unique_ptr<nxH4::PNeXus> nxs_file = std::make_unique<nxH4::PNeXus>(fRunPathName.Data());
2229 if (nxs_file == nullptr) {
2230 std::cerr << std::endl << "**ERROR** allocation of nxH4::PNeXus object failed." << std::endl;
2231 return true;
2232 }
2233
2234 // check for IDF_version
2235 if (nxs_file->HasDataset("/run/IDF_version")) {
2236 idf = nxs_file->GetDataset<int>("/run/IDF_version").GetData()[0];
2237 std::cout << ">> PRunDataHandler::ReadNexusFile(): IDF V" << idf << std::endl;
2238 }
2239 if (idf == -1) { // IDF_version not found
2240 if (nxs_file->HasDataset("/raw_data_1/IDF_version")) {
2241 idf = nxs_file->GetDataset<int>("/raw_data_1/IDF_version").GetData()[0];
2242 std::cout << ">> PRunDataHandler::ReadNexusFile(): IDF V" << idf << std::endl;
2243 }
2244 }
2245 if ((idf != 1) && (idf != 2)) {
2246 std::cerr << std::endl << ">> PRunDataHandler::ReadNexusFile(): a NeXus file with an invalid IDF V" << idf << std::endl;
2247 return false;
2248 }
2249
2250 if (idf == 1) { // HDF4 IDF V1
2251 if (!ReadNexusFileIdf1(nxs_file))
2252 return false;
2253 } else { // HDF4 IDF V2
2254 // not yet implemented
2255 }
2256#endif
2257 } else { // HDF5
2258 std::unique_ptr<nxH5::PNeXus> nxs_file = std::make_unique<nxH5::PNeXus>(fRunPathName.Data());
2259 if (nxs_file == nullptr) {
2260 std::cerr << std::endl << "**ERROR** allocation of nxH5::PNeXus object failed." << std::endl;
2261 return true;
2262 }
2263
2264 // check for IDF_version
2265 if (nxs_file->HasDataset("/run/IDF_version")) {
2266 idf = nxs_file->GetDataset<int>("/run/IDF_version").GetData()[0];
2267 std::cout << ">> PRunDataHandler::ReadNexusFile(): IDF V" << idf << std::endl;
2268 }
2269 if (idf == -1) { // IDF_version not found
2270 if (nxs_file->HasDataset("/raw_data_1/IDF_version")) {
2271 idf = nxs_file->GetDataset<int>("/raw_data_1/IDF_version").GetData()[0];
2272 std::cout << ">> PRunDataHandler::ReadNexusFile(): IDF V" << idf << std::endl;
2273 }
2274 }
2275 if ((idf != 1) && (idf != 2)) {
2276 std::cerr << std::endl << ">> PRunDataHandler::ReadNexusFile(): a NeXus file with an invalid IDF V" << idf << std::endl;
2277 return false;
2278 }
2279
2280 if (idf == 1) { // HDF5 IDF V1
2281 if (!ReadNexusFileIdf1(nxs_file))
2282 return false;
2283 } else { // HDF5 IDF V2
2284 if (!ReadNexusFileIdf2(nxs_file))
2285 return false;
2286 }
2287 }
2288#else
2289 std::cout << std::endl << ">> PRunDataHandler::ReadNexusFile(): Sorry, not enabled at configuration level, i.e. --enable-NeXus when executing configure" << std::endl << std::endl;
2290#endif
2291 return true;
2292}
2293
2294//--------------------------------------------------------------------------
2295// ReadWkmFile (private)
2296//--------------------------------------------------------------------------
2306{
2307 PDoubleVector histoData;
2308 PRawRunData runData;
2309
2310 // open file
2311 std::ifstream f;
2312
2313 // open wkm-file
2314 f.open(fRunPathName.Data(), std::ifstream::in);
2315 if (!f.is_open()) {
2316 std::cerr << std::endl << ">> PRunDataHandler::ReadWkmFile: **ERROR** Couldn't open run data (" << fRunPathName.Data() << ") file for reading, sorry ...";
2317 std::cerr << std::endl;
2318 return false;
2319 }
2320
2321 // read header
2322 Bool_t headerInfo = true;
2323 Char_t instr[512];
2324 TString line, linecp;
2325 Double_t dval;
2326 Int_t ival;
2327 Bool_t ok;
2328 Int_t groups = 0, channels = 0;
2329
2330 // skip leading empty lines
2331 do {
2332 f.getline(instr, sizeof(instr));
2333 line = TString(instr);
2334 if (!line.IsWhitespace())
2335 break;
2336 } while (!f.eof());
2337
2338 // real header data should start here
2339 Ssiz_t idx;
2340 do {
2341 line = TString(instr);
2342 if (line.IsDigit()) { // end of header reached
2343 headerInfo = false;
2344 } else { // real stuff, hence filter data
2345 if (line.Contains("Title") || line.Contains("Titel")) {
2346 idx = line.Index(":");
2347 line.Replace(0, idx+1, nullptr, 0); // remove 'Title:'
2348 StripWhitespace(line);
2349 runData.SetRunTitle(line);
2350 } else if (line.Contains("Run:")) {
2351 idx = line.Index(":");
2352 line.Replace(0, idx+1, nullptr, 0); // remove 'Run:'
2353 StripWhitespace(line);
2354 ival = ToInt(line, ok);
2355 if (ok)
2356 runData.SetRunNumber(ival);
2357 } else if (line.Contains("Field")) {
2358 idx = line.Index(":");
2359 line.Replace(0, idx+1, nullptr, 0); // remove 'Field:'
2360 StripWhitespace(line);
2361 idx = line.Index("G"); // check if unit is given
2362 if (idx > 0) // unit is indeed given
2363 line.Resize(idx);
2364 dval = ToDouble(line, ok);
2365 if (ok)
2366 runData.SetField(dval);
2367 } else if (line.Contains("Setup")) {
2368 idx = line.Index(":");
2369 line.Replace(0, idx+1, nullptr, 0); // remove 'Setup:'
2370 StripWhitespace(line);
2371 runData.SetSetup(line);
2372 } else if (line.Contains("Temp:") || line.Contains("Temp(meas1):")) {
2373 linecp = line;
2374 idx = line.Index(":");
2375 line.Replace(0, idx+1, nullptr, 0); // remove 'Temp:'
2376 StripWhitespace(line);
2377 idx = line.Index("+/-"); // remove "+/- ..." part
2378 if (idx > 0)
2379 line.Resize(idx);
2380 idx = line.Index("K"); // remove "K ..." part
2381 if (idx > 0)
2382 line.Resize(idx);
2383 dval = ToDouble(line, ok);
2384 if (ok) {
2385 runData.SetTemperature(0, dval, 0.0);
2386 }
2387 idx = linecp.Index("+/-"); // get the error
2388 linecp.Replace(0, idx+3, nullptr, 0);
2389 StripWhitespace(linecp);
2390 dval = ToDouble(linecp, ok);
2391 if (ok) {
2392 runData.SetTempError(0, dval);
2393 }
2394 } else if (line.Contains("Temp(meas2):")) {
2395 linecp = line;
2396 idx = line.Index(":");
2397 line.Replace(0, idx+1, nullptr, 0); // remove 'Temp(meas2):'
2398 StripWhitespace(line);
2399 idx = line.Index("+/-"); // remove "+/- ..." part
2400 if (idx > 0)
2401 line.Resize(idx);
2402 idx = line.Index("K"); // remove "K ..." part
2403 if (idx > 0)
2404 line.Resize(idx);
2405 dval = ToDouble(line, ok);
2406 if (ok) {
2407 runData.SetTemperature(1, dval, 0.0);
2408 }
2409 idx = linecp.Index("+/-"); // get the error
2410 linecp.Replace(0, idx+3, nullptr, 0);
2411 StripWhitespace(linecp);
2412 dval = ToDouble(linecp, ok);
2413 if (ok) {
2414 runData.SetTempError(1, dval);
2415 }
2416 } else if (line.Contains("Groups")) {
2417 idx = line.Index(":");
2418 line.Replace(0, idx+1, nullptr, 0); // remove 'Groups:'
2419 StripWhitespace(line);
2420 ival = ToInt(line, ok);
2421 if (ok)
2422 groups = ival;
2423 } else if (line.Contains("Channels")) {
2424 idx = line.Index(":");
2425 line.Replace(0, idx+1, nullptr, 0); // remove 'Channels:'
2426 StripWhitespace(line);
2427 ival = ToInt(line, ok);
2428 if (ok)
2429 channels = ival;
2430 } else if (line.Contains("Resolution")) {
2431 idx = line.Index(":");
2432 line.Replace(0, idx+1, nullptr, 0); // remove 'Resolution:'
2433 StripWhitespace(line);
2434 dval = ToDouble(line, ok);
2435 if (ok)
2436 runData.SetTimeResolution(dval*1.0e3); // us -> ns
2437 }
2438 }
2439
2440 if (headerInfo)
2441 f.getline(instr, sizeof(instr));
2442 } while (headerInfo && !f.eof());
2443
2444 if ((groups == 0) || (channels == 0) || runData.GetTimeResolution() == 0.0) {
2445 std::cerr << std::endl << ">> PRunDataHandler::ReadWkmFile(): **ERROR** essential header informations are missing!";
2446 std::cerr << std::endl << ">> groups = " << groups;
2447 std::cerr << std::endl << ">> channels = " << channels;
2448 std::cerr << std::endl << ">> time resolution = " << runData.GetTimeResolution();
2449 std::cerr << std::endl;
2450 f.close();
2451 return false;
2452 }
2453
2454 // read data ---------------------------------------------------------
2455 UInt_t group_counter = 0;
2456 Int_t val;
2457 TObjArray *tokens;
2458 TObjString *ostr;
2459 TString str;
2460 UInt_t histoNo = 0;
2461 PRawRunDataSet dataSet;
2462 do {
2463 // check if empty line, i.e. new group
2464 if (IsWhitespace(instr)) {
2465 dataSet.Clear();
2466 dataSet.SetHistoNo(++histoNo);
2467 dataSet.SetData(histoData);
2468
2469 // get a T0 estimate
2470 Double_t maxVal = 0.0;
2471 Int_t maxBin = 0;
2472 for (UInt_t i=0; i<histoData.size(); i++) {
2473 if (histoData[i] > maxVal) {
2474 maxVal = histoData[i];
2475 maxBin = i;
2476 }
2477 }
2478 dataSet.SetTimeZeroBinEstimated(maxBin);
2479
2480 runData.SetDataSet(dataSet);
2481
2482 histoData.clear();
2483 group_counter++;
2484 } else {
2485 // extract values
2486 line = TString(instr);
2487 // check if line starts with character. Needed for RAL WKM format
2488 if (!line.IsDigit()) {
2489 f.getline(instr, sizeof(instr));
2490 continue;
2491 }
2492 tokens = line.Tokenize(" ");
2493
2494 if (!tokens) { // no tokens found
2495 std::cerr << std::endl << ">> PRunDataHandler::ReadWkmFile(): **ERROR** while reading data: coulnd't tokenize run data.";
2496 return false;
2497 }
2498 for (Int_t i=0; i<tokens->GetEntries(); i++) {
2499 ostr = dynamic_cast<TObjString*>(tokens->At(i));
2500 str = ostr->GetString();
2501 val = ToInt(str, ok);
2502 if (ok) {
2503 histoData.push_back(val);
2504 } else {
2505 std::cerr << std::endl << ">> PRunDataHandler::ReadWkmFile(): **ERROR** while reading data: data line contains non-integer values.";
2506 // clean up
2507 delete tokens;
2508 return false;
2509 }
2510 }
2511 // clean up
2512 if (tokens) {
2513 delete tokens;
2514 tokens = nullptr;
2515 }
2516 }
2517
2518 f.getline(instr, sizeof(instr));
2519
2520 } while (!f.eof());
2521
2522 // handle last line if present
2523 if (strlen(instr) != 0) {
2524 // extract values
2525 line = TString(instr);
2526 tokens = line.Tokenize(" ");
2527 if (!tokens) { // no tokens found
2528 std::cerr << std::endl << ">> PRunDataHandler::ReadWkmFile(): **ERROR** while reading data: coulnd't tokenize run data.";
2529 return false;
2530 }
2531 for (Int_t i=0; i<tokens->GetEntries(); i++) {
2532 ostr = dynamic_cast<TObjString*>(tokens->At(i));
2533 str = ostr->GetString();
2534 val = ToInt(str, ok);
2535 if (ok) {
2536 histoData.push_back(val);
2537 } else {
2538 std::cerr << std::endl << ">> PRunDataHandler::ReadWkmFile(): **ERROR** while reading data: data line contains non-integer values.";
2539 // clean up
2540 delete tokens;
2541 return false;
2542 }
2543 }
2544 // clean up
2545 if (tokens) {
2546 delete tokens;
2547 tokens = nullptr;
2548 }
2549 }
2550
2551 // save the last histo if not empty
2552 if (histoData.size() > 0) {
2553 dataSet.Clear();
2554 dataSet.SetHistoNo(++histoNo);
2555 dataSet.SetData(histoData);
2556
2557 // get a T0 estimate
2558 Double_t maxVal = 0.0;
2559 Int_t maxBin = 0;
2560 for (UInt_t i=0; i<histoData.size(); i++) {
2561 if (histoData[i] > maxVal) {
2562 maxVal = histoData[i];
2563 maxBin = i;
2564 }
2565 }
2566 dataSet.SetTimeZeroBinEstimated(maxBin);
2567
2568 runData.SetDataSet(dataSet);
2569 histoData.clear();
2570 }
2571
2572 // close file
2573 f.close();
2574
2575 // check if all groups are found
2576 if (static_cast<Int_t>(runData.GetNoOfHistos()) != groups) {
2577 std::cerr << std::endl << ">> PRunDataHandler::ReadWkmFile(): **ERROR**";
2578 std::cerr << std::endl << ">> expected " << groups << " histos, but found " << runData.GetNoOfHistos();
2579 return false;
2580 }
2581
2582 // check if all groups have enough channels
2583 for (UInt_t i=0; i<runData.GetNoOfHistos(); i++) {
2584 if (static_cast<Int_t>(runData.GetDataBin(i+1)->size()) != channels) {
2585 std::cerr << std::endl << ">> PRunDataHandler::ReadWkmFile(): **ERROR**";
2586 std::cerr << std::endl << ">> expected " << channels << " bins in histo " << i+1 << ", but found " << runData.GetDataBin(i)->size();
2587 return false;
2588 }
2589 }
2590
2591 // keep run name
2592 runData.SetRunName(fRunName);
2593
2594 // add run to the run list
2595 fData.push_back(runData);
2596
2597 return true;
2598}
2599
2600//--------------------------------------------------------------------------
2601// ReadPsiBinFile (private)
2602//--------------------------------------------------------------------------
2612{
2613 MuSR_td_PSI_bin psiBin;
2614 Int_t status;
2615 Bool_t success;
2616
2617 // read psi bin file
2618 status = psiBin.Read(fRunPathName.Data());
2619 switch (status) {
2620 case 0: // everything perfect
2621 success = true;
2622 break;
2623 case 1: // couldn't open file, or failed while reading the header
2624 std::cerr << std::endl << ">> **ERROR** couldn't open psi-bin file, or failed while reading the header";
2625 std::cerr << std::endl;
2626 success = false;
2627 break;
2628 case 2: // unsupported version of the data
2629 std::cerr << std::endl << ">> **ERROR** psi-bin file: unsupported version of the data";
2630 std::cerr << std::endl;
2631 success = false;
2632 break;
2633 case 3: // error when allocating data buffer
2634 std::cerr << std::endl << ">> **ERROR** psi-bin file: error when allocating data buffer";
2635 std::cerr << std::endl;
2636 success = false;
2637 break;
2638 case 4: // number of histograms/record not equals 1
2639 std::cerr << std::endl << ">> **ERROR** psi-bin file: number of histograms/record not equals 1";
2640 std::cerr << std::endl;
2641 success = false;
2642 break;
2643 default: // you never should have reached this point
2644 success = false;
2645 break;
2646 }
2647
2648 // if any reading error happend, get out of here
2649 if (!success)
2650 return success;
2651
2652 // fill necessary header informations
2653 PRawRunData runData;
2654 Double_t dval;
2655
2656 // set file name
2657 Ssiz_t pos = fRunPathName.Last('/');
2658 TString fln(fRunPathName);
2659 fln.Remove(0, pos+1);
2660 runData.SetFileName(fln);
2661
2662 // set laboratory
2663 runData.SetLaboratory("PSI");
2664
2665 // filter from the file name the instrument
2666 TString instrument("n/a"), beamline("n/a");
2667 TString muonSource("n/a"), muonSpecies("n/a");
2668 if (fRunPathName.Contains("_gps_", TString::kIgnoreCase)) {
2669 instrument = "GPS";
2670 beamline = "piM3.2";
2671 muonSource = "continuous surface muon source";
2672 muonSpecies = "positive muons";
2673 } else if (fRunPathName.Contains("_ltf_", TString::kIgnoreCase)) {
2674 instrument = "LTF";
2675 beamline = "piM3.3";
2676 muonSource = "continuous surface muon source";
2677 muonSpecies = "positive muons";
2678 } else if (fRunPathName.Contains("_gpd_", TString::kIgnoreCase)) {
2679 instrument = "GPD";
2680 beamline = "muE1";
2681 muonSource = "continuous decay channel muon source";
2682 muonSpecies = "positive muons";
2683 } else if (fRunPathName.Contains("_dolly_", TString::kIgnoreCase)) {
2684 instrument = "DOLLY";
2685 beamline = "piE1";
2686 muonSource = "continuous surface muon source";
2687 muonSpecies = "positive muons";
2688 } else if (fRunPathName.Contains("_alc_", TString::kIgnoreCase)) {
2689 instrument = "ALC";
2690 beamline = "piE3";
2691 muonSource = "continuous surface muon source";
2692 muonSpecies = "positive muons";
2693 } else if (fRunPathName.Contains("_hifi_", TString::kIgnoreCase)) {
2694 instrument = "HIFI";
2695 beamline = "piE3";
2696 muonSource = "continuous surface muon source";
2697 muonSpecies = "positive muons";
2698 }
2699 runData.SetInstrument(instrument);
2700 runData.SetBeamline(beamline);
2701 runData.SetMuonSource(muonSource);
2702 runData.SetMuonSpecies(muonSpecies);
2703
2704 // keep run name
2705 runData.SetRunName(fRunName);
2706 // get run title
2707 runData.SetRunTitle(TString(psiBin.GetComment().c_str())); // run title
2708 // get run number
2709 runData.SetRunNumber(psiBin.GetRunNumberInt());
2710 // get setup
2711 runData.SetSetup(TString(psiBin.GetComment().c_str()));
2712 // get sample
2713 runData.SetSample(TString(psiBin.GetSample().c_str()));
2714 // get orientation
2715 runData.SetOrientation(TString(psiBin.GetOrient().c_str()));
2716 // get comment
2717 runData.SetComment(TString(psiBin.GetComment().c_str()));
2718 // set LEM specific information to default value since it is not in the file and not used...
2719 runData.SetEnergy(PMUSR_UNDEFINED);
2721 // get field
2722 Double_t scale = 0.0;
2723 if (psiBin.GetField().rfind("G") != std::string::npos)
2724 scale = 1.0;
2725 if (psiBin.GetField().rfind("T") != std::string::npos)
2726 scale = 1.0e4;
2727 status = sscanf(psiBin.GetField().c_str(), "%lf", &dval);
2728 if (status == 1)
2729 runData.SetField(scale*dval);
2730 // get temperature
2731 PDoubleVector tempVec(psiBin.GetTemperaturesVector());
2732 PDoubleVector tempDevVec(psiBin.GetDevTemperaturesVector());
2733 if ((tempVec.size() > 1) && (tempDevVec.size() > 1) && tempVec[0] && tempVec[1]) {
2734 // take only the first two values for now...
2735 //maybe that's not enough - e.g. in older GPD data I saw the "correct values in the second and third entry..."
2736 for (UInt_t i(0); i<2; i++) {
2737 runData.SetTemperature(i, tempVec[i], tempDevVec[i]);
2738 }
2739 tempVec.clear();
2740 tempDevVec.clear();
2741 } else {
2742 status = sscanf(psiBin.GetTemp().c_str(), "%lfK", &dval);
2743 if (status == 1)
2744 runData.SetTemperature(0, dval, 0.0);
2745 }
2746
2747 // get time resolution (ns)
2748 runData.SetTimeResolution(psiBin.GetBinWidthNanoSec());
2749
2750 // get start/stop time
2751 std::vector<std::string> sDateTime = psiBin.GetTimeStartVector();
2752 if (sDateTime.size() < 2) {
2753 std::cerr << std::endl << ">> **WARNING** psi-bin file: couldn't obtain run start date/time" << std::endl;
2754 }
2755 std::string date("");
2756 if (DateToISO8601(sDateTime[0], date)) {
2757 runData.SetStartDate(date);
2758 } else {
2759 std::cerr << std::endl << ">> **WARNING** failed to convert start date: " << sDateTime[0] << " into ISO 8601 date." << std::endl;
2760 runData.SetStartDate(sDateTime[0]);
2761 }
2762 runData.SetStartTime(sDateTime[1]);
2763 sDateTime.clear();
2764
2765 sDateTime = psiBin.GetTimeStopVector();
2766 if (sDateTime.size() < 2) {
2767 std::cerr << std::endl << ">> **WARNING** psi-bin file: couldn't obtain run stop date/time" << std::endl;
2768 }
2769 date = std::string("");
2770 if (DateToISO8601(sDateTime[0], date)) {
2771 runData.SetStopDate(date);
2772 } else {
2773 std::cerr << std::endl << ">> **WARNING** failed to convert stop date: " << sDateTime[0] << " into ISO 8601 date." << std::endl;
2774 runData.SetStopDate(sDateTime[0]);
2775 }
2776 runData.SetStopTime(sDateTime[1]);
2777 sDateTime.clear();
2778
2779 // get t0's
2780 PIntVector t0 = psiBin.GetT0Vector();
2781
2782 if (t0.empty()) {
2783 std::cerr << std::endl << ">> **ERROR** psi-bin file: couldn't obtain any t0's";
2784 std::cerr << std::endl;
2785 return false;
2786 }
2787
2788 // get first good bin
2789 PIntVector fgb = psiBin.GetFirstGoodVector();
2790 if (fgb.empty()) {
2791 std::cerr << std::endl << ">> **ERROR** psi-bin file: couldn't obtain any fgb's";
2792 std::cerr << std::endl;
2793 return false;
2794 }
2795
2796 // get last good bin
2797 PIntVector lgb = psiBin.GetLastGoodVector();
2798 if (lgb.empty()) {
2799 std::cerr << std::endl << ">> **ERROR** psi-bin file: couldn't obtain any lgb's";
2800 std::cerr << std::endl;
2801 return false;
2802 }
2803
2804 // fill raw data
2805 PRawRunDataSet dataSet;
2806 PDoubleVector histoData;
2807 std::vector<Int_t> histo;
2808 for (Int_t i=0; i<psiBin.GetNumberHistoInt(); i++) {
2809 histo = psiBin.GetHistoArrayInt(i);
2810 for (Int_t j=0; j<psiBin.GetHistoLengthBin(); j++) {
2811 histoData.push_back(histo[j]);
2812 }
2813
2814 // estimate T0 from maximum of the data
2815 Double_t maxVal = 0.0;
2816 Int_t maxBin = 0;
2817 for (UInt_t j=0; j<histoData.size(); j++) {
2818 if (histoData[j] > maxVal) {
2819 maxVal = histoData[j];
2820 maxBin = j;
2821 }
2822 }
2823
2824 dataSet.Clear();
2825 dataSet.SetName(psiBin.GetNameHisto(i).c_str());
2826 dataSet.SetHistoNo(i+1); // i.e. hist numbering starts at 1
2827 if (i < static_cast<Int_t>(t0.size()))
2828 dataSet.SetTimeZeroBin(t0[i]);
2829 dataSet.SetTimeZeroBinEstimated(maxBin);
2830 if (i < static_cast<Int_t>(fgb.size()))
2831 dataSet.SetFirstGoodBin(fgb[i]);
2832 if (i < static_cast<Int_t>(lgb.size()))
2833 dataSet.SetLastGoodBin(lgb[i]);
2834 dataSet.SetData(histoData);
2835
2836 runData.SetDataSet(dataSet);
2837
2838 histoData.clear();
2839 }
2840
2841 // add run to the run list
2842 fData.push_back(runData);
2843
2844 return success;
2845}
2846
2847//--------------------------------------------------------------------------
2848// ReadMudFile (private)
2849//--------------------------------------------------------------------------
2858{
2859 Int_t fh;
2860 UINT32 type, val;
2861 Int_t success;
2862 Char_t str[1024];
2863 Double_t dval;
2864
2865 PRawRunData runData;
2866
2867 fh = MUD_openRead((char*)fRunPathName.Data(), &type);
2868 if (fh == -1) {
2869 std::cerr << std::endl << ">> **ERROR** Couldn't open mud-file " << fRunPathName.Data() << ", sorry.";
2870 std::cerr << std::endl;
2871 return false;
2872 }
2873
2874 // read necessary header information
2875
2876 // keep run name
2877 runData.SetRunName(fRunName);
2878
2879 // get/set the lab
2880 success = MUD_getLab( fh, str, sizeof(str) );
2881 if ( !success ) {
2882 std::cerr << std::endl << ">> **WARNING** Couldn't obtain the laboratory name of run " << fRunName.Data();
2883 std::cerr << std::endl;
2884 strcpy(str, "n/a");
2885 }
2886 runData.SetLaboratory(TString(str));
2887
2888 // get/set the beamline
2889 success = MUD_getArea( fh, str, sizeof(str) );
2890 if ( !success ) {
2891 std::cerr << std::endl << ">> **WARNING** Couldn't obtain the beamline of run " << fRunName.Data();
2892 std::cerr << std::endl;
2893 strcpy(str, "n/a");
2894 }
2895 runData.SetBeamline(TString(str));
2896
2897 // get/set the instrument
2898 success = MUD_getApparatus( fh, str, sizeof(str) );
2899 if ( !success ) {
2900 std::cerr << std::endl << ">> **WARNING** Couldn't obtain the instrument name of run " << fRunName.Data();
2901 std::cerr << std::endl;
2902 strcpy(str, "n/a");
2903 }
2904 runData.SetInstrument(TString(str));
2905
2906 // get run title
2907 success = MUD_getTitle( fh, str, sizeof(str) );
2908 if ( !success ) {
2909 std::cerr << std::endl << ">> **WARNING** Couldn't obtain the run title of run " << fRunName.Data();
2910 std::cerr << std::endl;
2911 }
2912 runData.SetRunTitle(TString(str));
2913
2914 // get run number
2915 success = MUD_getRunNumber( fh, &val );
2916 if (success) {
2917 runData.SetRunNumber(static_cast<Int_t>(val));
2918 }
2919
2920 // get start/stop time of the run
2921 time_t tval;
2922 struct tm *dt;
2923 TString stime("");
2924 success = MUD_getTimeBegin( fh, (UINT32*)&tval );
2925 if (success) {
2926 runData.SetStartDateTime(static_cast<const time_t>(tval));
2927 dt = localtime((const time_t*)&tval);
2928
2929 if (dt) {
2930 // start date
2931 strftime(str, sizeof(str), "%F", dt);
2932 stime = str;
2933 runData.SetStartDate(stime);
2934 // start time
2935 memset(str, 0, sizeof(str));
2936 strftime(str, sizeof(str), "%T", dt);
2937 stime = str;
2938 runData.SetStartTime(stime);
2939 } else {
2940 std::cerr << "PRunDataHandler::ReadMudFile: **WARNING** run start time readback wrong, will set it to 1900-01-01, 00:00:00" << std::endl;
2941 stime = "1900-01-01";
2942 runData.SetStartDate(stime);
2943 stime = "00:00:00";
2944 runData.SetStartTime(stime);
2945 }
2946 }
2947
2948 stime = TString("");
2949 success = MUD_getTimeEnd( fh, (UINT32*)&tval );
2950 if (success) {
2951 runData.SetStopDateTime((const time_t)tval);
2952 dt = localtime((const time_t*)&tval);
2953
2954 if (dt) {
2955 // stop date
2956 strftime(str, sizeof(str), "%F", dt);
2957 stime = str;
2958 runData.SetStopDate(stime);
2959 // stop time
2960 memset(str, 0, sizeof(str));
2961 strftime(str, sizeof(str), "%T", dt);
2962 stime = str;
2963 runData.SetStopTime(stime);
2964 } else {
2965 std::cerr << "PRunDataHandler::ReadMudFile: **WARNING** run stop time readback wrong, will set it to 1900-01-01, 00:00:00" << std::endl;
2966 stime = "1900-01-01";
2967 runData.SetStopDate(stime);
2968 stime = "00:00:00";
2969 runData.SetStopTime(stime);
2970 }
2971 }
2972
2973 // get setup
2974 TString setup;
2975 REAL64 timeResMultiplier = 1.0e9; // Multiplier time resolution
2976 success = MUD_getLab( fh, str, sizeof(str) );
2977 if (success) {
2978 setup = TString(str) + TString("/");
2979 }
2980 success = MUD_getArea( fh, str, sizeof(str) );
2981 if (success) {
2982 setup += TString(str) + TString("/");
2983 if (TString(str) == "BNQR" || TString(str) == "BNMR") {
2984 std::cerr << "PRunDataHandler::ReadMudFile: **INFORMATION** this run was performed on " << str << std::endl;
2985 std::cerr << "PRunDataHandler::ReadMudFile: **INFORMATION** apply correction to time resolution" << std::endl;
2986 // identified BNMR/BNQR, correct time resolution.
2987 timeResMultiplier = 1.0e9;
2988 }
2989 }
2990 success = MUD_getApparatus( fh, str, sizeof(str) );
2991 if (success) {
2992 setup += TString(str) + TString("/");
2993 }
2994 success = MUD_getSample( fh, str, sizeof(str) );
2995 if (success) {
2996 setup += TString(str);
2997 runData.SetSample(str);
2998 }
2999 runData.SetSetup(setup);
3000
3001 // set LEM specific information to default value since it is not in the file and not used...
3002 runData.SetEnergy(PMUSR_UNDEFINED);
3004
3005 // get field
3006 success = MUD_getField( fh, str, sizeof(str) );
3007 if (success) {
3008 success = sscanf(str, "%lf G", &dval);
3009 if (success == 1) {
3010 runData.SetField(dval);
3011 } else {
3012 runData.SetField(PMUSR_UNDEFINED);
3013 }
3014 } else {
3015 runData.SetField(PMUSR_UNDEFINED);
3016 }
3017
3018 // get temperature
3019 success = MUD_getTemperature( fh, str, sizeof(str) );
3020 if (success) {
3021 success = sscanf(str, "%lf K", &dval);
3022 if (success == 1) {
3023 runData.SetTemperature(0, dval, 0.0);
3024 } else {
3025 runData.SetTemperature(0, PMUSR_UNDEFINED, 0.0);
3026 }
3027 } else {
3028 runData.SetTemperature(0, PMUSR_UNDEFINED, 0.0);
3029 }
3030
3031 // get number of histogramms
3032 success = MUD_getHists(fh, &type, &val);
3033 if ( !success ) {
3034 std::cerr << std::endl << ">> **ERROR** Couldn't obtain the number of histograms of run " << fRunName.Data();
3035 std::cerr << std::endl;
3036 MUD_closeRead(fh);
3037 return false;
3038 }
3039 Int_t noOfHistos = static_cast<Int_t>(val);
3040
3041 // get time resolution (ns)
3042 // check that time resolution is identical for all histograms
3043 // >> currently it is not forseen to handle histos with different time resolutions <<
3044 // >> perhaps this needs to be reconsidered later on <<
3045 REAL64 timeResolution = 0.0; // in seconds!!
3046 REAL64 lrval = 0.0;
3047 for (Int_t i=1; i<=noOfHistos; i++) {
3048 success = MUD_getHistSecondsPerBin( fh, i, &lrval );
3049 if (!success) {
3050 std::cerr << std::endl << ">> **ERROR** Couldn't obtain the time resolution of run " << fRunName.Data();
3051 std::cerr << std::endl << ">> which is fatal, sorry.";
3052 std::cerr << std::endl;
3053 MUD_closeRead(fh);
3054 return false;
3055 }
3056 if (i==1) {
3057 timeResolution = lrval;
3058 } else {
3059 if (lrval != timeResolution) {
3060 std::cerr << std::endl << ">> **ERROR** various time resolutions found in run " << fRunName.Data();
3061 std::cerr << std::endl << ">> this is currently not supported, sorry.";
3062 std::cerr << std::endl;
3063 MUD_closeRead(fh);
3064 return false;
3065 }
3066 }
3067 }
3068
3069 runData.SetTimeResolution(static_cast<Double_t>(timeResolution) * timeResMultiplier); // s -> ns or s -> ms for bNMR
3070 // Other possibility:
3071 // Check if it is a bNMR run and fix it or check if "timeres" line
3072 // was introduced in the msr file
3073
3074
3075 // read histograms
3076 UINT32 *pData; // histo memory
3077 pData = nullptr;
3078 PDoubleVector histoData;
3079 PRawRunDataSet dataSet;
3080 UInt_t noOfBins;
3081
3082 for (Int_t i=1; i<=noOfHistos; i++) {
3083 dataSet.Clear();
3084
3085 dataSet.SetHistoNo(i);
3086
3087 // get t0's
3088 success = MUD_getHistT0_Bin( fh, i, &val );
3089 if ( !success ) {
3090 std::cerr << std::endl << ">> **WARNING** Couldn't get t0 of histo " << i << " of run " << fRunName.Data();
3091 std::cerr << std::endl;
3092 }
3093 dataSet.SetTimeZeroBin(static_cast<Double_t>(val));
3094
3095 // get bkg bins
3096 success = MUD_getHistBkgd1( fh, i, &val );
3097 if ( !success ) {
3098 std::cerr << std::endl << ">> **WARNING** Couldn't get bkg bin 1 of histo " << i << " of run " << fRunName.Data();
3099 std::cerr << std::endl;
3100 val = 0;
3101 }
3102 dataSet.SetFirstBkgBin(static_cast<Int_t>(val));
3103
3104 success = MUD_getHistBkgd2( fh, i, &val );
3105 if ( !success ) {
3106 std::cerr << std::endl << ">> **WARNING** Couldn't get bkg bin 2 of histo " << i << " of run " << fRunName.Data();
3107 std::cerr << std::endl;
3108 val = 0;
3109 }
3110 dataSet.SetLastBkgBin(static_cast<Int_t>(val));
3111
3112 // get good data bins
3113 success = MUD_getHistGoodBin1( fh, i, &val );
3114 if ( !success ) {
3115 std::cerr << std::endl << ">> **WARNING** Couldn't get good bin 1 of histo " << i << " of run " << fRunName.Data();
3116 std::cerr << std::endl;
3117 val = 0;
3118 }
3119 dataSet.SetFirstGoodBin(static_cast<Int_t>(val));
3120
3121 success = MUD_getHistGoodBin2( fh, i, &val );
3122 if ( !success ) {
3123 std::cerr << std::endl << ">> **WARNING** Couldn't get good bin 2 of histo " << i << " of run " << fRunName.Data();
3124 std::cerr << std::endl;
3125 val = 0;
3126 }
3127 dataSet.SetLastGoodBin(static_cast<Int_t>(val));
3128
3129 // get number of bins
3130 success = MUD_getHistNumBins( fh, i, &val );
3131 if ( !success ) {
3132 std::cerr << std::endl << ">> **ERROR** Couldn't get the number of bins of histo " << i << ".";
3133 std::cerr << std::endl << ">> This is fatal, sorry.";
3134 std::cerr << std::endl;
3135 MUD_closeRead( fh );
3136 return false;
3137 }
3138 noOfBins = static_cast<UInt_t>(val);
3139
3140 pData = (UINT32*)malloc(noOfBins*sizeof(pData));
3141 if (pData == nullptr) {
3142 std::cerr << std::endl << ">> **ERROR** Couldn't allocate memory for data.";
3143 std::cerr << std::endl << ">> This is fatal, sorry.";
3144 std::cerr << std::endl;
3145 MUD_closeRead( fh );
3146 return false;
3147 }
3148
3149 // get histogram
3150 success = MUD_getHistData( fh, i, pData );
3151 if ( !success ) {
3152 std::cerr << std::endl << ">> **ERROR** Couldn't get histo no " << i << ".";
3153 std::cerr << std::endl << ">> This is fatal, sorry.";
3154 std::cerr << std::endl;
3155 MUD_closeRead( fh );
3156 return false;
3157 }
3158
3159 for (UInt_t j=0; j<noOfBins; j++) {
3160 histoData.push_back(pData[j]);
3161 }
3162 dataSet.SetData(histoData);
3163
3164 // estimate T0 from maximum of the data
3165 Double_t maxVal = 0.0;
3166 Int_t maxBin = 0;
3167 for (UInt_t j=0; j<histoData.size(); j++) {
3168 if (histoData[j] > maxVal) {
3169 maxVal = histoData[j];
3170 maxBin = j;
3171 }
3172 }
3173 dataSet.SetTimeZeroBinEstimated(maxBin);
3174
3175 runData.SetDataSet(dataSet);
3176
3177 histoData.clear();
3178
3179 free(pData);
3180 }
3181
3182 MUD_closeRead(fh);
3183
3184 // add run to the run list
3185 fData.push_back(runData);
3186
3187 return true;
3188}
3189
3190//--------------------------------------------------------------------------
3191// ReadMduAsciiFile (private)
3192//--------------------------------------------------------------------------
3220{
3221 Bool_t success = true;
3222
3223 // open file
3224 std::ifstream f;
3225
3226 // open data-file
3227 f.open(fRunPathName.Data(), std::ifstream::in);
3228 if (!f.is_open()) {
3229 std::cerr << std::endl << ">> PRunDataHandler::ReadMduAsciiFile **ERROR** Couldn't open data file (" << fRunPathName.Data() << ") for reading, sorry ...";
3230 std::cerr << std::endl;
3231 return false;
3232 }
3233
3234 PRawRunData runData;
3235
3236 // keep run name
3237 runData.SetRunName(fRunName);
3238
3239 Int_t lineNo = 0;
3240 Char_t instr[512];
3241 TString line, workStr;
3242 Bool_t headerTag = false;
3243 Bool_t dataTag = false;
3244 Int_t dataLineCounter = 0;
3245 TObjString *ostr;
3246 TObjArray *tokens = nullptr;
3247 TString str;
3248 Int_t groups = 0;
3249 Int_t channels = 0;
3250 Double_t dval = 0.0, unitScaling = 0.0;
3251 std::vector<PDoubleVector> data;
3252
3253 while (!f.eof()) {
3254 f.getline(instr, sizeof(instr));
3255 line = TString(instr);
3256 lineNo++;
3257
3258 // ignore comment lines
3259 if (line.BeginsWith("#") || line.BeginsWith("%"))
3260 continue;
3261
3262 // ignore empty lines
3263 if (line.IsWhitespace())
3264 continue;
3265
3266 // check if header tag
3267 workStr = line;
3268 workStr.Remove(TString::kLeading, ' '); // remove spaces from the begining
3269 if (workStr.BeginsWith("header", TString::kIgnoreCase)) {
3270 headerTag = true;
3271 dataTag = false;
3272 continue;
3273 }
3274
3275 // check if data tag
3276 workStr = line;
3277 workStr.Remove(TString::kLeading, ' '); // remove spaces from the beining
3278 if (workStr.BeginsWith("data", TString::kIgnoreCase)) {
3279 headerTag = false;
3280 dataTag = true;
3281 continue;
3282 }
3283
3284 if (headerTag) {
3285 workStr = line;
3286 workStr.Remove(TString::kLeading, ' '); // remove spaces from the beining
3287 if (workStr.BeginsWith("title:", TString::kIgnoreCase)) {
3288 runData.SetRunTitle(TString(workStr.Data()+workStr.First(":")+2));
3289 } else if (workStr.BeginsWith("field:", TString::kIgnoreCase)) {
3290 tokens = workStr.Tokenize(":("); // field: val (units)
3291 // check if expected number of tokens present
3292 if (tokens->GetEntries() != 3) {
3293 std::cerr << std::endl << ">> PRunDataHandler::ReadMduAsciiFile **ERROR** line no " << lineNo << ", invalid field entry in header.";
3294 std::cerr << std::endl << ">> " << line.Data();
3295 std::cerr << std::endl;
3296 success = false;
3297 break;
3298 }
3299 // check if field value is a number
3300 ostr = dynamic_cast<TObjString*>(tokens->At(1));
3301 if (ostr->GetString().IsFloat()) {
3302 dval = ostr->GetString().Atof();
3303 } else {
3304 std::cerr << std::endl << ">> PRunDataHandler::ReadMduAsciiFile **ERROR** line no " << lineNo << ", field value is not float/doulbe.";
3305 std::cerr << std::endl << ">> " << line.Data();
3306 std::cerr << std::endl;
3307 success = false;
3308 break;
3309 }
3310 // check units, accept (G), (T)
3311 ostr = dynamic_cast<TObjString*>(tokens->At(2));
3312 if (ostr->GetString().Contains("G"))
3313 unitScaling = 1.0;
3314 else if (ostr->GetString().Contains("T"))
3315 unitScaling = 1.0e4;
3316 else {
3317 std::cerr << std::endl << ">> PRunDataHandler::ReadMduAsciiFile **ERROR** line no " << lineNo << ", unkown field units.";
3318 std::cerr << std::endl << ">> " << line.Data();
3319 std::cerr << std::endl;
3320 success = false;
3321 break;
3322 }
3323 runData.SetField(dval*unitScaling);
3324
3325 // clean up tokens
3326 if (tokens) {
3327 delete tokens;
3328 tokens = nullptr;
3329 }
3330 } else if (workStr.BeginsWith("temp:", TString::kIgnoreCase)) {
3331 tokens = workStr.Tokenize(":("); // temp: val (units)
3332 // check if expected number of tokens present
3333 if (tokens->GetEntries() != 3) {
3334 std::cerr << std::endl << ">> PRunDataHandler::ReadMduAsciiFile **ERROR** line no " << lineNo << ", invalid temperatue entry in header.";
3335 std::cerr << std::endl << ">> " << line.Data();
3336 std::cerr << std::endl;
3337 success = false;
3338 break;
3339 }
3340 // check if field value is a number
3341 ostr = dynamic_cast<TObjString*>(tokens->At(1));
3342 if (ostr->GetString().IsFloat()) {
3343 dval = ostr->GetString().Atof();
3344 } else {
3345 std::cerr << std::endl << ">> PRunDataHandler::ReadMduAsciiFile **ERROR** line no " << lineNo << ", temperature value is not float/doulbe.";
3346 std::cerr << std::endl << ">> " << line.Data();
3347 std::cerr << std::endl;
3348 success = false;
3349 break;
3350 }
3351 runData.SetTemperature(0, dval, 0.0);
3352
3353 // clean up tokens
3354 if (tokens) {
3355 delete tokens;
3356 tokens = nullptr;
3357 }
3358 } else if (workStr.BeginsWith("setup:", TString::kIgnoreCase)) {
3359 runData.SetSetup(TString(workStr.Data()+workStr.First(":")+2));
3360 } else if (workStr.BeginsWith("groups:", TString::kIgnoreCase)) {
3361 workStr = TString(workStr.Data()+workStr.First(":")+2);
3362 groups = workStr.Atoi();
3363 if (groups == 0) {
3364 std::cerr << std::endl << ">> PRunDataHandler::ReadMduAsciiFile **ERROR** line no " << lineNo << ", groups is not a number or 0.";
3365 std::cerr << std::endl;
3366 success = false;
3367 break;
3368 }
3369 data.resize(groups);
3370 } else if (workStr.BeginsWith("channels:", TString::kIgnoreCase)) {
3371 workStr = TString(workStr.Data()+workStr.First(":")+2);
3372 channels = workStr.Atoi();
3373 if (channels == 0) {
3374 std::cerr << std::endl << ">> PRunDataHandler::ReadMduAsciiFile **ERROR** line no " << lineNo << ", channels is not a number or 0.";
3375 std::cerr << std::endl;
3376 success = false;
3377 break;
3378 }
3379 } else if (workStr.BeginsWith("resolution:", TString::kIgnoreCase)) {
3380 tokens = workStr.Tokenize(":("); // resolution: val (units)
3381 // check if expected number of tokens present
3382 if (tokens->GetEntries() != 3) {
3383 std::cerr << std::endl << ">> PRunDataHandler::ReadMduAsciiFile **ERROR** line no " << lineNo << ", invalid time resolution entry in header.";
3384 std::cerr << std::endl << line.Data();
3385 std::cerr << std::endl;
3386 success = false;
3387 break;
3388 }
3389 // check if timeresolution value is a number
3390 ostr = dynamic_cast<TObjString*>(tokens->At(1));
3391 if (ostr->GetString().IsFloat()) {
3392 dval = ostr->GetString().Atof();
3393 } else {
3394 std::cerr << std::endl << ">> PRunDataHandler::ReadMduAsciiFile **ERROR** line no " << lineNo << ", time resolution value is not float/doulbe.";
3395 std::cerr << std::endl << ">> " << line.Data();
3396 std::cerr << std::endl;
3397 success = false;
3398 break;
3399 }
3400 // check units, accept (fs), (ps), (ns), (us)
3401 ostr = dynamic_cast<TObjString*>(tokens->At(2));
3402 if (ostr->GetString().Contains("fs"))
3403 unitScaling = 1.0e-6;
3404 else if (ostr->GetString().Contains("ps"))
3405 unitScaling = 1.0e-3;
3406 else if (ostr->GetString().Contains("ns"))
3407 unitScaling = 1.0;
3408 else if (ostr->GetString().Contains("us"))
3409 unitScaling = 1.0e3;
3410 else {
3411 std::cerr << std::endl << ">> PRunDataHandler::ReadMduAsciiFile **ERROR** line no " << lineNo << ", unkown time resolution units.";
3412 std::cerr << std::endl << ">> " << line.Data();
3413 std::cerr << std::endl;
3414 success = false;
3415 break;
3416 }
3417 runData.SetTimeResolution(dval*unitScaling);
3418
3419 // clean up tokens
3420 if (tokens) {
3421 delete tokens;
3422 tokens = nullptr;
3423 }
3424 } else { // error
3425 std::cerr << std::endl << ">> PRunDataHandler::ReadMduAsciiFile **ERROR** line no " << lineNo << ", illegal header line.";
3426 std::cerr << std::endl;
3427 success = false;
3428 break;
3429 }
3430 } else if (dataTag) {
3431 dataLineCounter++;
3432 tokens = line.Tokenize(" ,\t");
3433 // check if the number of data line entries is correct
3434 if (tokens->GetEntries() != groups+1) {
3435 std::cerr << std::endl << ">> PRunDataHandler::ReadMduAsciiFile **ERROR** found data line with a wrong data format, cannot be handled (line no " << lineNo << ")";
3436 std::cerr << std::endl << ">> line:";
3437 std::cerr << std::endl << ">> " << line.Data();
3438 std::cerr << std::endl;
3439 success = false;
3440 break;
3441 }
3442
3443 for (Int_t i=1; i<tokens->GetEntries(); i++) {
3444 ostr = dynamic_cast<TObjString*>(tokens->At(i));
3445 data[i-1].push_back(ostr->GetString().Atof());
3446 }
3447
3448 // clean up tokens
3449 if (tokens) {
3450 delete tokens;
3451 tokens = nullptr;
3452 }
3453 }
3454 }
3455
3456 f.close();
3457
3458 // keep data
3459 PRawRunDataSet dataSet;
3460 for (UInt_t i=0; i<data.size(); i++) {
3461 dataSet.Clear();
3462 dataSet.SetHistoNo(i);
3463 dataSet.SetData(data[i]);
3464
3465 // estimate T0 from maximum of the data
3466 Double_t maxVal = 0.0;
3467 Int_t maxBin = 0;
3468 for (UInt_t j=0; j<data[i].size(); j++) {
3469 if (data[i][j] > maxVal) {
3470 maxVal = data[i][j];
3471 maxBin = j;
3472 }
3473 }
3474 dataSet.SetTimeZeroBinEstimated(maxBin);
3475 runData.SetDataSet(dataSet);
3476 }
3477
3478 // clean up
3479 for (UInt_t i=0; i<data.size(); i++)
3480 data[i].clear();
3481 data.clear();
3482
3483 if (dataLineCounter != channels) {
3484 std::cerr << std::endl << ">> PRunDataHandler::ReadMduAsciiFile **WARNING** found " << dataLineCounter << " data bins,";
3485 std::cerr << std::endl << ">> expected " << channels << " according to the header." << std::endl;
3486 }
3487
3488 fData.push_back(runData);
3489
3490 return success;
3491}
3492
3493//--------------------------------------------------------------------------
3494// ReadAsciiFile (private)
3495//--------------------------------------------------------------------------
3533{
3534 Bool_t success = true;
3535
3536 // open file
3537 std::ifstream f;
3538
3539 // open data-file
3540 f.open(fRunPathName.Data(), std::ifstream::in);
3541 if (!f.is_open()) {
3542 std::cerr << std::endl << ">> PRunDataHandler::ReadAsciiFile **ERROR** Couldn't open data file (" << fRunPathName.Data() << ") for reading, sorry ...";
3543 std::cerr << std::endl;
3544 return false;
3545 }
3546
3547 PRawRunData runData;
3548
3549 // init some stuff
3550 runData.fDataNonMusr.SetFromAscii(true);
3551 runData.fDataNonMusr.AppendLabel("??"); // x default label
3552 runData.fDataNonMusr.AppendLabel("??"); // y default label
3553
3554 runData.SetRunName(fRunName); // keep the run name
3555
3556 Int_t lineNo = 0;
3557 Char_t instr[512];
3558 TString line, workStr;
3559 Bool_t headerTag = false;
3560 Bool_t dataTag = false;
3561 Double_t x, y, ey;
3562 PDoubleVector xVec, exVec, yVec, eyVec;
3563
3564 while (!f.eof()) {
3565 f.getline(instr, sizeof(instr));
3566 line = TString(instr);
3567 lineNo++;
3568
3569 // check if comment line
3570 if (line.BeginsWith("#") || line.BeginsWith("%"))
3571 continue;
3572
3573 // check if header tag
3574 workStr = line;
3575 workStr.Remove(TString::kLeading, ' '); // remove spaces from the begining
3576 if (workStr.BeginsWith("header", TString::kIgnoreCase)) {
3577 headerTag = true;
3578 dataTag = false;
3579 continue;
3580 }
3581
3582 // check if data tag
3583 workStr = line;
3584 workStr.Remove(TString::kLeading, ' '); // remove spaces from the beining
3585 if (workStr.BeginsWith("data", TString::kIgnoreCase)) {
3586 headerTag = false;
3587 dataTag = true;
3588 continue;
3589 }
3590
3591 if (headerTag) {
3592 if (line.IsWhitespace()) // ignore empty lines
3593 continue;
3594 workStr = line;
3595 workStr.Remove(TString::kLeading, ' '); // remove spaces from the beining
3596 if (workStr.BeginsWith("title:", TString::kIgnoreCase)) {
3597 runData.SetRunTitle(TString(workStr.Data()+workStr.First(":")+2));
3598 } else if (workStr.BeginsWith("setup:", TString::kIgnoreCase)) {
3599 runData.SetSetup(TString(workStr.Data()+workStr.First(":")+2));
3600 } else if (workStr.BeginsWith("field:", TString::kIgnoreCase)) {
3601 workStr = TString(workStr.Data()+workStr.First(":")+2);
3602 if (!workStr.IsFloat()) {
3603 std::cerr << std::endl << ">> PRunDataHandler::ReadAsciiFile **ERROR** line no " << lineNo << ", field is not a number.";
3604 std::cerr << std::endl;
3605 success = false;
3606 break;
3607 }
3608 runData.SetField(workStr.Atof());
3609 } else if (workStr.BeginsWith("x-axis-title:", TString::kIgnoreCase)) {
3610 runData.fDataNonMusr.SetLabel(0, TString(workStr.Data()+workStr.First(":")+2));
3611 } else if (workStr.BeginsWith("y-axis-title:", TString::kIgnoreCase)) {
3612 runData.fDataNonMusr.SetLabel(1, TString(workStr.Data()+workStr.First(":")+2));
3613 } else if (workStr.BeginsWith("temp:", TString::kIgnoreCase)) {
3614 workStr = TString(workStr.Data()+workStr.First(":")+2);
3615 if (!workStr.IsFloat()) {
3616 std::cerr << std::endl << ">> PRunDataHandler::ReadAsciiFile **ERROR** line no " << lineNo << ", temperature is not a number.";
3617 std::cerr << std::endl;
3618 success = false;
3619 break;
3620 }
3621 runData.SetTemperature(0, workStr.Atof(), 0.0);
3622 } else if (workStr.BeginsWith("energy:", TString::kIgnoreCase)) {
3623 workStr = TString(workStr.Data()+workStr.First(":")+2);
3624 if (!workStr.IsFloat()) {
3625 std::cerr << std::endl << ">> PRunDataHandler::ReadAsciiFile **ERROR** line no " << lineNo << ", energy is not a number.";
3626 std::cerr << std::endl;
3627 success = false;
3628 break;
3629 }
3630 runData.SetEnergy(workStr.Atof());
3631 runData.SetTransport(PMUSR_UNDEFINED); // just to initialize the variables to some "meaningful" value
3632 } else { // error
3633 std::cerr << std::endl << ">> PRunDataHandler::ReadAsciiFile **ERROR** line no " << lineNo << ", illegal header line.";
3634 std::cerr << std::endl;
3635 success = false;
3636 break;
3637 }
3638 } else if (dataTag) {
3639 if (line.IsWhitespace()) // ignore empty lines
3640 continue;
3641 TObjString *ostr;
3642 TObjArray *tokens;
3643
3644 // Remove trailing end of line
3645 line.Remove(TString::kTrailing, '\r');
3646
3647 // check if data have x, y [, error y] structure, and that x, y, and error y are numbers
3648 tokens = line.Tokenize(" ,\t");
3649 // check if the number of data line entries is 2 or 3
3650 if ((tokens->GetEntries() != 2) && (tokens->GetEntries() != 3)) {
3651 std::cerr << std::endl << ">> PRunDataHandler::ReadAsciiFile **ERROR** found data line with a structure different than \"x, y [, error y]\", cannot be handled (line no " << lineNo << ")";
3652 std::cerr << std::endl;
3653 success = false;
3654 break;
3655 }
3656
3657 // get x
3658 ostr = dynamic_cast<TObjString*>(tokens->At(0));
3659 if (!ostr->GetString().IsFloat()) {
3660 std::cerr << std::endl << ">> PRunDataHandler::ReadAsciiFile **ERROR** line no " << lineNo << ": x = " << ostr->GetString().Data() << " is not a number, sorry.";
3661 std::cerr << std::endl;
3662 success = false;
3663 break;
3664 }
3665 x = ostr->GetString().Atof();
3666
3667 // get y
3668 ostr = dynamic_cast<TObjString*>(tokens->At(1));
3669 if (!ostr->GetString().IsFloat()) {
3670 std::cerr << std::endl << ">> PRunDataHandler::ReadAsciiFile **ERROR** line no " << lineNo << ": y = " << ostr->GetString().Data() << " is not a number, sorry.";
3671 std::cerr << std::endl;
3672 success = false;
3673 break;
3674 }
3675 y = ostr->GetString().Atof();
3676
3677 // get error y if present
3678 if (tokens->GetEntries() == 3) {
3679 ostr = dynamic_cast<TObjString*>(tokens->At(2));
3680 if (!ostr->GetString().IsFloat()) {
3681 std::cerr << std::endl << ">> PRunDataHandler::ReadAsciiFile **ERROR** line no " << lineNo << ": error y = " << ostr->GetString().Data() << " is not a number, sorry.";
3682 std::cerr << std::endl;
3683 success = false;
3684 break;
3685 }
3686 ey = ostr->GetString().Atof();
3687 if (ey == 0) {
3688 std::cerr << std::endl << ">> PRunDataHandler::ReadAsciiFile **WARNING** line no " << lineNo << ": error y = 0 which doesn't make sense. Will set it to 1.0. Please check!!";
3689 std::cerr << std::endl;
3690 ey = 1.0;
3691 }
3692 } else {
3693 std::cerr << std::endl << ">> PRunDataHandler::ReadAsciiFile **WARNING** line no " << lineNo << ": error y = 0 which doesn't make sense. Will set it to 1.0. Please check!!";
3694 std::cerr << std::endl;
3695 ey = 1.0;
3696 }
3697
3698 // clean up tokens
3699 if (tokens) {
3700 delete tokens;
3701 tokens = nullptr;
3702 }
3703
3704 // keep values
3705 xVec.push_back(x);
3706 exVec.push_back(1.0);
3707 yVec.push_back(y);
3708 eyVec.push_back(ey);
3709
3710 } else {
3711 std::cerr << std::endl << ">> PRunDataHandler::ReadAsciiFile **ERROR** line no " << lineNo << " neither header nor data line. No idea how to handle it!";
3712 std::cerr << std::endl;
3713 success = false;
3714 break;
3715 }
3716 }
3717
3718 f.close();
3719
3720 // keep values
3721 runData.fDataNonMusr.AppendData(xVec);
3722 runData.fDataNonMusr.AppendErrData(exVec);
3723 runData.fDataNonMusr.AppendData(yVec);
3724 runData.fDataNonMusr.AppendErrData(eyVec);
3725
3726 fData.push_back(runData);
3727
3728 // clean up
3729 xVec.clear();
3730 exVec.clear();
3731 yVec.clear();
3732 eyVec.clear();
3733
3734 return success;
3735}
3736
3737//--------------------------------------------------------------------------
3738// ReadDBFile (private)
3739//--------------------------------------------------------------------------
3851{
3852 Bool_t success = true;
3853
3854 // open file
3855 std::ifstream f;
3856
3857 // open db-file
3858 f.open(fRunPathName.Data(), std::ifstream::in);
3859 if (!f.is_open()) {
3860 std::cerr << std::endl << ">> PRunDataHandler::ReadDBFile **ERROR** Couldn't open data file (" << fRunPathName.Data() << ") for reading, sorry ...";
3861 std::cerr << std::endl;
3862 return false;
3863 }
3864
3865 PRawRunData runData;
3866
3867 runData.fDataNonMusr.SetFromAscii(false);
3868
3869 Int_t lineNo = 0;
3870 Int_t idx;
3871 Int_t dbTag = -1;
3872 Char_t instr[512];
3873 TString line, workStr;
3874 Double_t val;
3875 Bool_t firstData = true; // needed as a switch to check in which format the data are given.
3876 Bool_t labelledFormat = true; // flag showing if the data are given in row format, or as labelled format (see description above, default is labelled format)
3877 Bool_t dataTagsRead = false; // flag showing if the data tags are alread read
3878
3879 // variables needed to tokenize strings
3880 TString tstr;
3881 TObjString *ostr;
3882 TObjArray *tokens = nullptr;
3883
3884 while (!f.eof()) {
3885 // get next line from file
3886 f.getline(instr, sizeof(instr));
3887 line = TString(instr);
3888 lineNo++;
3889
3890 // check if comment line
3891 if (line.BeginsWith("#") || line.BeginsWith("%"))
3892 continue;
3893
3894 // ignore empty lines
3895 if (line.IsWhitespace())
3896 continue;
3897
3898 // check for db specific tags
3899 workStr = line;
3900 workStr.Remove(TString::kLeading, ' '); // remove spaces from the begining
3901 if (workStr.BeginsWith("title", TString::kIgnoreCase)) {
3902 dbTag = 0;
3903 continue;
3904 } else if (workStr.BeginsWith("abstract", TString::kIgnoreCase)) {
3905 dbTag = 1;
3906 continue;
3907 } else if (workStr.BeginsWith("comments", TString::kIgnoreCase)) {
3908 dbTag = 2;
3909 continue;
3910 } else if (workStr.BeginsWith("label", TString::kIgnoreCase)) {
3911 dbTag = 3;
3912 continue;
3913 } else if (workStr.BeginsWith("data", TString::kIgnoreCase) && !dataTagsRead) {
3914 dataTagsRead = true;
3915 dbTag = 4;
3916
3917 // filter out all data tags
3918 tokens = workStr.Tokenize(" ,\t");
3919 for (Int_t i=1; i<tokens->GetEntries(); i++) {
3920 ostr = dynamic_cast<TObjString*>(tokens->At(i));
3921 runData.fDataNonMusr.AppendDataTag(ostr->GetString());
3922 }
3923
3924 // clean up tokens
3925 if (tokens) {
3926 delete tokens;
3927 tokens = nullptr;
3928 }
3929 continue;
3930 }
3931
3932 switch (dbTag) {
3933 case 0: // TITLE
3934 runData.SetRunTitle(workStr);
3935 break;
3936 case 1: // ABSTRACT
3937 // nothing to be done for now
3938 break;
3939 case 2: // COMMENTS
3940 // nothing to be done for now
3941 break;
3942 case 3: // LABEL
3943 runData.fDataNonMusr.AppendLabel(workStr);
3944 break;
3945 case 4: // DATA
3946 // filter out potential start data tag
3947 if (workStr.BeginsWith("\\-e", TString::kIgnoreCase) ||
3948 workStr.BeginsWith("\\e", TString::kIgnoreCase) ||
3949 workStr.BeginsWith("/-e", TString::kIgnoreCase) ||
3950 workStr.BeginsWith("/e", TString::kIgnoreCase)) {
3951 continue;
3952 }
3953
3954 // check if first real data line
3955 if (firstData) {
3956 // check if data are given just as rows are as labelled columns (see description above)
3957 tokens = workStr.Tokenize(",");
3958 ostr = dynamic_cast<TObjString*>(tokens->At(0));
3959 if (!ostr->GetString().IsFloat()) {
3960 labelledFormat = true;
3961 } else {
3962 labelledFormat = false;
3963 }
3964 // clean up tokens
3965 if (tokens) {
3966 delete tokens;
3967 tokens = nullptr;
3968 }
3969
3970 // prepare data vector for use
3971 PDoubleVector dummy;
3972 for (UInt_t i=0; i<runData.fDataNonMusr.GetDataTags()->size(); i++) {
3973 runData.fDataNonMusr.AppendData(dummy);
3974 runData.fDataNonMusr.AppendErrData(dummy);
3975 }
3976
3977 firstData = false;
3978 }
3979
3980 if (labelledFormat) { // handle labelled formated data
3981 // check if run line
3982 const Char_t *str = workStr.Data();
3983 if (isdigit(str[0])) { // run line
3984 TString run("run");
3985 idx = GetDataTagIndex(run, runData.fDataNonMusr.GetDataTags());
3986 if (idx == -1) {
3987 std::cerr << std::endl << ">> PRunDataHandler::ReadDBFile **ERROR** in line no " << lineNo << ":";
3988 std::cerr << std::endl << ">> " << workStr.Data();
3989 std::cerr << std::endl << ">> found potential run data line without run data tag.";
3990 return false;
3991 }
3992 // split string in tokens
3993 tokens = workStr.Tokenize(","); // line has structure: runNo,,, runTitle
3994 ostr = dynamic_cast<TObjString*>(tokens->At(0));
3995 tstr = ostr->GetString();
3996 if (!tstr.IsFloat()) {
3997 std::cerr << std::endl << ">> PRunDataHandler::ReadDBFile **ERROR** in line no " << lineNo << ":";
3998 std::cerr << std::endl << ">> " << workStr.Data();
3999 std::cerr << std::endl << ">> Expected db-data line with structure: runNo,,, runTitle";
4000 std::cerr << std::endl << ">> runNo = " << tstr.Data() << ", seems to be not a number.";
4001 delete tokens;
4002 return false;
4003 }
4004 val = tstr.Atof();
4005 runData.fDataNonMusr.AppendSubData(idx, val);
4006 runData.fDataNonMusr.AppendSubErrData(idx, 1.0);
4007 } else { // tag = data line
4008 // remove all possible spaces
4009 workStr.ReplaceAll(" ", "");
4010 // split string in tokens
4011 tokens = workStr.Tokenize("=,"); // line has structure: tag = val,err1,err2,
4012 if (tokens->GetEntries() < 3) {
4013 std::cerr << std::endl << ">> PRunDataHandler::ReadDBFile **ERROR** in line no " << lineNo << ":";
4014 std::cerr << std::endl << ">> " << workStr.Data();
4015 std::cerr << std::endl << ">> Expected db-data line with structure: tag = val,err1,err2,\\";
4016 delete tokens;
4017 return false;
4018 }
4019 ostr = dynamic_cast<TObjString*>(tokens->At(0));
4020 tstr = ostr->GetString();
4021 idx = GetDataTagIndex(tstr, runData.fDataNonMusr.GetDataTags());
4022 if (idx == -1) {
4023 std::cerr << std::endl << ">> PRunDataHandler::ReadDBFile **ERROR** in line no " << lineNo << ":";
4024 std::cerr << std::endl << ">> " << workStr.Data();
4025 std::cerr << std::endl << ">> data tag error: " << tstr.Data() << " seems not present in the data tag list";
4026 delete tokens;
4027 return false;
4028 }
4029
4030 switch (tokens->GetEntries()) {
4031 case 3: // tag = val,,,
4032 ostr = dynamic_cast<TObjString*>(tokens->At(1));
4033 tstr = ostr->GetString();
4034 if (!tstr.IsFloat()) {
4035 std::cerr << std::endl << ">> PRunDataHandler::ReadDBFile **ERROR** in line no " << lineNo << ":";
4036 std::cerr << std::endl << ">> " << workStr.Data();
4037 std::cerr << std::endl << ">> Expected db-data line with structure: tag = val,err1,err2,\\";
4038 std::cerr << std::endl << ">> val = " << tstr.Data() << ", seems to be not a number.";
4039 delete tokens;
4040 return false;
4041 }
4042 val = tstr.Atof();
4043 runData.fDataNonMusr.AppendSubData(idx, val);
4044 runData.fDataNonMusr.AppendSubErrData(idx, 1.0);
4045 break;
4046 case 4: // tag = val,err,,
4047 case 5: // tag = val,err1,err2,
4048 // handle val
4049 ostr = dynamic_cast<TObjString*>(tokens->At(1));
4050 tstr = ostr->GetString();
4051 if (!tstr.IsFloat()) {
4052 std::cerr << std::endl << ">> PRunDataHandler::ReadDBFile **ERROR** in line no " << lineNo << ":";
4053 std::cerr << std::endl << ">> " << workStr.Data();
4054 std::cerr << std::endl << ">> Expected db-data line with structure: tag = val,err1,err2,\\";
4055 std::cerr << std::endl << ">> val = " << tstr.Data() << ", seems to be not a number.";
4056 delete tokens;
4057 return false;
4058 }
4059 val = tstr.Atof();
4060 runData.fDataNonMusr.AppendSubData(idx, val);
4061 // handle err1 (err2 will be ignored for the time being)
4062 ostr = dynamic_cast<TObjString*>(tokens->At(2));
4063 tstr = ostr->GetString();
4064 if (!tstr.IsFloat()) {
4065 std::cerr << std::endl << ">> PRunDataHandler::ReadDBFile **ERROR** in line no " << lineNo << ":";
4066 std::cerr << std::endl << ">> " << workStr.Data();
4067 std::cerr << std::endl << ">> Expected db-data line with structure: tag = val,err1,err2,\\";
4068 std::cerr << std::endl << ">> err1 = " << tstr.Data() << ", seems to be not a number.";
4069 delete tokens;
4070 return false;
4071 }
4072 val = tstr.Atof();
4073 runData.fDataNonMusr.AppendSubErrData(idx, val);
4074 break;
4075 default:
4076 std::cerr << std::endl << ">> PRunDataHandler::ReadDBFile **ERROR** in line no " << lineNo << ":";
4077 std::cerr << std::endl << ">> " << workStr.Data();
4078 std::cerr << std::endl << ">> Expected db-data line with structure: tag = val,err1,err2,\\";
4079 delete tokens;
4080 return false;
4081 }
4082 }
4083
4084 } else { // handle row formated data
4085 // split string in tokens
4086 tokens = workStr.Tokenize(","); // line has structure: val1, err11, err12, ..., valn, errn1, errn2, runNo, , , , runTitle
4087 if (tokens->GetEntries() != static_cast<Int_t>(3*runData.fDataNonMusr.GetDataTags()->size()+1)) {
4088 std::cerr << std::endl << ">> PRunDataHandler::ReadDBFile **ERROR** in line no " << lineNo << ":";
4089 std::cerr << std::endl << ">> " << workStr.Data();
4090 std::cerr << std::endl << ">> Expected db-data line with structure: val1, err11, err12, ..., valn, errn1, errn2, runNo, , , , runTitle";
4091 std::cerr << std::endl << ">> found = " << tokens->GetEntries() << " tokens, however expected " << 3*runData.fDataNonMusr.GetDataTags()->size()+1;
4092 std::cerr << std::endl << ">> Perhaps there are commas without space inbetween, like 12.3,, 3.2,...";
4093 delete tokens;
4094 return false;
4095 }
4096 // extract data
4097 Int_t j=0;
4098 for (Int_t i=0; i<tokens->GetEntries()-1; i+=3) {
4099 // handle value
4100 ostr = dynamic_cast<TObjString*>(tokens->At(i));
4101 tstr = ostr->GetString();
4102 if (!tstr.IsFloat()) {
4103 std::cerr << std::endl << ">> PRunDataHandler::ReadDBFile **ERROR** in line no " << lineNo << ":";
4104 std::cerr << std::endl << ">> " << workStr.Data();
4105 std::cerr << std::endl << ">> Expected db-data line with structure: val1, err11, err12, ..., valn, errn1, errn2, runNo, , , , runTitle";
4106 std::cerr << std::endl << ">> value=" << tstr.Data() << " seems not to be a number";
4107 delete tokens;
4108 return false;
4109 }
4110 runData.fDataNonMusr.AppendSubData(j, tstr.Atof());
4111
4112 // handle 1st error if present (2nd will be ignored for now)
4113 ostr = dynamic_cast<TObjString*>(tokens->At(i+1));
4114 tstr = ostr->GetString();
4115 if (tstr.IsWhitespace()) {
4116 runData.fDataNonMusr.AppendSubErrData(j, 1.0);
4117 } else if (tstr.IsFloat()) {
4118 runData.fDataNonMusr.AppendSubErrData(j, tstr.Atof());
4119 } else {
4120 std::cerr << std::endl << ">> PRunDataHandler::ReadDBFile **ERROR** in line no " << lineNo << ":";
4121 std::cerr << std::endl << ">> " << workStr.Data();
4122 std::cerr << std::endl << ">> Expected db-data line with structure: val1, err11, err12, ..., valn, errn1, errn2, runNo, , , , runTitle";
4123 std::cerr << std::endl << ">> error1=" << tstr.Data() << " seems not to be a number";
4124 delete tokens;
4125 return false;
4126 }
4127 j++;
4128 }
4129 }
4130 break;
4131 default:
4132 break;
4133 }
4134 }
4135
4136 f.close();
4137
4138 // check that the number of labels == the number of data tags
4139 if (runData.fDataNonMusr.GetLabels()->size() != runData.fDataNonMusr.GetDataTags()->size()) {
4140 std::cerr << std::endl << ">> PRunDataHandler::ReadDBFile **ERROR**";
4141 std::cerr << std::endl << ">> number of LABELS found = " << runData.fDataNonMusr.GetLabels()->size();
4142 std::cerr << std::endl << ">> number of Data tags found = " << runData.fDataNonMusr.GetDataTags()->size();
4143 std::cerr << std::endl << ">> They have to be equal!!";
4144 if (tokens) {
4145 delete tokens;
4146 tokens = nullptr;
4147 }
4148 return false;
4149 }
4150
4151 // check if all vectors have the same size
4152 for (UInt_t i=1; i<runData.fDataNonMusr.GetData()->size(); i++) {
4153 if (runData.fDataNonMusr.GetData()->at(i).size() != runData.fDataNonMusr.GetData()->at(i-1).size()) {
4154 std::cerr << std::endl << ">> PRunDataHandler::ReadDBFile **ERROR** in line no " << lineNo;
4155 std::cerr << std::endl << ">> label: " << runData.fDataNonMusr.GetDataTags()->at(i-1).Data() << ", number data elements = " << runData.fDataNonMusr.GetData()->at(i-1).size();
4156 std::cerr << std::endl << ">> label: " << runData.fDataNonMusr.GetDataTags()->at(i).Data() << ", number data elements = " << runData.fDataNonMusr.GetData()->at(i).size();
4157 std::cerr << std::endl << ">> They have to be equal!!";
4158 success = false;
4159 break;
4160 }
4161 if (runData.fDataNonMusr.GetErrData()->at(i).size() != runData.fDataNonMusr.GetErrData()->at(i-1).size()) {
4162 std::cerr << std::endl << ">> PRunDataHandler::ReadDBFile **ERROR** in line no " << lineNo;
4163 std::cerr << std::endl << ">> label: " << runData.fDataNonMusr.GetDataTags()->at(i-1).Data() << ", number data elements = " << runData.fDataNonMusr.GetData()->at(i-1).size();
4164 std::cerr << std::endl << ">> label: " << runData.fDataNonMusr.GetDataTags()->at(i).Data() << ", number error data elements = " << runData.fDataNonMusr.GetErrData()->at(i).size();
4165 std::cerr << std::endl << ">> They have to be equal!!";
4166 success = false;
4167 break;
4168 }
4169 }
4170
4171 // clean up tokens
4172 if (tokens) {
4173 delete tokens;
4174 tokens = nullptr;
4175 }
4176
4177 // keep run name
4178 runData.SetRunName(fRunName);
4179
4180 fData.push_back(runData);
4181
4182 return success;
4183}
4184
4185//--------------------------------------------------------------------------
4186// ReadDatFile (private)
4187//--------------------------------------------------------------------------
4197{
4198 Bool_t success = true;
4199
4200 // open file
4201 std::ifstream f;
4202
4203 // open dat-file
4204 f.open(fRunPathName.Data(), std::ifstream::in);
4205 if (!f.is_open()) {
4206 std::cerr << std::endl << ">> PRunDataHandler::ReadDatFile **ERROR** Couldn't open data file (" << fRunPathName.Data() << ") for reading, sorry ...";
4207 std::cerr << std::endl;
4208 return false;
4209 }
4210
4211 PRawRunData runData;
4212 runData.fDataNonMusr.SetFromAscii(false);
4213
4214 Int_t lineNo = 0;
4215 Char_t instr[4096];
4216 TString line;
4217 Bool_t headerInfo=true;
4218
4219 // variables needed to tokenize strings
4220 TString tstr;
4221 TObjString *ostr;
4222 TObjArray *tokens = nullptr;
4223
4224 UInt_t noOfDataSets = 0, noOfEntries = 0;
4225 PBoolVector isData;
4226 Double_t dval;
4227
4228 while (!f.eof()) {
4229 // get next line from file
4230 f.getline(instr, sizeof(instr));
4231 line = TString(instr);
4232 lineNo++;
4233
4234 // check if comment line
4235 if (line.BeginsWith("#") || line.BeginsWith("%"))
4236 continue;
4237
4238 // ignore empty lines
4239 if (line.IsWhitespace())
4240 continue;
4241
4242 tokens = line.Tokenize(" \t");
4243 if (tokens == nullptr) { // error
4244 std::cerr << std::endl << ">> PRunDataHandler::ReadDatFile **ERROR** couldn't tokenize the line, in lineNo: " << lineNo;
4245 std::cerr << std::endl << ">> line: '" << line << "'.";
4246 std::cerr << std::endl;
4247 return false;
4248 }
4249
4250 // filter header information
4251 if (headerInfo) {
4252 headerInfo = false;
4253
4254 // filter out all data tags: this labels are used in the msr-file to select the proper data set
4255 // for the dat-files, label and dataTag are the same
4256 noOfEntries = tokens->GetEntries();
4257 for (Int_t i=0; i<noOfEntries; i++) {
4258 ostr = dynamic_cast<TObjString*>(tokens->At(i));
4259 tstr = ostr->GetString();
4260 if (!tstr.EndsWith("Err", TString::kExact)) {
4261 noOfDataSets++;
4262 isData.push_back(true);
4263 runData.fDataNonMusr.AppendDataTag(tstr);
4264 runData.fDataNonMusr.AppendLabel(tstr);
4265 } else {
4266 isData.push_back(false);
4267 }
4268 }
4269 // set the size for the data
4270 runData.fDataNonMusr.SetSize(noOfDataSets);
4271 } else { // deal with data
4272 if (noOfEntries == 0) {
4273 std::cerr << std::endl << ">> PRunDataHandler::ReadDatFile **ERROR** header information is missing.";
4274 std::cerr << std::endl;
4275 return false;
4276 }
4277 if (tokens->GetEntries() != noOfEntries) { // error
4278 std::cerr << std::endl << ">> PRunDataHandler::ReadDatFile **ERROR** data set with wrong number of entries: " << tokens->GetEntries() << ", should be " << noOfEntries << ".";
4279 std::cerr << std::endl << ">> in line: " << lineNo;
4280 std::cerr << std::endl << ">> line: '" << line << "'.";
4281 std::cerr << std::endl;
4282 return false;
4283 }
4284 // fill data and dataErr sets
4285 UInt_t idx = 0;
4286 for (UInt_t i=0; i<noOfEntries; i++) {
4287 // 1st: check that entry is indeed a number
4288 ostr = dynamic_cast<TObjString*>(tokens->At(i));
4289 tstr = ostr->GetString();
4290 if (!tstr.IsFloat()) { // make sure it is a number
4291 std::cerr << std::endl << ">> PRunDataHandler::ReadDatFile **ERROR** data set entry is not a number: " << tstr.Data();
4292 std::cerr << std::endl << ">> in line: " << lineNo;
4293 std::cerr << std::endl;
4294 return false;
4295 }
4296 dval = tstr.Atof();
4297 if (isData[i]) {
4298 runData.fDataNonMusr.AppendSubData(idx, dval);
4299 idx++;
4300 } else { // error value
4301 if (isData[i-1] == 1) { // Err or PosErr hence keep it
4302 if (dval == 0.0) {
4303 std::cout << std::endl << ">> PRunDataHandler::ReadDatFile **WARNING** found Err value = 0. Doesn't make sense! Will set it to 1. Please check!";
4304 std::cerr << std::endl << ">> in line: " << lineNo;
4305 std::cerr << std::endl;
4306 dval = 1.0;
4307 }
4308 runData.fDataNonMusr.AppendSubErrData(idx-1, dval);
4309 }
4310 }
4311 }
4312 }
4313 // cleanup
4314 if (tokens) {
4315 delete tokens;
4316 tokens = nullptr;
4317 }
4318 }
4319
4320 f.close();
4321
4322 // got through all the data sets and if there is NO error vector set it to '1.0'
4323 for (UInt_t i=0; i<noOfDataSets; i++) {
4324 if (runData.fDataNonMusr.GetErrData()->at(i).size() == 0) {
4325 for (UInt_t j=0; j<runData.fDataNonMusr.GetData()->at(i).size(); j++) {
4326 runData.fDataNonMusr.AppendSubErrData(i, 1.0);
4327 }
4328 }
4329 }
4330
4331 // keep run name
4332 runData.SetRunName(fRunName);
4333
4334 fData.push_back(runData);
4335
4336 return success;
4337}
4338
4339//--------------------------------------------------------------------------
4340// WriteMusrRootFile (private)
4341//--------------------------------------------------------------------------
4350Bool_t PRunDataHandler::WriteMusrRootFile(Int_t tag, TString fln)
4351{
4352 Bool_t ok = false;
4353 fln = GenerateOutputFileName(fln, ".root", ok);
4354 if (!ok)
4355 return false;
4356
4357 if (!fAny2ManyInfo->useStandardOutput)
4358 std::cout << std::endl << ">> PRunDataHandler::WriteMusrRootFile(): writing a root data file (" << fln.Data() << ") ... " << std::endl;
4359
4360 // write file
4361 std::unique_ptr<TFile> fout = std::make_unique<TFile>(fln, "RECREATE", fln);
4362 if (fout == nullptr) {
4363 std::cerr << std::endl << "PRunDataHandler::WriteMusrRootFile(): **ERROR** Couldn't create ROOT file '" << fln << "'" << std::endl;
4364 return false;
4365 }
4366 fout->cd();
4367
4368 // generate data file
4369 std::unique_ptr<TMusrRunHeader> header = std::make_unique<TMusrRunHeader>(true);
4370 TFolder *histosFolder, *decayAnaModule, *runHeader;
4371 TDirectory *histosDir, *decayAnaDir, *runHeaderDir;
4372 if (tag == A2M_MUSR_ROOT) { // TFolder
4373 histosFolder = new TFolder("histos", "Histograms");
4374 decayAnaModule = histosFolder->AddFolder("DecayAnaModule", "muSR decay histograms");
4375 runHeader = new TFolder("RunHeader", "MusrRoot Run Header Info");
4376 } else { // TDirectory
4377 histosDir = fout->mkdir("histos");
4378 decayAnaDir = histosDir->mkdir("decayAnaModule");
4379 runHeaderDir = fout->mkdir("RunHeader");
4380 }
4381
4382 // feed header info
4383 TString str, pathName;
4384 Int_t ival;
4385 Double_t dval[2];
4386 time_t start{0}, stop{0};
4387 Bool_t valid{false};
4389
4390 // feed RunInfo
4391 str = fData[0].GetGenericValidatorUrl()->Copy();
4392 header->Set("RunInfo/Generic Validator URL", str);
4393 str = fData[0].GetSpecificValidatorUrl()->Copy();
4394 header->Set("RunInfo/Specific Validator URL", str);
4395 str = fData[0].GetGenerator()->Copy();
4396 header->Set("RunInfo/Generator", str);
4397 str = fData[0].GetFileName()->Copy();
4398 header->Set("RunInfo/File Name", str);
4399 str = fData[0].GetRunTitle()->Copy();
4400 header->Set("RunInfo/Run Title", str);
4401 header->Set("RunInfo/Run Number", fData[0].GetRunNumber());
4402 str = fData[0].GetStartDate()->Copy() + " " + fData[0].GetStartTime()->Copy();
4403 header->Set("RunInfo/Run Start Time", str);
4404 str = fData[0].GetStopDate()->Copy() + " " + fData[0].GetStopTime()->Copy();
4405 header->Set("RunInfo/Run Stop Time", str);
4406 start = fData[0].CalcStartDateTime(valid);
4407 if (valid)
4408 stop = fData[0].CalcStopDateTime(valid);
4409 if (valid)
4410 ival = (int)stop - (int)start;
4411 prop.Set("Run Duration", ival, "sec");
4412 header->Set("RunInfo/Run Duration", prop);
4413 str = fData[0].GetLaboratory()->Copy();
4414 header->Set("RunInfo/Laboratory", str);
4415 str = fData[0].GetInstrument()->Copy();
4416 header->Set("RunInfo/Instrument", str);
4417 dval[0] = fData[0].GetMuonBeamMomentum();
4418 prop.Set("Muon Beam Momentum", dval[0], "MeV/c");
4419 header->Set("RunInfo/Muon Beam Momentum", prop);
4420 str = fData[0].GetMuonSpecies()->Copy();
4421 header->Set("RunInfo/Muon Species", str);
4422 str = fData[0].GetMuonSource()->Copy();
4423 header->Set("RunInfo/Muon Source", str);
4424 str = fData[0].GetSetup()->Copy();
4425 header->Set("RunInfo/Setup", str);
4426 str = fData[0].GetComment()->Copy();
4427 header->Set("RunInfo/Comment", str);
4428 str = fData[0].GetSample()->Copy();
4429 header->Set("RunInfo/Sample Name", str);
4430 dval[0] = fData[0].GetTemperature(0);
4431 dval[1] = fData[0].GetTempError(0);
4432 prop.Set("Sample Temperature", MRH_UNDEFINED, dval[0], dval[1], "K");
4433 header->Set("RunInfo/Sample Temperature", prop);
4434 dval[0] = fData[0].GetField();
4435 prop.Set("Sample Magnetic Field", dval[0], "G");
4436 header->Set("RunInfo/Sample Magnetic Field", prop);
4437 header->Set("RunInfo/No of Histos", static_cast<Int_t>(fData[0].GetNoOfHistos()));
4438 dval[0] = fData[0].GetTimeResolution();
4439 prop.Set("Time Resolution", dval[0], "ns");
4440 header->Set("RunInfo/Time Resolution", prop);
4441 header->Set("RunInfo/RedGreen Offsets", fData[0].GetRedGreenOffset());
4442
4443 // feed DetectorInfo
4444 Int_t histoNo = 0;
4445 PRawRunDataSet *dataSet;
4446 UInt_t size = fData[0].GetNoOfHistos();
4447 for (UInt_t i=0; i<size; i++) {
4448 dataSet = fData[0].GetDataSet(i, false); // i.e. the false means, that i is the index and NOT the histo number
4449 if (dataSet == nullptr) { // something is really wrong
4450 std::cerr << std::endl << ">> PRunDataHandler::WriteMusrRootFile: **ERROR** Couldn't get data set (idx=" << i << ")";
4451 std::cerr << std::endl << ">> something is really wrong!" << std::endl;
4452 return false;
4453 }
4454 histoNo = dataSet->GetHistoNo();
4455 pathName.Form("DetectorInfo/Detector%03d/Name", histoNo);
4456 str = dataSet->GetName();
4457 if (!str.CompareTo("n/a"))
4458 str.Form("Detector%3d", histoNo);
4459 header->Set(pathName, str);
4460 pathName.Form("DetectorInfo/Detector%03d/Histo Number", histoNo);
4461 header->Set(pathName, histoNo);
4462 pathName.Form("DetectorInfo/Detector%03d/Histo Length", histoNo);
4463 header->Set(pathName, static_cast<Int_t>(dataSet->GetData()->size()/fAny2ManyInfo->rebin));
4464 pathName.Form("DetectorInfo/Detector%03d/Time Zero Bin", histoNo);
4465 header->Set(pathName, dataSet->GetTimeZeroBin()/fAny2ManyInfo->rebin);
4466 pathName.Form("DetectorInfo/Detector%03d/First Good Bin", histoNo);
4467 ival = dataSet->GetFirstGoodBin();
4468 header->Set(pathName, static_cast<Int_t>(ival/fAny2ManyInfo->rebin));
4469 pathName.Form("DetectorInfo/Detector%03d/Last Good Bin", histoNo);
4470 ival = dataSet->GetLastGoodBin();
4471 header->Set(pathName, static_cast<Int_t>(ival/fAny2ManyInfo->rebin));
4472 }
4473
4474 // feed SampleEnvironmentInfo
4475 str = fData[0].GetCryoName()->Copy();
4476 header->Set("SampleEnvironmentInfo/Cryo", str);
4477
4478 // feed MagneticFieldEnvironmentInfo
4479 str = fData[0].GetMagnetName()->Copy();
4480 header->Set("MagneticFieldEnvironmentInfo/Magnet Name", str);
4481
4482 // feed BeamlineInfo
4483 str = fData[0].GetBeamline()->Copy();
4484 header->Set("BeamlineInfo/Name", str);
4485
4486 // feed histos
4487 std::vector<TH1F*> histos;
4488 TH1F *histo = nullptr;
4489 UInt_t length = 0;
4490 if (fAny2ManyInfo->rebin == 1) {
4491 for (UInt_t i=0; i<size; i++) {
4492 dataSet = fData[0].GetDataSet(i, false); // i.e. the false means, that i is the index and NOT the histo number
4493 if (dataSet == nullptr) { // something is really wrong
4494 std::cerr << std::endl << ">> PRunDataHandler::WriteMusrRootFile: **ERROR** Couldn't get data set (idx=" << i << ")";
4495 std::cerr << std::endl << ">> something is really wrong!" << std::endl;
4496 return false;
4497 }
4498 str.Form("hDecay%03d", dataSet->GetHistoNo());
4499 length = dataSet->GetData()->size();
4500 histo = new TH1F(str.Data(), str.Data(), length+1, -0.5, static_cast<Double_t>(length)+0.5);
4501 Int_t sum=0, entries=0;
4502 for (UInt_t j=0; j<length; j++) {
4503 entries = dataSet->GetData()->at(j);
4504 histo->SetBinContent(j+1, entries);
4505 sum += entries;
4506 }
4507 histo->SetEntries(sum);
4508 histos.push_back(histo);
4509 }
4510 } else { // rebin > 1
4511 UInt_t dataRebin = 0;
4512 UInt_t dataCount = 0;
4513 for (UInt_t i=0; i<size; i++) {
4514 dataSet = fData[0].GetDataSet(i, false); // i.e. the false means, that i is the index and NOT the histo number
4515 if (dataSet == nullptr) { // something is really wrong
4516 std::cerr << std::endl << ">> PRunDataHandler::WriteMusrRootFile: **ERROR** Couldn't get data set (idx=" << i << ")";
4517 std::cerr << std::endl << ">> something is really wrong!" << std::endl;
4518 return false;
4519 }
4520 str.Form("hDecay%03d", dataSet->GetHistoNo());
4521 length = dataSet->GetData()->size();
4522 histo = new TH1F(str.Data(), str.Data(), static_cast<Int_t>(length/fAny2ManyInfo->rebin)+1, -0.5, static_cast<Double_t>(static_cast<Int_t>(length/fAny2ManyInfo->rebin))+0.5);
4523 dataCount = 0;
4524 Int_t sum=0, entries=0;
4525 for (UInt_t j=0; j<length; j++) {
4526 if ((j > 0) && (j % fAny2ManyInfo->rebin == 0)) {
4527 dataCount++;
4528 histo->SetBinContent(dataCount, dataRebin);
4529 dataRebin = 0;
4530 }
4531 entries = dataSet->GetData()->at(j);
4532 sum += entries;
4533 dataRebin += static_cast<UInt_t>(entries);
4534 }
4535 histo->SetEntries(sum);
4536 histos.push_back(histo);
4537 }
4538 }
4539
4540 if (tag == A2M_MUSR_ROOT) { // TFolder
4541 // add histos to the DecayAnaModule folder
4542 for (UInt_t i=0; i<histos.size(); i++)
4543 decayAnaModule->Add(histos[i]);
4544 } else { // TDirectory
4545 // add histos to the DecayAnaModule directory
4546 for (UInt_t i=0; i<histos.size(); i++)
4547 decayAnaDir->Add(histos[i]);
4548 }
4549
4550 if (tag == A2M_MUSR_ROOT) { // TFolder
4551 if (header->FillFolder(runHeader))
4552 runHeader->Write();
4553 histosFolder->Write();
4554 } else { // TDirectory
4555 if (header->FillDirectory(runHeaderDir)) {
4556 runHeaderDir->Write();
4557 }
4558 histosDir->Write();
4559 }
4560 fout->Close();
4561
4562 // check if root file shall be streamed to stdout
4563 if (fAny2ManyInfo->useStandardOutput && (fAny2ManyInfo->compressionTag == 0)) {
4564 // stream file to stdout
4565 std::ifstream is;
4566 int length=1024;
4567 char *buffer;
4568
4569 is.open(fln.Data(), std::ios::binary);
4570 if (!is.is_open()) {
4571 std::cerr << std::endl << "PRunDataHandler::WriteMusrRootFile(): **ERROR** Couldn't open the root-file for streaming." << std::endl;
4572 remove(fln.Data());
4573 return false;
4574 }
4575
4576 // get length of file
4577 is.seekg(0, std::ios::end);
4578 length = is.tellg();
4579 is.seekg(0, std::ios::beg);
4580
4581 if (length == -1) {
4582 std::cerr << std::endl << "PRunDataHandler::WriteMusrRootFile(): **ERROR** Couldn't determine the root-file size." << std::endl;
4583 remove(fln.Data());
4584 return false;
4585 }
4586
4587 // allocate memory
4588 buffer = new char [length];
4589
4590 // read data as a block
4591 while (!is.eof()) {
4592 is.read(buffer, length);
4593 std::cout.write(buffer, length);
4594 }
4595
4596 is.close();
4597
4598 delete [] buffer;
4599
4600 // delete temporary root file
4601 remove(fln.Data());
4602 }
4603
4604 return true;
4605}
4606
4607//--------------------------------------------------------------------------
4608// WriteRootFile (private)
4609//--------------------------------------------------------------------------
4620{
4621 Bool_t ok = false;
4622 fln = GenerateOutputFileName(fln, ".root", ok);
4623 if (!ok)
4624 return false;
4625
4626
4627 if (!fAny2ManyInfo->useStandardOutput)
4628 std::cout << std::endl << ">> PRunDataHandler::WriteRootFile(): writing a root data file (" << fln.Data() << ") ... " << std::endl;
4629
4630 // generate data file
4631 TFolder *histosFolder;
4632 TFolder *decayAnaModule;
4633 TFolder *runInfo;
4634
4635 histosFolder = gROOT->GetRootFolder()->AddFolder("histos", "Histograms");
4636 gROOT->GetListOfBrowsables()->Add(histosFolder, "histos");
4637 decayAnaModule = histosFolder->AddFolder("DecayAnaModule", "muSR decay histograms");
4638
4639 runInfo = gROOT->GetRootFolder()->AddFolder("RunInfo", "LEM RunInfo");
4640 gROOT->GetListOfBrowsables()->Add(runInfo, "RunInfo");
4641 std::unique_ptr<TLemRunHeader> header = std::make_unique<TLemRunHeader>();
4642 gROOT->GetListOfBrowsables()->Add(runInfo, "RunInfo");
4643
4644 // feed header info
4645 header->SetRunTitle(fData[0].GetRunTitle()->Data());
4646 header->SetLemSetup(fData[0].GetSetup()->Data());
4647 header->SetRunNumber(fData[0].GetRunNumber());
4648 TString dt = *fData[0].GetStartDate() + "/" + *fData[0].GetStartTime();
4649 header->SetStartTimeString(dt.Data());
4650 dt = *fData[0].GetStopDate() + "/" + *fData[0].GetStopTime();
4651 header->SetStopTimeString(dt.Data());
4652 header->SetStartTime(fData[0].GetStartDateTime());
4653 header->SetStopTime(fData[0].GetStopDateTime());
4654 header->SetModeratorHV(-999.9, 0.0);
4655 header->SetSampleHV(-999.9, 0.0);
4656 header->SetImpEnergy(-999.9);
4657 header->SetSampleTemperature(fData[0].GetTemperature(0), fData[0].GetTempError(0));
4658 header->SetSampleBField(fData[0].GetField(), 0.0);
4659 header->SetTimeResolution(fData[0].GetTimeResolution());
4660 PRawRunDataSet *dataSet = fData[0].GetDataSet(0, false); // i.e. the false means, that i is the index and NOT the histo number
4661 header->SetNChannels(static_cast<UInt_t>(dataSet->GetData()->size()/fAny2ManyInfo->rebin));
4662 header->SetNHist(fData[0].GetNoOfHistos());
4663 header->SetCuts("none");
4664 header->SetModerator("none");
4665
4666 // feed t0's if possible
4667 UInt_t NoT0s = fData[0].GetNoOfHistos();
4668 if (fData[0].GetNoOfHistos() > NHIST) {
4669 std::cerr << std::endl << ">> PRunDataHandler::WriteRootFile: **WARNING** found more T0's (" << NoT0s << ") than can be handled (" << NHIST << ").";
4670 std::cerr << std::endl << ">> Will only write the first " << NHIST << " T0s!!" << std::endl;
4671 NoT0s = NHIST;
4672 }
4673 Double_t *tt0 = new Double_t[NoT0s];
4674
4675 for (UInt_t i=0; i<NoT0s; i++) {
4676 dataSet = fData[0].GetDataSet(i, false); // i.e. the false means, that i is the index and NOT the histo number
4677 tt0[i] = dataSet->GetTimeZeroBin()/fAny2ManyInfo->rebin;
4678 }
4679 header->SetTimeZero(tt0);
4680 runInfo->Add(header.get()); // add header to RunInfo folder
4681
4682 // feed histos
4683 std::vector<TH1F*> histos;
4684 TH1F *histo = nullptr;
4685 Char_t str[32];
4686 UInt_t size = 0;
4687 if (fAny2ManyInfo->rebin == 1) {
4688 for (UInt_t i=0; i<fData[0].GetNoOfHistos(); i++) {
4689 dataSet = fData[0].GetDataSet(i, false); // i.e. the false means, that i is the index and NOT the histo number
4690 if (dataSet == nullptr) { // something is really wrong
4691 std::cerr << std::endl << ">> PRunDataHandler::WriteRootFile: **ERROR** Couldn't get data set (idx=0" << i << ")";
4692 std::cerr << std::endl << ">> something is really wrong!" << std::endl;
4693 return false;
4694 }
4695 size = dataSet->GetData()->size();
4696 snprintf(str, sizeof(str), "hDecay%02d", static_cast<Int_t>(i));
4697 histo = new TH1F(str, str, size+1, -0.5, static_cast<Double_t>(size)+0.5);
4698 for (UInt_t j=0; j<size; j++) {
4699 histo->SetBinContent(j+1, dataSet->GetData()->at(j));
4700 }
4701 histos.push_back(histo);
4702 }
4703 } else { // rebin > 1
4704 UInt_t dataRebin = 0;
4705 UInt_t dataCount = 0;
4706 for (UInt_t i=0; i<fData[0].GetNoOfHistos(); i++) {
4707 dataSet = fData[0].GetDataSet(i, false); // i.e. the false means, that i is the index and NOT the histo number
4708 if (dataSet == nullptr) { // something is really wrong
4709 std::cerr << std::endl << ">> PRunDataHandler::WriteRootFile: **ERROR** Couldn't get data set (idx=0" << i << ")";
4710 std::cerr << std::endl << ">> something is really wrong!" << std::endl;
4711 return false;
4712 }
4713 size = dataSet->GetData()->size();
4714 snprintf(str, sizeof(str), "hDecay%02d", static_cast<Int_t>(i));
4715 histo = new TH1F(str, str, static_cast<UInt_t>(size/fAny2ManyInfo->rebin)+1, -0.5, static_cast<Double_t>(size)/static_cast<Double_t>(fAny2ManyInfo->rebin)+0.5);
4716 dataCount = 0;
4717 for (UInt_t j=0; j<size; j++) {
4718 if ((j > 0) && (j % fAny2ManyInfo->rebin == 0)) {
4719 dataCount++;
4720 histo->SetBinContent(dataCount, dataRebin);
4721 dataRebin = 0;
4722 }
4723 dataRebin += static_cast<UInt_t>(dataSet->GetData()->at(j));
4724 }
4725 histos.push_back(histo);
4726 }
4727 }
4728
4729 // add histos to the DecayAnaModule folder
4730 for (UInt_t i=0; i<histos.size(); i++)
4731 decayAnaModule->Add(histos[i]);
4732
4733 // write file
4734 std::unique_ptr<TFile> fout = std::make_unique<TFile>(fln, "RECREATE", fln);
4735 if (fout == nullptr) {
4736 std::cerr << std::endl << "PRunDataHandler::WriteRootFile(): **ERROR** Couldn't create ROOT file '" << fln << "'" << std::endl;
4737 return false;
4738 }
4739
4740 fout->cd();
4741 runInfo->Write();
4742 histosFolder->Write();
4743 fout->Close();
4744
4745 // clean up
4746 for (UInt_t i=0; i<histos.size(); i++) {
4747 delete histos[i];
4748 }
4749 histos.clear();
4750 delete [] tt0;
4751
4752 // check if root file shall be streamed to stdout
4753 if (fAny2ManyInfo->useStandardOutput && (fAny2ManyInfo->compressionTag == 0)) {
4754 // stream file to stdout
4755 std::ifstream is;
4756 int length=1024;
4757 char *buffer;
4758
4759 is.open(fln.Data(), std::ios::binary);
4760 if (!is.is_open()) {
4761 std::cerr << std::endl << "PRunDataHandler::WriteRootFile(): **ERROR** Couldn't open the root-file for streaming." << std::endl;
4762 remove(fln.Data());
4763 return false;
4764 }
4765
4766 // get length of file
4767 is.seekg(0, std::ios::end);
4768 length = is.tellg();
4769 is.seekg(0, std::ios::beg);
4770
4771 if (length == -1) {
4772 std::cerr << std::endl << "PRunDataHandler::WriteRootFile(): **ERROR** Couldn't determine the root-file size." << std::endl;
4773 remove(fln.Data());
4774 return false;
4775 }
4776
4777 // allocate memory
4778 buffer = new char [length];
4779
4780 // read data as a block
4781 while (!is.eof()) {
4782 is.read(buffer, length);
4783 std::cout.write(buffer, length);
4784 }
4785
4786 is.close();
4787
4788 delete [] buffer;
4789
4790 // delete temporary root file
4791 remove(fln.Data());
4792 }
4793
4794 return true;
4795}
4796
4797//--------------------------------------------------------------------------
4798// WriteNexusFile (private)
4799//--------------------------------------------------------------------------
4807Bool_t PRunDataHandler::WriteNexusFile(TString format, TString fln)
4808{
4809#ifdef PNEXUS_ENABLED
4810 std::string str{""};
4811 Bool_t ok = false;
4812 fln = GenerateOutputFileName(fln, ".nxs", ok);
4813 if (!ok)
4814 return false;
4815
4816 if (!fAny2ManyInfo->useStandardOutput)
4817 std::cout << std::endl << ">> PRunDataHandler::WriteNexusFile(): writing a NeXus data file (" << fln.Data() << ") ... " << std::endl;
4818
4819 if (format.Contains("HDF4", TString::kIgnoreCase)) { // HDF4
4820#ifdef HAVE_HDF4
4821 try {
4822 // create NeXus object
4823 std::unique_ptr<nxH4::PNeXus> nxs = std::make_unique<nxH4::PNeXus>();
4824 if (nxs == nullptr) {
4825 std::cerr << std::endl << ">> PRunDataHandler::WriteNexusFile(): **ERROR** couldn't invoke the NeXus object." << std::endl;
4826 return false;
4827 }
4828
4829 // set NeXus version
4830 nxs->AddGroupAttribute("/", "NeXus_version", std::string("4.3.0"));
4831
4832 // set HDF4 version
4833 nxs->AddGroupAttribute("/", "HDF_version", nxs->GetHdf4LibVersion());
4834
4835 // set file name
4836 nxs->AddGroupAttribute("/", "file_name", std::string(fln.Data()));
4837
4838 // set creation time
4839 std::string dt = nxs::getIso8601TimestampLocal();
4840 nxs->AddGroupAttribute("/", "file_time", dt);
4841
4842 if (fAny2ManyInfo->idf == 1) { // IDF V1
4843 // set IDF version
4844 nxs->AddDataset<int>("/run/IDF_version", {(int)fAny2ManyInfo->idf}, {1}, nxH4::H4DataType::kINT32);
4845
4846 // set program name
4847 nxs->AddDataset<std::string>("/run/program_name", {"any2many"}, {1}, nxH4::H4DataType::kCHAR8);
4848 str="n/a";
4849 #ifdef HAVE_CONFIG_H
4850 str = PACKAGE_VERSION;
4851 #endif
4852 nxs->AddDatasetAttribute<std::string>("/run/program_name", "version", str);
4853
4854 // set run number
4855 nxs->AddDataset<int>("/run/number", {fData[0].GetRunNumber()}, {1}, nxH4::H4DataType::kINT32);
4856
4857 // set title
4858 nxs->AddDataset<std::string>("/run/title", {fData[0].GetRunTitle()->Data()}, {1}, nxH4::H4DataType::kCHAR8);
4859
4860 // set notes
4861 nxs->AddDataset<std::string>("/run/notes", {std::string("n/a")}, {1}, nxH4::H4DataType::kCHAR8);
4862
4863 // set analysis
4864 nxs->AddDataset<std::string>("/run/analysis", {std::string("muonTD")}, {1}, nxH4::H4DataType::kCHAR8);
4865
4866 // set lab
4867 str = *fData[0].GetLaboratory();
4868 nxs->AddDataset<std::string>("/run/lab", {str}, {1}, nxH4::H4DataType::kCHAR8);
4869
4870 // set beamline
4871 str = *fData[0].GetBeamline();
4872 nxs->AddDataset<std::string>("/run/beamline", {str}, {1}, nxH4::H4DataType::kCHAR8);
4873
4874 // set start time
4875 str = std::string(fData[0].GetStartDate()->Data()) + std::string("T") + std::string(fData[0].GetStartTime()->Data());
4876 nxs->AddDataset<std::string>("/run/start_time", {str}, {1}, nxH4::H4DataType::kCHAR8);
4877
4878 // set stop time
4879 str = std::string(fData[0].GetStopDate()->Data()) + std::string("T") + std::string(fData[0].GetStopTime()->Data());
4880 nxs->AddDataset<std::string>("/run/stop_time", {str}, {1}, nxH4::H4DataType::kCHAR8);
4881
4882 // set switching state
4883 nxs->AddDataset<int>("/run/switching_states", {1}, {1}, nxH4::H4DataType::kINT32);
4884
4885 // set user name
4886 nxs->AddDataset<std::string>("/run/user/name", {std::string("n/a")}, {1}, nxH4::H4DataType::kCHAR8);
4887
4888 // set user experiment_number
4889 nxs->AddDataset<std::string>("/run/user/experiment_number", {std::string("n/a")}, {1}, nxH4::H4DataType::kCHAR8);
4890
4891 // set sample name
4892 nxs->AddDataset<std::string>("/run/sample/name", {fData[0].GetSample()->Data()}, {1}, nxH4::H4DataType::kCHAR8);
4893
4894 // set sample temperature
4895 nxs->AddDataset<float>("/run/sample/temperature", {(float)fData[0].GetTemperature(0)}, {1}, nxH4::H4DataType::kFLOAT32);
4896 nxs->AddDatasetAttribute<float>("/run/sample/temperature", "units", std::string("Kelvin"));
4897
4898 // set magnetic field
4899 nxs->AddDataset<float>("/run/sample/magnetic_field", {(float)fData[0].GetField()}, {1}, nxH4::H4DataType::kFLOAT32);
4900 nxs->AddDatasetAttribute<float>("/run/sample/magnetic_field", "units", std::string("Gauss"));
4901
4902 // set sample environment
4903 nxs->AddDataset<std::string>("/run/sample/environment", {fData[0].GetSetup()->Data()}, {1}, nxH4::H4DataType::kCHAR8);
4904
4905 // set sample shape
4906 nxs->AddDataset<std::string>("/run/sample/shape", {std::string("n/a")}, {1}, nxH4::H4DataType::kCHAR8);
4907
4908 // set magnetic field vector
4909 nxs->AddDataset<float>("/run/sample/magnetic_field_vector", {1.0f, 1.0f, 1.0f}, {3}, nxH4::H4DataType::kFLOAT32);
4910 nxs->AddDatasetAttribute<float>("/run/sample/magnetic_field_vector", "coordinate_system", std::string("cartesian"));
4911 nxs->AddDatasetAttribute<float>("/run/sample/magnetic_field_vector", "units", std::string("Gauss"));
4912 nxs->AddDatasetAttribute<float>("/run/sample/magnetic_field_vector", "available", 0);
4913
4914 // set instrument name
4915 str = *fData[0].GetInstrument();
4916 nxs->AddDataset<std::string>("/run/instrument/name", {str}, {1}, nxH4::H4DataType::kCHAR8);
4917
4918 // set instrument number of detectors
4919 nxs->AddDataset<int>("/run/instrument/detector/number", {(int)fData[0].GetNoOfHistos()}, {1}, nxH4::H4DataType::kINT32);
4920
4921 // set instrument collimator
4922 nxs->AddDataset<std::string>("/run/instrument/collimator/type", {std::string("n/a")}, {1}, nxH4::H4DataType::kCHAR8);
4923
4924 // set instrument beam total number of counts in Mev
4925 // calculate the total number of counts
4926 double total_counts = 0;
4927 PRawRunDataSet *dataSet = nullptr;
4928 for (unsigned int i=0; i<fData[0].GetNoOfHistos(); i++) {
4929 dataSet = fData[0].GetDataSet(i, false); // i.e. the false means, that i is the index and NOT the histo number
4930 if (dataSet == nullptr) { // something is really wrong
4931 std::cerr << std::endl << ">> PRunDataHandler::WriteNexusFile: **ERROR** Couldn't get data set (idx=0" << i << ")";
4932 std::cerr << std::endl << ">> something is really wrong!" << std::endl;
4933 return false;
4934 }
4935 for (unsigned int j=0; j<dataSet->GetData()->size(); j++)
4936 total_counts += dataSet->GetData()->at(j);
4937 }
4938 float total_counts_mev = (float) total_counts / 1.0e6;
4939 nxs->AddDataset<float>("/run/instrument/beam/total_counts", {total_counts_mev}, {1}, nxH4::H4DataType::kFLOAT32);
4940 nxs->AddDatasetAttribute<float>("/run/instrument/beam/total_counts", "units", std::string("MEv"));
4941
4942 // set time resolution (use FLOAT instead of INT)
4943 float res = (float)(fData[0].GetTimeResolution()*fAny2ManyInfo->rebin*1.0e3);
4944 nxs->AddDataset<float>("/run/histogram_data_1/resolution", {res}, {1}, nxH4::H4DataType::kFLOAT32);
4945 nxs->AddDatasetAttribute<float>("/run/histogram_data_1/resolution", "units", std::string("picoseconds"));
4946
4947 // set time zero time to 0. see t0_bin attribute of counts!
4948 nxs->AddDataset<int>("/run/histogram_data_1/time_zero", {0}, {1}, nxH4::H4DataType::kINT32);
4949 nxs->AddDatasetAttribute<int>("/run/histogram_data_1/time_zero", "units", std::string("microseconds"));
4950 nxs->AddDatasetAttribute<int>("/run/histogram_data_1/time_zero", "available", 0);
4951
4952 // set raw_time
4953 res = (float)(fData[0].GetTimeResolution()*fAny2ManyInfo->rebin*1.0e-3);
4954 dataSet = fData[0].GetDataSet(0, false); // i.e. the false means, that i is the index and NOT the histo number
4955 unsigned int length = (int)(dataSet->GetData()->size() / fAny2ManyInfo->rebin);
4956 std::vector<float> time;
4957 for (unsigned int i=0; i<length; i++)
4958 time.push_back(((float)i+0.5)*res);
4959 nxs->AddDataset<float>("/run/histogram_data_1/raw_time", time, {length}, nxH4::H4DataType::kFLOAT32);
4960 nxs->AddDatasetAttribute<float>("/run/histogram_data_1/raw_time", "axis", 1);
4961 nxs->AddDatasetAttribute<float>("/run/histogram_data_1/raw_time", "primary", 0);
4962 nxs->AddDatasetAttribute<float>("/run/histogram_data_1/raw_time", "units", std::string("microseconds"));
4963 nxs->AddDatasetAttribute<float>("/run/histogram_data_1/raw_time", "available", 0);
4964
4965 // set corrected_time
4966 nxs->AddDataset<float>("/run/histogram_data_1/corrected_time", time, {length}, nxH4::H4DataType::kFLOAT32);
4967 nxs->AddDatasetAttribute<float>("/run/histogram_data_1/corrected_time", "axis", 1);
4968 nxs->AddDatasetAttribute<float>("/run/histogram_data_1/corrected_time", "units", std::string("microseconds"));
4969 nxs->AddDatasetAttribute<float>("/run/histogram_data_1/corrected_time", "available", 0);
4970
4971 // set grouping
4972 std::vector<int> grouping(fData[0].GetNoOfHistos(), 0);
4973 nxs->AddDataset<int>("/run/histogram_data_1/grouping", grouping, {(uint32_t)grouping.size()}, nxH4::H4DataType::kINT32);
4974 nxs->AddDatasetAttribute<int>("/run/histogram_data_1/grouping", "avaliabe", 0);
4975
4976 // set alpha
4977 int ival=1;
4978 nxs->AddDataset<int>("/run/histogram_data_1/alpha", {ival}, {1}, nxH4::H4DataType::kINT32);
4979 nxs->AddDatasetAttribute<int>("/run/histogram_data_1/alpha", "avaliabe", 0);
4980
4981 // set counts
4982 // feed histos
4983 PIntVector data;
4984 UInt_t size = 0;
4985 int noHisto, histoLength;
4986 if (fAny2ManyInfo->rebin == 1) {
4987 noHisto = fData[0].GetNoOfHistos();
4988 for (UInt_t i=0; i<fData[0].GetNoOfHistos(); i++) {
4989 dataSet = fData[0].GetDataSet(i, false); // i.e. the false means, that i is the index and NOT the histo number
4990 if (dataSet == nullptr) { // something is really wrong
4991 std::cerr << std::endl << ">> PRunDataHandler::WriteNexusFile: **ERROR** Couldn't get data set (idx=" << i << ")";
4992 std::cerr << std::endl << ">> something is really wrong!" << std::endl;
4993 return false;
4994 }
4995 size = dataSet->GetData()->size();
4996 histoLength = size;
4997 for (UInt_t j=0; j<size; j++) {
4998 data.push_back((UInt_t)dataSet->GetData()->at(j));
4999 }
5000 }
5001 } else { // rebin > 1
5002 UInt_t dataRebin = 0;
5003 UInt_t dataCount = 0;
5004 noHisto = fData[0].GetNoOfHistos();
5005 for (UInt_t i=0; i<fData[0].GetNoOfHistos(); i++) {
5006 dataSet = fData[0].GetDataSet(i, false); // i.e. the false means, that i is the index and NOT the histo number
5007 if (dataSet == nullptr) { // something is really wrong
5008 std::cerr << std::endl << ">> PRunDataHandler::WriteNexusFile: **ERROR** Couldn't get data set (idx=" << i << ")";
5009 std::cerr << std::endl << ">> something is really wrong!" << std::endl;
5010 return false;
5011 }
5012 size = dataSet->GetData()->size();
5013 dataCount = 0;
5014 for (UInt_t j=0; j<size; j++) {
5015 if ((j > 0) && (j % fAny2ManyInfo->rebin == 0)) {
5016 dataCount++;
5017 data.push_back(dataRebin);
5018 dataRebin = 0;
5019 }
5020 dataRebin += static_cast<UInt_t>(dataSet->GetData()->at(j));
5021 }
5022 }
5023 size = dataCount;
5024 }
5025 nxs->AddDataset<int>("/run/histogram_data_1/counts", data, {(uint32_t)noHisto, (uint32_t)size}, nxH4::H4DataType::kINT32);
5026 nxs->AddDatasetAttribute<int>("/run/histogram_data_1/counts", "units", std::string("counts"));
5027 nxs->AddDatasetAttribute<int>("/run/histogram_data_1/counts", "signal", 1);
5028 nxs->AddDatasetAttribute<int>("/run/histogram_data_1/counts", "number", noHisto);
5029 nxs->AddDatasetAttribute<int>("/run/histogram_data_1/counts", "length", (int)size);
5030 nxs->AddDatasetAttribute<int>("/run/histogram_data_1/counts", "t0_bin", 0);
5031 nxs->AddDatasetAttribute<int>("/run/histogram_data_1/counts", "first_good_bin", 0);
5032 nxs->AddDatasetAttribute<int>("/run/histogram_data_1/counts", "last_good_bin", 0);
5033 res = (float)(fData[0].GetTimeResolution()*fAny2ManyInfo->rebin*1.0e3)/2.0;
5034 nxs->AddDatasetAttribute<int>("/run/histogram_data_1/counts", "offset", res);
5035 } else { // IDF V2
5036 nxs->AddGroupAttribute("/raw_data_1", "NX_class", std::string("NXentry"));
5037
5038 // set IDF version
5039 nxs->AddDataset<int>("/raw_data_1/IDF_version", {(int)fAny2ManyInfo->idf}, {1}, nxH4::H4DataType::kINT32);
5040
5041 // set beamline
5042 str = *fData[0].GetBeamline();
5043 nxs->AddDataset<std::string>("/raw_data_1/beamline", {str}, {1}, nxH4::H4DataType::kCHAR8);
5044
5045 // set definition
5046 nxs->AddDataset<std::string>("/raw_data_1/definition", {std::string("muonTD")}, {1}, nxH4::H4DataType::kCHAR8);
5047
5048 // set run_number
5049 nxs->AddDataset<int>("/raw_data_1/run_number", {fData[0].GetRunNumber()}, {1}, nxH4::H4DataType::kINT32);
5050
5051 // set title
5052 nxs->AddDataset<std::string>("/raw_data_1/title", {fData[0].GetRunTitle()->Data()}, {1}, nxH4::H4DataType::kCHAR8);
5053
5054 // set start time
5055 str = std::string(fData[0].GetStartDate()->Data()) + std::string("T") + std::string(fData[0].GetStartTime()->Data());
5056 nxs->AddDataset<std::string>("/raw_data_1/start_time", {str}, {1}, nxH4::H4DataType::kCHAR8);
5057 nxs->AddDatasetAttribute<std::string>("/raw_data_1/start_time", "units", "ISO8601");
5058
5059 // set end time
5060 str = std::string(fData[0].GetStopDate()->Data()) + std::string("T") + std::string(fData[0].GetStopTime()->Data());
5061 nxs->AddDataset<std::string>("/raw_data_1/end_time", {str}, {1}, nxH4::H4DataType::kCHAR8);
5062 nxs->AddDatasetAttribute<std::string>("/raw_data_1/end_time", "units", "ISO8601");
5063
5064 // set experiment_identifier
5065 str = "n/a";
5066 nxs->AddDataset<std::string>("/raw_data_1/experiment_identifier", {str}, {1}, nxH4::H4DataType::kCHAR8);
5067
5068 // set instrument attribute
5069 nxs->AddGroupAttribute("/raw_data_1/instrument", "NX_class", std::string("NXinstrument"));
5070
5071 // set instrument name
5072 str = *fData[0].GetInstrument();
5073 nxs->AddDataset<std::string>("/raw_data_1/instrument/name", {str}, {1}, nxH4::H4DataType::kCHAR8);
5074
5075 // set instrument/source attribute
5076 nxs->AddGroupAttribute("/raw_data_1/instrument/source", "NX_class", std::string("NXsource"));
5077
5078 // set instrument/source/name
5079 str = fData[0].GetLaboratory()->Data();
5080 nxs->AddDataset<std::string>("/raw_data_1/instrument/source/name", {str}, {1}, nxH4::H4DataType::kCHAR8);
5081
5082 // set instrument/source/type
5083 TString tstr = *fData[0].GetInstrument();
5084 std::string type{"n/a"};
5085 if (tstr.Contains("LEM", TString::kIgnoreCase)) {
5086 type = "low energy muon source";
5087 } else if (tstr.Contains("GPS", TString::kIgnoreCase) || tstr.Contains("GPD", TString::kIgnoreCase) ||
5088 tstr.Contains("LTF", TString::kIgnoreCase) || tstr.Contains("FLAME", TString::kIgnoreCase) ||
5089 tstr.Contains("HAL-9500", TString::kIgnoreCase) || tstr.Contains("DOLLY", TString::kIgnoreCase) ||
5090 tstr.Contains("VMS", TString::kIgnoreCase)) {
5091 type = "quasi-continous muon source";
5092 } else if (tstr.Contains("EMU", TString::kIgnoreCase) || tstr.Contains("MUSR", TString::kIgnoreCase) ||
5093 tstr.Contains("HIFI", TString::kIgnoreCase)) {
5094 type = "pulsed muon source";
5095 }
5096 nxs->AddDataset<std::string>("/raw_data_1/instrument/source/type", {type}, {1}, nxH4::H4DataType::kCHAR8);
5097
5098 // set instrument/source/probe
5099 str = "positive muons";
5100 nxs->AddDataset<std::string>("/raw_data_1/instrument/source/probe", {str}, {1}, nxH4::H4DataType::kCHAR8);
5101
5102 // set instrument/detector info
5103 nxs->AddGroupAttribute("/raw_data_1/instrument/detector_1", "NX_class", std::string("NXdetector"));
5104
5105 // set instrument/detector/spectrum_index
5106 int noHistos = fData[0].GetNoOfHistos();
5107 std::vector<int> spectrum_index(noHistos);
5108 for (unsigned int i=0; i<spectrum_index.size(); i++)
5109 spectrum_index[i] = i+1;
5110 nxs->AddDataset<int>("/raw_data_1/instrument/detector_1/spectrum_index", spectrum_index, {(uint32_t)spectrum_index.size()}, nxH4::H4DataType::kINT32);
5111
5112 // set instrument/detector/raw_time (not useful for quasi-continuous sources)
5113 int ival=0;
5114 nxs->AddDataset<int>("/raw_data_1/instrument/detector_1/raw_time", {ival}, {1}, nxH4::H4DataType::kINT32);
5115 nxs->AddDatasetAttribute<int>("/raw_data_1/instrument/detector_1/raw_time", "available", 0);
5116
5117 // set instrument/detector/counts
5118 // set counts
5119 // feed histos
5120 PRawRunDataSet *dataSet = nullptr;
5121 PIntVector data;
5122 UInt_t size = 0;
5123 int noHisto, histoLength;
5124 if (fAny2ManyInfo->rebin == 1) {
5125 noHisto = fData[0].GetNoOfHistos();
5126 for (UInt_t i=0; i<fData[0].GetNoOfHistos(); i++) {
5127 dataSet = fData[0].GetDataSet(i, false); // i.e. the false means, that i is the index and NOT the histo number
5128 if (dataSet == nullptr) { // something is really wrong
5129 std::cerr << std::endl << ">> PRunDataHandler::WriteNexusFile: **ERROR** Couldn't get data set (idx=" << i << ")";
5130 std::cerr << std::endl << ">> something is really wrong!" << std::endl;
5131 return false;
5132 }
5133 size = dataSet->GetData()->size();
5134 histoLength = size;
5135 for (UInt_t j=0; j<size; j++) {
5136 data.push_back((UInt_t)dataSet->GetData()->at(j));
5137 }
5138 }
5139 } else { // rebin > 1
5140 UInt_t dataRebin = 0;
5141 UInt_t dataCount = 0;
5142 noHisto = fData[0].GetNoOfHistos();
5143 for (UInt_t i=0; i<fData[0].GetNoOfHistos(); i++) {
5144 dataSet = fData[0].GetDataSet(i, false); // i.e. the false means, that i is the index and NOT the histo number
5145 if (dataSet == nullptr) { // something is really wrong
5146 std::cerr << std::endl << ">> PRunDataHandler::WriteNexusFile: **ERROR** Couldn't get data set (idx=" << i << ")";
5147 std::cerr << std::endl << ">> something is really wrong!" << std::endl;
5148 return false;
5149 }
5150 size = dataSet->GetData()->size();
5151 dataCount = 0;
5152 for (UInt_t j=0; j<size; j++) {
5153 if ((j > 0) && (j % fAny2ManyInfo->rebin == 0)) {
5154 dataCount++;
5155 data.push_back(dataRebin);
5156 dataRebin = 0;
5157 }
5158 dataRebin += static_cast<UInt_t>(dataSet->GetData()->at(j));
5159 }
5160 }
5161 size = dataCount;
5162 }
5163 nxs->AddDataset<int>("/raw_data_1/instrument/detector_1/counts", data, {(uint32_t)noHisto, (uint32_t)size}, nxH4::H4DataType::kINT32);
5164 nxs->AddDatasetAttribute<int>("/raw_data_1/instrument/detector_1/counts", "axes", std::string("spectrum_index,time_bin"));
5165 nxs->AddDatasetAttribute<int>("/raw_data_1/instrument/detector_1/counts", "long_name", std::string("positon counts"));
5166 nxs->AddDatasetAttribute<int>("/raw_data_1/instrument/detector_1/counts", "signal", 1);
5167 // t0_bin attributes
5168 std::vector<int> t0_bin;
5169 for (unsigned int i=0; i<fData[0].GetNoOfHistos(); i++)
5170 t0_bin.push_back((int)(fData[0].GetT0Bin(i+1)/fAny2ManyInfo->rebin));
5171 nxs->AddDatasetAttribute<int>("/raw_data_1/instrument/detector_1/counts", "t0_bin", {t0_bin});
5172 nxs->AddDatasetAttribute<int>("/raw_data_1/instrument/detector_1/counts", "units", std::string("counts"));
5173
5174 // set raw_data_1/detector info
5175 nxs->AddGroupAttribute("/raw_data_1/detector_1", "NX_class", std::string("NXdata"));
5176
5177 // set detector/counts
5178 nxs->AddDataset<int>("/raw_data_1/detector_1/counts", data, {(uint32_t)noHisto, (uint32_t)size}, nxH4::H4DataType::kINT32);
5179 nxs->AddDatasetAttribute<int>("/raw_data_1/detector_1/counts", "axes", std::string("spectrum_index,time_bin"));
5180 nxs->AddDatasetAttribute<int>("/raw_data_1/detector_1/counts", "long_name", std::string("positon counts"));
5181 nxs->AddDatasetAttribute<int>("/raw_data_1/detector_1/counts", "signal", 1);
5182 }
5183
5184 int result = nxs->WriteNexusFile(fln.Data(), fAny2ManyInfo->idf);
5185 if (result != 0) {
5186 std::cerr << std::endl << "**ERROR** PRunDataHandler::WriteNexusFile, fln=" << fln << std::endl;
5187 return false;
5188 }
5189 } catch (const std::runtime_error& e) {
5190 std::cerr << std::endl << "HDF4 error: " << e.what() << std::endl;
5191 return false;
5192 }
5193#endif
5194 } else { // HDF5
5195 try {
5196 // create NeXus object
5197 std::unique_ptr<nxH5::PNeXus> nxs = std::make_unique<nxH5::PNeXus>();
5198 if (nxs == nullptr) {
5199 std::cerr << std::endl << ">> PRunDataHandler::WriteNexusFile(): **ERROR** couldn't invoke the NeXus object." << std::endl;
5200 return false;
5201 }
5202
5203 // set NeXus version
5204 nxs->AddGroupAttribute("/", "NeXus_version", std::string("4.3.0"));
5205
5206 // set HDF5 version
5207 nxs->AddGroupAttribute("/", "HDF_version", nxs->GetHdf5LibVersion());
5208
5209 // set file name
5210 nxs->AddGroupAttribute("/", "file_name", std::string(fln.Data()));
5211
5212 // set creation time
5213 std::string dt = nxs::getIso8601TimestampLocal();
5214 nxs->AddGroupAttribute("/", "file_time", dt);
5215
5216 if (fAny2ManyInfo->idf == 1) { // IDF V1
5217 // set IDF version
5218 nxs->AddDataset<int>("/run/IDF_version", {(int)fAny2ManyInfo->idf}, {1}, H5::PredType::NATIVE_INT32);
5219
5220 // set program name
5221 nxs->AddDataset<std::string>("/run/program_name", {"any2many"}, {1}, H5::StrType(H5::PredType::C_S1, H5T_VARIABLE));
5222 str="n/a";
5223 #ifdef HAVE_CONFIG_H
5224 str = PACKAGE_VERSION;
5225 #endif
5226 nxs->AddDatasetAttribute<std::string>("/run/program_name", "version", str);
5227
5228 // set run number
5229 nxs->AddDataset<int>("/run/number", {fData[0].GetRunNumber()}, {1}, H5::PredType::NATIVE_INT32);
5230
5231 // set title
5232 nxs->AddDataset<std::string>("/run/title", {fData[0].GetRunTitle()->Data()}, {1}, H5::StrType(H5::PredType::C_S1, H5T_VARIABLE));
5233
5234 // set notes
5235 nxs->AddDataset<std::string>("/run/notes", {std::string("n/a")}, {1}, H5::StrType(H5::PredType::C_S1, H5T_VARIABLE));
5236
5237 // set analysis
5238 nxs->AddDataset<std::string>("/run/analysis", {std::string("muonTD")}, {1}, H5::StrType(H5::PredType::C_S1, H5T_VARIABLE));
5239
5240 // set lab
5241 str = *fData[0].GetLaboratory();
5242 nxs->AddDataset<std::string>("/run/lab", {str}, {1}, H5::StrType(H5::PredType::C_S1, H5T_VARIABLE));
5243
5244 // set beamline
5245 str = *fData[0].GetBeamline();
5246 nxs->AddDataset<std::string>("/run/beamline", {str}, {1}, H5::StrType(H5::PredType::C_S1, H5T_VARIABLE));
5247
5248 // set start time
5249 str = std::string(fData[0].GetStartDate()->Data()) + std::string("T") + std::string(fData[0].GetStartTime()->Data());
5250 nxs->AddDataset<std::string>("/run/start_time", {str}, {1}, H5::StrType(H5::PredType::C_S1, H5T_VARIABLE));
5251
5252 // set stop time
5253 str = std::string(fData[0].GetStopDate()->Data()) + std::string("T") + std::string(fData[0].GetStopTime()->Data());
5254 nxs->AddDataset<std::string>("/run/stop_time", {str}, {1}, H5::StrType(H5::PredType::C_S1, H5T_VARIABLE));
5255
5256 // set switching state
5257 nxs->AddDataset<int>("/run/switching_states", {1}, {1}, H5::PredType::NATIVE_INT32);
5258
5259 // set user name
5260 nxs->AddDataset<std::string>("/run/user/name", {std::string("n/a")}, {1}, H5::StrType(H5::PredType::C_S1, H5T_VARIABLE));
5261
5262 // set user experiment_number
5263 nxs->AddDataset<std::string>("/run/user/experiment_number", {std::string("n/a")}, {1}, H5::StrType(H5::PredType::C_S1, H5T_VARIABLE));
5264
5265 // set sample name
5266 nxs->AddDataset<std::string>("/run/sample/name", {fData[0].GetSample()->Data()}, {1}, H5::StrType(H5::PredType::C_S1, H5T_VARIABLE));
5267
5268 // set sample temperature
5269 nxs->AddDataset<float>("/run/sample/temperature", {(float)fData[0].GetTemperature(0)}, {1}, H5::PredType::NATIVE_FLOAT);
5270 nxs->AddDatasetAttribute<float>("/run/sample/temperature", "units", std::string("Kelvin"));
5271
5272 // set magnetic field
5273 nxs->AddDataset<float>("/run/sample/magnetic_field", {(float)fData[0].GetField()}, {1}, H5::PredType::NATIVE_FLOAT);
5274 nxs->AddDatasetAttribute<float>("/run/sample/magnetic_field", "units", std::string("Gauss"));
5275
5276 // set sample environment
5277 nxs->AddDataset<std::string>("/run/sample/environment", {fData[0].GetSetup()->Data()}, {1}, H5::StrType(H5::PredType::C_S1, H5T_VARIABLE));
5278
5279 // set sample shape
5280 nxs->AddDataset<std::string>("/run/sample/shape", {std::string("n/a")}, {1}, H5::StrType(H5::PredType::C_S1, H5T_VARIABLE));
5281
5282 // set magnetic field vector
5283 nxs->AddDataset<float>("/run/sample/magnetic_field_vector", {1.0, 1.0, 1.0}, {3}, H5::PredType::NATIVE_FLOAT);
5284 nxs->AddDatasetAttribute<float>("/run/sample/magnetic_field_vector", "coordinate_system", std::string("cartesian"));
5285 nxs->AddDatasetAttribute<float>("/run/sample/magnetic_field_vector", "units", std::string("Gauss"));
5286 nxs->AddDatasetAttribute<float>("/run/sample/magnetic_field_vector", "available", 0);
5287
5288 // set instrument name
5289 str = *fData[0].GetInstrument();
5290 nxs->AddDataset<std::string>("/run/instrument/name", {str}, {1}, H5::StrType(H5::PredType::C_S1, H5T_VARIABLE));
5291
5292 // set instrument number of detectors
5293 nxs->AddDataset<int>("/run/instrument/detector/number", {(int)fData[0].GetNoOfHistos()}, {1}, H5::PredType::NATIVE_INT32);
5294
5295 // set instrument collimator
5296 nxs->AddDataset<std::string>("/run/instrument/collimator/type", {std::string("n/a")}, {1}, H5::StrType(H5::PredType::C_S1, H5T_VARIABLE));
5297
5298 // set instrument beam total number of counts in Mev
5299 // calculate the total number of counts
5300 double total_counts = 0;
5301 PRawRunDataSet *dataSet = nullptr;
5302 for (unsigned int i=0; i<fData[0].GetNoOfHistos(); i++) {
5303 dataSet = fData[0].GetDataSet(i, false); // i.e. the false means, that i is the index and NOT the histo number
5304 if (dataSet == nullptr) { // something is really wrong
5305 std::cerr << std::endl << ">> PRunDataHandler::WriteNexusFile: **ERROR** Couldn't get data set (idx=0" << i << ")";
5306 std::cerr << std::endl << ">> something is really wrong!" << std::endl;
5307 return false;
5308 }
5309 for (unsigned int j=0; j<dataSet->GetData()->size(); j++)
5310 total_counts += dataSet->GetData()->at(j);
5311 }
5312 float total_counts_mev = (float) total_counts / 1.0e6;
5313 nxs->AddDataset<float>("/run/instrument/beam/total_counts", {total_counts_mev}, {1}, H5::PredType::NATIVE_FLOAT);
5314 nxs->AddDatasetAttribute<float>("/run/instrument/beam/total_counts", "units", std::string("MEv"));
5315
5316 // set time resolution (use FLOAT instead of INT)
5317 float res = (float)(fData[0].GetTimeResolution()*fAny2ManyInfo->rebin*1.0e3);
5318 nxs->AddDataset<float>("/run/histogram_data_1/resolution", {res}, {1}, H5::PredType::NATIVE_FLOAT);
5319 nxs->AddDatasetAttribute<float>("/run/histogram_data_1/resolution", "units", std::string("picoseconds"));
5320
5321 // set time zero time to 0. see t0_bin attribute of counts!
5322 nxs->AddDataset<int>("/run/histogram_data_1/time_zero", {0}, {1}, H5::PredType::NATIVE_INT32);
5323 nxs->AddDatasetAttribute<int>("/run/histogram_data_1/time_zero", "units", std::string("microseconds"));
5324 nxs->AddDatasetAttribute<int>("/run/histogram_data_1/time_zero", "available", 0);
5325
5326 // set raw_time
5327 res = (float)(fData[0].GetTimeResolution()*fAny2ManyInfo->rebin*1.0e-3);
5328 dataSet = fData[0].GetDataSet(0, false); // i.e. the false means, that i is the index and NOT the histo number
5329 unsigned int length = (int)(dataSet->GetData()->size() / fAny2ManyInfo->rebin);
5330 std::vector<float> time;
5331 for (unsigned int i=0; i<length; i++)
5332 time.push_back(((float)i+0.5)*res);
5333 nxs->AddDataset<float>("/run/histogram_data_1/raw_time", time, {length}, H5::PredType::NATIVE_FLOAT);
5334 nxs->AddDatasetAttribute<float>("/run/histogram_data_1/raw_time", "axis", 1);
5335 nxs->AddDatasetAttribute<float>("/run/histogram_data_1/raw_time", "primary", 0);
5336 nxs->AddDatasetAttribute<float>("/run/histogram_data_1/raw_time", "units", std::string("microseconds"));
5337 nxs->AddDatasetAttribute<float>("/run/histogram_data_1/raw_time", "available", 0);
5338
5339 // set corrected_time
5340 nxs->AddDataset<float>("/run/histogram_data_1/corrected_time", time, {length}, H5::PredType::NATIVE_FLOAT);
5341 nxs->AddDatasetAttribute<float>("/run/histogram_data_1/corrected_time", "axis", 1);
5342 nxs->AddDatasetAttribute<float>("/run/histogram_data_1/corrected_time", "units", std::string("microseconds"));
5343 nxs->AddDatasetAttribute<float>("/run/histogram_data_1/corrected_time", "available", 0);
5344
5345 // set grouping
5346 std::vector<int> grouping(fData[0].GetNoOfHistos(), 0);
5347 nxs->AddDataset<int>("/run/histogram_data_1/grouping", grouping, {grouping.size()}, H5::PredType::NATIVE_INT32);
5348 nxs->AddDatasetAttribute<int>("/run/histogram_data_1/grouping", "avaliabe", 0);
5349
5350 // set alpha
5351 int ival=1;
5352 nxs->AddDataset<int>("/run/histogram_data_1/alpha", {ival}, {1}, H5::PredType::NATIVE_INT32);
5353 nxs->AddDatasetAttribute<int>("/run/histogram_data_1/alpha", "avaliabe", 0);
5354
5355 // set counts
5356 // feed histos
5357 PIntVector data;
5358 UInt_t size = 0;
5359 int noHisto, histoLength;
5360 if (fAny2ManyInfo->rebin == 1) {
5361 noHisto = fData[0].GetNoOfHistos();
5362 for (UInt_t i=0; i<fData[0].GetNoOfHistos(); i++) {
5363 dataSet = fData[0].GetDataSet(i, false); // i.e. the false means, that i is the index and NOT the histo number
5364 if (dataSet == nullptr) { // something is really wrong
5365 std::cerr << std::endl << ">> PRunDataHandler::WriteNexusFile: **ERROR** Couldn't get data set (idx=" << i << ")";
5366 std::cerr << std::endl << ">> something is really wrong!" << std::endl;
5367 return false;
5368 }
5369 size = dataSet->GetData()->size();
5370 histoLength = size;
5371 for (UInt_t j=0; j<size; j++) {
5372 data.push_back((UInt_t)dataSet->GetData()->at(j));
5373 }
5374 }
5375 } else { // rebin > 1
5376 UInt_t dataRebin = 0;
5377 UInt_t dataCount = 0;
5378 noHisto = fData[0].GetNoOfHistos();
5379 for (UInt_t i=0; i<fData[0].GetNoOfHistos(); i++) {
5380 dataSet = fData[0].GetDataSet(i, false); // i.e. the false means, that i is the index and NOT the histo number
5381 if (dataSet == nullptr) { // something is really wrong
5382 std::cerr << std::endl << ">> PRunDataHandler::WriteNexusFile: **ERROR** Couldn't get data set (idx=" << i << ")";
5383 std::cerr << std::endl << ">> something is really wrong!" << std::endl;
5384 return false;
5385 }
5386 size = dataSet->GetData()->size();
5387 dataCount = 0;
5388 for (UInt_t j=0; j<size; j++) {
5389 if ((j > 0) && (j % fAny2ManyInfo->rebin == 0)) {
5390 dataCount++;
5391 data.push_back(dataRebin);
5392 dataRebin = 0;
5393 }
5394 dataRebin += static_cast<UInt_t>(dataSet->GetData()->at(j));
5395 }
5396 }
5397 size = dataCount;
5398 }
5399 nxs->AddDataset<int>("/run/histogram_data_1/counts", data, {(long unsigned int)noHisto, size}, H5::PredType::NATIVE_INT32);
5400 nxs->AddDatasetAttribute<int>("/run/histogram_data_1/counts", "units", std::string("counts"));
5401 nxs->AddDatasetAttribute<int>("/run/histogram_data_1/counts", "signal", 1);
5402 nxs->AddDatasetAttribute<int>("/run/histogram_data_1/counts", "number", noHisto);
5403 nxs->AddDatasetAttribute<int>("/run/histogram_data_1/counts", "length", size);
5404 nxs->AddDatasetAttribute<int>("/run/histogram_data_1/counts", "t0_bin", 0);
5405 nxs->AddDatasetAttribute<int>("/run/histogram_data_1/counts", "first_good_bin", 0);
5406 nxs->AddDatasetAttribute<int>("/run/histogram_data_1/counts", "last_good_bin", 0);
5407 res = (float)(fData[0].GetTimeResolution()*fAny2ManyInfo->rebin*1.0e3)/2.0;
5408 nxs->AddDatasetAttribute<int>("/run/histogram_data_1/counts", "offset", res);
5409 } else { // IDF V2
5410 nxs->AddGroupAttribute("/raw_data_1", "NX_class", std::string("NXentry"));
5411
5412 // set IDF version
5413 nxs->AddDataset<int>("/raw_data_1/IDF_version", {(int)fAny2ManyInfo->idf}, {1}, H5::PredType::NATIVE_INT32);
5414
5415 // set beamline
5416 str = *fData[0].GetBeamline();
5417 nxs->AddDataset<std::string>("/raw_data_1/beamline", {str}, {1}, H5::StrType(H5::PredType::C_S1, H5T_VARIABLE));
5418
5419 // set definition
5420 nxs->AddDataset<std::string>("/raw_data_1/definition", {std::string("muonTD")}, {1}, H5::StrType(H5::PredType::C_S1, H5T_VARIABLE));
5421
5422 // set run_number
5423 nxs->AddDataset<int>("/raw_data_1/run_number", {fData[0].GetRunNumber()}, {1}, H5::PredType::NATIVE_INT32);
5424
5425 // set title
5426 nxs->AddDataset<std::string>("/raw_data_1/title", {fData[0].GetRunTitle()->Data()}, {1}, H5::StrType(H5::PredType::C_S1, H5T_VARIABLE));
5427
5428 // set start time
5429 str = std::string(fData[0].GetStartDate()->Data()) + std::string("T") + std::string(fData[0].GetStartTime()->Data());
5430 nxs->AddDataset<std::string>("/raw_data_1/start_time", {str}, {1}, H5::StrType(H5::PredType::C_S1, H5T_VARIABLE));
5431 nxs->AddDatasetAttribute<std::string>("/raw_data_1/start_time", "units", "ISO8601");
5432
5433 // set end time
5434 str = std::string(fData[0].GetStopDate()->Data()) + std::string("T") + std::string(fData[0].GetStopTime()->Data());
5435 nxs->AddDataset<std::string>("/raw_data_1/end_time", {str}, {1}, H5::StrType(H5::PredType::C_S1, H5T_VARIABLE));
5436 nxs->AddDatasetAttribute<std::string>("/raw_data_1/end_time", "units", "ISO8601");
5437
5438 // set experiment_identifier
5439 str = "n/a";
5440 nxs->AddDataset<std::string>("/raw_data_1/experiment_identifier", {str}, {1}, H5::StrType(H5::PredType::C_S1, H5T_VARIABLE));
5441
5442 // set instrument attribute
5443 nxs->AddGroupAttribute("/raw_data_1/instrument", "NX_class", std::string("NXinstrument"));
5444
5445 // set instrument name
5446 str = *fData[0].GetInstrument();
5447 nxs->AddDataset<std::string>("/raw_data_1/instrument/name", {str}, {1}, H5::StrType(H5::PredType::C_S1, H5T_VARIABLE));
5448
5449 // set instrument/source attribute
5450 nxs->AddGroupAttribute("/raw_data_1/instrument/source", "NX_class", std::string("NXsource"));
5451
5452 // set instrument/source/name
5453 str = fData[0].GetLaboratory()->Data();
5454 nxs->AddDataset<std::string>("/raw_data_1/instrument/source/name", {str}, {1}, H5::StrType(H5::PredType::C_S1, H5T_VARIABLE));
5455
5456 // set instrument/source/type
5457 TString tstr = *fData[0].GetInstrument();
5458 std::string type{"n/a"};
5459 if (tstr.Contains("LEM", TString::kIgnoreCase)) {
5460 type = "low energy muon source";
5461 } else if (tstr.Contains("GPS", TString::kIgnoreCase) || tstr.Contains("GPD", TString::kIgnoreCase) ||
5462 tstr.Contains("LTF", TString::kIgnoreCase) || tstr.Contains("FLAME", TString::kIgnoreCase) ||
5463 tstr.Contains("HAL-9500", TString::kIgnoreCase) || tstr.Contains("DOLLY", TString::kIgnoreCase) ||
5464 tstr.Contains("VMS", TString::kIgnoreCase)) {
5465 type = "quasi-continous muon source";
5466 } else if (tstr.Contains("EMU", TString::kIgnoreCase) || tstr.Contains("MUSR", TString::kIgnoreCase) ||
5467 tstr.Contains("HIFI", TString::kIgnoreCase)) {
5468 type = "pulsed muon source";
5469 }
5470 nxs->AddDataset<std::string>("/raw_data_1/instrument/source/type", {type}, {1}, H5::StrType(H5::PredType::C_S1, H5T_VARIABLE));
5471
5472 // set instrument/source/probe
5473 str = "positive muons";
5474 nxs->AddDataset<std::string>("/raw_data_1/instrument/source/probe", {str}, {1}, H5::StrType(H5::PredType::C_S1, H5T_VARIABLE));
5475
5476 // set instrument/detector info
5477 nxs->AddGroupAttribute("/raw_data_1/instrument/detector_1", "NX_class", std::string("NXdetector"));
5478
5479 // set instrument/detector/spectrum_index
5480 int noHistos = fData[0].GetNoOfHistos();
5481 std::vector<int> spectrum_index(noHistos);
5482 for (unsigned int i=0; i<spectrum_index.size(); i++)
5483 spectrum_index[i] = i+1;
5484 nxs->AddDataset<int>("/raw_data_1/instrument/detector_1/spectrum_index", spectrum_index, {spectrum_index.size()}, H5::PredType::NATIVE_INT32);
5485
5486 // set instrument/detector/raw_time (not useful for quasi-continuous sources)
5487 int ival=0;
5488 nxs->AddDataset<int>("/raw_data_1/instrument/detector_1/raw_time", {ival}, {1}, H5::PredType::NATIVE_INT32);
5489 nxs->AddDatasetAttribute<int>("/raw_data_1/instrument/detector_1/raw_time", "available", 0);
5490
5491 // set instrument/detector/counts
5492 // set counts
5493 // feed histos
5494 PRawRunDataSet *dataSet = nullptr;
5495 PIntVector data;
5496 UInt_t size = 0;
5497 int noHisto, histoLength;
5498 if (fAny2ManyInfo->rebin == 1) {
5499 noHisto = fData[0].GetNoOfHistos();
5500 for (UInt_t i=0; i<fData[0].GetNoOfHistos(); i++) {
5501 dataSet = fData[0].GetDataSet(i, false); // i.e. the false means, that i is the index and NOT the histo number
5502 if (dataSet == nullptr) { // something is really wrong
5503 std::cerr << std::endl << ">> PRunDataHandler::WriteNexusFile: **ERROR** Couldn't get data set (idx=" << i << ")";
5504 std::cerr << std::endl << ">> something is really wrong!" << std::endl;
5505 return false;
5506 }
5507 size = dataSet->GetData()->size();
5508 histoLength = size;
5509 for (UInt_t j=0; j<size; j++) {
5510 data.push_back((UInt_t)dataSet->GetData()->at(j));
5511 }
5512 }
5513 } else { // rebin > 1
5514 UInt_t dataRebin = 0;
5515 UInt_t dataCount = 0;
5516 noHisto = fData[0].GetNoOfHistos();
5517 for (UInt_t i=0; i<fData[0].GetNoOfHistos(); i++) {
5518 dataSet = fData[0].GetDataSet(i, false); // i.e. the false means, that i is the index and NOT the histo number
5519 if (dataSet == nullptr) { // something is really wrong
5520 std::cerr << std::endl << ">> PRunDataHandler::WriteNexusFile: **ERROR** Couldn't get data set (idx=" << i << ")";
5521 std::cerr << std::endl << ">> something is really wrong!" << std::endl;
5522 return false;
5523 }
5524 size = dataSet->GetData()->size();
5525 dataCount = 0;
5526 for (UInt_t j=0; j<size; j++) {
5527 if ((j > 0) && (j % fAny2ManyInfo->rebin == 0)) {
5528 dataCount++;
5529 data.push_back(dataRebin);
5530 dataRebin = 0;
5531 }
5532 dataRebin += static_cast<UInt_t>(dataSet->GetData()->at(j));
5533 }
5534 }
5535 size = dataCount;
5536 }
5537 nxs->AddDataset<int>("/raw_data_1/instrument/detector_1/counts", data, {(long unsigned int)noHisto, size}, H5::PredType::NATIVE_INT32);
5538 nxs->AddDatasetAttribute<int>("/raw_data_1/instrument/detector_1/counts", "axes", std::string("spectrum_index,time_bin"));
5539 nxs->AddDatasetAttribute<int>("/raw_data_1/instrument/detector_1/counts", "long_name", std::string("positon counts"));
5540 nxs->AddDatasetAttribute<int>("/raw_data_1/instrument/detector_1/counts", "signal", 1);
5541 // t0_bin attributes
5542 std::vector<int> t0_bin;
5543 for (unsigned int i=0; i<fData[0].GetNoOfHistos(); i++)
5544 t0_bin.push_back((int)(fData[0].GetT0Bin(i+1)/fAny2ManyInfo->rebin));
5545 nxs->AddDatasetAttribute<int>("/raw_data_1/instrument/detector_1/counts", "t0_bin", {t0_bin});
5546 nxs->AddDatasetAttribute<int>("/raw_data_1/instrument/detector_1/counts", "units", std::string("counts"));
5547
5548 // set raw_data_1/detector info
5549 nxs->AddGroupAttribute("/raw_data_1/detector_1", "NX_class", std::string("NXdata"));
5550
5551 // set detector/counts
5552 nxs->AddDataset<int>("/raw_data_1/detector_1/counts", data, {(long unsigned int)noHisto, size}, H5::PredType::NATIVE_INT32);
5553 nxs->AddDatasetAttribute<int>("/raw_data_1/detector_1/counts", "axes", std::string("spectrum_index,time_bin"));
5554 nxs->AddDatasetAttribute<int>("/raw_data_1/detector_1/counts", "long_name", std::string("positon counts"));
5555 nxs->AddDatasetAttribute<int>("/raw_data_1/detector_1/counts", "signal", 1);
5556 }
5557
5558 int result = nxs->WriteNexusFile(fln.Data(), fAny2ManyInfo->idf);
5559 if (result != 0) {
5560 std::cerr << std::endl << "**ERROR** PRunDataHandler::WriteNexusFile, fln=" << fln << std::endl;
5561 return false;
5562 }
5563 } catch (const H5::Exception& e) {
5564 std::cerr << std::endl << "HDF5 error: " << e.getDetailMsg() << std::endl;
5565 }
5566 }
5567
5568 return true;
5569#else
5570 std::cout << std::endl << ">> PRunDataHandler::WriteNexusFile(): Sorry, not enabled at configuration level, i.e. -Dnexus=1 when executing configure" << std::endl << std::endl;
5571#endif
5572
5573 return true;
5574}
5575
5576//--------------------------------------------------------------------------
5577// WriteWkmFile (private)
5578//--------------------------------------------------------------------------
5589{
5590 // check if a LEM nemu file needs to be written
5591 bool lem_wkm_style = false;
5592 if (!fData[0].GetBeamline()->CompareTo("mue4", TString::kIgnoreCase))
5593 lem_wkm_style = true;
5594
5595 Bool_t ok = false;
5596 if (lem_wkm_style)
5597 fln = GenerateOutputFileName(fln, ".nemu", ok);
5598 else
5599 fln = GenerateOutputFileName(fln, ".wkm", ok);
5600
5601 if (!ok)
5602 return false;
5603
5604 TString fileName = fln;
5605
5606 if (!fAny2ManyInfo->useStandardOutput)
5607 std::cout << std::endl << ">> PRunDataHandler::WriteWkmFile(): writing a wkm data file (" << fln.Data() << ") ... " << std::endl;
5608
5609 // write ascii file
5610 std::ofstream fout;
5611 std::streambuf* strm_buffer = nullptr;
5612
5613 if (!fAny2ManyInfo->useStandardOutput || (fAny2ManyInfo->compressionTag > 0)) {
5614 // open data-file
5615 fout.open(fln.Data(), std::ofstream::out);
5616 if (!fout.is_open()) {
5617 std::cerr << std::endl << ">> PRunDataHandler::WriteWkmFile **ERROR** Couldn't open data file (" << fln.Data() << ") for writing, sorry ...";
5618 std::cerr << std::endl;
5619 return false;
5620 }
5621
5622 // save output buffer of the stream
5623 strm_buffer = std::cout.rdbuf();
5624
5625 // redirect output into the file
5626 std::cout.rdbuf(fout.rdbuf());
5627 }
5628
5629 // write header
5630 std::cout << "- WKM data file converted with any2many";
5631 if (lem_wkm_style) {
5632 std::cout << std::endl << "NEMU_Run: " << fData[0].GetRunNumber();
5633 std::cout << std::endl << "nemu_Run: " << fileName.Data();
5634 } else {
5635 std::cout << std::endl << "Run: " << fData[0].GetRunNumber();
5636 }
5637 std::cout << std::endl << "Date: " << fData[0].GetStartTime()->Data() << " " << fData[0].GetStartDate()->Data() << " / " << fData[0].GetStopTime()->Data() << " " << fData[0].GetStopDate()->Data();
5638 if (fData[0].GetRunTitle()->Length() > 0)
5639 std::cout << std::endl << "Title: " << fData[0].GetRunTitle()->Data();
5640 if (fData[0].GetField() != PMUSR_UNDEFINED) {
5641 std::cout << std::endl << "Field: " << fData[0].GetField();
5642 } else {
5643 std::cout << std::endl << "Field: ??";
5644 }
5645 std::cout << std::endl << "Setup: " << fData[0].GetSetup()->Data();
5646 if (fData[0].GetNoOfTemperatures() == 1) {
5647 std::cout << std::endl << "Temp: " << fData[0].GetTemperature(0);
5648 } else if (fData[0].GetNoOfTemperatures() > 1) {
5649 std::cout << std::endl << "Temp(meas1): " << fData[0].GetTemperature(0) << " +- " << fData[0].GetTempError(0);
5650 std::cout << std::endl << "Temp(meas2): " << fData[0].GetTemperature(1) << " +- " << fData[0].GetTempError(1);
5651 } else {
5652 std::cout << std::endl << "Temp: ??";
5653 }
5654 if (lem_wkm_style)
5655 std::cout << std::endl << "TOF(M3S1): nocut";
5656 std::cout << std::endl << "Groups: " << fData[0].GetNoOfHistos();
5657 UInt_t histo0 = 1;
5658 if (fAny2ManyInfo->groupHistoList.size() != 0) { // red/green list found
5659 histo0 = fAny2ManyInfo->groupHistoList[0]+1; // take the first available red/green entry
5660 }
5661 std::cout << std::endl << "Channels: " << static_cast<UInt_t>(fData[0].GetDataBin(histo0)->size()/fAny2ManyInfo->rebin);
5662 std::cout.precision(10);
5663 std::cout << std::endl << "Resolution: " << fData[0].GetTimeResolution()*fAny2ManyInfo->rebin/1.0e3; // ns->us
5664 std::cout.setf(std::ios::fixed,std::ios::floatfield); // floatfield set to fixed
5665
5666 // write data
5667 UInt_t no_of_bins_per_line = 16;
5668 if (lem_wkm_style)
5669 no_of_bins_per_line = 10;
5670
5671 PRawRunDataSet *dataSet;
5672
5673 if (fAny2ManyInfo->rebin == 1) {
5674 for (UInt_t i=0; i<fData[0].GetNoOfHistos(); i++) {
5675 std::cout << std::endl << std::endl;
5676 dataSet = fData[0].GetDataSet(i, false); // i.e. the false means, that i is the index and NOT the histo number
5677 for (UInt_t j=0; j<dataSet->GetData()->size(); j++) {
5678 if ((j > 0) && (j % no_of_bins_per_line == 0))
5679 std::cout << std::endl;
5680 if (lem_wkm_style)
5681 std::cout << std::setw(8) << static_cast<Int_t>(dataSet->GetData()->at(j));
5682 else
5683 std::cout << static_cast<Int_t>(dataSet->GetData()->at(j)) << " ";
5684 }
5685 }
5686 } else { // rebin > 1
5687 Int_t dataRebin = 0;
5688 UInt_t count = 0;
5689 for (UInt_t i=0; i<fData[0].GetNoOfHistos(); i++) {
5690 std::cout << std::endl << std::endl;
5691 count = 0;
5692 dataRebin = 0; // reset rebin
5693 dataSet = fData[0].GetDataSet(i, false); // i.e. the false means, that i is the index and NOT the histo number
5694 for (UInt_t j=0; j<dataSet->GetData()->size(); j++) {
5695 if ((j > 0) && (j % fAny2ManyInfo->rebin == 0)) {
5696 if (lem_wkm_style)
5697 std::cout << std::setw(8) << dataRebin;
5698 else
5699 std::cout << dataRebin << " ";
5700 count++;
5701 dataRebin = 0;
5702 if ((count > 0) && (count % no_of_bins_per_line == 0) && (j != dataSet->GetData()->size()-1))
5703 std::cout << std::endl;
5704 } else {
5705 dataRebin += static_cast<Int_t>(dataSet->GetData()->at(j));
5706 }
5707 }
5708 }
5709 }
5710
5711 if (!fAny2ManyInfo->useStandardOutput || (fAny2ManyInfo->compressionTag > 0)) {
5712 // restore old output buffer
5713 std::cout.rdbuf(strm_buffer);
5714
5715 fout.close();
5716 }
5717
5718 return true;
5719}
5720
5721//--------------------------------------------------------------------------
5722// WritePsiBinFile (private)
5723//--------------------------------------------------------------------------
5734{
5735 Bool_t ok = false;
5736 fln = GenerateOutputFileName(fln, ".bin", ok);
5737 if (!ok)
5738 return false;
5739
5740 if (!fAny2ManyInfo->useStandardOutput)
5741 std::cout << std::endl << ">> PRunDataHandler::WritePsiBinFile(): writing a psi-bin data file (" << fln.Data() << ") ... " << std::endl;
5742
5743 MuSR_td_PSI_bin psibin;
5744 int status = 0;
5745
5746 // fill header information
5747 // run number
5748 psibin.PutRunNumberInt(fData[0].GetRunNumber());
5749 // length of histograms
5750 UInt_t histo0 = 1;
5751 if (fAny2ManyInfo->groupHistoList.size() != 0) { // red/green list found
5752 histo0 = fAny2ManyInfo->groupHistoList[0]+1; // take the first available red/green entry
5753 }
5754 psibin.PutHistoLengthBin(static_cast<int>(fData[0].GetDataBin(histo0)->size()/fAny2ManyInfo->rebin));
5755 // number of histograms
5756 psibin.PutNumberHistoInt(static_cast<int>(fData[0].GetNoOfHistos()));
5757 // run title = sample (10 char) / temp (10 char) / field (10 char) / orientation (10 char)
5758 char cstr[11];
5759 // sample
5760 if (fData[0].GetSample()->Length() > 0)
5761 strncpy(cstr, fData[0].GetSample()->Data(), 10);
5762 else
5763 strcpy(cstr, "??");
5764 cstr[10] = '\0';
5765 psibin.PutSample(cstr);
5766 // temp
5767 if (fData[0].GetNoOfTemperatures() > 0)
5768 snprintf(cstr, 10, "%.1f K", fData[0].GetTemperature(0));
5769 else
5770 strcpy(cstr, "?? K");
5771 cstr[10] = '\0';
5772 psibin.PutTemp(cstr);
5773 // field
5774 if (fData[0].GetField() > 0)
5775 snprintf(cstr, 10, "%.1f G", fData[0].GetField());
5776 else
5777 strcpy(cstr, "?? G");
5778 cstr[10] = '\0';
5779 psibin.PutField(cstr);
5780 // orientation
5781 if (fData[0].GetOrientation()->Length() > 0)
5782 strncpy(cstr, fData[0].GetOrientation()->Data(), 10);
5783 else
5784 strcpy(cstr, "??");
5785 cstr[10] = '\0';
5786 psibin.PutOrient(cstr);
5787 // setup
5788 if (fData[0].GetSetup()->Length() > 0)
5789 strncpy(cstr, fData[0].GetSetup()->Data(), 10);
5790 else
5791 strcpy(cstr, "??");
5792 cstr[10] = '\0';
5793 psibin.PutSetup(cstr);
5794
5795 // handle PSI-BIN start/stop Time/Date. PSI-BIN requires: Time -> HH:MM:SS, and Date -> DD-MMM-YY
5796 // internally given: Time -> HH:MM:SS, and Date -> YYYY-MM-DD
5797 // run start date
5798 std::vector<std::string> svec;
5799 TString str, date;
5800 TDatime dt;
5801 int year, month, day;
5802
5803 // 28-Aug-2014, TP: the following line does not work, it generates the wrong date
5804 //dt.Set(fData[0].GetStartDateTime()); //as35
5805 // the following generates the correct date entry
5806 date.Append(*fData[0].GetStartDate());
5807 sscanf((const char*)date.Data(),"%04d-%02d-%02d", &year, &month, &day);
5808 dt.Set(year, month, day, 0, 0, 0);
5809
5810 date.Form("%02d-", dt.GetDay());
5811 date.Append(GetMonth(dt.GetMonth()));
5812 date.Append("-");
5813 date.Append(GetYear(dt.GetYear()));
5814 strncpy(cstr, date.Data(), 9);
5815 cstr[9] = '\0';
5816 svec.push_back(cstr);
5817 // run start time
5818 strncpy(cstr, fData[0].GetStartTime()->Data(), 8);
5819 cstr[8] = '\0';
5820 svec.push_back(cstr);
5821 psibin.PutTimeStartVector(svec);
5822 svec.clear();
5823
5824 // run stop date
5825 // 28-Aug-2014, TP: the following line does not work, it generates the wrong date
5826 //dt.Set(fData[0].GetStopDateTime());
5827 // the following generates the correct date entry
5828 date.Clear();
5829 date.Append(*fData[0].GetStopDate());
5830 sscanf((const char*)date.Data(),"%04d-%02d-%02d", &year, &month, &day);
5831 dt.Set(year, month, day, 0, 0, 0);
5832
5833 date.Form("%02d-", dt.GetDay());
5834 date.Append(GetMonth(dt.GetMonth()));
5835 date.Append("-");
5836 date.Append(GetYear(dt.GetYear()));
5837 strncpy(cstr, date.Data(), 9);
5838 cstr[9] = '\0';
5839 svec.push_back(cstr);
5840 // run stop time
5841 strncpy(cstr, fData[0].GetStopTime()->Data(), 8);
5842 cstr[8] = '\0';
5843 svec.push_back(cstr);
5844 psibin.PutTimeStopVector(svec);
5845 svec.clear();
5846
5847 // number of measured temperatures
5848 psibin.PutNumberTemperatureInt(fData[0].GetNoOfTemperatures());
5849
5850 // mean temperatures
5851 std::vector<double> dvec;
5852 for (UInt_t i=0; i<fData[0].GetNoOfTemperatures(); i++)
5853 dvec.push_back(fData[0].GetTemperature(i));
5854 psibin.PutTemperaturesVector(dvec);
5855
5856 // standard deviation of temperatures
5857 dvec.clear();
5858 for (UInt_t i=0; i<fData[0].GetNoOfTemperatures(); i++)
5859 dvec.push_back(fData[0].GetTempError(i));
5860 psibin.PutDevTemperaturesVector(dvec);
5861
5862 // write comment
5863 psibin.PutComment(fData[0].GetRunTitle()->Data());
5864
5865 // write time resolution
5866 psibin.PutBinWidthNanoSec(fData[0].GetTimeResolution()*fAny2ManyInfo->rebin);
5867
5868 // write scaler dummies
5869 psibin.PutNumberScalerInt(0);
5870
5871 // feed detector related info like, histogram names, t0, fgb, lgb
5872 Int_t ival = 0;
5873 PRawRunDataSet *dataSet;
5874 UInt_t size = fData[0].GetNoOfHistos();
5875 // collect histo names in order to see if they are still unique after cropping to 4 char.
5876 PStringVector hName, hNCrop;
5877 TString sCrop;
5878 for (UInt_t i=0; i<size; i++) {
5879 dataSet = fData[0].GetDataSet(i, false); // i.e. the false means, that i is the index and NOT the histo number
5880 // detector name
5881 str = dataSet->GetName();
5882 hName.push_back(str);
5883 sCrop = str;
5884 sCrop.Remove(4);
5885 hNCrop.push_back(sCrop);
5886 }
5887 // check cropped for uniqueness
5888 ival = 1;
5889 for (UInt_t i=0; i<size; i++) {
5890 for (UInt_t j=i+1; j<size; j++) {
5891 if (hNCrop[i] == hNCrop[j]) {
5892 std::string nn = std::to_string(ival);
5893 hNCrop[j][3] = nn[0];
5894 ival++;
5895 }
5896 }
5897 }
5898 // handle rest of the detectors
5899 for (UInt_t i=0; i<size; i++) {
5900 dataSet = fData[0].GetDataSet(i, false); // i.e. the false means, that i is the index and NOT the histo number
5901 if (dataSet == nullptr) { // something is really wrong
5902 std::cerr << std::endl << ">> PRunDataHandler::WritePsiBinFile: **ERROR** Couldn't get data set (idx=" << i << ")";
5903 std::cerr << std::endl << ">> something is really wrong!" << std::endl;
5904 return false;
5905 }
5906
5907 // detector name
5908 psibin.PutNameHisto(hNCrop[i].Data(), i);
5909 // time zero bin
5910 ival = static_cast<Int_t>(dataSet->GetTimeZeroBin()/fAny2ManyInfo->rebin);
5911 psibin.PutT0Int(i, ival);
5912 // first good bin
5913 ival = static_cast<Int_t>(dataSet->GetFirstGoodBin()/fAny2ManyInfo->rebin);
5914 psibin.PutFirstGoodInt(i, ival);
5915 // last good bin
5916 ival = static_cast<Int_t>(dataSet->GetLastGoodBin()/fAny2ManyInfo->rebin);
5917 psibin.PutLastGoodInt(i, ival);
5918 }
5919
5920 // feed histos
5921 std::vector< std::vector<int> > histos;
5922 histos.resize(fData[0].GetNoOfHistos());
5923 UInt_t length = 0;
5924 if (fAny2ManyInfo->rebin == 1) {
5925 for (UInt_t i=0; i<size; i++) {
5926 dataSet = fData[0].GetDataSet(i, false); // i.e. the false means, that i is the index and NOT the histo number
5927 if (dataSet == nullptr) { // something is really wrong
5928 std::cerr << std::endl << ">> PRunDataHandler::WritePsiBinFile: **ERROR** Couldn't get data set (idx=" << i << ")";
5929 std::cerr << std::endl << ">> something is really wrong!" << std::endl;
5930 return false;
5931 }
5932 length = dataSet->GetData()->size();
5933 histos[i].resize(length);
5934 for (UInt_t j=0; j<length; j++) {
5935 histos[i][j] = static_cast<Int_t>(dataSet->GetData()->at(j));
5936 }
5937 }
5938 } else { // rebin > 1
5939 UInt_t dataRebin = 0;
5940 UInt_t dataCount = 0;
5941 for (UInt_t i=0; i<size; i++) {
5942 dataSet = fData[0].GetDataSet(i, false); // i.e. the false means, that i is the index and NOT the histo number
5943 if (dataSet == nullptr) { // something is really wrong
5944 std::cerr << std::endl << ">> PRunDataHandler::WritePsiBinFile: **ERROR** Couldn't get data set (idx=" << i << ")";
5945 std::cerr << std::endl << ">> something is really wrong!" << std::endl;
5946 return false;
5947 }
5948 length = dataSet->GetData()->size();
5949 dataCount = 0;
5950 for (UInt_t j=0; j<length; j++) {
5951 if ((j > 0) && (j % fAny2ManyInfo->rebin == 0)) {
5952 dataCount++;
5953 histos[i].push_back(dataRebin);
5954 dataRebin = 0;
5955 }
5956 dataRebin += static_cast<UInt_t>(dataSet->GetData()->at(j));
5957 }
5958 }
5959 }
5960 status = psibin.PutHistoArrayInt(histos, 2); // tag 2 means: lift histo length restriction on only make sure it is < 32512
5961 if (status != 0) {
5962 std::cerr << std::endl << ">> PRunDataHandler::WritePsiBinFile(): " << psibin.ConsistencyStatus() << std::endl;
5963 return false;
5964 }
5965
5966 if (!psibin.CheckDataConsistency(2)) {
5967 std::cerr << std::endl << ">> PRunDataHandler::WritePsiBinFile(): " << psibin.ConsistencyStatus() << std::endl;
5968 return false;
5969 }
5970
5971 // write data to file
5972 status = psibin.Write(fln.Data());
5973
5974 if (status != 0) {
5975 std::cerr << std::endl << ">> PRunDataHandler::WritePsiBinFile(): " << psibin.WriteStatus() << std::endl;
5976 return false;
5977 }
5978
5979 return true;
5980}
5981
5982//--------------------------------------------------------------------------
5983// WriteMudFile (private)
5984//--------------------------------------------------------------------------
5995{
5996 Bool_t ok = false;
5997 fln = GenerateOutputFileName(fln, ".msr", ok);
5998 if (!ok)
5999 return false;
6000
6001 if (!fAny2ManyInfo->useStandardOutput)
6002 std::cout << std::endl << ">> PRunDataHandler::WriteMudFile(): writing a mud data file (" << fln.Data() << ") ... " << std::endl;
6003
6004 // generate the mud data file
6005 int fd = MUD_openWrite((char*)fln.Data(), MUD_FMT_TRI_TD_ID);
6006 if (fd == -1) {
6007 std::cerr << std::endl << ">> PRunDataHandler::WriteMudFile(): **ERROR** couldn't open mud data file for write ..." << std::endl;
6008 return false;
6009 }
6010
6011 // generate header information
6012 char dummy[32], info[128];
6013 strcpy(dummy, "???");
6015 MUD_setExptNumber(fd, 0);
6016 MUD_setRunNumber(fd, fData[0].GetRunNumber());
6017 Int_t ival = fData[0].GetStopDateTime()-fData[0].GetStartDateTime();
6018 MUD_setElapsedSec(fd, ival);
6019 MUD_setTimeBegin(fd, fData[0].GetStartDateTime());
6020 MUD_setTimeEnd(fd, fData[0].GetStopDateTime());
6021 MUD_setTitle(fd, (char *)fData[0].GetRunTitle()->Data());
6022 MUD_setLab(fd, (char *)fData[0].GetLaboratory()->Data());
6023 MUD_setArea(fd, (char *)fData[0].GetBeamline()->Data());
6024 MUD_setMethod(fd, (char *)fData[0].GetSetup()->Data());
6025 MUD_setApparatus(fd, (char *)fData[0].GetInstrument()->Data());
6026 MUD_setInsert(fd, dummy);
6027 MUD_setSample(fd, (char *)fData[0].GetSample()->Data());
6028 MUD_setOrient(fd, (char *)fData[0].GetOrientation()->Data());
6029 MUD_setDas(fd, dummy);
6030 MUD_setExperimenter(fd, dummy);
6031 snprintf(info, sizeof(info), "%lf+-%lf (K)", fData[0].GetTemperature(0), fData[0].GetTempError(0));
6032 MUD_setTemperature(fd, info);
6033 snprintf(info, sizeof(info), "%lf", fData[0].GetField());
6034 MUD_setField(fd, info);
6035
6036 // generate the histograms
6037 MUD_setHists(fd, MUD_GRP_TRI_TD_HIST_ID, fData[0].GetNoOfHistos());
6038
6039 UInt_t *data, dataSize = fData[0].GetDataSet(0, false)->GetData()->size()/fAny2ManyInfo->rebin + 1;
6040 data = new UInt_t[dataSize];
6041 if (data == nullptr) {
6042 std::cerr << std::endl << ">> PRunDataHandler::WriteMudFile(): **ERROR** couldn't allocate memory for the data ..." << std::endl;
6043 MUD_closeWrite(fd);
6044 return false;
6045 }
6046
6047 UInt_t noOfEvents = 0, k = 0;
6048 ival = 0;
6049 PRawRunDataSet *dataSet;
6050 for (UInt_t i=0; i<fData[0].GetNoOfHistos(); i++) {
6051 dataSet = fData[0].GetDataSet(i, false); // i.e. the false means, that i is the index and NOT the histo number
6052 if (dataSet == nullptr) { // something is really wrong
6053 std::cerr << std::endl << ">> PRunDataHandler::WriteMudFile: **ERROR** Couldn't get data set (idx=" << i << ")";
6054 std::cerr << std::endl << ">> something is really wrong!" << std::endl;
6055 return false;
6056 }
6057
6058 // fill data
6059 for (UInt_t j=0; j<dataSize; j++)
6060 data[j] = 0;
6061 noOfEvents = 0;
6062 k = 0;
6063 for (UInt_t j=0; j<dataSet->GetData()->size(); j++) {
6064 if ((j > 0) && (j % fAny2ManyInfo->rebin == 0)) {
6065 data[k] = ival;
6066 noOfEvents += ival;
6067 k++;
6068 ival = 0;
6069 }
6070 ival += static_cast<UInt_t>(dataSet->GetData()->at(j));
6071 }
6072
6073 // feed data relevant information
6074 // the numbering of the histograms start from '1', hence i+1 needed!!
6075 MUD_setHistType(fd, i+1, MUD_GRP_TRI_TD_HIST_ID);
6076 MUD_setHistNumBytes(fd, i+1, sizeof(data));
6077 MUD_setHistNumBins(fd, i+1, dataSize);
6078 MUD_setHistBytesPerBin(fd, i+1, 0);
6079 MUD_setHistFsPerBin(fd, i+1, static_cast<UINT32>(1.0e6*fAny2ManyInfo->rebin*fData[0].GetTimeResolution())); // time resolution is given in (ns)
6080 MUD_setHistT0_Ps(fd, i+1, static_cast<UINT32>(1.0e3*fData[0].GetTimeResolution()*((dataSet->GetTimeZeroBin()+fAny2ManyInfo->rebin/2)/fAny2ManyInfo->rebin)));
6081 MUD_setHistT0_Bin(fd, i+1, static_cast<UINT32>(dataSet->GetTimeZeroBin()/fAny2ManyInfo->rebin));
6082 MUD_setHistGoodBin1(fd, i+1, static_cast<UINT32>(dataSet->GetFirstGoodBin()/fAny2ManyInfo->rebin));
6083 MUD_setHistGoodBin2(fd, i+1, static_cast<UINT32>(dataSet->GetLastGoodBin()/fAny2ManyInfo->rebin));
6084 MUD_setHistBkgd1(fd, i+1, 0);
6085 MUD_setHistBkgd2(fd, i+1, 0);
6086 MUD_setHistNumEvents(fd, i+1, (UINT32)noOfEvents);
6087 MUD_setHistTitle(fd, i+1, (char *)dataSet->GetName().Data());
6088 REAL64 timeResolution = (fAny2ManyInfo->rebin*fData[0].GetTimeResolution())/1.0e9; // ns -> s
6089 MUD_setHistSecondsPerBin(fd, i+1, timeResolution);
6090
6091 MUD_setHistData(fd, i+1, data);
6092 }
6093
6094 MUD_closeWrite(fd);
6095
6096 delete [] data;
6097
6098 // check if mud file shall be streamed to stdout
6099 if (fAny2ManyInfo->useStandardOutput && (fAny2ManyInfo->compressionTag == 0)) {
6100 // stream file to stdout
6101 std::ifstream is;
6102 int length=1024;
6103 char *buffer;
6104
6105 is.open(fln.Data(), std::ios::binary);
6106 if (!is.is_open()) {
6107 std::cerr << std::endl << "PRunDataHandler::WriteMudFile(): **ERROR** Couldn't open the mud-file for streaming." << std::endl;
6108 remove(fln.Data());
6109 return false;
6110 }
6111
6112 // get length of file
6113 is.seekg(0, std::ios::end);
6114 length = is.tellg();
6115 is.seekg(0, std::ios::beg);
6116
6117 if (length == -1) {
6118 std::cerr << std::endl << "PRunDataHandler::WriteMudFile(): **ERROR** Couldn't determine the mud-file size." << std::endl;
6119 remove(fln.Data());
6120 return false;
6121 }
6122
6123 // allocate memory
6124 buffer = new char [length];
6125
6126 // read data as a block
6127 while (!is.eof()) {
6128 is.read(buffer, length);
6129 std::cout.write(buffer, length);
6130 }
6131
6132 is.close();
6133
6134 delete [] buffer;
6135
6136 // delete temporary root file
6137 remove(fln.Data());
6138 }
6139 return true;
6140}
6141
6142//--------------------------------------------------------------------------
6143// WriteAsciiFile (private)
6144//--------------------------------------------------------------------------
6155{
6156 Bool_t ok = false;
6157 fln = GenerateOutputFileName(fln, ".ascii", ok);
6158 if (!ok)
6159 return false;
6160
6161 TString fileName = fln;
6162
6163 if (!fAny2ManyInfo->useStandardOutput)
6164 std::cout << std::endl << ">> PRunDataHandler::WriteAsciiFile(): writing an ascii data file (" << fln.Data() << ") ... " << std::endl;
6165
6166 // write ascii file
6167 std::ofstream fout;
6168 std::streambuf* strm_buffer = nullptr;
6169
6170 if (!fAny2ManyInfo->useStandardOutput || (fAny2ManyInfo->compressionTag > 0)) {
6171 // open data-file
6172 fout.open(fln.Data(), std::ofstream::out);
6173 if (!fout.is_open()) {
6174 std::cerr << std::endl << ">> PRunDataHandler::WriteAsciiFile **ERROR** Couldn't open data file (" << fln.Data() << ") for writing, sorry ...";
6175 std::cerr << std::endl;
6176 return false;
6177 }
6178
6179 // save output buffer of the stream
6180 strm_buffer = std::cout.rdbuf();
6181
6182 // redirect output into the file
6183 std::cout.rdbuf(fout.rdbuf());
6184 }
6185
6186 // write header
6187 std::cout << "%*************************************************************************";
6188 std::cout << std::endl << "% file name : " << fileName.Data();
6189 if (fData[0].GetRunTitle()->Length() > 0)
6190 std::cout << std::endl << "% title : " << fData[0].GetRunTitle()->Data();
6191 if (fData[0].GetRunNumber() >= 0)
6192 std::cout << std::endl << "% run number : " << fData[0].GetRunNumber();
6193 if (fData[0].GetSetup()->Length() > 0)
6194 std::cout << std::endl << "% setup : " << fData[0].GetSetup()->Data();
6195 std::cout << std::endl << "% field : " << fData[0].GetField() << " (G)";
6196 if (fData[0].GetStartTime()->Length() > 0)
6197 std::cout << std::endl << "% date : " << fData[0].GetStartTime()->Data() << " " << fData[0].GetStartDate()->Data() << " / " << fData[0].GetStopTime()->Data() << " " << fData[0].GetStopDate()->Data();
6198 if (fData[0].GetNoOfTemperatures() > 0) {
6199 std::cout << std::endl << "% temperature : ";
6200 for (UInt_t i=0; i<fData[0].GetNoOfTemperatures()-1; i++) {
6201 std::cout << fData[0].GetTemperature(i) << "+-" << fData[0].GetTempError(i) << "(K) , ";
6202 }
6203 std::cout << fData[0].GetTemperature(fData[0].GetNoOfTemperatures()-1) << "+-" << fData[0].GetTempError(fData[0].GetNoOfTemperatures()-1) << "(K)";
6204 }
6205 if (fData[0].GetEnergy() != PMUSR_UNDEFINED)
6206 std::cout << std::endl << "% energy : " << fData[0].GetEnergy() << " (keV)";
6207 if (fData[0].GetTransport() != PMUSR_UNDEFINED)
6208 std::cout << std::endl << "% transport : " << fData[0].GetTransport() << " (kV)";
6209 if (fData[0].GetTimeResolution() != PMUSR_UNDEFINED) {
6210 std::cout.precision(10);
6211 std::cout << std::endl << "% time resolution : " << fData[0].GetTimeResolution()*fAny2ManyInfo->rebin << " (ns)";
6212 std::cout.setf(std::ios::fixed,std::ios::floatfield); // floatfield set to fixed
6213 }
6214 PRawRunDataSet *dataSet;
6215 std::cout << std::endl << "% t0 : ";
6216 for (UInt_t i=0; i<fData[0].GetNoOfHistos()-1; i++) {
6217 dataSet = fData[0].GetDataSet(i, false); // i.e. the false means, that i is the index and NOT the histo number
6218 std::cout << static_cast<UInt_t>(dataSet->GetTimeZeroBin()/fAny2ManyInfo->rebin) << ", ";
6219 }
6220 dataSet = fData[0].GetDataSet(fData[0].GetNoOfHistos()-1, false); // i.e. the false means, that i is the index and NOT the histo number
6221 std::cout << static_cast<UInt_t>(dataSet->GetTimeZeroBin()/fAny2ManyInfo->rebin);
6222
6223 std::cout << std::endl << "% # histos : " << fData[0].GetNoOfHistos();
6224 dataSet = fData[0].GetDataSet(0, false); // i.e. the false means, that i is the index and NOT the histo number
6225 std::cout << std::endl << "% # of bins : " << static_cast<UInt_t>(dataSet->GetData()->size()/fAny2ManyInfo->rebin);
6226 std::cout << std::endl << "%*************************************************************************";
6227
6228 // write data
6229 UInt_t length = fData[0].GetDataSet(0,false)->GetData()->size();
6230 if (fAny2ManyInfo->rebin == 1) {
6231 for (UInt_t i=0; i<length; i++) {
6232 std::cout << std::endl;
6233 for (UInt_t j=0; j<fData[0].GetNoOfHistos(); j++) {
6234 dataSet = fData[0].GetDataSet(j, false); // i.e. the false means, that i is the index and NOT the histo number
6235 std::cout.width(8);
6236 std::cout << static_cast<Int_t>(dataSet->GetData()->at(i));
6237 }
6238 }
6239 } else {
6240 PUIntVector dataRebin(fData[0].GetNoOfHistos());
6241
6242 // initialize the dataRebin vector
6243 for (UInt_t i=0; i<dataRebin.size(); i++) {
6244 dataSet = fData[0].GetDataSet(i, false); // i.e. the false means, that i is the index and NOT the histo number
6245 dataRebin[i] = static_cast<UInt_t>(dataSet->GetData()->at(0));
6246 }
6247
6248 for (UInt_t i=0; i<length; i++) {
6249 if ((i > 0) && ((i % fAny2ManyInfo->rebin) == 0)) {
6250 std::cout << std::endl;
6251 for (UInt_t j=0; j<dataRebin.size(); j++) {
6252 std::cout.width(8);
6253 std::cout << dataRebin[j];
6254 }
6255 // initialize the dataRebin vector for the next pack
6256 for (UInt_t j=0; j<dataRebin.size(); j++) {
6257 dataSet = fData[0].GetDataSet(j, false); // i.e. the false means, that i is the index and NOT the histo number
6258 dataRebin[j] = static_cast<UInt_t>(dataSet->GetData()->at(i));
6259 }
6260 } else {
6261 for (UInt_t j=0; j<fData[0].GetNoOfHistos(); j++) {
6262 dataSet = fData[0].GetDataSet(j, false); // i.e. the false means, that i is the index and NOT the histo number
6263 dataRebin[j] += static_cast<UInt_t>(dataSet->GetData()->at(i));
6264 }
6265 }
6266 }
6267 }
6268
6269 std::cout << std::endl;
6270
6271 if (!fAny2ManyInfo->useStandardOutput || (fAny2ManyInfo->compressionTag > 0)) {
6272 // restore old output buffer
6273 std::cout.rdbuf(strm_buffer);
6274
6275 fout.close();
6276 }
6277
6278 return true;
6279}
6280
6281
6282//--------------------------------------------------------------------------
6283// StripWhitespace (private)
6284//--------------------------------------------------------------------------
6296{
6297 Char_t *s = nullptr;
6298 Char_t *subs = nullptr;
6299 Int_t i;
6300 Int_t start;
6301 Int_t end;
6302 Int_t size;
6303
6304 size = static_cast<Int_t>(str.Length());
6305 s = new Char_t[size+1];
6306
6307 if (!s)
6308 return false;
6309
6310 for (Int_t i=0; i<size+1; i++)
6311 s[i] = str[i];
6312 s[size] = 0;
6313
6314 // check for whitespaces at the beginning of the string
6315 i = 0;
6316 while (isblank(s[i]) || iscntrl(s[i])) {
6317 i++;
6318 }
6319 start = i;
6320
6321 // check for whitespaces at the end of the string
6322 i = strlen(s);
6323 while (isblank(s[i]) || iscntrl(s[i])) {
6324 i--;
6325 }
6326 end = i;
6327
6328 if (end < start)
6329 return false;
6330
6331 // make substring
6332 subs = new Char_t[end-start+2];
6333 if (!subs)
6334 return false;
6335
6336 strncpy(subs, s+start, end-start+1);
6337 subs[end-start+1] = '\0';
6338
6339 str = TString(subs);
6340
6341 // clean up
6342 if (subs) {
6343 delete [] subs;
6344 subs = nullptr;
6345 }
6346 if (s) {
6347 delete [] s;
6348 s = nullptr;
6349 }
6350
6351 return true;
6352}
6353
6354//--------------------------------------------------------------------------
6355// IsWhitespace (private)
6356//--------------------------------------------------------------------------
6367Bool_t PRunDataHandler::IsWhitespace(const Char_t *str)
6368{
6369 UInt_t i=0;
6370
6371 while (isblank(str[i]) || iscntrl(str[i])) {
6372 if (str[i] == 0)
6373 break;
6374 i++;
6375 }
6376
6377 if (i == strlen(str))
6378 return true;
6379 else
6380 return false;
6381}
6382
6383//--------------------------------------------------------------------------
6384// ToDouble (private)
6385//--------------------------------------------------------------------------
6396Double_t PRunDataHandler::ToDouble(TString &str, Bool_t &ok)
6397{
6398 Char_t *s;
6399 Double_t value;
6400 Int_t size, status;
6401
6402 ok = true;
6403
6404 size = static_cast<Int_t>(str.Length());
6405 s = new Char_t[size+1];
6406
6407 if (!s) {
6408 ok = false;
6409 return 0.0;
6410 }
6411
6412 // copy string; stupid way but it works
6413 for (Int_t i=0; i<size+1; i++)
6414 s[i] = str[i];
6415 s[size] = 0;
6416
6417 // extract value
6418 status = sscanf(s, "%lf", &value);
6419 if (status != 1) {
6420 ok = false;
6421 return 0.0;
6422 }
6423
6424 // clean up
6425 if (s) {
6426 delete [] s;
6427 s = nullptr;
6428 }
6429
6430 return value;
6431}
6432
6433//--------------------------------------------------------------------------
6434// ToInt (private)
6435//--------------------------------------------------------------------------
6446Int_t PRunDataHandler::ToInt(TString &str, Bool_t &ok)
6447{
6448 Char_t *s;
6449 Int_t value;
6450 Int_t size, status;
6451
6452 ok = true;
6453
6454 size = static_cast<Int_t>(str.Length());
6455 s = new Char_t[size+1];
6456
6457 if (!s) {
6458 ok = false;
6459 return 0;
6460 }
6461
6462 // copy string; stupid way but it works
6463 for (Int_t i=0; i<size+1; i++)
6464 s[i] = str[i];
6465 s[size] = 0;
6466
6467 // extract value
6468 status = sscanf(s, "%d", &value);
6469 if (status != 1) {
6470 ok = false;
6471 return 0;
6472 }
6473
6474 // clean up
6475 if (s) {
6476 delete [] s;
6477 s = nullptr;
6478 }
6479
6480 return value;
6481}
6482
6483//--------------------------------------------------------------------------
6484// GetDataTagIndex (private)
6485//--------------------------------------------------------------------------
6496Int_t PRunDataHandler::GetDataTagIndex(TString &str, const PStringVector* dataTags)
6497{
6498 Int_t result = -1;
6499
6500 // check all the other possible data tags
6501 for (UInt_t i=0; i<dataTags->size(); i++) {
6502 if (!dataTags->at(i).CompareTo(str, TString::kIgnoreCase)) {
6503 result = i;
6504 break;
6505 }
6506 }
6507
6508 return result;
6509}
6510
6511
6512//--------------------------------------------------------------------------
6513// GenerateOutputFileName (private)
6514//--------------------------------------------------------------------------
6528TString PRunDataHandler::GenerateOutputFileName(const TString fileName, const TString extension, Bool_t &ok)
6529{
6530 TString fln = fileName;
6531 ok = true;
6532
6533 if (fAny2ManyInfo == nullptr)
6534 return fln;
6535
6536 // generate output file name if needed
6537 if (!fAny2ManyInfo->useStandardOutput || (fAny2ManyInfo->compressionTag > 0)) {
6538 if (fln.Length() == 0) {
6539 ok = false;
6540 fln = GetFileName(extension, ok);
6541 if (!ok) {
6542 fln = "";
6543 return fln;
6544 }
6545 } else {
6546 fln.Prepend(fAny2ManyInfo->outPath);
6547 }
6548
6549 // make sure that the file name doesn't already exist as a real file
6550 if (!gSystem->AccessPathName(fln)) { // file name already exists!!
6551 Int_t count = 1;
6552 TString newFln;
6553 do {
6554 newFln = fln;
6555 newFln.Insert(newFln.Last('.'), TString::Format(".%d", count++));
6556 } while (!gSystem->AccessPathName(newFln));
6557 std::cerr << std::endl << ">> PRunDataHandler::GenerateOutputFileName **WARNING** needed to modify output filename to " << newFln << ",";
6558 std::cerr << std::endl << ">> due to potential conflict with already existing files." << std::endl << std::endl;
6559 fln = newFln;
6560 }
6561
6562 // keep the file name if compression is whished
6563 fAny2ManyInfo->outPathFileName.push_back(fln);
6564 } else {
6565 fln = fAny2ManyInfo->outPath + TString("__tmp.") + extension;
6566 }
6567
6568 return fln;
6569}
6570
6571//--------------------------------------------------------------------------
6572// GetFileName (private)
6573//--------------------------------------------------------------------------
6584TString PRunDataHandler::GetFileName(const TString extension, Bool_t &ok)
6585{
6586 TString fileName = "";
6587 ok = true;
6588
6589 Int_t start = fRunPathName.Last('/');
6590 Int_t end = fRunPathName.Last('.');
6591 if (end == -1) {
6592 std::cerr << std::endl << ">> PRunDataHandler::GetFileName(): **ERROR** couldn't generate the output file name ..." << std::endl;
6593 ok = false;
6594 return fileName;
6595 }
6596 // cut out the filename (get rid of the extension, and the path)
6597 Char_t str1[1024], str2[1024];
6598 strncpy(str1, fRunPathName.Data(), sizeof(str1));
6599 for (Int_t i=0; i<end-start-1; i++) {
6600 str2[i] = str1[i+start+1];
6601 }
6602 str2[end-start-1] = 0;
6603
6604 if (fAny2ManyInfo->inFormat == fAny2ManyInfo->outFormat) { // only rebinning
6605 TString rebinStr;
6606 rebinStr += fAny2ManyInfo->rebin;
6607 fileName = fAny2ManyInfo->outPath + str2 + "_rebin" + rebinStr + extension;
6608 } else { // real conversion
6609 fileName = fAny2ManyInfo->outPath + str2 + extension;
6610 }
6611
6612 return fileName;
6613}
6614
6615//--------------------------------------------------------------------------
6616// FileNameFromTemplate (private)
6617//--------------------------------------------------------------------------
6635TString PRunDataHandler::FileNameFromTemplate(TString &fileNameTemplate, Int_t run, TString &year, Bool_t &ok)
6636{
6637 TString result("");
6638
6639 TObjArray *tok=nullptr;
6640 TObjString *ostr;
6641 TString str;
6642
6643 // check year string
6644 if ((year.Length() != 2) && (year.Length() != 4)) {
6645 std::cerr << std::endl << ">> PRunDataHandler::FileNameFromTemplate: **ERROR** year needs to be of the format";
6646 std::cerr << std::endl << ">> 'yy' or 'yyyy', found " << year << std::endl;
6647 return result;
6648 }
6649
6650 // make a short year version 'yy' and a long year version 'yyyy'
6651 TString yearShort="", yearLong="";
6652 if (year.Length() == 2) {
6653 yearShort = year;
6654 yearLong = "20" ;
6655 yearLong += year;
6656 } else {
6657 yearShort = year[2];
6658 yearShort += year[3];
6659 yearLong = year;
6660 }
6661
6662 // tokenize template string
6663 tok = fileNameTemplate.Tokenize("[]");
6664 if (tok == nullptr) {
6665 std::cerr << std::endl << ">> PRunDataHandler::FileNameFromTemplate: **ERROR** couldn't tokenize template!" << std::endl;
6666 return result;
6667 }
6668 if (tok->GetEntries()==1) {
6669 std::cerr << std::endl << ">> PRunDataHandler::FileNameFromTemplate: **WARNING** template without tags." << std::endl;
6670 }
6671
6672 // go through the tokens and generate the result string
6673 for (Int_t i=0; i<tok->GetEntries(); i++) {
6674 ostr = dynamic_cast<TObjString*>(tok->At(i));
6675 str = ostr->GetString();
6676
6677 // check tokens
6678 if (!str.CompareTo("yy", TString::kExact)) { // check for 'yy'
6679 result += yearShort;
6680 } else if (!str.CompareTo("yyyy", TString::kExact)) { // check for 'yyyy'
6681 result += yearLong;
6682 } else if (str.Contains("rr")) { // check for run
6683 // make sure ONLY 'r' are present
6684 Int_t idx;
6685 for (idx=0; idx<str.Length(); idx++) {
6686 if (str[idx] != 'r')
6687 break;
6688 }
6689 if (idx == str.Length()) { // 'r' only
6690 TString runStr("");
6691 char fmt[128];
6692 snprintf(fmt, sizeof(fmt), "%%0%dd", str.Length());
6693 runStr.Form(fmt, run);
6694 result += runStr;
6695 } else { // not only 'r'
6696 result += str;
6697 }
6698 } else { // all parts which are NOT tags
6699 result += str;
6700 }
6701 }
6702
6703 // clean up
6704 if (tok)
6705 delete tok;
6706
6707 // everything fine here
6708 ok = true;
6709
6710 return result;
6711}
6712
6713//--------------------------------------------------------------------------
6714// DateToISO8601 (private)
6715//--------------------------------------------------------------------------
6724bool PRunDataHandler::DateToISO8601(std::string inDate, std::string &iso8601Date)
6725{
6726 iso8601Date = std::string("");
6727
6728 struct tm tm;
6729
6730 // currently only dates like dd-mmm-yy are handled, where dd day of the month, mmm month as abbrivation, e.g. JAN, and yy as the year
6731 if (!strptime(inDate.c_str(), "%d-%b-%y", &tm)) // failed
6732 return false;
6733
6734 TString str("");
6735 str.Form("%04d-%02d-%02d", 1900+tm.tm_year, tm.tm_mon+1, tm.tm_mday);
6736
6737 iso8601Date = str.Data();
6738
6739 return true;
6740}
6741
6742//--------------------------------------------------------------------------
6743// SplitTimeData (private)
6744//--------------------------------------------------------------------------
6754void PRunDataHandler::SplitTimeDate(TString timeData, TString &time, TString &date, Bool_t &ok)
6755{
6756 struct tm tm;
6757 memset(&tm, 0, sizeof(tm));
6758 strptime(timeData.Data(), "%Y-%m-%d %H:%M:S", &tm);
6759 if (tm.tm_year == 0)
6760 strptime(timeData.Data(), "%Y-%m-%dT%H:%M:S", &tm);
6761
6762 if (tm.tm_year == 0) {
6763 ok = false;
6764 return;
6765 }
6766
6767 time = TString::Format("%02d:%02d:%02d", tm.tm_hour, tm.tm_min, tm.tm_sec);
6768 date = TString::Format("%04d-%02d-%02d", tm.tm_year+1900, tm.tm_mon+1, tm.tm_mday);
6769}
6770
6771//--------------------------------------------------------------------------
6772// GetMonth (private)
6773//--------------------------------------------------------------------------
6781TString PRunDataHandler::GetMonth(Int_t month)
6782{
6783 TString monthString = "???";
6784
6785 switch (month) {
6786 case 1:
6787 monthString = "JAN";
6788 break;
6789 case 2:
6790 monthString = "FEB";
6791 break;
6792 case 3:
6793 monthString = "MAR";
6794 break;
6795 case 4:
6796 monthString = "APR";
6797 break;
6798 case 5:
6799 monthString = "MAY";
6800 break;
6801 case 6:
6802 monthString = "JUN";
6803 break;
6804 case 7:
6805 monthString = "JUL";
6806 break;
6807 case 8:
6808 monthString = "AUG";
6809 break;
6810 case 9:
6811 monthString = "SEP";
6812 break;
6813 case 10:
6814 monthString = "OCT";
6815 break;
6816 case 11:
6817 monthString = "NOV";
6818 break;
6819 case 12:
6820 monthString = "DEC";
6821 break;
6822 default:
6823 break;
6824 }
6825
6826 return monthString;
6827}
6828
6829//--------------------------------------------------------------------------
6830// GetYear (private)
6831//--------------------------------------------------------------------------
6839TString PRunDataHandler::GetYear(Int_t year)
6840{
6841 TString yearString = "??";
6842 Int_t yy=0;
6843
6844 if (year < 2000) {
6845 yy = year - 1900;
6846 if (yy > 0)
6847 yearString.Form("%02d", yy);
6848 } else {
6849 yy = year - 2000;
6850 if ((yy >= 0) && (yy <= 99))
6851 yearString.Form("%02d", yy);
6852 }
6853
6854 return yearString;
6855}
#define POST_PILEUP_HISTO_OFFSET
Definition PMusr.h:163
std::vector< UInt_t > PUIntVector
Definition PMusr.h:361
std::vector< PMsrRunBlock > PMsrRunList
Definition PMusr.h:1245
#define PMUSR_UNDEFINED
Definition PMusr.h:172
std::vector< Bool_t > PBoolVector
Definition PMusr.h:355
std::vector< Int_t > PIntVector
Definition PMusr.h:367
std::vector< TString > PStringVector
Definition PMusr.h:403
std::vector< Double_t > PDoubleVector
Definition PMusr.h:385
NeXus HDF4/HDF5 file reader and writer for muon spin rotation data.
#define PRH_MUSR_ROOT_DIR
#define PHR_INIT_ANY2MANY
#define PHR_INIT_ALL
#define PRH_LEM_ROOT
#define PRH_PPC_OFFSET
#define PRH_MUSR_ROOT
#define PHR_INIT_MSR
return status
#define MRH_UNDEFINED
int Write(const char *fileName)
Method to write a PSI-bin or an MDU file.
std::string GetOrient()
Method returning a string containing the orientation specified in the title.
int PutDevTemperaturesVector(std::vector< double > &devTemps)
Method setting a vector of doubles containing standard deviations of the monitored values (usually te...
int PutNameHisto(std::string histoName, int i)
Method setting a string containing the name of the histogram <i>
std::vector< int > GetT0Vector()
Method returning a vector of integer containing the t0 values of the histograms specified in the head...
std::string GetNameHisto(int i)
Method returning a string containing the name of the histogram <i>
int PutNumberTemperatureInt(int noOfTemps)
Method setting an integer representing the number of temperatures.
int PutFirstGoodInt(int i, int j)
Method setting an integer representing the first good bin specified in the header for a specified his...
int PutTemp(std::string temp)
Method setting a string containing the fSample temperature.
bool CheckDataConsistency(int tag=0)
Check if a given set of data is consistent with the PSI-BIN limitations. If false,...
int PutSample(std::string sample)
Method setting a string containing the fSample name.
std::vector< double > GetTemperaturesVector()
Method returning a vector of doubles containing monitored values (usually temperatures)
std::vector< int > GetLastGoodVector()
Method returning a vector of integer containing the last good bin values of the histograms specified ...
std::vector< int > GetHistoArrayInt(int histo_num)
Method to obtain an array of type integer containing the values of the histogram <histo_num>
int PutT0Int(int histoNo, int t0)
Method setting an integer representing the t0 point (from the "integer" t0 in the header) for a speci...
std::string ConsistencyStatus() const
Method to obtain error/success information on data consistency check.
std::string GetField()
Method returning a string containing the field specified in the title.
void PutNumberHistoInt(int val)
int PutField(std::string field)
Method setting a string containing the field.
int PutComment(std::string comment)
Method setting a string containing the comment.
std::string GetTemp()
Method returning a string containing the temperature specified in the title.
std::vector< std::string > GetTimeStartVector()
Method returning a vector of strings containing 1) the date when the run was started and 2) the time ...
int PutHistoArrayInt(std::vector< std::vector< int > > &histo, int tag=0)
Method to set the histograms which is a vector of vector of int's (histogram). There are two differen...
std::vector< int > GetFirstGoodVector()
Method returning a vector of integer containing the first good bin values of the histograms specified...
int PutLastGoodInt(int i, int j)
Method to modify the last good bin (value <j>) of the histogram <i>
std::vector< std::string > GetTimeStopVector()
Method returning a vector of strings containing 1) the date when the run was stopped and 2) the time ...
void PutBinWidthNanoSec(double binWidth)
Method setting a double representing the bin-width in nanoseconds.
std::vector< double > GetDevTemperaturesVector()
Method returning a vector of doubles containing standard deviations of the monitored values (usually ...
std::string WriteStatus() const
Method to obtain error/success information after writing.
int PutTimeStartVector(std::vector< std::string > timeStart)
Method setting a vector of strings containing 1) the date when the run was started and 2) the time wh...
double GetBinWidthNanoSec()
Method returning a double representing the bin-width in nanoseconds.
int PutRunNumberInt(int i)
Method to modify the run number (value <i>)
int Read(const char *fileName)
Method to read a PSI-bin or an MDU file.
int PutSetup(std::string setup)
Method setting a string containing the setup.
int PutNumberScalerInt(int val)
Method seting the number of scalers present.
std::string GetSample()
Method returning a string containing the fSample name.
void PutHistoLengthBin(int val)
std::string GetComment()
Method returning a string containing the comment specified in the title.
int PutTemperaturesVector(std::vector< double > &temps)
Method setting a vector of doubles containing monitored values (usually temperatures)
int PutOrient(std::string orientation)
Method setting a string containing the fSample orientation.
int PutTimeStopVector(std::vector< std::string > timeStop)
Method setting a vector of strings containing 1) the date when the run was started and 2) the time wh...
MSR file parser and manager for the musrfit framework.
virtual TString * GetInstitute(UInt_t idx=0)
Definition PMusr.cpp:1385
virtual TString * GetFileFormat(UInt_t idx=0)
Definition PMusr.cpp:1427
virtual void SetBeamline(TString &str, Int_t idx=-1)
Definition PMusr.cpp:1360
virtual TString * GetBeamline(UInt_t idx=0)
Definition PMusr.cpp:1343
virtual void SetFileFormat(TString &str, Int_t idx=-1)
Definition PMusr.cpp:1444
virtual TString * GetRunName(UInt_t idx=0)
Definition PMusr.cpp:1301
virtual void SetInstitute(TString &str, Int_t idx=-1)
Definition PMusr.cpp:1402
virtual void AppendLabel(const TString str)
Definition PMusr.h:575
virtual void AppendErrData(const PDoubleVector &data)
Definition PMusr.h:593
virtual void AppendSubErrData(const UInt_t idx, const Double_t dval)
Definition PMusr.cpp:229
virtual const PStringVector * GetDataTags()
Returns pointer to vector of data tags (identifiers for each data column)
Definition PMusr.h:556
virtual void AppendDataTag(const TString str)
Definition PMusr.h:587
virtual void AppendSubData(const UInt_t idx, const Double_t dval)
Definition PMusr.cpp:209
virtual void SetFromAscii(const Bool_t bval)
Definition PMusr.h:564
virtual const std::vector< PDoubleVector > * GetData()
Returns pointer to vector of data columns.
Definition PMusr.h:558
virtual const PStringVector * GetLabels()
Returns pointer to vector of axis/column labels.
Definition PMusr.h:554
virtual const std::vector< PDoubleVector > * GetErrData()
Returns pointer to vector of error data columns.
Definition PMusr.h:560
virtual void SetSize(const UInt_t size)
Definition PMusr.cpp:162
virtual void AppendData(const PDoubleVector &data)
Definition PMusr.h:590
virtual void SetLabel(const UInt_t idx, const TString str)
Definition PMusr.cpp:189
virtual Int_t GetFirstGoodBin()
Returns the first bin of good data range (after prompt peak)
Definition PMusr.h:647
virtual PDoubleVector * GetData()
Returns pointer to raw histogram data vector (counts per bin)
Definition PMusr.h:655
virtual void SetLastBkgBin(Int_t lbb)
Definition PMusr.h:685
virtual void Clear()
Clears all data from this histogram set.
Definition PMusr.cpp:261
virtual void SetLastGoodBin(Int_t lgb)
Definition PMusr.h:679
virtual Double_t GetTimeZeroBin()
Returns the time-zero bin (t0) position.
Definition PMusr.h:643
virtual void SetHistoNo(Int_t no)
Definition PMusr.h:667
virtual void SetData(PDoubleVector data)
Definition PMusr.h:688
virtual Int_t GetHistoNo()
Returns the histogram number as stored in the data file.
Definition PMusr.h:641
virtual TString GetName()
Returns the histogram name.
Definition PMusr.h:639
virtual void SetName(TString str)
Definition PMusr.h:664
virtual Int_t GetLastGoodBin()
Returns the last bin of good data range.
Definition PMusr.h:649
virtual void SetTimeZeroBinEstimated(Double_t tzb)
Definition PMusr.h:673
virtual void SetFirstBkgBin(Int_t fbb)
Definition PMusr.h:682
virtual void SetTitle(TString str)
Definition PMusr.h:661
virtual void SetTimeZeroBin(Double_t tzb)
Definition PMusr.h:670
virtual void SetFirstGoodBin(Int_t fgb)
Definition PMusr.h:676
virtual void SetStopDate(const TString str)
Definition PMusr.h:904
virtual void SetRingAnode(const UInt_t idx, const Double_t dval)
Definition PMusr.cpp:750
PNonMusrRawRunData fDataNonMusr
keeps all ascii- or db-file info in case of nonMusr fit
Definition PMusr.h:923
virtual void SetGenerator(const TString &str)
Definition PMusr.h:886
virtual const PDoubleVector * GetDataBin(const UInt_t histoNo)
Definition PMusr.h:880
virtual const Double_t GetTimeResolution()
Definition PMusr.h:868
virtual void SetMuonSource(const TString &str)
Definition PMusr.h:892
virtual void SetTimeResolution(const Double_t dval)
Definition PMusr.h:917
virtual void SetSample(const TString str)
Definition PMusr.h:909
virtual void SetVersion(const TString &str)
Definition PMusr.h:883
virtual void SetEnergy(const Double_t dval)
Definition PMusr.h:914
virtual void SetStartDate(const TString str)
Definition PMusr.h:901
virtual void SetTransport(const Double_t dval)
Definition PMusr.h:915
virtual void SetRunName(const TString &str)
Definition PMusr.h:896
virtual void SetOrientation(const TString str)
Definition PMusr.h:910
virtual void SetRedGreenOffset(PIntVector &ivec)
Definition PMusr.h:918
virtual void SetSetup(const TString str)
Definition PMusr.h:899
virtual void SetStopTime(const TString str)
Definition PMusr.h:903
virtual void SetSpecificValidatorUrl(const TString &str)
Definition PMusr.h:885
virtual void SetStopDateTime(const time_t val)
Definition PMusr.h:905
virtual void SetRunTitle(const TString str)
Definition PMusr.h:898
virtual void SetMuonSpinAngle(const Double_t dval)
Definition PMusr.h:895
virtual void SetTemperature(const UInt_t idx, const Double_t temp, const Double_t errTemp)
Definition PMusr.cpp:767
virtual void SetCryoName(const TString str)
Definition PMusr.h:908
virtual void SetFileName(const TString &str)
Definition PMusr.h:888
virtual void SetComment(const TString &str)
Definition PMusr.h:887
virtual void SetMuonSpecies(const TString &str)
Definition PMusr.h:893
virtual void SetBeamline(const TString &str)
Definition PMusr.h:890
virtual void SetTempError(const UInt_t idx, const Double_t errTemp)
Definition PMusr.cpp:785
virtual void SetRunNumber(const Int_t &val)
Definition PMusr.h:897
virtual void ClearTemperature()
Definition PMusr.h:911
virtual void SetMuonBeamMomentum(const Double_t dval)
Definition PMusr.h:894
virtual void SetInstrument(const TString &str)
Definition PMusr.h:891
virtual void SetStartDateTime(const time_t val)
Definition PMusr.h:902
virtual void SetField(const Double_t dval)
Definition PMusr.h:907
virtual void SetStartTime(const TString str)
Definition PMusr.h:900
virtual const UInt_t GetNoOfHistos()
Definition PMusr.h:878
virtual void SetLaboratory(const TString &str)
Definition PMusr.h:889
virtual void SetMagnetName(const TString str)
Definition PMusr.h:906
virtual void SetDataSet(PRawRunDataSet &dataSet, UInt_t idx=-1)
Definition PMusr.h:921
virtual void SetGenericValidatorUrl(const TString &str)
Definition PMusr.h:884
PRunDataHandler()
Default constructor creating an uninitialized handler.
PMsrHandler * fMsrInfo
Pointer to MSR file handler (not owned, don't delete)
virtual TString FileNameFromTemplate(TString &fileNameTemplate, Int_t run, TString &year, Bool_t &ok)
virtual void SplitTimeDate(TString timeDate, TString &time, TString &date, Bool_t &ok)
virtual Bool_t ReadAsciiFile()
virtual Bool_t ReadWkmFile()
virtual Bool_t ReadRootFile()
Bool_t ReadNexusFileIdf2(T &nxs_file)
virtual Bool_t WriteWkmFile(TString fln="")
TString fRunName
Current run name being processed (used during file reading)
virtual Bool_t ReadDBFile()
virtual void ReadData()
Reads all data files specified in MSR file or configuration.
virtual Bool_t StripWhitespace(TString &str)
virtual Bool_t IsWhitespace(const Char_t *str)
virtual Bool_t ReadFilesMsr()
Bool_t ReadNexusFileIdf1(T &nxs_file)
Bool_t fAllDataAvailable
Flag: true if all requested data files loaded successfully, false if any failed.
virtual Int_t ToInt(TString &str, Bool_t &ok)
PRawRunDataList fData
List of all loaded raw run data (histograms + metadata)
virtual Bool_t WriteData(TString fileName="")
Writes data to file in the specified format.
virtual Bool_t ReadNexusFile()
virtual TString GenerateOutputFileName(const TString fileName, const TString extension, Bool_t &ok)
virtual Bool_t WriteAsciiFile(TString fln="")
virtual Bool_t ReadMudFile()
virtual Bool_t FileExistsCheck(PMsrRunBlock &runInfo, const UInt_t idx)
virtual Bool_t WritePsiBinFile(TString fln="")
virtual PRawRunData * GetRunData(const TString &runName)
Retrieves run data by run name.
virtual TString GetFileName(const TString extension, Bool_t &ok)
virtual Bool_t WriteMudFile(TString fln="")
TString fFileFormat
Explicitly specified file format (overrides auto-detection)
virtual TString GetMonth(Int_t month)
virtual Bool_t WriteMusrRootFile(Int_t tag=A2M_MUSR_ROOT_DIR, TString fln="")
virtual Int_t GetDataTagIndex(TString &str, const PStringVector *fLabels)
virtual Bool_t ReadMduAsciiFile()
virtual Bool_t WriteRootFile(TString fln="")
PStringVector fDataPath
Search paths for data files (checked sequentially until file found)
TString fRunPathName
Full path to current data file being read.
virtual ~PRunDataHandler()
Virtual destructor that frees all loaded data.
virtual void TestFileName(TString &runName, const TString &ext)
virtual Bool_t WriteNexusFile(TString format, TString fln="")
virtual bool DateToISO8601(std::string inDate, std::string &iso8601Date)
virtual Bool_t ReadWriteFilesList()
virtual Bool_t SetRunData(PRawRunData *data, UInt_t idx=0)
Sets or replaces run data at specified index.
virtual void Init(const Int_t tag=0)
PAny2ManyInfo * fAny2ManyInfo
Pointer to any2many conversion configuration (not owned, don't delete)
virtual Bool_t FileAlreadyRead(TString runName)
virtual Bool_t ReadPsiBinFile()
virtual Bool_t ReadDatFile()
virtual TString GetYear(Int_t month)
virtual Double_t ToDouble(TString &str, Bool_t &ok)
virtual void ConvertData()
Performs format conversion (for any2many utility).
virtual Double_t GetError() const
virtual Double_t GetValue() const
virtual void Set(TString label, Double_t demand, Double_t value, Double_t error, TString unit, TString description=TString("n/a"))
virtual TString GetUnit() const
#define A2M_NEXUS
NeXus HDF5 format (ISIS, JPARC standard - self-describing, hierarchical)
#define A2M_MUD
TRIUMF MUD (Muon Data) format (TRIUMF's standard binary format)
#define A2M_ROOT
Generic ROOT file (minimal structure, basic histograms only)
#define A2M_PSIBIN
PSI binary format (legacy PSI format, platform-specific byte ordering)
#define A2M_ASCII
Generic ASCII format (two-column time-value data for non-μSR applications)
#define A2M_MUSR_ROOT
MusrRoot format (PSI-specific ROOT with complete metadata and run info)
#define A2M_WKM
WKM format (older PSI format, deprecated but still supported for legacy data)
#define A2M_UNDEFINED
Undefined or unknown format (used for error indication)
#define A2M_PSIMDU
PSI MDU ASCII format (ASCII variant of PSI format with metadata)
#define A2M_MUSR_ROOT_DIR
MusrRoot with directory structure (organized by run number, year, etc.)
unsigned long UINT32
Definition mud.h:146
#define MUD_SEC_GEN_RUN_DESC_ID
Definition mud.h:73
#define MUD_GRP_TRI_TD_HIST_ID
Definition mud.h:90
#define MUD_FMT_TRI_TD_ID
Definition mud.h:57
double REAL64
Definition mud.h:149
int MUD_getHistSecondsPerBin(int fd, int num, REAL64 *pSecondsPerBin)
int MUD_setHistData(int fd, int num, void *pData)
int MUD_openWrite(char *filename, UINT32 type)
int MUD_setHistSecondsPerBin(int fd, int num, REAL64 secondsPerBin)
int MUD_setHists(int fd, UINT32 type, UINT32 num)
int MUD_closeWrite(int fd)
int MUD_setRunDesc(int fd, UINT32 type)
int MUD_openRead(char *filename, UINT32 *pType)
int MUD_getHistData(int fd, int num, void *pData)
int MUD_closeRead(int fd)
@ kFLOAT32
32-bit floating point (DFNT_FLOAT32)
Definition PNeXus.h:331
@ kCHAR8
8-bit character (DFNT_CHAR8)
Definition PNeXus.h:333
@ kINT32
32-bit signed integer (DFNT_INT32)
Definition PNeXus.h:330
Common utilities for NeXus file handling.
HDFType
Enumeration of supported HDF file types.
Definition PNeXus.h:141
@ HDF5
HDF5 format (magic: 0x89 'H' 'D' 'F' 0x0d 0x0a 0x1a 0x0a)
Definition PNeXus.h:143
@ Unknown
Unrecognized file format.
Definition PNeXus.h:144
@ HDF4
HDF4 format (magic: 0x0e 0x03 0x13 0x01)
Definition PNeXus.h:142
HDFType checkHDFType(const std::string &filename)
Determine the HDF format type of a file by reading its header.
Definition PNeXus.cpp:100
std::string getIso8601TimestampLocal()
get the current time and return it as na IOS8601 time stamp.
Definition PNeXus.cpp:139