/*************************************************************************** PRunDataHandler.cpp Author: Andreas Suter e-mail: andreas.suter@psi.ch ***************************************************************************/ /*************************************************************************** * Copyright (C) 2007-2014 by Andreas Suter * * andreas.suter@psi.ch * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #include #include #include #include using namespace std; #include #include #include #include #include #include #include #include #include #include "TMusrRunHeader.h" #include "TLemRunHeader.h" #include "MuSR_td_PSI_bin.h" #include "mud.h" #ifdef PNEXUS_ENABLED #include "PNeXus.h" #endif #include "PRunDataHandler.h" #define PRH_MUSR_ROOT 0 #define PRH_LEM_ROOT 1 #define PRH_NPP_OFFSET 0 #define PRH_PPC_OFFSET 20 #define A2M_UNDEFINED 0 #define A2M_ROOT 1 #define A2M_MUSR_ROOT 2 #define A2M_PSIBIN 3 #define A2M_PSIMDU 4 #define A2M_MUD 5 #define A2M_NEXUS 6 #define A2M_WKM 7 #define A2M_ASCII 8 #define PHR_INIT_ALL 0 #define PHR_INIT_MSR 1 #define PHR_INIT_ANY2MANY 2 //-------------------------------------------------------------------------- // Constructor //-------------------------------------------------------------------------- /** *

Empty Constructor */ PRunDataHandler::PRunDataHandler() { Init(); } //-------------------------------------------------------------------------- // Constructor //-------------------------------------------------------------------------- /** *

Constructor which just reads a single muSR data file. * * \param fileName * \param fileFormat */ PRunDataHandler::PRunDataHandler(TString fileName, const TString fileFormat) : fFileFormat(fileFormat) { Init(); FileExistsCheck(fileName); } //-------------------------------------------------------------------------- // Constructor //-------------------------------------------------------------------------- /** *

Constructor which just reads a single muSR data file. * * \param fileName * \param fileFormat * \param dataPath */ PRunDataHandler::PRunDataHandler(TString fileName, const TString fileFormat, const PStringVector dataPath) : fDataPath(dataPath), fFileFormat(fileFormat) { Init(); FileExistsCheck(fileName); } //-------------------------------------------------------------------------- // Constructor //-------------------------------------------------------------------------- /** *

Constructor which just writes a single muSR data file. * * \param fileName * \param fileFormat * \param dataPath * \param runData */ PRunDataHandler::PRunDataHandler(TString fileName, const TString fileFormat, const TString dataPath, PRawRunData &runData) { Init(); } //-------------------------------------------------------------------------- // Constructor //-------------------------------------------------------------------------- /** *

Constructor, reading the data histogramm files. * * \param msrInfo pointer to the msr-file handler */ PRunDataHandler::PRunDataHandler(PAny2ManyInfo *any2ManyInfo) : fAny2ManyInfo(any2ManyInfo) { Init(PHR_INIT_ANY2MANY); } //-------------------------------------------------------------------------- // Constructor //-------------------------------------------------------------------------- /** *

Constructor, reading the data histogramm files. * * \param any2ManyInfo pointer to the PAny2ManyInfo structure needed to convert data * \param dataPath contains all data search paths. */ PRunDataHandler::PRunDataHandler(PAny2ManyInfo *any2ManyInfo, const PStringVector dataPath) : fAny2ManyInfo(any2ManyInfo), fDataPath(dataPath) { Init(PHR_INIT_ANY2MANY); } //-------------------------------------------------------------------------- // Constructor //-------------------------------------------------------------------------- /** *

Constructor, reading the data histogramm files. * * \param msrInfo pointer to the msr-file handler */ PRunDataHandler::PRunDataHandler(PMsrHandler *msrInfo) : fMsrInfo(msrInfo) { Init(PHR_INIT_MSR); } //-------------------------------------------------------------------------- // Constructor //-------------------------------------------------------------------------- /** *

Constructor, reading the data histogramm files, and keeping a copy * of potential search paths. * * \param msrInfo pointer to the msr-file handler * \param dataPath vector containing search paths where to find raw data files. */ PRunDataHandler::PRunDataHandler(PMsrHandler *msrInfo, const PStringVector dataPath) : fMsrInfo(msrInfo), fDataPath(dataPath) { Init(PHR_INIT_MSR); } //-------------------------------------------------------------------------- // Destructor //-------------------------------------------------------------------------- /** *

Destructor. */ PRunDataHandler::~PRunDataHandler() { fDataPath.clear(); fData.clear(); } //-------------------------------------------------------------------------- // GetRunData //-------------------------------------------------------------------------- /** *

Checks if runName is found, and if so return these data. * * return: * - if data are found: pointer to the data. * - otherwise the null pointer will be returned. * * \param runName run name, e.g. 2009/lem09_his_1234 */ PRawRunData* PRunDataHandler::GetRunData(const TString &runName) { UInt_t i; for (i=0; iCompareTo(runName)) // run found break; } if (i == fData.size()) return 0; else return &fData[i]; } //-------------------------------------------------------------------------- // ReadData //-------------------------------------------------------------------------- /** *

Read data. Used to read data, either msr-file triggered, or a single * explicit data file should be read. */ void PRunDataHandler::ReadData() { if (fMsrInfo) { // i.e. msr-file triggered if (!ReadFilesMsr()) // couldn't read file fAllDataAvailable = false; else fAllDataAvailable = true; } else if (!fRunPathName.IsWhitespace()) { // i.e. file name triggered if ((fFileFormat == "MusrRoot") || (fFileFormat == "musrroot")) { fAllDataAvailable = ReadRootFile(); } else if ((fFileFormat == "NeXus") || (fFileFormat == "nexus")) { fAllDataAvailable = ReadNexusFile(); } else if ((fFileFormat == "PsiBin") || (fFileFormat == "psibin")) { fAllDataAvailable = ReadPsiBinFile(); } else if ((fFileFormat == "Mud") || (fFileFormat == "mud")) { fAllDataAvailable = ReadMudFile(); } else if ((fFileFormat == "Wkm") || (fFileFormat == "wkm")) { fAllDataAvailable = ReadWkmFile(); } else { cerr << endl << ">> PRunDataHandler::ReadData(): **ERROR** unkown file format \"" << fFileFormat << "\" found." << endl; fAllDataAvailable = false; } } else { cerr << endl << ">> PRunDataHandler::ReadData(): **ERROR** Couldn't read files." << endl; fAllDataAvailable = false; } } //-------------------------------------------------------------------------- // ConvertData //-------------------------------------------------------------------------- /** *

Read data and convert it. This routine is used by any2many. */ void PRunDataHandler::ConvertData() { if (!ReadWriteFilesList()) // couldn't read file fAllDataAvailable = false; else fAllDataAvailable = true; } //-------------------------------------------------------------------------- // WriteData //-------------------------------------------------------------------------- /** *

Write data. This routine is used to write a single file. */ void PRunDataHandler::WriteData() { } //-------------------------------------------------------------------------- // Init (private) //-------------------------------------------------------------------------- /** *

Common initializer. */ void PRunDataHandler::Init(const Int_t tag) { if ((tag==PHR_INIT_ALL) || (tag==PHR_INIT_ANY2MANY)) fMsrInfo = 0; if ((tag==PHR_INIT_ALL) || (tag==PHR_INIT_MSR)) fAny2ManyInfo = 0; fAllDataAvailable = false; if (tag!=PHR_INIT_ALL) fFileFormat = TString(""); fRunName = TString(""); fRunPathName = TString(""); } //-------------------------------------------------------------------------- // ReadFilesMsr (private) //-------------------------------------------------------------------------- /** *

The main read file routine which is filtering what read sub-routine * needs to be called. Called when the input is a msr-file. * * return: * - true if reading was successful, * - false if reading failed. */ Bool_t PRunDataHandler::ReadFilesMsr() { Bool_t success = true; // loop over the full RUN list to see what needs to be read PMsrRunList *runList = 0; runList = fMsrInfo->GetMsrRunList(); if (runList == 0) { cerr << endl << ">> PRunDataHandler::ReadFilesMsr(): **ERROR** Couldn't obtain run list from PMsrHandler: something VERY fishy"; cerr << endl; return false; } for (UInt_t i=0; isize(); i++) { for (UInt_t j=0; jat(i).GetRunNameSize(); j++) { fRunName = *(runList->at(i).GetRunName(j)); // check if file actually exists if (!FileExistsCheck(runList->at(i), j)) return false; // check special case for ROOT-NPP/ROOT-PPC (LEM) if (!runList->at(i).GetFileFormat(j)->CompareTo("root-npp")) { // not post pile up corrected histos // check if forward/backward histoNo are within proper bounds, i.e. < PRH_PPC_OFFSET for (UInt_t k=0; kat(i).GetForwardHistoNoSize(); k++) { if (runList->at(i).GetForwardHistoNo(k) > PRH_PPC_OFFSET) runList->at(i).SetForwardHistoNo(runList->at(i).GetForwardHistoNo(k)-PRH_PPC_OFFSET, k); } for (UInt_t k=0; kat(i).GetBackwardHistoNoSize(); k++) { if (runList->at(i).GetBackwardHistoNo(k) > PRH_PPC_OFFSET) runList->at(i).SetBackwardHistoNo(runList->at(i).GetBackwardHistoNo(k)-PRH_PPC_OFFSET, k); } } else if (!runList->at(i).GetFileFormat(j)->CompareTo("root-ppc")) { // post pile up corrected histos // check if forward/backward histoNo are within proper bounds, i.e. > PRH_PPC_OFFSET for (UInt_t k=0; kat(i).GetForwardHistoNoSize(); k++) { if (runList->at(i).GetForwardHistoNo(k) < PRH_PPC_OFFSET) runList->at(i).SetForwardHistoNo(runList->at(i).GetForwardHistoNo(k)+PRH_PPC_OFFSET, k); } for (UInt_t k=0; kat(i).GetBackwardHistoNoSize(); k++) { if (runList->at(i).GetBackwardHistoNo(k) < PRH_PPC_OFFSET) runList->at(i).SetBackwardHistoNo(runList->at(i).GetBackwardHistoNo(k)+PRH_PPC_OFFSET, k); } } // check is file is already read if (FileAlreadyRead(*(runList->at(i).GetRunName(j)))) continue; // everything looks fine, hence try to read the data file if (!runList->at(i).GetFileFormat(j)->CompareTo("root-npp")) { // not post pile up corrected histos success = ReadRootFile(); } else if (!runList->at(i).GetFileFormat(j)->CompareTo("root-ppc")) { // post pile up corrected histos success = ReadRootFile(); } else if (!runList->at(i).GetFileFormat(j)->CompareTo("musr-root")) { // MusrRoot style file success = ReadRootFile(); } else if (!runList->at(i).GetFileFormat(j)->CompareTo("nexus")) { success = ReadNexusFile(); } else if (!runList->at(i).GetFileFormat(j)->CompareTo("psi-bin")) { success = ReadPsiBinFile(); } else if (!runList->at(i).GetFileFormat(j)->CompareTo("psi-mdu")) { success = ReadPsiBinFile(); } else if (!runList->at(i).GetFileFormat(j)->CompareTo("mud")) { success = ReadMudFile(); } else if (!runList->at(i).GetFileFormat(j)->CompareTo("wkm")) { success = ReadWkmFile(); } else if (!runList->at(i).GetFileFormat(j)->CompareTo("mdu-ascii")) { success = ReadMduAsciiFile(); } else if (!runList->at(i).GetFileFormat(j)->CompareTo("ascii")) { success = ReadAsciiFile(); } else if (!runList->at(i).GetFileFormat(j)->CompareTo("db")) { success = ReadDBFile(); } else { success = false; } } } return success; } //-------------------------------------------------------------------------- // ReadWriteFilesList (private) //-------------------------------------------------------------------------- /** *

The main read file routine which is filtering what read sub-routine * needs to be called. Called when the input is a list of runs. Used with * any2many. If the input data file is successfully read, it will write the * converted data file. * * return: * - true if reading was successful, * - false if reading failed. */ Bool_t PRunDataHandler::ReadWriteFilesList() { if ((fAny2ManyInfo->inFileName.size() == 0) && (fAny2ManyInfo->runList.size() == 0)) { cerr << endl << ">> PRunDataHandler::ReadWriteFilesList(): **ERROR** Couldn't obtain run list from fAny2ManyInfo: something VERY fishy"; cerr << endl; return false; } // get input file format tag Int_t inTag = A2M_UNDEFINED; if (!fAny2ManyInfo->inFormat.CompareTo("root", TString::kIgnoreCase)) inTag = A2M_ROOT; else if (!fAny2ManyInfo->inFormat.CompareTo("musrroot", TString::kIgnoreCase)) inTag = A2M_MUSR_ROOT; else if (!fAny2ManyInfo->inFormat.CompareTo("psi-bin", TString::kIgnoreCase)) inTag = A2M_PSIBIN; else if (!fAny2ManyInfo->inFormat.CompareTo("psi-mdu", TString::kIgnoreCase)) inTag = A2M_PSIMDU; else if (!fAny2ManyInfo->inFormat.CompareTo("mud", TString::kIgnoreCase)) inTag = A2M_MUD; else if (!fAny2ManyInfo->inFormat.CompareTo("nexus", TString::kIgnoreCase)) inTag = A2M_NEXUS; else if (!fAny2ManyInfo->inFormat.CompareTo("wkm", TString::kIgnoreCase)) inTag = A2M_WKM; else inTag = A2M_UNDEFINED; if (inTag == A2M_UNDEFINED) { cerr << endl << ">> PRunDataHandler::ReadWriteFilesList(): **ERROR** no valid input data file format found: '" << fAny2ManyInfo->inFormat.Data() << "'" << endl; return false; } // get output file format tag Int_t outTag = A2M_UNDEFINED; if (!fAny2ManyInfo->outFormat.CompareTo("root", TString::kIgnoreCase)) outTag = A2M_ROOT; else if (!fAny2ManyInfo->outFormat.CompareTo("musrroot", TString::kIgnoreCase)) outTag = A2M_MUSR_ROOT; else if (!fAny2ManyInfo->outFormat.CompareTo("psi-bin", TString::kIgnoreCase)) outTag = A2M_PSIBIN; else if (!fAny2ManyInfo->outFormat.CompareTo("mud",TString::kIgnoreCase)) outTag = A2M_MUD; else if (fAny2ManyInfo->outFormat.BeginsWith("nexus", TString::kIgnoreCase)) outTag = A2M_NEXUS; else if (!fAny2ManyInfo->outFormat.CompareTo("wkm", TString::kIgnoreCase)) outTag = A2M_WKM; else if (!fAny2ManyInfo->outFormat.CompareTo("ascii", TString::kIgnoreCase)) outTag = A2M_ASCII; else outTag = A2M_UNDEFINED; if (outTag == A2M_UNDEFINED) { cerr << endl << ">> PRunDataHandler::ReadWriteFilesList(): **ERROR** no valid output data file format found: '" << fAny2ManyInfo->outFormat.Data() << "'" << endl; return false; } if (fAny2ManyInfo->inFileName.size() != 0) { // file name list given // loop over all runs of the run list for (UInt_t i=0; iinFileName.size(); i++) { if (!FileExistsCheck(true, i)) { cerr << endl << ">> PRunDataHandler::ReadWriteFilesList(): **ERROR** Couldn't find file " << fAny2ManyInfo->inFileName[i].Data() << endl; return false; } // read input file Bool_t success = false; switch (inTag) { case A2M_ROOT: case A2M_MUSR_ROOT: success = ReadRootFile(); break; case A2M_PSIBIN: case A2M_PSIMDU: success = ReadPsiBinFile(); break; case A2M_NEXUS: success = ReadNexusFile(); break; case A2M_MUD: success = ReadMudFile(); break; case A2M_WKM: success = ReadWkmFile(); break; default: break; } if (!success) { cerr << endl << ">> PRunDataHandler::ReadWriteFilesList(): **ERROR** Couldn't read file " << fAny2ManyInfo->inFileName[i].Data() << endl; return false; } // write 'converted' output data file success = false; switch (outTag) { case A2M_ROOT: if (fAny2ManyInfo->outFileName.Length() == 0) success = WriteRootFile(); else success = WriteRootFile(fAny2ManyInfo->outFileName); break; case A2M_MUSR_ROOT: if (fAny2ManyInfo->outFileName.Length() == 0) success = WriteMusrRootFile(); else success = WriteMusrRootFile(fAny2ManyInfo->outFileName); break; break; case A2M_PSIBIN: if (fAny2ManyInfo->outFileName.Length() == 0) success = WritePsiBinFile(); else success = WritePsiBinFile(fAny2ManyInfo->outFileName); break; case A2M_PSIMDU: if (fAny2ManyInfo->outFileName.Length() == 0) success = WritePsiBinFile(); else success = WritePsiBinFile(fAny2ManyInfo->outFileName); break; case A2M_NEXUS: if (fAny2ManyInfo->outFileName.Length() == 0) success = WriteNexusFile(); else success = WriteNexusFile(fAny2ManyInfo->outFileName); break; case A2M_MUD: if (fAny2ManyInfo->outFileName.Length() == 0) success = WriteMudFile(); else success = WriteMudFile(fAny2ManyInfo->outFileName); break; case A2M_WKM: if (fAny2ManyInfo->outFileName.Length() == 0) success = WriteWkmFile(); else success = WriteWkmFile(fAny2ManyInfo->outFileName); break; case A2M_ASCII: if (fAny2ManyInfo->outFileName.Length() == 0) success = WriteAsciiFile(); else success = WriteAsciiFile(fAny2ManyInfo->outFileName); break; default: break; } if (success == false) { cerr << endl << ">> PRunDataHandler::ReadWriteFilesList(): **ERROR** Couldn't write converted output file." << endl; return false; } // throw away the current data set fData.clear(); } } if (fAny2ManyInfo->runList.size() != 0) { // run list given // loop over all runs of the run list for (UInt_t i=0; irunList.size(); i++) { if (!FileExistsCheck(false, i)) { cerr << endl << ">> PRunDataHandler::ReadWriteFilesList(): **ERROR** Couldn't find run " << fAny2ManyInfo->runList[i] << endl; return false; } // read input file Bool_t success = false; switch (inTag) { case A2M_ROOT: case A2M_MUSR_ROOT: success = ReadRootFile(); break; case A2M_PSIBIN: case A2M_PSIMDU: success = ReadPsiBinFile(); break; case A2M_NEXUS: success = ReadNexusFile(); break; case A2M_MUD: success = ReadMudFile(); break; case A2M_WKM: success = ReadWkmFile(); break; default: break; } if (!success) { cerr << endl << ">> PRunDataHandler::ReadWriteFilesList(): **ERROR** Couldn't read file " << fRunPathName.Data() << endl; return false; } TString year(""); TDatime dt; year += dt.GetYear(); if (fAny2ManyInfo->year.Length() > 0) year = fAny2ManyInfo->year; Bool_t ok; TString fln = FileNameFromTemplate(fAny2ManyInfo->outTemplate, fAny2ManyInfo->runList[i], year, ok); if (!ok) { cerr << endl << ">> PRunDataHandler::ReadWriteFilesList(): **ERROR** Couldn't create necessary output file name." << endl; return false; } // write 'converted' output data file success = false; switch (outTag) { case A2M_ROOT: success = WriteRootFile(fln); break; case A2M_MUSR_ROOT: success = WriteMusrRootFile(fln); break; case A2M_PSIBIN: success = WritePsiBinFile(fln); break; case A2M_PSIMDU: success = WritePsiBinFile(fln); break; case A2M_NEXUS: success = WriteNexusFile(fln); break; case A2M_MUD: success = WriteMudFile(fln); break; case A2M_WKM: success = WriteWkmFile(fln); break; case A2M_ASCII: success = WriteAsciiFile(fln); break; default: break; } if (success == false) { cerr << endl << ">> PRunDataHandler::ReadWriteFilesList(): **ERROR** Couldn't write converted output file." << endl; return false; } // throw away the current data set fData.clear(); } } // check if compression is wished if (fAny2ManyInfo->compressionTag > 0) { TString fln = fAny2ManyInfo->outPath + fAny2ManyInfo->compressFileName; // currently system call is used, which means this is only running under Linux and Mac OS X but not under Windows char cmd[256]; if (fAny2ManyInfo->outPathFileName.size() == 1) { if (fAny2ManyInfo->compressionTag == 1) // gzip fln += TString(".tar.gz"); else // bzip2 fln += TString(".tar.bz2"); if (fAny2ManyInfo->compressionTag == 1) // gzip sprintf(cmd, "tar -zcf %s %s", fln.Data(), fAny2ManyInfo->outPathFileName[0].Data()); else // bzip2 sprintf(cmd, "tar -jcf %s %s", fln.Data(), fAny2ManyInfo->outPathFileName[0].Data()); system(cmd); } else { fln += TString(".tar"); for (UInt_t i=0; ioutPathFileName.size(); i++) { if (i==0) { sprintf(cmd, "tar -cf %s %s", fln.Data(), fAny2ManyInfo->outPathFileName[i].Data()); } else { sprintf(cmd, "tar -rf %s %s", fln.Data(), fAny2ManyInfo->outPathFileName[i].Data()); } system(cmd); } if (fAny2ManyInfo->compressionTag == 1) { // gzip sprintf(cmd, "gzip %s", fln.Data()); fln += ".gz"; } else { sprintf(cmd, "bzip2 -z %s", fln.Data()); fln += ".bz2"; } system(cmd); } // check if the compressed file shall be streamed to the stdout if (fAny2ManyInfo->useStandardOutput) { // stream file to stdout ifstream is; int length=1024; char *buffer; is.open(fln.Data(), ios::binary); if (!is.is_open()) { cerr << endl << "PRunDataHandler::ReadWriteFilesList(): **ERROR** Couldn't open the file for streaming." << endl; remove(fln.Data()); return false; } // get length of file is.seekg(0, ios::end); length = is.tellg(); is.seekg(0, ios::beg); if (length == -1) { cerr << endl << "PRunDataHandler::ReadWriteFilesList(): **ERROR** Couldn't determine the file size." << endl; remove(fln.Data()); return false; } // allocate memory buffer = new char [length]; // read data as a block while (!is.eof()) { is.read(buffer, length); cout.write(buffer, length); } is.close(); delete [] buffer; // delete temporary root file remove(fln.Data()); } // remove all the converted files for (UInt_t i=0; ioutPathFileName.size(); i++) remove(fAny2ManyInfo->outPathFileName[i].Data()); } return true; } //-------------------------------------------------------------------------- // FileAlreadyRead (private) //-------------------------------------------------------------------------- /** *

Checks if a file has been already read in order to prevent multiple * reading of data files. * * return: * - true if the file has been read before, * - otherwise false. * * \param runName run name to be check if the corresponding file is already read. */ Bool_t PRunDataHandler::FileAlreadyRead(TString runName) { for (UInt_t i=0; iCompareTo(runName)) { // run alread read return true; } } return false; } //-------------------------------------------------------------------------- // TestFileName (private) //-------------------------------------------------------------------------- /** *

Tests if a file exists (with or without given extension). * The given file-name string will be modified to show the found file name or an empty string if no file is found. * * \param runName run name with full path to be checked * \param ext extension to be checked */ void PRunDataHandler::TestFileName(TString &runName, const TString &ext) { TString tmpStr(runName), tmpExt(ext); // check first if the file exists with the default extension which is not given with the run name tmpStr += TString(".") + ext; if (gSystem->AccessPathName(tmpStr.Data()) != true) { // found runName = tmpStr; return; } // test if the file exists with the given run name but an only upper-case extension which is not included in the file name tmpStr = runName; tmpExt.ToUpper(); tmpStr += TString(".") + tmpExt; if (gSystem->AccessPathName(tmpStr.Data()) != true) { // found runName = tmpStr; return; } // test if the file exists with the given run name but an only lower-case extension which is not included in the file name tmpStr = runName; tmpExt.ToLower(); tmpStr += TString(".") + tmpExt; if (gSystem->AccessPathName(tmpStr.Data()) != true) { // found runName = tmpStr; return; } // test if the file exists with only upper-case letters tmpStr = runName + TString(".") + tmpExt; tmpStr.ToUpper(); if (gSystem->AccessPathName(tmpStr.Data()) != true) { // found runName = tmpStr; return; } // test if the file exists with only lower-case letters tmpStr.ToLower(); if (gSystem->AccessPathName(tmpStr.Data()) != true) { // found runName = tmpStr; return; } tmpStr = runName; // the extension is already part of the file name, therefore, do not append it if (tmpStr.EndsWith(ext.Data(), TString::kIgnoreCase)) { if (gSystem->AccessPathName(tmpStr.Data()) != true) { // found runName = tmpStr; return; } // assume some extension is part of the given file name but the real data file ends with an lower-case extension tmpExt.ToLower(); tmpStr = tmpStr.Replace(static_cast(tmpStr.Length()-tmpExt.Length()), tmpExt.Length(), tmpExt); if (gSystem->AccessPathName(tmpStr.Data()) != true) { // found runName = tmpStr; return; } // assume some extension is part of the given file name but the real data file ends with an upper-case extension tmpExt.ToUpper(); tmpStr = runName; tmpStr = tmpStr.Replace(static_cast(tmpStr.Length()-tmpExt.Length()), tmpExt.Length(), tmpExt); if (gSystem->AccessPathName(tmpStr.Data()) != true) { // found runName = tmpStr; return; } // test if the file exists with only lower-case letters and the extension already included in the file name tmpStr = runName; tmpStr.ToLower(); if (gSystem->AccessPathName(tmpStr.Data()) != true) { // found runName = tmpStr; return; } // test if the file exists with only upper-case letters and the extension already included in the file name tmpStr = runName; tmpStr.ToUpper(); if (gSystem->AccessPathName(tmpStr.Data()) != true) { // found runName = tmpStr; return; } } // if the file has not been found, set the run name to be empty runName = ""; return; } //-------------------------------------------------------------------------- // FileExistsCheck (private) //-------------------------------------------------------------------------- /** *

Checks if a given data file exists. * * return: * - true if data file exists, * - otherwise false. * * \param runInfo reference to the msr-run-structure * \param idx index of the run (needed for ADDRUN feature). */ Bool_t PRunDataHandler::FileExistsCheck(PMsrRunBlock &runInfo, const UInt_t idx) { Bool_t success = true; // local init TROOT root("PRunBase", "PRunBase", 0); TString pathName = "???"; TString str, *pstr; TString ext; pstr = runInfo.GetBeamline(idx); if (pstr == 0) { cerr << endl << ">> PRunDataHandler::FileExistsCheck: **ERROR** Couldn't obtain beamline data." << endl; assert(0); } pstr->ToLower(); runInfo.SetBeamline(*pstr, idx); pstr = runInfo.GetInstitute(idx); if (pstr == 0) { cerr << endl << ">> PRunDataHandler::FileExistsCheck: **ERROR** Couldn't obtain institute data." << endl; assert(0); } pstr->ToLower(); runInfo.SetInstitute(*pstr, idx); pstr = runInfo.GetFileFormat(idx); if (pstr == 0) { cerr << endl << ">> PRunDataHandler::FileExistsCheck: **ERROR** Couldn't obtain file format data." << endl; assert(0); } pstr->ToLower(); runInfo.SetFileFormat(*pstr, idx); // file extensions for the various formats if (!runInfo.GetFileFormat(idx)->CompareTo("root-npp")) // not post pile up corrected histos ext = TString("root"); else if (!runInfo.GetFileFormat(idx)->CompareTo("root-ppc")) // post pile up corrected histos ext = TString("root"); else if (!runInfo.GetFileFormat(idx)->CompareTo("musr-root")) // post pile up corrected histos ext = TString("root"); else if (!runInfo.GetFileFormat(idx)->CompareTo("nexus")) ext = TString("NXS"); else if (!runInfo.GetFileFormat(idx)->CompareTo("psi-bin")) ext = TString("bin"); else if (!runInfo.GetFileFormat(idx)->CompareTo("psi-mdu")) ext = TString("mdu"); else if (!runInfo.GetFileFormat(idx)->CompareTo("mud")) ext = TString("msr"); else if (!runInfo.GetFileFormat(idx)->CompareTo("wkm")) { if (!runInfo.GetBeamline(idx)->CompareTo("mue4")) ext = TString("nemu"); else ext = *runInfo.GetBeamline(idx); } else if (!runInfo.GetFileFormat(idx)->CompareTo("mdu-ascii")) ext = TString("mdua"); else if (!runInfo.GetFileFormat(idx)->CompareTo("ascii")) ext = TString("dat"); else if (!runInfo.GetFileFormat(idx)->CompareTo("db")) ext = TString("db"); else success = false; // unkown file format found if (!success) { pstr = runInfo.GetFileFormat(idx); if (pstr == 0) { cerr << endl << ">> PRunDataHandler::FileExistsCheck: **ERROR** Couldn't obtain file format data." << endl; assert(0); } pstr->ToUpper(); cerr << endl << ">> PRunDataHandler::FileExistsCheck: **ERROR** File Format '" << pstr->Data() << "' unsupported."; cerr << endl << ">> support file formats are:"; cerr << endl << ">> ROOT-NPP -> root not post pileup corrected for lem"; cerr << endl << ">> ROOT-PPC -> root post pileup corrected for lem"; cerr << endl << ">> MUSR-ROOT -> MusrRoot file format"; cerr << endl << ">> NEXUS -> nexus file format, HDF4, HDF5, or XML"; cerr << endl << ">> PSI-BIN -> psi bin file format"; cerr << endl << ">> PSI-MDU -> psi mdu file format (see also MDU-ASCII)"; cerr << endl << ">> MUD -> triumf mud file format"; cerr << endl << ">> WKM -> wkm ascii file format"; cerr << endl << ">> MDU-ASCII -> psi mdu ascii file format"; cerr << endl << ">> ASCII -> column like file format"; cerr << endl << ">> DB -> triumf db file \"format\""; cerr << endl; return success; } // check if the file is in the local directory str = *runInfo.GetRunName(idx); TestFileName(str, ext); if (!str.IsNull()) { pathName = str; } // check if the file is found in the if (pathName.CompareTo("???") == 0) { // not found in local directory search str = *fMsrInfo->GetMsrFileDirectoryPath() + *runInfo.GetRunName(idx); TestFileName(str, ext); if (!str.IsNull()) { pathName = str; } } // check if the file is found in the directory given in the startup file if (pathName.CompareTo("???") == 0) { // not found in local directory search and not found in the search for (UInt_t i=0; iGetenv("MUSRFULLDATAPATH"); if (pathName.CompareTo("???") == 0) { // not found in local directory and xml path str = TString(musrpath); // MUSRFULLDATAPATH has the structure: path_1:path_2:...:path_n TObjArray *tokens = str.Tokenize(":"); TObjString *ostr; for (Int_t i=0; iGetEntries(); i++) { ostr = dynamic_cast(tokens->At(i)); str = ostr->GetString() + TString("/") + *runInfo.GetRunName(idx); TestFileName(str, ext); if (!str.IsNull()) { pathName = str; break; } } // cleanup if (tokens) { delete tokens; tokens = 0; } } // check if the file is found in the generated default path if (pathName.CompareTo("???") == 0) { // not found in MUSRFULLDATAPATH search str = TString(musrpath); // MUSRFULLDATAPATH has the structure: path_1:path_2:...:path_n TObjArray *tokens = str.Tokenize(":"); TObjString *ostr; pstr = runInfo.GetInstitute(idx); if (pstr == 0) { cerr << endl << ">> PRunDataHandler::FileExistsCheck: **ERROR** Couldn't obtain institute data." << endl; assert(0); } pstr->ToUpper(); runInfo.SetInstitute(*pstr, idx); pstr = runInfo.GetBeamline(idx); if (pstr == 0) { cerr << endl << ">> PRunDataHandler::FileExistsCheck: **ERROR** Couldn't obtain beamline data." << endl; assert(0); } pstr->ToUpper(); runInfo.SetBeamline(*pstr, idx); for (Int_t i=0; iGetEntries(); i++) { ostr = dynamic_cast(tokens->At(i)); str = ostr->GetString() + TString("/DATA/") + *runInfo.GetInstitute(idx) + TString("/") + *runInfo.GetBeamline(idx) + TString("/") + *runInfo.GetRunName(idx); TestFileName(str, ext); if (!str.IsNull()) { // found pathName = str; break; } } // clean up if (tokens) { delete tokens; tokens = 0; } } // no proper path name found if (pathName.CompareTo("???") == 0) { cerr << endl << ">> PRunDataHandler::FileExistsCheck(): **ERROR** Couldn't find '" << runInfo.GetRunName(idx)->Data() << "' in any standard path."; cerr << endl << ">> standard search pathes are:"; cerr << endl << ">> 1. the local directory"; cerr << endl << ">> 2. the data directory given in the startup XML file"; cerr << endl << ">> 3. the directories listed in MUSRFULLDATAPATH"; cerr << endl << ">> 4. default path construct which is described in the manual"; return false; } fRunPathName = pathName; return true; } //-------------------------------------------------------------------------- // FileExistsCheck (private) //-------------------------------------------------------------------------- /** *

Checks if a given data file exists. Used for the any2many program. * * return: * - true if data file exists, * - otherwise false. * * \param fileName flag showing if a file name shall be handled or a run number * \param idx index of the run. idx == -1 means that a single input data file name is given. */ Bool_t PRunDataHandler::FileExistsCheck(const Bool_t fileName, const Int_t idx) { TString pathName("???"); TString str(""); TString fln(""); if (fileName) { // single input file name if (idx >= (Int_t)fAny2ManyInfo->inFileName.size()) { cerr << endl << ">> PRunDataHandler::FileExistsCheck(): **ERROR** idx=" << idx << " out of range. (inFileName.size()==" << fAny2ManyInfo->inFileName.size() << ")" << endl; return false; } fln = fAny2ManyInfo->inFileName[idx]; } else { // run file list entry shall be handled if (idx >= (Int_t)fAny2ManyInfo->runList.size()) { cerr << endl << ">> PRunDataHandler::FileExistsCheck(): **ERROR** idx=" << idx << " out of range. (inFileName.size()==" << fAny2ManyInfo->runList.size() << ")" << endl; return false; } // check for input/output templates if ((fAny2ManyInfo->inTemplate.Length() == 0) || (fAny2ManyInfo->outTemplate.Length() == 0)) { cerr << endl << ">> PRunDataHandler::FileExistsCheck(): **ERROR** when using run lists, input/output templates are needed as well." << endl; return false; } // make the input file name according to the input template TString year(""); TDatime dt; year += dt.GetYear(); if (fAny2ManyInfo->year.Length() > 0) year = fAny2ManyInfo->year; Bool_t ok; fln = FileNameFromTemplate(fAny2ManyInfo->inTemplate, fAny2ManyInfo->runList[idx], year, ok); if (!ok) return false; } // check if the file is in the local directory if (gSystem->AccessPathName(fln) != true) { // found in the local dir pathName = fln; } // check if the file is found in the directory given in the startup file if (pathName.CompareTo("???") == 0) { // not found in local directory search for (UInt_t i=0; iAccessPathName(str.Data())!=true) { // found pathName = str; break; } } } // check if the file is found in the directories given by MUSRFULLDATAPATH const Char_t *musrpath = gSystem->Getenv("MUSRFULLDATAPATH"); if (pathName.CompareTo("???") == 0) { // not found in local directory and xml path str = TString(musrpath); // MUSRFULLDATAPATH has the structure: path_1:path_2:...:path_n TObjArray *tokens = str.Tokenize(":"); TObjString *ostr; for (Int_t i=0; iGetEntries(); i++) { ostr = dynamic_cast(tokens->At(i)); str = ostr->GetString() + TString("/") + fln; if (gSystem->AccessPathName(str.Data())!=true) { // found pathName = str; break; } } // cleanup if (tokens) { delete tokens; tokens = 0; } } // no proper path name found if (pathName.CompareTo("???") == 0) { cerr << endl << ">> PRunDataHandler::FileExistsCheck(): **ERROR** Couldn't find '" << fln.Data() << "' in any standard path."; cerr << endl << ">> standard search pathes are:"; cerr << endl << ">> 1. the local directory"; cerr << endl << ">> 2. the data directory given in the startup XML file"; cerr << endl << ">> 3. the directories listed in MUSRFULLDATAPATH"; return false; } fRunPathName = pathName; return true; } //-------------------------------------------------------------------------- // FileExistsCheck (private) //-------------------------------------------------------------------------- /** *

Checks if a given data file exists. Used for the any2many program. * * return: * - true if data file exists, * - otherwise false. * * \param fileName file name */ Bool_t PRunDataHandler::FileExistsCheck(const TString fileName) { TString pathName("???"); TString str(""); // check if the file is in the local directory if (gSystem->AccessPathName(fileName) != true) { // found in the local dir pathName = fileName; } // check if the file is found in the directory given in the startup file if (pathName.CompareTo("???") == 0) { // not found in local directory search for (UInt_t i=0; iAccessPathName(str.Data())!=true) { // found pathName = str; break; } } } // check if the file is found in the directories given by MUSRFULLDATAPATH const Char_t *musrpath = gSystem->Getenv("MUSRFULLDATAPATH"); if (pathName.CompareTo("???") == 0) { // not found in local directory and xml path str = TString(musrpath); // MUSRFULLDATAPATH has the structure: path_1:path_2:...:path_n TObjArray *tokens = str.Tokenize(":"); TObjString *ostr; for (Int_t i=0; iGetEntries(); i++) { ostr = dynamic_cast(tokens->At(i)); str = ostr->GetString() + TString("/") + fileName; if (gSystem->AccessPathName(str.Data())!=true) { // found pathName = str; break; } } // cleanup if (tokens) { delete tokens; tokens = 0; } } // no proper path name found if (pathName.CompareTo("???") == 0) { cerr << endl << ">> PRunDataHandler::FileExistsCheck(): **ERROR** Couldn't find '" << fileName.Data() << "' in any standard path."; cerr << endl << ">> standard search pathes are:"; cerr << endl << ">> 1. the local directory"; cerr << endl << ">> 2. the data directory given in the startup XML file"; cerr << endl << ">> 3. the directories listed in MUSRFULLDATAPATH"; return false; } fRunPathName = pathName; return true; } //-------------------------------------------------------------------------- // ReadRootFile (private) //-------------------------------------------------------------------------- /** *

Reads both, the "old" LEM-data ROOT-files with TLemRunHeader, and the more general * new MusrRoot file. * * return: * - true at successful reading, * - otherwise false. */ Bool_t PRunDataHandler::ReadRootFile() { PDoubleVector histoData; PRawRunData runData; PRawRunDataSet dataSet; TFile f(fRunPathName.Data()); if (f.IsZombie()) { return false; } UInt_t fileType = PRH_MUSR_ROOT; TFolder *folder; f.GetObject("RunInfo", folder); // try first LEM-ROOT style file (used until 2011). if (!folder) { // either something is wrong, or it is a MusrRoot file f.GetObject("RunHeader", folder); if (!folder) { // something is wrong!! cerr << endl << ">> PRunDataHandler::ReadRootFile: **ERROR** Couldn't neither obtain RunInfo (LEM),"; cerr << endl << " nor RunHeader (MusrRoot) from " << fRunPathName.Data() << endl; f.Close(); return false; } else { fileType = PRH_MUSR_ROOT; } } else { fileType = PRH_LEM_ROOT; } if (fileType == PRH_LEM_ROOT) { // read header and check if some missing run info need to be fed TLemRunHeader *runHeader = dynamic_cast(folder->FindObjectAny("TLemRunHeader")); // check if run header is valid if (!runHeader) { cerr << endl << ">> PRunDataHandler::ReadRootFile: **ERROR** Couldn't obtain run header info from ROOT file " << fRunPathName.Data() << endl; f.Close(); return false; } // set laboratory / beamline / instrument runData.SetLaboratory("PSI"); runData.SetBeamline("muE4"); runData.SetInstrument("LEM"); runData.SetMuonSource("low energy muon source"); runData.SetMuonSpecies("positive muons"); // get run title TObjString ostr = runHeader->GetRunTitle(); runData.SetRunTitle(ostr.GetString()); // get run number runData.SetRunNumber((Int_t)runHeader->GetRunNumber()); // get temperature runData.ClearTemperature(); runData.SetTemperature(0, runHeader->GetSampleTemperature(), runHeader->GetSampleTemperatureError()); // get field runData.SetField(runHeader->GetSampleBField()); // get implantation energy runData.SetEnergy(runHeader->GetImpEnergy()); // get moderator HV runData.SetTransport(runHeader->GetModeratorHV()); // get setup runData.SetSetup(runHeader->GetLemSetup().GetString()); // get start time/date // start date time_t idt = (time_t)runHeader->GetStartTime(); runData.SetStartDateTime(idt); struct tm *dt = localtime(&idt); char str[128]; strftime(str, sizeof(str), "%F", dt); TString stime(str); runData.SetStartDate(stime); // start time memset(str, 0, sizeof(str)); strftime(str, sizeof(str), "%T", dt); stime = str; runData.SetStartTime(stime); // get stop time/date // stop date idt = (time_t)runHeader->GetStopTime(); runData.SetStopDateTime(idt); dt = localtime(&idt); memset(str, 0, sizeof(str)); strftime(str, sizeof(str), "%F", dt); stime = str; runData.SetStopDate(stime); // stop time memset(str, 0, sizeof(str)); strftime(str, sizeof(str), "%T", dt); stime = str; runData.SetStopTime(stime); // get time resolution runData.SetTimeResolution(runHeader->GetTimeResolution()); // get number of histogramms Int_t noOfHistos = runHeader->GetNHist(); // get t0's there will be handled together with the data Double_t *t0 = runHeader->GetTimeZero(); // read run summary to obtain ring anode HV values TObjArray *runSummary = dynamic_cast(folder->FindObjectAny("RunSummary")); // check if run summary is valid if (!runSummary) { cout << endl << "**INFO** Couldn't obtain run summary info from ROOT file " << fRunPathName.Data() << endl; // this is not fatal... only RA-HV values are not available } else { // it follows a (at least) little bit strange extraction of the RA values from Thomas' TObjArray... //streaming of a ASCII-file would be more easy TString s; TObjArrayIter summIter(runSummary); TObjString *os(dynamic_cast(summIter.Next())); TObjArray *oa(0); TObjString *objTok(0); while (os != 0) { s = os->GetString(); // will put four parallel if's since it may be that more than one RA-values are on one line if (s.Contains("RA-L")) { oa = s.Tokenize(" "); TObjArrayIter lineIter(oa); objTok = dynamic_cast(lineIter.Next()); while (objTok != 0) { if (!objTok->GetString().CompareTo("RA-L")) { objTok = dynamic_cast(lineIter.Next()); // "=" if (objTok != 0 && !objTok->GetString().CompareTo("=")) { objTok = dynamic_cast(lineIter.Next()); // HV value runData.SetRingAnode(0, objTok->GetString().Atof()); // fill RA-R value into the runData structure break; } } objTok = dynamic_cast(lineIter.Next()); // next token... } // clean up if (oa) { delete oa; oa = 0; } } if (s.Contains("RA-R")) { oa = s.Tokenize(" "); TObjArrayIter lineIter(oa); objTok = dynamic_cast(lineIter.Next()); while (objTok != 0){ if (!objTok->GetString().CompareTo("RA-R")) { objTok = dynamic_cast(lineIter.Next()); // "=" if (objTok != 0 && !objTok->GetString().CompareTo("=")) { objTok = dynamic_cast(lineIter.Next()); // HV value runData.SetRingAnode(1, objTok->GetString().Atof()); // fill RA-R value into the runData structure break; } } objTok = dynamic_cast(lineIter.Next()); // next token... } // clean up if (oa) { delete oa; oa = 0; } } if (s.Contains("RA-T")) { oa = s.Tokenize(" "); TObjArrayIter lineIter(oa); objTok = dynamic_cast(lineIter.Next()); while (objTok != 0){ if (!objTok->GetString().CompareTo("RA-T")) { objTok = dynamic_cast(lineIter.Next()); // "=" if (objTok != 0 && !objTok->GetString().CompareTo("=")) { objTok = dynamic_cast(lineIter.Next()); // HV value runData.SetRingAnode(2, objTok->GetString().Atof()); // fill RA-T value into the runData structure break; } } objTok = dynamic_cast(lineIter.Next()); // next token... } // clean up if (oa) { delete oa; oa = 0; } } if (s.Contains("RA-B")) { oa = s.Tokenize(" "); TObjArrayIter lineIter(oa); objTok = dynamic_cast(lineIter.Next()); while (objTok != 0){ if (!objTok->GetString().CompareTo("RA-B")) { objTok = dynamic_cast(lineIter.Next()); // "=" if (objTok != 0 && !objTok->GetString().CompareTo("=")) { objTok = dynamic_cast(lineIter.Next()); // HV value runData.SetRingAnode(3, objTok->GetString().Atof()); // fill RA-B value into the runData structure break; } } objTok = dynamic_cast(lineIter.Next()); // next token... } // clean up if (oa) { delete oa; oa = 0; } } os = dynamic_cast(summIter.Next()); // next summary line... } } // read data --------------------------------------------------------- // check if histos folder is found f.GetObject("histos", folder); if (!folder) { cerr << endl << ">> PRunDataHandler::ReadRootFile: **ERROR** Couldn't obtain histos from " << fRunPathName.Data() << endl; f.Close(); return false; } // get all the data Char_t histoName[32]; for (Int_t i=0; i(folder->FindObjectAny(histoName)); if (!histo) { cerr << endl << ">> PRunDataHandler::ReadRootFile: **ERROR** Couldn't get histo " << histoName; cerr << endl; f.Close(); return false; } // fill data for (Int_t j=1; j<=histo->GetNbinsX(); j++) { histoData.push_back(histo->GetBinContent(j)); } // fill the data set dataSet.Clear(); dataSet.SetName(histo->GetTitle()); dataSet.SetHistoNo(i+1); dataSet.SetTimeZeroBin(t0[i]); dataSet.SetTimeZeroBinEstimated(histo->GetMaximumBin()); dataSet.SetFirstGoodBin((Int_t)t0[i]); dataSet.SetLastGoodBin(histo->GetNbinsX()-1); dataSet.SetData(histoData); runData.SetDataSet(dataSet); // clear histoData for the next histo histoData.clear(); } // check if any post pileup histos are present at all (this is not the case for LEM data 2006 and earlier) sprintf(histoName, "hDecay%02d", POST_PILEUP_HISTO_OFFSET); if (!folder->FindObjectAny(histoName)) { cerr << endl << ">> PRunDataHandler::ReadRootFile: **WARNING** Couldn't get histo " << histoName; cerr << endl << ">> most probably this is an old (2006 or earlier) LEM file without post pileup histos."; cerr << endl; } else { for (Int_t i=0; i(folder->FindObjectAny(histoName)); if (!histo) { cerr << endl << ">> PRunDataHandler::ReadRootFile: **ERROR** Couldn't get histo " << histoName; cerr << endl; f.Close(); return false; } // fill data for (Int_t j=1; j<=histo->GetNbinsX(); j++) histoData.push_back(histo->GetBinContent(j)); // fill the data set dataSet.Clear(); dataSet.SetName(histo->GetTitle()); dataSet.SetHistoNo(i+1+POST_PILEUP_HISTO_OFFSET); dataSet.SetTimeZeroBin(t0[i]); dataSet.SetTimeZeroBinEstimated(histo->GetMaximumBin()); dataSet.SetFirstGoodBin((Int_t)t0[i]); dataSet.SetLastGoodBin(histo->GetNbinsX()-1); dataSet.SetData(histoData); runData.SetDataSet(dataSet); // clear histoData for the next histo histoData.clear(); } } } else { // MusrRoot file // invoke the MusrRoot header object TMusrRunHeader *header = new TMusrRunHeader(true); // read quite if (header == 0) { cerr << endl << ">> PRunDataHandler::ReadRootFile: **ERROR** Couldn't invoke MusrRoot RunHeader in file:" << fRunPathName; cerr << endl; f.Close(); return false; } // try to populate the MusrRoot header object if (!header->ExtractAll(folder)) { cerr << endl << ">> PRunDataHandler::ReadRootFile: **ERROR** Couldn't invoke MusrRoot RunHeader in file:" << fRunPathName; cerr << endl; f.Close(); return false; } // get all the header information Bool_t ok; TString str, path, pathName; Int_t ival, noOfHistos=0; Double_t dval; TMusrRunPhysicalQuantity prop; PIntVector ivec, redGreenOffsets; header->Get("RunInfo/Version", str, ok); if (ok) runData.SetVersion(str); header->Get("RunInfo/Generic Validator URL", str, ok); if (ok) runData.SetGenericValidatorUrl(str); header->Get("RunInfo/Specific Validator URL", str, ok); if (ok) runData.SetSpecificValidatorUrl(str); header->Get("RunInfo/Generator", str, ok); if (ok) runData.SetGenerator(str); header->Get("RunInfo/File Name", str, ok); if (ok) runData.SetFileName(str); header->Get("RunInfo/Run Title", str, ok); if (ok) runData.SetRunTitle(str); header->Get("RunInfo/Run Number", ival, ok); if (ok) runData.SetRunNumber(ival); header->Get("RunInfo/Run Start Time", str, ok); if (ok) { Ssiz_t pos = str.Index(' '); TString substr = str; substr.Remove(pos, str.Length()); runData.SetStartDate(substr); substr = str; substr.Remove(0, pos+1); runData.SetStartTime(substr); } header->Get("RunInfo/Run Stop Time", str, ok); if (ok) { Ssiz_t pos = str.Index(' '); TString substr = str; substr.Remove(pos, str.Length()); runData.SetStopDate(substr); substr = str; substr.Remove(0, pos+1); runData.SetStopTime(substr); } header->Get("RunInfo/Laboratory", str, ok); if (ok) runData.SetLaboratory(str); header->Get("RunInfo/Instrument", str, ok); if (ok) runData.SetInstrument(str); header->Get("RunInfo/Muon Beam Momentum", prop, ok); if (ok) { if (!prop.GetUnit().CompareTo("MeV/c")) runData.SetMuonBeamMomentum(prop.GetValue()); } header->Get("RunInfo/Muon Species", str, ok); if (ok) runData.SetMuonSpecies(str); header->Get("RunInfo/Muon Source", str, ok); if (ok) runData.SetMuonSource(str); header->Get("RunInfo/Muon Spin Angle", prop, ok); if (ok) { runData.SetMuonSpinAngle(prop.GetValue()); } header->Get("RunInfo/Setup", str, ok); if (ok) runData.SetSetup(str); header->Get("RunInfo/Comment", str, ok); if (ok) runData.SetComment(str); header->Get("RunInfo/Sample Name", str, ok); if (ok) runData.SetSample(str); header->Get("RunInfo/Sample Temperature", prop, ok); if (ok) runData.SetTemperature(0, prop.GetValue(), prop.GetError()); header->Get("RunInfo/Sample Magnetic Field", prop, ok); if (ok) { dval = MRH_UNDEFINED; if (!prop.GetUnit().CompareTo("G") || !prop.GetUnit().CompareTo("Gauss")) dval = prop.GetValue(); else if (!prop.GetUnit().CompareTo("T") || !prop.GetUnit().CompareTo("Tesla")) dval = prop.GetValue() * 1.0e4; runData.SetField(dval); } header->Get("RunInfo/No of Histos", ival, ok); if (ok) { noOfHistos = ival; } header->Get("RunInfo/Time Resolution", prop, ok); if (ok) { dval = -1.0; if (!prop.GetUnit().CompareTo("ps") || !prop.GetUnit().CompareTo("picosec")) dval = prop.GetValue()/1.0e3; else if (!prop.GetUnit().CompareTo("ns") || !prop.GetUnit().CompareTo("nanosec")) dval = prop.GetValue(); else if (!prop.GetUnit().CompareTo("us") || !prop.GetUnit().CompareTo("microsec")) dval = prop.GetValue()*1.0e3; else cerr << endl << ">> PRunDataHandler::ReadRootFile: **ERROR** Found unrecognized Time Resolution unit: " << prop.GetUnit() << endl; runData.SetTimeResolution(dval); } header->Get("RunInfo/RedGreen Offsets", ivec, ok); if (ok) { redGreenOffsets = ivec; runData.SetRedGreenOffset(ivec); } // check further for LEM specific stuff in RunInfo header->Get("RunInfo/Moderator HV", prop, ok); if (ok) runData.SetTransport(prop.GetValue()); header->Get("RunInfo/Implantation Energy", prop, ok); if (ok) runData.SetEnergy(prop.GetValue()); // read the SampleEnvironmentInfo header->Get("SampleEnvironmentInfo/Cryo", str, ok); if (ok) runData.SetCryoName(str); // read the MagneticFieldEnvironmentInfo header->Get("MagneticFieldEnvironmentInfo/Magnet Name", str, ok); if (ok) runData.SetMagnetName(str); // read the BeamlineInfo header->Get("BeamlineInfo/Name", str, ok); if (ok) runData.SetBeamline(str); // read run summary to obtain ring anode HV values TObjArray *runSummary = dynamic_cast(folder->FindObjectAny("RunSummary")); // check if run summary is valid if (!runSummary) { cout << endl << "**INFO** Couldn't obtain run summary info from ROOT file " << fRunPathName.Data() << endl; // this is not fatal... only RA-HV values are not available } else { // it follows a (at least) little bit strange extraction of the RA values from Thomas' TObjArray... //streaming of a ASCII-file would be more easy TString s; TObjArrayIter summIter(runSummary); TObjString *os(dynamic_cast(summIter.Next())); TObjArray *oa(0); TObjString *objTok(0); while (os != 0) { s = os->GetString(); // will put four parallel if's since it may be that more than one RA-values are on one line if (s.Contains("RA-L")) { oa = s.Tokenize(" "); TObjArrayIter lineIter(oa); objTok = dynamic_cast(lineIter.Next()); while (objTok != 0) { if (!objTok->GetString().CompareTo("RA-L")) { objTok = dynamic_cast(lineIter.Next()); // "=" if (objTok != 0 && !objTok->GetString().CompareTo("=")) { objTok = dynamic_cast(lineIter.Next()); // HV value runData.SetRingAnode(0, objTok->GetString().Atof()); // fill RA-R value into the runData structure break; } } objTok = dynamic_cast(lineIter.Next()); // next token... } // clean up if (oa) { delete oa; oa = 0; } } if (s.Contains("RA-R")) { oa = s.Tokenize(" "); TObjArrayIter lineIter(oa); objTok = dynamic_cast(lineIter.Next()); while (objTok != 0){ if (!objTok->GetString().CompareTo("RA-R")) { objTok = dynamic_cast(lineIter.Next()); // "=" if (objTok != 0 && !objTok->GetString().CompareTo("=")) { objTok = dynamic_cast(lineIter.Next()); // HV value runData.SetRingAnode(1, objTok->GetString().Atof()); // fill RA-R value into the runData structure break; } } objTok = dynamic_cast(lineIter.Next()); // next token... } // clean up if (oa) { delete oa; oa = 0; } } if (s.Contains("RA-T")) { oa = s.Tokenize(" "); TObjArrayIter lineIter(oa); objTok = dynamic_cast(lineIter.Next()); while (objTok != 0){ if (!objTok->GetString().CompareTo("RA-T")) { objTok = dynamic_cast(lineIter.Next()); // "=" if (objTok != 0 && !objTok->GetString().CompareTo("=")) { objTok = dynamic_cast(lineIter.Next()); // HV value runData.SetRingAnode(2, objTok->GetString().Atof()); // fill RA-T value into the runData structure break; } } objTok = dynamic_cast(lineIter.Next()); // next token... } // clean up if (oa) { delete oa; oa = 0; } } if (s.Contains("RA-B")) { oa = s.Tokenize(" "); TObjArrayIter lineIter(oa); objTok = dynamic_cast(lineIter.Next()); while (objTok != 0){ if (!objTok->GetString().CompareTo("RA-B")) { objTok = dynamic_cast(lineIter.Next()); // "=" if (objTok != 0 && !objTok->GetString().CompareTo("=")) { objTok = dynamic_cast(lineIter.Next()); // HV value runData.SetRingAnode(3, objTok->GetString().Atof()); // fill RA-B value into the runData structure break; } } objTok = dynamic_cast(lineIter.Next()); // next token... } // clean up if (oa) { delete oa; oa = 0; } } os = dynamic_cast(summIter.Next()); // next summary line... } } // read data --------------------------------------------------------- // check if histos folder is found f.GetObject("histos", folder); if (!folder) { cerr << endl << ">> PRunDataHandler::ReadRootFile: **ERROR** Couldn't obtain histos from " << fRunPathName.Data() << endl; f.Close(); return false; } // get all the data for (UInt_t i=0; i(folder->FindObjectAny(str.Data())); if (!histo) { cerr << endl << ">> PRunDataHandler::ReadRootFile: **ERROR** Couldn't get histo " << str; cerr << endl; f.Close(); return false; } dataSet.Clear(); dataSet.SetName(histo->GetTitle()); dataSet.SetHistoNo(redGreenOffsets[i]+j+1); // get detector info path.Form("DetectorInfo/Detector%03d/", redGreenOffsets[i]+j+1); pathName = path + "Time Zero Bin"; header->Get(pathName, dval, ok); if (ok) dataSet.SetTimeZeroBin(dval); pathName = path + "First Good Bin"; header->Get(pathName, ival, ok); if (ok) dataSet.SetFirstGoodBin(ival); pathName = path + "Last Good Bin"; header->Get(pathName, ival, ok); if (ok) dataSet.SetLastGoodBin(ival); dataSet.SetTimeZeroBinEstimated(histo->GetMaximumBin()); // fill data for (Int_t j=1; j<=histo->GetNbinsX(); j++) { histoData.push_back(histo->GetBinContent(j)); } dataSet.SetData(histoData); runData.SetDataSet(dataSet); // clear histoData for the next histo histoData.clear(); } } // clean up if (header) { delete header; header=0; } } f.Close(); // keep run name runData.SetRunName(fRunName); // add run to the run list fData.push_back(runData); return true; } //-------------------------------------------------------------------------- // ReadNexusFile (private) //-------------------------------------------------------------------------- /** *

Will read the NeXuS File Format as soon as PSI will have an implementation. * * return: * - true at successful reading, * - otherwise false. */ Bool_t PRunDataHandler::ReadNexusFile() { #ifdef PNEXUS_ENABLED cout << endl << ">> PRunDataHandler::ReadNexusFile(): Will read nexus file " << fRunPathName.Data() << " ..."; PDoubleVector histoData; PRawRunData runData; PRawRunDataSet dataSet; TString str; string sstr; Double_t dval; bool ok; PNeXus *nxs_file = new PNeXus(fRunPathName.Data()); if (!nxs_file->IsValid()) { cerr << endl << ">> PRunDataHandler::ReadNexusFile(): Not a valid NeXus file."; cerr << endl << ">> Error Message: " << nxs_file->GetErrorMsg().data() << endl; return false; } if (nxs_file->GetIdfVersion() == 1) { if (!nxs_file->IsValid()) { cout << endl << "**ERROR** invalid NeXus IDF 2 version file found." << endl; return false; } // get header information // get/set laboratory str = TString(nxs_file->GetEntryIdf1()->GetLaboratory()); runData.SetLaboratory(str); // get/set beamline str = TString(nxs_file->GetEntryIdf1()->GetBeamline()); runData.SetBeamline(str); // get/set instrument str = TString(nxs_file->GetEntryIdf1()->GetInstrument()->GetName()); runData.SetInstrument(str); // get/set run title str = TString(nxs_file->GetEntryIdf1()->GetTitle()); runData.SetRunTitle(str); // get/set run number runData.SetRunNumber(nxs_file->GetEntryIdf1()->GetRunNumber()); // get/set temperature dval = nxs_file->GetEntryIdf1()->GetSample()->GetPhysPropValue("temperature", ok); if (ok) runData.SetTemperature(0, dval, 0.0); // get/set field dval = nxs_file->GetEntryIdf1()->GetSample()->GetPhysPropValue("magnetic_field", ok); nxs_file->GetEntryIdf1()->GetSample()->GetPhysPropUnit("magnetic_field", sstr, ok); str = sstr; // since field has to be given in Gauss, check the units Double_t factor=1.0; if (!str.CompareTo("gauss", TString::kIgnoreCase)) factor=1.0; else if (!str.CompareTo("tesla", TString::kIgnoreCase)) factor=1.0e4; else factor=1.0; runData.SetField(factor*dval); // get/set implantation energy runData.SetEnergy(PMUSR_UNDEFINED); // get/set moderator HV runData.SetTransport(PMUSR_UNDEFINED); // get/set RA HV's (LEM specific) for (UInt_t i=0; i<4; i++) runData.SetRingAnode(i, PMUSR_UNDEFINED); // get/set setup runData.SetSetup(nxs_file->GetEntryIdf1()->GetNotes()); // get/set sample runData.SetSample(nxs_file->GetEntryIdf1()->GetSample()->GetName()); // get/set orientation runData.SetOrientation("??"); // get/set time resolution (ns) runData.SetTimeResolution(nxs_file->GetEntryIdf1()->GetData()->GetTimeResolution("ns")); // get/set start/stop time sstr = nxs_file->GetEntryIdf1()->GetStartTime(); str = sstr; TString date, time; SplitTimeDate(str, time, date, ok); if (ok) { runData.SetStartTime(time); runData.SetStartDate(date); } sstr = nxs_file->GetEntryIdf1()->GetStopTime(); str = sstr; SplitTimeDate(str, time, date, ok); if (ok) { runData.SetStopTime(time); runData.SetStopDate(date); } // get/set t0, firstGoodBin, lastGoodBin vector *t0 = nxs_file->GetEntryIdf1()->GetData()->GetT0s(); vector *fgb = nxs_file->GetEntryIdf1()->GetData()->GetFirstGoodBins(); vector *lgb = nxs_file->GetEntryIdf1()->GetData()->GetLastGoodBins(); // get/set data vector *pdata; unsigned int max=0, binMax=0; PDoubleVector data; for (UInt_t i=0; iGetEntryIdf1()->GetData()->GetNoOfHistos(); i++) { pdata = nxs_file->GetEntryIdf1()->GetData()->GetHisto(i); for (UInt_t j=0; jsize(); j++) { data.push_back(pdata->at(j)); if (pdata->at(j) > max) { max = pdata->at(j); binMax = j; } } // fill data set dataSet.Clear(); dataSet.SetHistoNo(i+1); // i.e. histo numbers start with 1 // set time zero bin if (isize()) dataSet.SetTimeZeroBin(t0->at(i)); else dataSet.SetTimeZeroBin(t0->at(0)); // set time zero bin estimate dataSet.SetTimeZeroBinEstimated(binMax); // set first good bin if (isize()) dataSet.SetFirstGoodBin(fgb->at(i)); else dataSet.SetFirstGoodBin(fgb->at(0)); // set last good bin if (isize()) dataSet.SetFirstGoodBin(lgb->at(i)); else dataSet.SetFirstGoodBin(lgb->at(0)); dataSet.SetData(data); runData.SetDataSet(dataSet); data.clear(); } // keep run name from the msr-file runData.SetRunName(fRunName); // keep the information fData.push_back(runData); } else if (nxs_file->GetIdfVersion() == 2) { if (!nxs_file->IsValid()) { cout << endl << "**ERROR** invalid NeXus IDF 2 version file found." << endl; return false; } // get header information // get/set laboratory str = TString(nxs_file->GetEntryIdf2()->GetInstrument()->GetSource()->GetName()); runData.SetLaboratory(str); // get/set beamline str = TString(nxs_file->GetEntryIdf2()->GetInstrument()->GetName()); runData.SetBeamline(str); // get/set instrument str = TString(nxs_file->GetEntryIdf2()->GetInstrument()->GetName()); runData.SetInstrument(str); // get/set muon source str = TString(nxs_file->GetEntryIdf2()->GetInstrument()->GetSource()->GetType()); runData.SetMuonSource(str); // get/set muon species str = TString(nxs_file->GetEntryIdf2()->GetInstrument()->GetSource()->GetProbe()); runData.SetMuonSpecies(str); // get/set run title str = TString(nxs_file->GetEntryIdf2()->GetTitle()); runData.SetRunTitle(str); // get/set run number runData.SetRunNumber(nxs_file->GetEntryIdf2()->GetRunNumber()); // get/set temperature dval = nxs_file->GetEntryIdf2()->GetSample()->GetPhysPropValue("temperature", ok); if (ok) runData.SetTemperature(0, dval, 0.0); // get/set field dval = nxs_file->GetEntryIdf2()->GetSample()->GetPhysPropValue("magnetic_field", ok); nxs_file->GetEntryIdf2()->GetSample()->GetPhysPropUnit("magnetic_field", sstr, ok); str = sstr; // since field has to be given in Gauss, check the units Double_t factor=1.0; if (!str.CompareTo("gauss", TString::kIgnoreCase)) factor=1.0; else if (!str.CompareTo("tesla", TString::kIgnoreCase)) factor=1.0e4; else factor=1.0; runData.SetField(factor*dval); // get/set implantation energy runData.SetEnergy(PMUSR_UNDEFINED); // get/set moderator HV runData.SetTransport(PMUSR_UNDEFINED); // get/set RA HV's (LEM specific) for (UInt_t i=0; i<4; i++) runData.SetRingAnode(i, PMUSR_UNDEFINED); // get/set setup take NXsample/temperature_1_env and NXsample/magnetic_field_1_env sstr = nxs_file->GetEntryIdf2()->GetSample()->GetEnvironmentTemp() + string("/"); sstr += nxs_file->GetEntryIdf2()->GetSample()->GetEnvironmentField(); str = sstr; runData.SetSetup(str); // get/set sample runData.SetSample(nxs_file->GetEntryIdf2()->GetSample()->GetName()); // get/set orientation runData.SetOrientation("??"); // get/set time resolution (ns) runData.SetTimeResolution(nxs_file->GetEntryIdf2()->GetInstrument()->GetDetector()->GetTimeResolution("ns")); // get/set start/stop time sstr = nxs_file->GetEntryIdf2()->GetStartTime(); str = sstr; TString date, time; SplitTimeDate(str, time, date, ok); if (ok) { runData.SetStartTime(time); runData.SetStartDate(date); } sstr = nxs_file->GetEntryIdf2()->GetStopTime(); str = sstr; SplitTimeDate(str, time, date, ok); if (ok) { runData.SetStopTime(time); runData.SetStopDate(date); } // get/set data, t0, fgb, lgb PDoubleVector data; PRawRunDataSet dataSet; UInt_t histoNo = 0; Int_t ival; int *histos = nxs_file->GetEntryIdf2()->GetInstrument()->GetDetector()->GetHistos(); if (nxs_file->GetEntryIdf2()->GetInstrument()->GetDetector()->GetNoOfPeriods() > 0) { // counts[][][] for (int i=0; iGetEntryIdf2()->GetInstrument()->GetDetector()->GetNoOfPeriods(); i++) { for (int j=0; jGetEntryIdf2()->GetInstrument()->GetDetector()->GetNoOfSpectra(); j++) { for (int k=0; kGetEntryIdf2()->GetInstrument()->GetDetector()->GetNoOfBins(); k++) { data.push_back(*(histos+i*nxs_file->GetEntryIdf2()->GetInstrument()->GetDetector()->GetNoOfSpectra()+j*nxs_file->GetEntryIdf2()->GetInstrument()->GetDetector()->GetNoOfBins()+k)); } dataSet.Clear(); dataSet.SetHistoNo(++histoNo); // i.e. histo numbers start with 1 // get t0 ival = nxs_file->GetEntryIdf2()->GetInstrument()->GetDetector()->GetT0(i,j); if (ival == -1) // i.e. single value only ival = nxs_file->GetEntryIdf2()->GetInstrument()->GetDetector()->GetT0(); dataSet.SetTimeZeroBin(ival); // get first good bin ival = nxs_file->GetEntryIdf2()->GetInstrument()->GetDetector()->GetFirstGoodBin(i,j); if (ival == -1) // i.e. single value only ival = nxs_file->GetEntryIdf2()->GetInstrument()->GetDetector()->GetFirstGoodBin(); dataSet.SetFirstGoodBin(ival); // get last good bin ival = nxs_file->GetEntryIdf2()->GetInstrument()->GetDetector()->GetLastGoodBin(i,j); if (ival == -1) // i.e. single value only ival = nxs_file->GetEntryIdf2()->GetInstrument()->GetDetector()->GetLastGoodBin(); dataSet.SetLastGoodBin(ival); dataSet.SetData(data); runData.SetDataSet(dataSet); data.clear(); } } } else { if (nxs_file->GetEntryIdf2()->GetInstrument()->GetDetector()->GetNoOfSpectra() > 0) { // counts[][] for (int i=0; iGetEntryIdf2()->GetInstrument()->GetDetector()->GetNoOfSpectra(); i++) { for (int j=0; jGetEntryIdf2()->GetInstrument()->GetDetector()->GetNoOfBins(); j++) { data.push_back(*(histos+i*nxs_file->GetEntryIdf2()->GetInstrument()->GetDetector()->GetNoOfBins()+j)); } dataSet.Clear(); dataSet.SetHistoNo(++histoNo); // i.e. histo numbers start with 1 // get t0 ival = nxs_file->GetEntryIdf2()->GetInstrument()->GetDetector()->GetT0(-1,i); if (ival == -1) // i.e. single value only ival = nxs_file->GetEntryIdf2()->GetInstrument()->GetDetector()->GetT0(); dataSet.SetTimeZeroBin(ival); // get first good bin ival = nxs_file->GetEntryIdf2()->GetInstrument()->GetDetector()->GetFirstGoodBin(-1,i); if (ival == -1) // i.e. single value only ival = nxs_file->GetEntryIdf2()->GetInstrument()->GetDetector()->GetFirstGoodBin(); dataSet.SetFirstGoodBin(ival); // get last good bin ival = nxs_file->GetEntryIdf2()->GetInstrument()->GetDetector()->GetLastGoodBin(-1,i); if (ival == -1) // i.e. single value only ival = nxs_file->GetEntryIdf2()->GetInstrument()->GetDetector()->GetLastGoodBin(); dataSet.SetLastGoodBin(ival); dataSet.SetData(data); runData.SetDataSet(dataSet); data.clear(); } } else { // counts[] for (int i=0; iGetEntryIdf2()->GetInstrument()->GetDetector()->GetNoOfBins(); i++) { data.push_back(*(histos+i)); } dataSet.Clear(); dataSet.SetHistoNo(++histoNo); // i.e. histo numbers start with 1 // get t0 ival = nxs_file->GetEntryIdf2()->GetInstrument()->GetDetector()->GetT0(); dataSet.SetTimeZeroBin(ival); // get first good bin ival = nxs_file->GetEntryIdf2()->GetInstrument()->GetDetector()->GetFirstGoodBin(); dataSet.SetFirstGoodBin(ival); // get last good bin ival = nxs_file->GetEntryIdf2()->GetInstrument()->GetDetector()->GetLastGoodBin(); dataSet.SetLastGoodBin(ival); dataSet.SetData(data); runData.SetDataSet(dataSet); data.clear(); } } // keep run name from the msr-file runData.SetRunName(fRunName); // keep the information fData.push_back(runData); } else { cout << endl << ">> PRunDataHandler::ReadNexusFile(): IDF version " << nxs_file->GetIdfVersion() << ", not implemented." << endl; } // clean up if (nxs_file) { delete nxs_file; nxs_file = 0; } #else cout << endl << ">> PRunDataHandler::ReadNexusFile(): Sorry, not enabled at configuration level, i.e. --enable-NeXus when executing configure" << endl << endl; #endif return true; } //-------------------------------------------------------------------------- // ReadWkmFile (private) //-------------------------------------------------------------------------- /** *

Reads, for backwards compatibility, the ascii-wkm-file data format. * The routine is clever enough to distinguish the different wkm-flavours (argh). * * return: * - true at successful reading, * - otherwise false. */ Bool_t PRunDataHandler::ReadWkmFile() { PDoubleVector histoData; PRawRunData runData; // open file ifstream f; // open wkm-file f.open(fRunPathName.Data(), ifstream::in); if (!f.is_open()) { cerr << endl << ">> PRunDataHandler::ReadWkmFile: **ERROR** Couldn't open run data (" << fRunPathName.Data() << ") file for reading, sorry ..."; cerr << endl; return false; } // read header Bool_t headerInfo = true; Char_t instr[512]; TString line, linecp; Double_t dval; Int_t ival; Bool_t ok; Int_t groups = 0, channels = 0; // skip leading empty lines do { f.getline(instr, sizeof(instr)); line = TString(instr); if (!line.IsWhitespace()) break; } while (!f.eof()); // real header data should start here Ssiz_t idx; do { line = TString(instr); if (line.IsDigit()) { // end of header reached headerInfo = false; } else { // real stuff, hence filter data if (line.Contains("Title") || line.Contains("Titel")) { idx = line.Index(":"); line.Replace(0, idx+1, 0, 0); // remove 'Title:' StripWhitespace(line); runData.SetRunTitle(line); } else if (line.Contains("Run:")) { idx = line.Index(":"); line.Replace(0, idx+1, 0, 0); // remove 'Run:' StripWhitespace(line); ival = ToInt(line, ok); if (ok) runData.SetRunNumber(ival); } else if (line.Contains("Field")) { idx = line.Index(":"); line.Replace(0, idx+1, 0, 0); // remove 'Field:' StripWhitespace(line); idx = line.Index("G"); // check if unit is given if (idx > 0) // unit is indeed given line.Resize(idx); dval = ToDouble(line, ok); if (ok) runData.SetField(dval); } else if (line.Contains("Setup")) { idx = line.Index(":"); line.Replace(0, idx+1, 0, 0); // remove 'Setup:' StripWhitespace(line); runData.SetSetup(line); } else if (line.Contains("Temp:") || line.Contains("Temp(meas1):")) { linecp = line; idx = line.Index(":"); line.Replace(0, idx+1, 0, 0); // remove 'Temp:' StripWhitespace(line); idx = line.Index("+/-"); // remove "+/- ..." part if (idx > 0) line.Resize(idx); idx = line.Index("K"); // remove "K ..." part if (idx > 0) line.Resize(idx); dval = ToDouble(line, ok); if (ok) { runData.SetTemperature(0, dval, 0.0); } idx = linecp.Index("+/-"); // get the error linecp.Replace(0, idx+3, 0, 0); StripWhitespace(linecp); dval = ToDouble(linecp, ok); if (ok) { runData.SetTempError(0, dval); } } else if (line.Contains("Temp(meas2):")) { linecp = line; idx = line.Index(":"); line.Replace(0, idx+1, 0, 0); // remove 'Temp(meas2):' StripWhitespace(line); idx = line.Index("+/-"); // remove "+/- ..." part if (idx > 0) line.Resize(idx); idx = line.Index("K"); // remove "K ..." part if (idx > 0) line.Resize(idx); dval = ToDouble(line, ok); if (ok) { runData.SetTemperature(1, dval, 0.0); } idx = linecp.Index("+/-"); // get the error linecp.Replace(0, idx+3, 0, 0); StripWhitespace(linecp); dval = ToDouble(linecp, ok); if (ok) { runData.SetTempError(1, dval); } } else if (line.Contains("Groups")) { idx = line.Index(":"); line.Replace(0, idx+1, 0, 0); // remove 'Groups:' StripWhitespace(line); ival = ToInt(line, ok); if (ok) groups = ival; } else if (line.Contains("Channels")) { idx = line.Index(":"); line.Replace(0, idx+1, 0, 0); // remove 'Channels:' StripWhitespace(line); ival = ToInt(line, ok); if (ok) channels = ival; } else if (line.Contains("Resolution")) { idx = line.Index(":"); line.Replace(0, idx+1, 0, 0); // remove 'Resolution:' StripWhitespace(line); dval = ToDouble(line, ok); if (ok) runData.SetTimeResolution(dval*1.0e3); // us -> ns } } if (headerInfo) f.getline(instr, sizeof(instr)); } while (headerInfo && !f.eof()); if ((groups == 0) || (channels == 0) || runData.GetTimeResolution() == 0.0) { cerr << endl << ">> PRunDataHandler::ReadWkmFile(): **ERROR** essential header informations are missing!"; cerr << endl << ">> groups = " << groups; cerr << endl << ">> channels = " << channels; cerr << endl << ">> time resolution = " << runData.GetTimeResolution(); cerr << endl; f.close(); return false; } // read data --------------------------------------------------------- UInt_t group_counter = 0; Int_t val; TObjArray *tokens; TObjString *ostr; TString str; UInt_t histoNo = 0; PRawRunDataSet dataSet; do { // check if empty line, i.e. new group if (IsWhitespace(instr)) { dataSet.Clear(); dataSet.SetHistoNo(++histoNo); dataSet.SetData(histoData); // get a T0 estimate Double_t maxVal = 0.0; Int_t maxBin = 0; for (UInt_t i=0; i maxVal) { maxVal = histoData[i]; maxBin = i; } } dataSet.SetTimeZeroBinEstimated(maxBin); runData.SetDataSet(dataSet); histoData.clear(); group_counter++; } else { // extract values line = TString(instr); // check if line starts with character. Needed for RAL WKM format if (!line.IsDigit()) { f.getline(instr, sizeof(instr)); continue; } tokens = line.Tokenize(" "); if (!tokens) { // no tokens found cerr << endl << ">> PRunDataHandler::ReadWkmFile(): **ERROR** while reading data: coulnd't tokenize run data."; return false; } for (Int_t i=0; iGetEntries(); i++) { ostr = dynamic_cast(tokens->At(i)); str = ostr->GetString(); val = ToInt(str, ok); if (ok) { histoData.push_back(val); } else { cerr << endl << ">> PRunDataHandler::ReadWkmFile(): **ERROR** while reading data: data line contains non-integer values."; // clean up delete tokens; return false; } } // clean up if (tokens) { delete tokens; tokens = 0; } } f.getline(instr, sizeof(instr)); } while (!f.eof()); // handle last line if present if (strlen(instr) != 0) { // extract values line = TString(instr); tokens = line.Tokenize(" "); if (!tokens) { // no tokens found cerr << endl << ">> PRunDataHandler::ReadWkmFile(): **ERROR** while reading data: coulnd't tokenize run data."; return false; } for (Int_t i=0; iGetEntries(); i++) { ostr = dynamic_cast(tokens->At(i)); str = ostr->GetString(); val = ToInt(str, ok); if (ok) { histoData.push_back(val); } else { cerr << endl << ">> PRunDataHandler::ReadWkmFile(): **ERROR** while reading data: data line contains non-integer values."; // clean up delete tokens; return false; } } // clean up if (tokens) { delete tokens; tokens = 0; } } // save the last histo if not empty if (histoData.size() > 0) { dataSet.Clear(); dataSet.SetHistoNo(++histoNo); dataSet.SetData(histoData); // get a T0 estimate Double_t maxVal = 0.0; Int_t maxBin = 0; for (UInt_t i=0; i maxVal) { maxVal = histoData[i]; maxBin = i; } } dataSet.SetTimeZeroBinEstimated(maxBin); runData.SetDataSet(dataSet); histoData.clear(); } // close file f.close(); // check if all groups are found if ((Int_t) runData.GetNoOfHistos() != groups) { cerr << endl << ">> PRunDataHandler::ReadWkmFile(): **ERROR**"; cerr << endl << ">> expected " << groups << " histos, but found " << runData.GetNoOfHistos(); return false; } // check if all groups have enough channels for (UInt_t i=0; isize() != channels) { cerr << endl << ">> PRunDataHandler::ReadWkmFile(): **ERROR**"; cerr << endl << ">> expected " << channels << " bins in histo " << i+1 << ", but found " << runData.GetDataBin(i)->size(); return false; } } // keep run name runData.SetRunName(fRunName); // add run to the run list fData.push_back(runData); return true; } //-------------------------------------------------------------------------- // ReadPsiBinFile (private) //-------------------------------------------------------------------------- /** *

Reads the old-fashioned PSI-BIN data-files. The MuSR_td_PSI_bin class * of Alex Amato is used. In case of problems, please contact alex.amato@psi.ch. * * return: * - true at successful reading, * - otherwise false. */ Bool_t PRunDataHandler::ReadPsiBinFile() { MuSR_td_PSI_bin psiBin; Int_t status; Bool_t success; // read psi bin file status = psiBin.read(fRunPathName.Data()); switch (status) { case 0: // everything perfect success = true; break; case 1: // couldn't open file, or failed while reading the header cerr << endl << ">> **ERROR** couldn't open psi-bin file, or failed while reading the header"; cerr << endl; success = false; break; case 2: // unsupported version of the data cerr << endl << ">> **ERROR** psi-bin file: unsupported version of the data"; cerr << endl; success = false; break; case 3: // error when allocating data buffer cerr << endl << ">> **ERROR** psi-bin file: error when allocating data buffer"; cerr << endl; success = false; break; case 4: // number of histograms/record not equals 1 cerr << endl << ">> **ERROR** psi-bin file: number of histograms/record not equals 1"; cerr << endl; success = false; break; default: // you never should have reached this point success = false; break; } // if any reading error happend, get out of here if (!success) return success; // fill necessary header informations PRawRunData runData; Double_t dval; // set file name Ssiz_t pos = fRunPathName.Last('/'); TString fln(fRunPathName); fln.Remove(0, pos+1); runData.SetFileName(fln); // set laboratory runData.SetLaboratory("PSI"); // filter from the file name the instrument TString instrument("n/a"), beamline("n/a"); TString muonSource("n/a"), muonSpecies("n/a"); if (fRunPathName.Contains("_gps_", TString::kIgnoreCase)) { instrument = "GPS"; beamline = "piM3.2"; muonSource = "continuous surface muon source"; muonSpecies = "positive muons"; } else if (fRunPathName.Contains("_ltf_", TString::kIgnoreCase)) { instrument = "LTF"; beamline = "piM3.3"; muonSource = "continuous surface muon source"; muonSpecies = "positive muons"; } else if (fRunPathName.Contains("_gpd_", TString::kIgnoreCase)) { instrument = "GPD"; beamline = "muE1"; muonSource = "continuous decay channel muon source"; muonSpecies = "positive muons"; } else if (fRunPathName.Contains("_dolly_", TString::kIgnoreCase)) { instrument = "DOLLY"; beamline = "piE1"; muonSource = "continuous surface muon source"; muonSpecies = "positive muons"; } else if (fRunPathName.Contains("_alc_", TString::kIgnoreCase)) { instrument = "ALC"; beamline = "piE3"; muonSource = "continuous surface muon source"; muonSpecies = "positive muons"; } else if (fRunPathName.Contains("_hifi_", TString::kIgnoreCase)) { instrument = "HIFI"; beamline = "piE3"; muonSource = "continuous surface muon source"; muonSpecies = "positive muons"; } runData.SetInstrument(instrument); runData.SetBeamline(beamline); runData.SetMuonSource(muonSource); runData.SetMuonSpecies(muonSpecies); // keep run name runData.SetRunName(fRunName); // get run title runData.SetRunTitle(TString(psiBin.get_comment().c_str())); // run title // get run number runData.SetRunNumber(psiBin.get_runNumber_int()); // get setup runData.SetSetup(TString(psiBin.get_comment().c_str())); // get sample runData.SetSample(TString(psiBin.get_sample().c_str())); // get orientation runData.SetOrientation(TString(psiBin.get_orient().c_str())); // get comment runData.SetComment(TString(psiBin.get_comment().c_str())); // set LEM specific information to default value since it is not in the file and not used... runData.SetEnergy(PMUSR_UNDEFINED); runData.SetTransport(PMUSR_UNDEFINED); // get field Double_t scale = 0.0; if (psiBin.get_field().rfind("G") != string::npos) scale = 1.0; if (psiBin.get_field().rfind("T") != string::npos) scale = 1.0e4; status = sscanf(psiBin.get_field().c_str(), "%lf", &dval); if (status == 1) runData.SetField(scale*dval); // get temperature PDoubleVector tempVec(psiBin.get_temperatures_vector()); PDoubleVector tempDevVec(psiBin.get_devTemperatures_vector()); if ((tempVec.size() > 1) && (tempDevVec.size() > 1) && tempVec[0] && tempVec[1]) { // take only the first two values for now... //maybe that's not enough - e.g. in older GPD data I saw the "correct values in the second and third entry..." for (UInt_t i(0); i<2; i++) { runData.SetTemperature(i, tempVec[i], tempDevVec[i]); } tempVec.clear(); tempDevVec.clear(); } else { status = sscanf(psiBin.get_temp().c_str(), "%lfK", &dval); if (status == 1) runData.SetTemperature(0, dval, 0.0); } // get time resolution (ns) runData.SetTimeResolution(psiBin.get_binWidth_ns()); // get start/stop time vector sDateTime = psiBin.get_timeStart_vector(); if (sDateTime.size() < 2) { cerr << endl << ">> **WARNING** psi-bin file: couldn't obtain run start date/time" << endl; } string date(""); if (DateToISO8601(sDateTime[0], date)) { runData.SetStartDate(date); } else { cerr << endl << ">> **WARNING** failed to convert start date: " << sDateTime[0] << " into ISO 8601 date." << endl; runData.SetStartDate(sDateTime[0]); } runData.SetStartTime(sDateTime[1]); sDateTime.clear(); sDateTime = psiBin.get_timeStop_vector(); if (sDateTime.size() < 2) { cerr << endl << ">> **WARNING** psi-bin file: couldn't obtain run stop date/time" << endl; } date = string(""); if (DateToISO8601(sDateTime[0], date)) { runData.SetStopDate(date); } else { cerr << endl << ">> **WARNING** failed to convert stop date: " << sDateTime[0] << " into ISO 8601 date." << endl; runData.SetStopDate(sDateTime[0]); } runData.SetStopTime(sDateTime[1]); sDateTime.clear(); // get t0's PIntVector t0 = psiBin.get_t0_vector(); if (t0.empty()) { cerr << endl << ">> **ERROR** psi-bin file: couldn't obtain any t0's"; cerr << endl; return false; } // get first good bin PIntVector fgb = psiBin.get_firstGood_vector(); if (fgb.empty()) { cerr << endl << ">> **ERROR** psi-bin file: couldn't obtain any fgb's"; cerr << endl; return false; } // get last good bin PIntVector lgb = psiBin.get_lastGood_vector(); if (lgb.empty()) { cerr << endl << ">> **ERROR** psi-bin file: couldn't obtain any lgb's"; cerr << endl; return false; } // fill raw data PRawRunDataSet dataSet; PDoubleVector histoData; Int_t *histo; for (Int_t i=0; i maxVal) { maxVal = histoData[j]; maxBin = j; } } dataSet.Clear(); dataSet.SetName(psiBin.get_nameHisto(i).c_str()); dataSet.SetHistoNo(i+1); // i.e. hist numbering starts at 1 if (i < (Int_t)t0.size()) dataSet.SetTimeZeroBin(t0[i]); dataSet.SetTimeZeroBinEstimated(maxBin); if (i < (Int_t)fgb.size()) dataSet.SetFirstGoodBin(fgb[i]); if (i < (Int_t)lgb.size()) dataSet.SetLastGoodBin(lgb[i]); dataSet.SetData(histoData); runData.SetDataSet(dataSet); histoData.clear(); } // add run to the run list fData.push_back(runData); return success; } //-------------------------------------------------------------------------- // ReadMudFile (private) //-------------------------------------------------------------------------- /** *

Reads the triumf mud-file format. * * return: * - true at successful reading, * - otherwise false. */ Bool_t PRunDataHandler::ReadMudFile() { Int_t fh; UINT32 type, val; Int_t success; Char_t str[1024]; Double_t dval; PRawRunData runData; fh = MUD_openRead((Char_t *)fRunPathName.Data(), &type); if (fh == -1) { cerr << endl << ">> **ERROR** Couldn't open mud-file " << fRunPathName.Data() << ", sorry."; cerr << endl; return false; } // read necessary header information // keep run name runData.SetRunName(fRunName); // get/set the lab success = MUD_getLab( fh, str, sizeof(str) ); if ( !success ) { cerr << endl << ">> **WARNING** Couldn't obtain the laboratory name of run " << fRunName.Data(); cerr << endl; strcpy(str, "n/a"); } runData.SetLaboratory(TString(str)); // get/set the beamline success = MUD_getArea( fh, str, sizeof(str) ); if ( !success ) { cerr << endl << ">> **WARNING** Couldn't obtain the beamline of run " << fRunName.Data(); cerr << endl; strcpy(str, "n/a"); } runData.SetBeamline(TString(str)); // get/set the instrument success = MUD_getApparatus( fh, str, sizeof(str) ); if ( !success ) { cerr << endl << ">> **WARNING** Couldn't obtain the instrument name of run " << fRunName.Data(); cerr << endl; strcpy(str, "n/a"); } runData.SetInstrument(TString(str)); // get run title success = MUD_getTitle( fh, str, sizeof(str) ); if ( !success ) { cerr << endl << ">> **WARNING** Couldn't obtain the run title of run " << fRunName.Data(); cerr << endl; } runData.SetRunTitle(TString(str)); // get run number success = MUD_getRunNumber( fh, &val ); if (success) { runData.SetRunNumber((Int_t)val); } // get start/stop time of the run time_t tval; struct tm *dt; TString stime(""); success = MUD_getTimeBegin( fh, (UINT32*)&tval ); if (success) { runData.SetStartDateTime((const time_t)tval); dt = localtime((const time_t*)&tval); assert(dt); // start date strftime(str, sizeof(str), "%F", dt); stime = str; runData.SetStartDate(stime); // start time memset(str, 0, sizeof(str)); strftime(str, sizeof(str), "%T", dt); stime = str; runData.SetStartTime(stime); } stime = TString(""); success = MUD_getTimeEnd( fh, (UINT32*)&tval ); if (success) { runData.SetStopDateTime((const time_t)tval); dt = localtime((const time_t*)&tval); assert(dt); // stop date strftime(str, sizeof(str), "%F", dt); stime = str; runData.SetStopDate(stime); // stop time memset(str, 0, sizeof(str)); strftime(str, sizeof(str), "%T", dt); stime = str; runData.SetStopTime(stime); } // get setup TString setup; success = MUD_getLab( fh, str, sizeof(str) ); if (success) { setup = TString(str) + TString("/"); } success = MUD_getArea( fh, str, sizeof(str) ); if (success) { setup += TString(str) + TString("/"); } success = MUD_getApparatus( fh, str, sizeof(str) ); if (success) { setup += TString(str) + TString("/"); } success = MUD_getSample( fh, str, sizeof(str) ); if (success) { setup += TString(str); runData.SetSample(str); } runData.SetSetup(setup); // set LEM specific information to default value since it is not in the file and not used... runData.SetEnergy(PMUSR_UNDEFINED); runData.SetTransport(PMUSR_UNDEFINED); // get field success = MUD_getField( fh, str, sizeof(str) ); if (success) { success = sscanf(str, "%lf G", &dval); if (success == 1) { runData.SetField(dval); } else { runData.SetField(PMUSR_UNDEFINED); } } else { runData.SetField(PMUSR_UNDEFINED); } // get temperature success = MUD_getTemperature( fh, str, sizeof(str) ); if (success) { success = sscanf(str, "%lf K", &dval); if (success == 1) { runData.SetTemperature(0, dval, 0.0); } else { runData.SetTemperature(0, PMUSR_UNDEFINED, 0.0); } } else { runData.SetTemperature(0, PMUSR_UNDEFINED, 0.0); } // get number of histogramms success = MUD_getHists(fh, &type, &val); if ( !success ) { cerr << endl << ">> **ERROR** Couldn't obtain the number of histograms of run " << fRunName.Data(); cerr << endl; MUD_closeRead(fh); return false; } Int_t noOfHistos = (Int_t)val; // get time resolution (ns) // check that time resolution is identical for all histograms // >> currently it is not forseen to handle histos with different time resolutions << // >> perhaps this needs to be reconsidered later on << REAL64 timeResolution = 0.0; // in seconds!! REAL64 lrval = 0.0; for (Int_t i=1; i<=noOfHistos; i++) { success = MUD_getHistSecondsPerBin( fh, i, &lrval ); if (!success) { cerr << endl << ">> **ERROR** Couldn't obtain the time resolution of run " << fRunName.Data(); cerr << endl << ">> which is fatal, sorry."; cerr << endl; MUD_closeRead(fh); return false; } if (i==1) { timeResolution = lrval; } else { if (lrval != timeResolution) { cerr << endl << ">> **ERROR** various time resolutions found in run " << fRunName.Data(); cerr << endl << ">> this is currently not supported, sorry."; cerr << endl; MUD_closeRead(fh); return false; } } } runData.SetTimeResolution((Double_t)timeResolution * 1.0e9); // s -> ns // read histograms UINT32 *pData; // histo memory pData = NULL; PDoubleVector histoData; PRawRunDataSet dataSet; UInt_t noOfBins; for (Int_t i=1; i<=noOfHistos; i++) { dataSet.Clear(); dataSet.SetHistoNo(i); // get t0's success = MUD_getHistT0_Bin( fh, i, &val ); if ( !success ) { cerr << endl << ">> **WARNING** Couldn't get t0 of histo " << i << " of run " << fRunName.Data(); cerr << endl; } dataSet.SetTimeZeroBin((Double_t)val); // get bkg bins success = MUD_getHistBkgd1( fh, i, &val ); if ( !success ) { cerr << endl << ">> **WARNING** Couldn't get bkg bin 1 of histo " << i << " of run " << fRunName.Data(); cerr << endl; val = 0; } dataSet.SetFirstBkgBin((Int_t)val); success = MUD_getHistBkgd2( fh, i, &val ); if ( !success ) { cerr << endl << ">> **WARNING** Couldn't get bkg bin 2 of histo " << i << " of run " << fRunName.Data(); cerr << endl; val = 0; } dataSet.SetLastBkgBin((Int_t)val); // get good data bins success = MUD_getHistGoodBin1( fh, i, &val ); if ( !success ) { cerr << endl << ">> **WARNING** Couldn't get good bin 1 of histo " << i << " of run " << fRunName.Data(); cerr << endl; val = 0; } dataSet.SetFirstGoodBin((Int_t)val); success = MUD_getHistGoodBin2( fh, i, &val ); if ( !success ) { cerr << endl << ">> **WARNING** Couldn't get good bin 2 of histo " << i << " of run " << fRunName.Data(); cerr << endl; val = 0; } dataSet.SetLastGoodBin((Int_t)val); // get number of bins success = MUD_getHistNumBins( fh, i, &val ); if ( !success ) { cerr << endl << ">> **ERROR** Couldn't get the number of bins of histo " << i << "."; cerr << endl << ">> This is fatal, sorry."; cerr << endl; MUD_closeRead( fh ); return false; } noOfBins = (UInt_t)val; pData = (UINT32*)malloc(noOfBins*sizeof(pData)); if (pData == NULL) { cerr << endl << ">> **ERROR** Couldn't allocate memory for data."; cerr << endl << ">> This is fatal, sorry."; cerr << endl; MUD_closeRead( fh ); return false; } // get histogram success = MUD_getHistData( fh, i, pData ); if ( !success ) { cerr << endl << ">> **ERROR** Couldn't get histo no " << i << "."; cerr << endl << ">> This is fatal, sorry."; cerr << endl; MUD_closeRead( fh ); return false; } for (UInt_t j=0; j maxVal) { maxVal = histoData[j]; maxBin = j; } } dataSet.SetTimeZeroBinEstimated(maxBin); runData.SetDataSet(dataSet); histoData.clear(); free(pData); } MUD_closeRead(fh); // add run to the run list fData.push_back(runData); return true; } //-------------------------------------------------------------------------- // ReadMduAsciiFile (private) //-------------------------------------------------------------------------- /** *

Reads the mdu ascii files (PSI). Needed to work around PSI-BIN limitations. * *

Lines starting with '#' or '%' are considered as comment lines. The file has * the following structure: * \verbatim * HEADER * TITLE: title-string * SETUP: setup-string * FIELD: val-string (G) or (T) (e.g. 123456 (G)) * TEMP: val-string (K) * GROUPS: # of histograms written * CHANNELS: # of bins per histogram written * RESOLUTION: timeresolution (fs) or (ps) or (ns) or (us) * \endverbatim * followed by the data, which are written in column format, starting with the DATA * tag, i.e. * \verbatim * DATA * * \endverbatim * * return: * - true at successful reading, * - otherwise false. */ Bool_t PRunDataHandler::ReadMduAsciiFile() { Bool_t success = true; // open file ifstream f; // open data-file f.open(fRunPathName.Data(), ifstream::in); if (!f.is_open()) { cerr << endl << ">> PRunDataHandler::ReadMduAsciiFile **ERROR** Couldn't open data file (" << fRunPathName.Data() << ") for reading, sorry ..."; cerr << endl; return false; } PRawRunData runData; // keep run name runData.SetRunName(fRunName); Int_t lineNo = 0; Char_t instr[512]; TString line, workStr; Bool_t headerTag = false; Bool_t dataTag = false; Int_t dataLineCounter = 0; TObjString *ostr; TObjArray *tokens = 0; TString str; Int_t groups = 0; Int_t channels = 0; Double_t dval = 0.0, unitScaling = 0.0; vector data; while (!f.eof()) { f.getline(instr, sizeof(instr)); line = TString(instr); lineNo++; // ignore comment lines if (line.BeginsWith("#") || line.BeginsWith("%")) continue; // ignore empty lines if (line.IsWhitespace()) continue; // check if header tag workStr = line; workStr.Remove(TString::kLeading, ' '); // remove spaces from the begining if (workStr.BeginsWith("header", TString::kIgnoreCase)) { headerTag = true; dataTag = false; continue; } // check if data tag workStr = line; workStr.Remove(TString::kLeading, ' '); // remove spaces from the beining if (workStr.BeginsWith("data", TString::kIgnoreCase)) { headerTag = false; dataTag = true; continue; } if (headerTag) { workStr = line; workStr.Remove(TString::kLeading, ' '); // remove spaces from the beining if (workStr.BeginsWith("title:", TString::kIgnoreCase)) { runData.SetRunTitle(TString(workStr.Data()+workStr.First(":")+2)); } else if (workStr.BeginsWith("field:", TString::kIgnoreCase)) { tokens = workStr.Tokenize(":("); // field: val (units) // check if expected number of tokens present if (tokens->GetEntries() != 3) { cerr << endl << ">> PRunDataHandler::ReadMduAsciiFile **ERROR** line no " << lineNo << ", invalid field entry in header."; cerr << endl << ">> " << line.Data(); cerr << endl; success = false; break; } // check if field value is a number ostr = dynamic_cast(tokens->At(1)); if (ostr->GetString().IsFloat()) { dval = ostr->GetString().Atof(); } else { cerr << endl << ">> PRunDataHandler::ReadMduAsciiFile **ERROR** line no " << lineNo << ", field value is not float/doulbe."; cerr << endl << ">> " << line.Data(); cerr << endl; success = false; break; } // check units, accept (G), (T) ostr = dynamic_cast(tokens->At(2)); if (ostr->GetString().Contains("G")) unitScaling = 1.0; else if (ostr->GetString().Contains("T")) unitScaling = 1.0e4; else { cerr << endl << ">> PRunDataHandler::ReadMduAsciiFile **ERROR** line no " << lineNo << ", unkown field units."; cerr << endl << ">> " << line.Data(); cerr << endl; success = false; break; } runData.SetField(dval*unitScaling); // clean up tokens if (tokens) { delete tokens; tokens = 0; } } else if (workStr.BeginsWith("temp:", TString::kIgnoreCase)) { tokens = workStr.Tokenize(":("); // temp: val (units) // check if expected number of tokens present if (tokens->GetEntries() != 3) { cerr << endl << ">> PRunDataHandler::ReadMduAsciiFile **ERROR** line no " << lineNo << ", invalid temperatue entry in header."; cerr << endl << ">> " << line.Data(); cerr << endl; success = false; break; } // check if field value is a number ostr = dynamic_cast(tokens->At(1)); if (ostr->GetString().IsFloat()) { dval = ostr->GetString().Atof(); } else { cerr << endl << ">> PRunDataHandler::ReadMduAsciiFile **ERROR** line no " << lineNo << ", temperature value is not float/doulbe."; cerr << endl << ">> " << line.Data(); cerr << endl; success = false; break; } runData.SetTemperature(0, dval, 0.0); // clean up tokens if (tokens) { delete tokens; tokens = 0; } } else if (workStr.BeginsWith("setup:", TString::kIgnoreCase)) { runData.SetSetup(TString(workStr.Data()+workStr.First(":")+2)); } else if (workStr.BeginsWith("groups:", TString::kIgnoreCase)) { workStr = TString(workStr.Data()+workStr.First(":")+2); groups = workStr.Atoi(); if (groups == 0) { cerr << endl << ">> PRunDataHandler::ReadMduAsciiFile **ERROR** line no " << lineNo << ", groups is not a number or 0."; cerr << endl; success = false; break; } data.resize(groups); } else if (workStr.BeginsWith("channels:", TString::kIgnoreCase)) { workStr = TString(workStr.Data()+workStr.First(":")+2); channels = workStr.Atoi(); if (channels == 0) { cerr << endl << ">> PRunDataHandler::ReadMduAsciiFile **ERROR** line no " << lineNo << ", channels is not a number or 0."; cerr << endl; success = false; break; } } else if (workStr.BeginsWith("resolution:", TString::kIgnoreCase)) { tokens = workStr.Tokenize(":("); // resolution: val (units) // check if expected number of tokens present if (tokens->GetEntries() != 3) { cerr << endl << ">> PRunDataHandler::ReadMduAsciiFile **ERROR** line no " << lineNo << ", invalid time resolution entry in header."; cerr << endl << line.Data(); cerr << endl; success = false; break; } // check if timeresolution value is a number ostr = dynamic_cast(tokens->At(1)); if (ostr->GetString().IsFloat()) { dval = ostr->GetString().Atof(); } else { cerr << endl << ">> PRunDataHandler::ReadMduAsciiFile **ERROR** line no " << lineNo << ", time resolution value is not float/doulbe."; cerr << endl << ">> " << line.Data(); cerr << endl; success = false; break; } // check units, accept (fs), (ps), (ns), (us) ostr = dynamic_cast(tokens->At(2)); if (ostr->GetString().Contains("fs")) unitScaling = 1.0e-6; else if (ostr->GetString().Contains("ps")) unitScaling = 1.0e-3; else if (ostr->GetString().Contains("ns")) unitScaling = 1.0; else if (ostr->GetString().Contains("us")) unitScaling = 1.0e3; else { cerr << endl << ">> PRunDataHandler::ReadMduAsciiFile **ERROR** line no " << lineNo << ", unkown time resolution units."; cerr << endl << ">> " << line.Data(); cerr << endl; success = false; break; } runData.SetTimeResolution(dval*unitScaling); // clean up tokens if (tokens) { delete tokens; tokens = 0; } } else { // error cerr << endl << ">> PRunDataHandler::ReadMduAsciiFile **ERROR** line no " << lineNo << ", illegal header line."; cerr << endl; success = false; break; } } else if (dataTag) { dataLineCounter++; tokens = line.Tokenize(" ,\t"); // check if the number of data line entries is correct if (tokens->GetEntries() != groups+1) { cerr << endl << ">> PRunDataHandler::ReadMduAsciiFile **ERROR** found data line with a wrong data format, cannot be handled (line no " << lineNo << ")"; cerr << endl << ">> line:"; cerr << endl << ">> " << line.Data(); cerr << endl; success = false; break; } for (Int_t i=1; iGetEntries(); i++) { ostr = dynamic_cast(tokens->At(i)); data[i-1].push_back(ostr->GetString().Atof()); } // clean up tokens if (tokens) { delete tokens; tokens = 0; } } } f.close(); // keep data PRawRunDataSet dataSet; for (UInt_t i=0; i maxVal) { maxVal = data[i][j]; maxBin = j; } } dataSet.SetTimeZeroBinEstimated(maxBin); runData.SetDataSet(dataSet); } // clean up for (UInt_t i=0; i> PRunDataHandler::ReadMduAsciiFile **WARNING** found " << dataLineCounter << " data bins,"; cerr << endl << ">> expected " << channels << " according to the header." << endl; } fData.push_back(runData); return success; } //-------------------------------------------------------------------------- // ReadAsciiFile (private) //-------------------------------------------------------------------------- /** *

Reads ascii files. Intended for the nonMuSR data. * * The file format definition is: * Comment lines start with a '#' or '%' character. * The file can start with some header info. The header is optional, as all its tags, but * if present it has the following format: * * \verbatim * HEADER * TITLE: title * X-AXIS-TITLE: x-axis title * Y-AXIS-TITLE: y-axis title * SETUP: setup * FIELD: field * TEMP: temperature * ENERGY: energy * \endverbatim * * field is assumed to be given in (G), the temperature in (K), the energy in (keV) * * The data are read column like and start with the data tag DATA, followed by the * data columns, i.e.: * * \verbatim * DATA * x, y [, error y] * \endverbatim * * where spaces, column, are a tab are possible separations. * If no error in y is present, the weighting in the fit will be equal. * * return: * - true at successful reading, * - otherwise false. */ Bool_t PRunDataHandler::ReadAsciiFile() { Bool_t success = true; // open file ifstream f; // open data-file f.open(fRunPathName.Data(), ifstream::in); if (!f.is_open()) { cerr << endl << ">> PRunDataHandler::ReadAsciiFile **ERROR** Couldn't open data file (" << fRunPathName.Data() << ") for reading, sorry ..."; cerr << endl; return false; } PRawRunData runData; // init some stuff runData.fDataNonMusr.SetFromAscii(true); runData.fDataNonMusr.AppendLabel("??"); // x default label runData.fDataNonMusr.AppendLabel("??"); // y default label runData.SetRunName(fRunName); // keep the run name Int_t lineNo = 0; Char_t instr[512]; TString line, workStr; Bool_t headerTag = false; Bool_t dataTag = false; Double_t x, y, ey; PDoubleVector xVec, exVec, yVec, eyVec; while (!f.eof()) { f.getline(instr, sizeof(instr)); line = TString(instr); lineNo++; // check if comment line if (line.BeginsWith("#") || line.BeginsWith("%")) continue; // check if header tag workStr = line; workStr.Remove(TString::kLeading, ' '); // remove spaces from the begining if (workStr.BeginsWith("header", TString::kIgnoreCase)) { headerTag = true; dataTag = false; continue; } // check if data tag workStr = line; workStr.Remove(TString::kLeading, ' '); // remove spaces from the beining if (workStr.BeginsWith("data", TString::kIgnoreCase)) { headerTag = false; dataTag = true; continue; } if (headerTag) { if (line.IsWhitespace()) // ignore empty lines continue; workStr = line; workStr.Remove(TString::kLeading, ' '); // remove spaces from the beining if (workStr.BeginsWith("title:", TString::kIgnoreCase)) { runData.SetRunTitle(TString(workStr.Data()+workStr.First(":")+2)); } else if (workStr.BeginsWith("setup:", TString::kIgnoreCase)) { runData.SetSetup(TString(workStr.Data()+workStr.First(":")+2)); } else if (workStr.BeginsWith("field:", TString::kIgnoreCase)) { workStr = TString(workStr.Data()+workStr.First(":")+2); if (!workStr.IsFloat()) { cerr << endl << ">> PRunDataHandler::ReadAsciiFile **ERROR** line no " << lineNo << ", field is not a number."; cerr << endl; success = false; break; } runData.SetField(workStr.Atof()); } else if (workStr.BeginsWith("x-axis-title:", TString::kIgnoreCase)) { runData.fDataNonMusr.SetLabel(0, TString(workStr.Data()+workStr.First(":")+2)); } else if (workStr.BeginsWith("y-axis-title:", TString::kIgnoreCase)) { runData.fDataNonMusr.SetLabel(1, TString(workStr.Data()+workStr.First(":")+2)); } else if (workStr.BeginsWith("temp:", TString::kIgnoreCase)) { workStr = TString(workStr.Data()+workStr.First(":")+2); if (!workStr.IsFloat()) { cerr << endl << ">> PRunDataHandler::ReadAsciiFile **ERROR** line no " << lineNo << ", temperature is not a number."; cerr << endl; success = false; break; } runData.SetTemperature(0, workStr.Atof(), 0.0); } else if (workStr.BeginsWith("energy:", TString::kIgnoreCase)) { workStr = TString(workStr.Data()+workStr.First(":")+2); if (!workStr.IsFloat()) { cerr << endl << ">> PRunDataHandler::ReadAsciiFile **ERROR** line no " << lineNo << ", energy is not a number."; cerr << endl; success = false; break; } runData.SetEnergy(workStr.Atof()); runData.SetTransport(PMUSR_UNDEFINED); // just to initialize the variables to some "meaningful" value } else { // error cerr << endl << ">> PRunDataHandler::ReadAsciiFile **ERROR** line no " << lineNo << ", illegal header line."; cerr << endl; success = false; break; } } else if (dataTag) { if (line.IsWhitespace()) // ignore empty lines continue; TObjString *ostr; TObjArray *tokens; // Remove trailing end of line line.Remove(TString::kTrailing, '\r'); // check if data have x, y [, error y] structure, and that x, y, and error y are numbers tokens = line.Tokenize(" ,\t"); // check if the number of data line entries is 2 or 3 if ((tokens->GetEntries() != 2) && (tokens->GetEntries() != 3)) { cerr << endl << ">> PRunDataHandler::ReadAsciiFile **ERROR** found data line with a structure different than \"x, y [, error y]\", cannot be handled (line no " << lineNo << ")"; cerr << endl; success = false; break; } // get x ostr = dynamic_cast(tokens->At(0)); if (!ostr->GetString().IsFloat()) { cerr << endl << ">> PRunDataHandler::ReadAsciiFile **ERROR** line no " << lineNo << ": x = " << ostr->GetString().Data() << " is not a number, sorry."; cerr << endl; success = false; break; } x = ostr->GetString().Atof(); // get y ostr = dynamic_cast(tokens->At(1)); if (!ostr->GetString().IsFloat()) { cerr << endl << ">> PRunDataHandler::ReadAsciiFile **ERROR** line no " << lineNo << ": y = " << ostr->GetString().Data() << " is not a number, sorry."; cerr << endl; success = false; break; } y = ostr->GetString().Atof(); // get error y if present if (tokens->GetEntries() == 3) { ostr = dynamic_cast(tokens->At(2)); if (!ostr->GetString().IsFloat()) { cerr << endl << ">> PRunDataHandler::ReadAsciiFile **ERROR** line no " << lineNo << ": error y = " << ostr->GetString().Data() << " is not a number, sorry."; cerr << endl; success = false; break; } ey = ostr->GetString().Atof(); } else { ey = 1.0; } // clean up tokens if (tokens) { delete tokens; tokens = 0; } // keep values xVec.push_back(x); exVec.push_back(1.0); yVec.push_back(y); eyVec.push_back(ey); } else { cerr << endl << ">> PRunDataHandler::ReadAsciiFile **ERROR** line no " << lineNo << " neither header nor data line. No idea how to handle it!"; cerr << endl; success = false; break; } } f.close(); // keep values runData.fDataNonMusr.AppendData(xVec); runData.fDataNonMusr.AppendErrData(exVec); runData.fDataNonMusr.AppendData(yVec); runData.fDataNonMusr.AppendErrData(eyVec); fData.push_back(runData); // clean up xVec.clear(); exVec.clear(); yVec.clear(); eyVec.clear(); return success; } //-------------------------------------------------------------------------- // ReadDBFile (private) //-------------------------------------------------------------------------- /** *

Reads triumf db-files. Intended for the nonMuSR data. * *

The file format definition is: * The following is a description of the features of the TRIUMF .db file format that are * currently recognized by musrfit/musrview. The available commands include: title, abstract, * comments, labels, and data. * * \verbatim * TITLE * The following line must contain the title. * * * ABSTRACT * The abstract is read in starting with the following line until an empty line is reached. * * COMMENTS * The comments are read in starting with the following line until an empty line is reached. * * * LABELS * One label must occupy each subsequent line until an empty line is reached. The number * of labels should preferably match the number of variables in the data. * * DATA * On the same line as the DATA command, there must appear a comma-delimited list of variable * names. These names should be kept short (some applications truncate to 4 characters). The * numerical data is read in beginning with the following line until an empty line is reached. * * In every line, there must appear exactly 3 comma-delimited fields for each specified name. * The first field is the value, the second is the positive error, and the third is the negative * error. If you leave the last field blank (the comma is still required), then the positive error * will be interpreted as a symmetric error. If you include only the value, then the errors will be * set to zero. * * To reiterate, if you provide a DATA command with 2 names, e.g. "DATA 1st, 2nd", then every subsequent * line must contain 2*3 - 1 = 5 commas. If you give 3 names, then there must be 3*3 - 1 = 8 commas. * * Example * TITLE * Most Excellent Fake Data * * ABSTRACT * This data was collected over * many minutes of light work * that was required to make it up. * * COMMENTS * This data was generated using C++. * The file was formatted with Emacs. * * LABEL * Randomized Linear * Randomized Gaussian * Randomized Lorentzian * Run * * DATA line, gauss, lrntz, run * -1.966, -0.168, -0.106, 0.048, 0.002, 0.005, 0.184, 0.010, 0.017, 1001, , , run 1001 title * -1.895, -0.151, -0.128, 0.014, 0.001, 0.001, 0.259, 0.017, 0.015, 1002, , , run 1002 title * -1.836, -0.127, -0.184, 0.013, 0.001, 0.001, 0.202, 0.017, 0.020, 1003, , , run 1003 title * -1.739, -0.064, -0.166, 0.057, 0.003, 0.004, 0.237, 0.016, 0.018, 1004, , , run 1004 title * -1.601, -0.062, -0.147, 0.104, 0.008, 0.006, 0.271, 0.012, 0.025, 1005, , , run 1005 title * . . . . . . . . . * . . . . . . . . . * . . . . . . . . . * Alternatively, the data often utilizes the continuation character ('\') and is labelled like * DATA line, gauss, lrntz * linear = -1.966, -0.168, -0.106, \ * gaussn = 0.048, 0.002, 0.005, \ * lorntz = 0.184, 0.010, 0.017, \ * 1001,,, run 1001 title * linear = -1.895, -0.151, -0.128, \ * gaussn = 0.014, 0.001, 0.001, \ * lorntz = 0.259, 0.017, 0.015, | * 1002,,, run 1002 title * linear = -1.836, -0.127, -0.184, \ * gaussn = 0.013, 0.001, 0.001, \ * lorntz = 0.202, 0.017, 0.020, | * 1003,,, run 1003 title * . . . . * . . . . * . . . . * If there is a run line as in the above examples, it must be at the end of the data and given * in this just slight odd manner (do not blame me, I haven't invented this format ;-) ). * \endverbatim * *

WARNING:For the row like data representation (the top DATA representation shown) * it is essential that there are always at least one space inbetween commas (the reason is that * I am too lazy to write my own tokenizer), e.g. * * \verbatim * -1.966, -0.168, , 0.048, , , 0.184, 0.010, 0.017, 1001, , , run 1001 title * \endverbatim * *

which is ok, but * * \verbatim * -1.966, -0.168,, 0.048,,, 0.184, 0.010, 0.017, 1001,,, run 1001 title * \endverbatim * *

will not work! * *

Some db-files do have a '\\-e' or '\\e' label just between the DATA tag line and the real data. * This tag will just be ignored. * * return: * - true at successful reading, * - otherwise false. */ Bool_t PRunDataHandler::ReadDBFile() { Bool_t success = true; // open file ifstream f; // open db-file f.open(fRunPathName.Data(), ifstream::in); if (!f.is_open()) { cerr << endl << ">> PRunDataHandler::ReadDBFile **ERROR** Couldn't open data file (" << fRunPathName.Data() << ") for reading, sorry ..."; cerr << endl; return false; } PRawRunData runData; runData.fDataNonMusr.SetFromAscii(false); Int_t lineNo = 0; Int_t idx; Int_t dbTag = -1; Char_t instr[512]; TString line, workStr; Double_t val; Bool_t firstData = true; // needed as a switch to check in which format the data are given. 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) Bool_t dataTagsRead = false; // flag showing if the data tags are alread read // variables needed to tokenize strings TString tstr; TObjString *ostr; TObjArray *tokens = 0; while (!f.eof()) { // get next line from file f.getline(instr, sizeof(instr)); line = TString(instr); lineNo++; // check if comment line if (line.BeginsWith("#") || line.BeginsWith("%")) continue; // ignore empty lines if (line.IsWhitespace()) continue; // check for db specific tags workStr = line; workStr.Remove(TString::kLeading, ' '); // remove spaces from the begining if (workStr.BeginsWith("title", TString::kIgnoreCase)) { dbTag = 0; continue; } else if (workStr.BeginsWith("abstract", TString::kIgnoreCase)) { dbTag = 1; continue; } else if (workStr.BeginsWith("comments", TString::kIgnoreCase)) { dbTag = 2; continue; } else if (workStr.BeginsWith("label", TString::kIgnoreCase)) { dbTag = 3; continue; } else if (workStr.BeginsWith("data", TString::kIgnoreCase) && !dataTagsRead) { dataTagsRead = true; dbTag = 4; // filter out all data tags tokens = workStr.Tokenize(" ,\t"); for (Int_t i=1; iGetEntries(); i++) { ostr = dynamic_cast(tokens->At(i)); runData.fDataNonMusr.AppendDataTag(ostr->GetString()); } // clean up tokens if (tokens) { delete tokens; tokens = 0; } continue; } switch (dbTag) { case 0: // TITLE runData.SetRunTitle(workStr); break; case 1: // ABSTRACT // nothing to be done for now break; case 2: // COMMENTS // nothing to be done for now break; case 3: // LABEL runData.fDataNonMusr.AppendLabel(workStr); break; case 4: // DATA // filter out potential start data tag if (workStr.BeginsWith("\\-e", TString::kIgnoreCase) || workStr.BeginsWith("\\e", TString::kIgnoreCase) || workStr.BeginsWith("/-e", TString::kIgnoreCase) || workStr.BeginsWith("/e", TString::kIgnoreCase)) { continue; } // check if first real data line if (firstData) { // check if data are given just as rows are as labelled columns (see description above) tokens = workStr.Tokenize(","); ostr = dynamic_cast(tokens->At(0)); if (!ostr->GetString().IsFloat()) { labelledFormat = true; } else { labelledFormat = false; } // clean up tokens if (tokens) { delete tokens; tokens = 0; } // prepare data vector for use PDoubleVector dummy; for (UInt_t i=0; isize(); i++) { runData.fDataNonMusr.AppendData(dummy); runData.fDataNonMusr.AppendErrData(dummy); } firstData = false; } if (labelledFormat) { // handle labelled formated data // check if run line const Char_t *str = workStr.Data(); if (isdigit(str[0])) { // run line TString run("run"); idx = GetDataTagIndex(run, runData.fDataNonMusr.GetDataTags()); if (idx == -1) { cerr << endl << ">> PRunDataHandler::ReadDBFile **ERROR** in line no " << lineNo << ":"; cerr << endl << ">> " << workStr.Data(); cerr << endl << ">> found potential run data line without run data tag."; return false; } // split string in tokens tokens = workStr.Tokenize(","); // line has structure: runNo,,, runTitle ostr = dynamic_cast(tokens->At(0)); tstr = ostr->GetString(); if (!tstr.IsFloat()) { cerr << endl << ">> PRunDataHandler::ReadDBFile **ERROR** in line no " << lineNo << ":"; cerr << endl << ">> " << workStr.Data(); cerr << endl << ">> Expected db-data line with structure: runNo,,, runTitle"; cerr << endl << ">> runNo = " << tstr.Data() << ", seems to be not a number."; delete tokens; return false; } val = tstr.Atof(); runData.fDataNonMusr.AppendSubData(idx, val); runData.fDataNonMusr.AppendSubErrData(idx, 1.0); } else { // tag = data line // remove all possible spaces workStr.ReplaceAll(" ", ""); // split string in tokens tokens = workStr.Tokenize("=,"); // line has structure: tag = val,err1,err2, if (tokens->GetEntries() < 3) { cerr << endl << ">> PRunDataHandler::ReadDBFile **ERROR** in line no " << lineNo << ":"; cerr << endl << ">> " << workStr.Data(); cerr << endl << ">> Expected db-data line with structure: tag = val,err1,err2,\\"; delete tokens; return false; } ostr = dynamic_cast(tokens->At(0)); tstr = ostr->GetString(); idx = GetDataTagIndex(tstr, runData.fDataNonMusr.GetDataTags()); if (idx == -1) { cerr << endl << ">> PRunDataHandler::ReadDBFile **ERROR** in line no " << lineNo << ":"; cerr << endl << ">> " << workStr.Data(); cerr << endl << ">> data tag error: " << tstr.Data() << " seems not present in the data tag list"; delete tokens; return false; } switch (tokens->GetEntries()) { case 3: // tag = val,,, ostr = dynamic_cast(tokens->At(1)); tstr = ostr->GetString(); if (!tstr.IsFloat()) { cerr << endl << ">> PRunDataHandler::ReadDBFile **ERROR** in line no " << lineNo << ":"; cerr << endl << ">> " << workStr.Data(); cerr << endl << ">> Expected db-data line with structure: tag = val,err1,err2,\\"; cerr << endl << ">> val = " << tstr.Data() << ", seems to be not a number."; delete tokens; return false; } val = tstr.Atof(); runData.fDataNonMusr.AppendSubData(idx, val); runData.fDataNonMusr.AppendSubErrData(idx, 1.0); break; case 4: // tag = val,err,, case 5: // tag = val,err1,err2, // handle val ostr = dynamic_cast(tokens->At(1)); tstr = ostr->GetString(); if (!tstr.IsFloat()) { cerr << endl << ">> PRunDataHandler::ReadDBFile **ERROR** in line no " << lineNo << ":"; cerr << endl << ">> " << workStr.Data(); cerr << endl << ">> Expected db-data line with structure: tag = val,err1,err2,\\"; cerr << endl << ">> val = " << tstr.Data() << ", seems to be not a number."; delete tokens; return false; } val = tstr.Atof(); runData.fDataNonMusr.AppendSubData(idx, val); // handle err1 (err2 will be ignored for the time being) ostr = dynamic_cast(tokens->At(2)); tstr = ostr->GetString(); if (!tstr.IsFloat()) { cerr << endl << ">> PRunDataHandler::ReadDBFile **ERROR** in line no " << lineNo << ":"; cerr << endl << ">> " << workStr.Data(); cerr << endl << ">> Expected db-data line with structure: tag = val,err1,err2,\\"; cerr << endl << ">> err1 = " << tstr.Data() << ", seems to be not a number."; delete tokens; return false; } val = tstr.Atof(); runData.fDataNonMusr.AppendSubErrData(idx, val); break; default: cerr << endl << ">> PRunDataHandler::ReadDBFile **ERROR** in line no " << lineNo << ":"; cerr << endl << ">> " << workStr.Data(); cerr << endl << ">> Expected db-data line with structure: tag = val,err1,err2,\\"; delete tokens; return false; break; } } } else { // handle row formated data // split string in tokens tokens = workStr.Tokenize(","); // line has structure: val1, err11, err12, ..., valn, errn1, errn2, runNo, , , , runTitle if (tokens->GetEntries() != (Int_t)(3*runData.fDataNonMusr.GetDataTags()->size()+1)) { cerr << endl << ">> PRunDataHandler::ReadDBFile **ERROR** in line no " << lineNo << ":"; cerr << endl << ">> " << workStr.Data(); cerr << endl << ">> Expected db-data line with structure: val1, err11, err12, ..., valn, errn1, errn2, runNo, , , , runTitle"; cerr << endl << ">> found = " << tokens->GetEntries() << " tokens, however expected " << 3*runData.fDataNonMusr.GetDataTags()->size()+1; cerr << endl << ">> Perhaps there are commas without space inbetween, like 12.3,, 3.2,..."; delete tokens; return false; } // extract data Int_t j=0; for (Int_t i=0; iGetEntries()-1; i+=3) { // handle value ostr = dynamic_cast(tokens->At(i)); tstr = ostr->GetString(); if (!tstr.IsFloat()) { cerr << endl << ">> PRunDataHandler::ReadDBFile **ERROR** in line no " << lineNo << ":"; cerr << endl << ">> " << workStr.Data(); cerr << endl << ">> Expected db-data line with structure: val1, err11, err12, ..., valn, errn1, errn2, runNo, , , , runTitle"; cerr << endl << ">> value=" << tstr.Data() << " seems not to be a number"; delete tokens; return false; } runData.fDataNonMusr.AppendSubData(j, tstr.Atof()); // handle 1st error if present (2nd will be ignored for now) ostr = dynamic_cast(tokens->At(i+1)); tstr = ostr->GetString(); if (tstr.IsWhitespace()) { runData.fDataNonMusr.AppendSubErrData(j, 1.0); } else if (tstr.IsFloat()) { runData.fDataNonMusr.AppendSubErrData(j, tstr.Atof()); } else { cerr << endl << ">> PRunDataHandler::ReadDBFile **ERROR** in line no " << lineNo << ":"; cerr << endl << ">> " << workStr.Data(); cerr << endl << ">> Expected db-data line with structure: val1, err11, err12, ..., valn, errn1, errn2, runNo, , , , runTitle"; cerr << endl << ">> error1=" << tstr.Data() << " seems not to be a number"; delete tokens; return false; } j++; } } break; default: break; } } f.close(); // check that the number of labels == the number of data tags if (runData.fDataNonMusr.GetLabels()->size() != runData.fDataNonMusr.GetDataTags()->size()) { cerr << endl << ">> PRunDataHandler::ReadDBFile **ERROR**"; cerr << endl << ">> number of LABELS found = " << runData.fDataNonMusr.GetLabels()->size(); cerr << endl << ">> number of Data tags found = " << runData.fDataNonMusr.GetDataTags()->size(); cerr << endl << ">> They have to be equal!!"; if (tokens) { delete tokens; tokens = 0; } return false; } // check if all vectors have the same size for (UInt_t i=1; isize(); i++) { if (runData.fDataNonMusr.GetData()->at(i).size() != runData.fDataNonMusr.GetData()->at(i-1).size()) { cerr << endl << ">> PRunDataHandler::ReadDBFile **ERROR** in line no " << lineNo; cerr << endl << ">> label: " << runData.fDataNonMusr.GetDataTags()->at(i-1).Data() << ", number data elements = " << runData.fDataNonMusr.GetData()->at(i-1).size(); cerr << endl << ">> label: " << runData.fDataNonMusr.GetDataTags()->at(i).Data() << ", number data elements = " << runData.fDataNonMusr.GetData()->at(i).size(); cerr << endl << ">> They have to be equal!!"; success = false; break; } if (runData.fDataNonMusr.GetErrData()->at(i).size() != runData.fDataNonMusr.GetErrData()->at(i-1).size()) { cerr << endl << ">> PRunDataHandler::ReadDBFile **ERROR** in line no " << lineNo; cerr << endl << ">> label: " << runData.fDataNonMusr.GetDataTags()->at(i-1).Data() << ", number data elements = " << runData.fDataNonMusr.GetData()->at(i-1).size(); cerr << endl << ">> label: " << runData.fDataNonMusr.GetDataTags()->at(i).Data() << ", number error data elements = " << runData.fDataNonMusr.GetErrData()->at(i).size(); cerr << endl << ">> They have to be equal!!"; success = false; break; } } // clean up tokens if (tokens) { delete tokens; tokens = 0; } // keep run name runData.SetRunName(fRunName); fData.push_back(runData); return success; } //-------------------------------------------------------------------------- // WriteMusrRootFile (private) //-------------------------------------------------------------------------- /** *

Write the MusrRoot file format. Only the required entries will be handled. * * return: * - true on successful writting, * - otherwise false. * * \param fln file name. If empty, the routine will try to construct one */ Bool_t PRunDataHandler::WriteMusrRootFile(TString fln) { Bool_t ok = false; fln = GenerateOutputFileName(fln, ".root", ok); if (!ok) return false; if (!fAny2ManyInfo->useStandardOutput) cout << endl << ">> PRunDataHandler::WriteMusrRootFile(): writing a root data file (" << fln.Data() << ") ... " << endl; // generate data file TFolder *histosFolder; TFolder *decayAnaModule; TFolder *runHeader; histosFolder = gROOT->GetRootFolder()->AddFolder("histos", "Histograms"); gROOT->GetListOfBrowsables()->Add(histosFolder, "histos"); decayAnaModule = histosFolder->AddFolder("DecayAnaModule", "muSR decay histograms"); runHeader = gROOT->GetRootFolder()->AddFolder("RunHeader", "MusrRoot Run Header Info"); gROOT->GetListOfBrowsables()->Add(runHeader, "RunHeader"); TMusrRunHeader *header = new TMusrRunHeader(true); gROOT->GetListOfBrowsables()->Add(runHeader, "RunHeader"); // feed header info TString str, pathName; Int_t ival; Double_t dval[2]; TMusrRunPhysicalQuantity prop; // feed RunInfo str = fData[0].GetGenericValidatorUrl()->Copy(); header->Set("RunInfo/Generic Validator URL", str); str = fData[0].GetSpecificValidatorUrl()->Copy(); header->Set("RunInfo/Specific Validator URL", str); str = fData[0].GetGenerator()->Copy(); header->Set("RunInfo/Generator", str); str = fData[0].GetFileName()->Copy(); header->Set("RunInfo/File Name", str); str = fData[0].GetRunTitle()->Copy(); header->Set("RunInfo/Run Title", str); header->Set("RunInfo/Run Number", fData[0].GetRunNumber()); str = fData[0].GetStartDate()->Copy() + " " + fData[0].GetStartTime()->Copy(); header->Set("RunInfo/Run Start Time", str); str = fData[0].GetStopDate()->Copy() + " " + fData[0].GetStopTime()->Copy(); header->Set("RunInfo/Run Stop Time", str); ival = fData[0].GetStopDateTime() - fData[0].GetStartDateTime(); prop.Set("Run Duration", ival, "sec"); header->Set("RunInfo/Run Duration", prop); str = fData[0].GetLaboratory()->Copy(); header->Set("RunInfo/Laboratory", str); str = fData[0].GetInstrument()->Copy(); header->Set("RunInfo/Instrument", str); dval[0] = fData[0].GetMuonBeamMomentum(); prop.Set("Muon Beam Momentum", dval[0], "MeV/c"); header->Set("RunInfo/Muon Beam Momentum", prop); str = fData[0].GetMuonSpecies()->Copy(); header->Set("RunInfo/Muon Species", str); str = fData[0].GetMuonSource()->Copy(); header->Set("RunInfo/Muon Source", str); str = fData[0].GetSetup()->Copy(); header->Set("RunInfo/Setup", str); str = fData[0].GetComment()->Copy(); header->Set("RunInfo/Comment", str); str = fData[0].GetSample()->Copy(); header->Set("RunInfo/Sample Name", str); dval[0] = fData[0].GetTemperature(0); dval[1] = fData[0].GetTempError(0); prop.Set("Sample Temperature", MRH_UNDEFINED, dval[0], dval[1], "K"); header->Set("RunInfo/Sample Temperature", prop); dval[0] = fData[0].GetField(); prop.Set("Sample Magnetic Field", dval[0], "G"); header->Set("RunInfo/Sample Magnetic Field", prop); header->Set("RunInfo/No of Histos", (Int_t)fData[0].GetNoOfHistos()); dval[0] = fData[0].GetTimeResolution(); prop.Set("Time Resolution", dval[0], "ns"); header->Set("RunInfo/Time Resolution", prop); header->Set("RunInfo/RedGreen Offsets", fData[0].GetRedGreenOffset()); // feed DetectorInfo Int_t histoNo = 0; PRawRunDataSet *dataSet; UInt_t size = fData[0].GetNoOfHistos(); for (UInt_t i=0; i> PRunDataHandler::WriteMusrRootFile: **ERROR** Couldn't get data set (idx=" << i << ")"; cerr << endl << ">> something is really wrong!" << endl; return false; } histoNo = dataSet->GetHistoNo(); pathName.Form("DetectorInfo/Detector%03d/Name", histoNo); str = dataSet->GetName(); if (!str.CompareTo("n/a")) str.Form("Detector%3d", histoNo); header->Set(pathName, str); pathName.Form("DetectorInfo/Detector%03d/Histo Number", histoNo); header->Set(pathName, histoNo); pathName.Form("DetectorInfo/Detector%03d/Histo Length", histoNo); header->Set(pathName, (Int_t)(dataSet->GetData()->size()/fAny2ManyInfo->rebin)); pathName.Form("DetectorInfo/Detector%03d/Time Zero Bin", histoNo); header->Set(pathName, dataSet->GetTimeZeroBin()/fAny2ManyInfo->rebin); pathName.Form("DetectorInfo/Detector%03d/First Good Bin", histoNo); ival = dataSet->GetFirstGoodBin(); header->Set(pathName, (Int_t)(ival/fAny2ManyInfo->rebin)); pathName.Form("DetectorInfo/Detector%03d/Last Good Bin", histoNo); ival = dataSet->GetLastGoodBin(); header->Set(pathName, (Int_t)(ival/fAny2ManyInfo->rebin)); } // feed SampleEnvironmentInfo str = fData[0].GetCryoName()->Copy(); header->Set("SampleEnvironmentInfo/Cryo", str); // feed MagneticFieldEnvironmentInfo str = fData[0].GetMagnetName()->Copy(); header->Set("MagneticFieldEnvironmentInfo/Magnet Name", str); // feed BeamlineInfo str = fData[0].GetBeamline()->Copy(); header->Set("BeamlineInfo/Name", str); // feed histos vector histos; TH1F *histo = 0; UInt_t length = 0; if (fAny2ManyInfo->rebin == 1) { for (UInt_t i=0; i> PRunDataHandler::WriteMusrRootFile: **ERROR** Couldn't get data set (idx=" << i << ")"; cerr << endl << ">> something is really wrong!" << endl; return false; } str.Form("hDecay%03d", dataSet->GetHistoNo()); length = dataSet->GetData()->size(); histo = new TH1F(str.Data(), str.Data(), length+1, -0.5, (Double_t)length+0.5); for (UInt_t j=0; jSetBinContent(j+1, dataSet->GetData()->at(j)); } histos.push_back(histo); } } else { // rebin > 1 UInt_t dataRebin = 0; UInt_t dataCount = 0; for (UInt_t i=0; i> PRunDataHandler::WriteMusrRootFile: **ERROR** Couldn't get data set (idx=" << i << ")"; cerr << endl << ">> something is really wrong!" << endl; return false; } str.Form("hDecay%03d", dataSet->GetHistoNo()); length = dataSet->GetData()->size(); histo = new TH1F(str.Data(), str.Data(), (Int_t)(length/fAny2ManyInfo->rebin)+1, -0.5, (Double_t)((Int_t)(length/fAny2ManyInfo->rebin))+0.5); dataCount = 0; for (UInt_t j=0; j 0) && (j % fAny2ManyInfo->rebin == 0)) { dataCount++; histo->SetBinContent(dataCount, dataRebin); dataRebin = 0; } dataRebin += static_cast(dataSet->GetData()->at(j)); } histos.push_back(histo); } } // add histos to the DecayAnaModule folder for (UInt_t i=0; iAdd(histos[i]); // write file TFile *fout = new TFile(fln, "RECREATE", fln); if (fout == 0) { cerr << endl << "PRunDataHandler::WriteMusrRootFile(): **ERROR** Couldn't create ROOT file '" << fln << "'" << endl; return false; } fout->cd(); if (header->FillFolder(runHeader)) runHeader->Write(); histosFolder->Write(); fout->Close(); // check if root file shall be streamed to stdout if (fAny2ManyInfo->useStandardOutput && (fAny2ManyInfo->compressionTag == 0)) { // stream file to stdout ifstream is; int length=1024; char *buffer; is.open(fln.Data(), ios::binary); if (!is.is_open()) { cerr << endl << "PRunDataHandler::WriteMusrRootFile(): **ERROR** Couldn't open the root-file for streaming." << endl; remove(fln.Data()); return false; } // get length of file is.seekg(0, ios::end); length = is.tellg(); is.seekg(0, ios::beg); if (length == -1) { cerr << endl << "PRunDataHandler::WriteMusrRootFile(): **ERROR** Couldn't determine the root-file size." << endl; remove(fln.Data()); return false; } // allocate memory buffer = new char [length]; // read data as a block while (!is.eof()) { is.read(buffer, length); cout.write(buffer, length); } is.close(); delete [] buffer; // delete temporary root file remove(fln.Data()); } return true; } //-------------------------------------------------------------------------- // WriteRootFile (private) //-------------------------------------------------------------------------- /** *

Write the PSI LEM root-file format. * * return: * - true on successful writting, * - otherwise false. * * \param fln file name. If empty, the routine will try to construct one */ Bool_t PRunDataHandler::WriteRootFile(TString fln) { Bool_t ok = false; fln = GenerateOutputFileName(fln, ".root", ok); if (!ok) return false; if (!fAny2ManyInfo->useStandardOutput) cout << endl << ">> PRunDataHandler::WriteRootFile(): writing a root data file (" << fln.Data() << ") ... " << endl; // generate data file TFolder *histosFolder; TFolder *decayAnaModule; TFolder *runInfo; histosFolder = gROOT->GetRootFolder()->AddFolder("histos", "Histograms"); gROOT->GetListOfBrowsables()->Add(histosFolder, "histos"); decayAnaModule = histosFolder->AddFolder("DecayAnaModule", "muSR decay histograms"); runInfo = gROOT->GetRootFolder()->AddFolder("RunInfo", "LEM RunInfo"); gROOT->GetListOfBrowsables()->Add(runInfo, "RunInfo"); TLemRunHeader *header = new TLemRunHeader(); gROOT->GetListOfBrowsables()->Add(runInfo, "RunInfo"); // feed header info header->SetRunTitle(fData[0].GetRunTitle()->Data()); header->SetLemSetup(fData[0].GetSetup()->Data()); header->SetRunNumber(fData[0].GetRunNumber()); TString dt = *fData[0].GetStartDate() + "/" + *fData[0].GetStartTime(); header->SetStartTimeString(dt.Data()); dt = *fData[0].GetStopDate() + "/" + *fData[0].GetStopTime(); header->SetStopTimeString(dt.Data()); header->SetStartTime(fData[0].GetStartDateTime()); header->SetStopTime(fData[0].GetStopDateTime()); header->SetModeratorHV(-999.9, 0.0); header->SetSampleHV(-999.9, 0.0); header->SetImpEnergy(-999.9); header->SetSampleTemperature(fData[0].GetTemperature(0), fData[0].GetTempError(0)); header->SetSampleBField(fData[0].GetField(), 0.0); header->SetTimeResolution(fData[0].GetTimeResolution()); PRawRunDataSet *dataSet = fData[0].GetDataSet(0, false); // i.e. the false means, that i is the index and NOT the histo number header->SetNChannels(static_cast(dataSet->GetData()->size()/fAny2ManyInfo->rebin)); header->SetNHist(fData[0].GetNoOfHistos()); header->SetCuts("none"); header->SetModerator("none"); // feed t0's if possible UInt_t NoT0s = fData[0].GetNoOfHistos(); if (fData[0].GetNoOfHistos() > NHIST) { cerr << endl << ">> PRunDataHandler::WriteRootFile: **WARNING** found more T0's (" << NoT0s << ") than can be handled (" << NHIST << ")."; cerr << endl << ">> Will only write the first " << NHIST << " T0s!!" << endl; NoT0s = NHIST; } Double_t *tt0 = new Double_t[NoT0s]; for (UInt_t i=0; iGetTimeZeroBin()/fAny2ManyInfo->rebin; } header->SetTimeZero(tt0); runInfo->Add(header); // add header to RunInfo folder // feed histos vector histos; TH1F *histo = 0; Char_t str[32]; UInt_t size = 0; if (fAny2ManyInfo->rebin == 1) { for (UInt_t i=0; i> PRunDataHandler::WriteRootFile: **ERROR** Couldn't get data set (idx=0" << i << ")"; cerr << endl << ">> something is really wrong!" << endl; return false; } size = dataSet->GetData()->size(); sprintf(str, "hDecay%02d", (Int_t)i); histo = new TH1F(str, str, size+1, -0.5, static_cast(size)+0.5); for (UInt_t j=0; jSetBinContent(j+1, dataSet->GetData()->at(j)); } histos.push_back(histo); } } else { // rebin > 1 UInt_t dataRebin = 0; UInt_t dataCount = 0; for (UInt_t i=0; i> PRunDataHandler::WriteNexusFile: **ERROR** Couldn't get data set (idx=0" << i << ")"; cerr << endl << ">> something is really wrong!" << endl; return false; } size = dataSet->GetData()->size(); sprintf(str, "hDecay%02d", (Int_t)i); histo = new TH1F(str, str, (UInt_t)(size/fAny2ManyInfo->rebin)+1, -0.5, (Double_t)size/(Double_t)fAny2ManyInfo->rebin+0.5); dataCount = 0; for (UInt_t j=0; j 0) && (j % fAny2ManyInfo->rebin == 0)) { dataCount++; histo->SetBinContent(dataCount, dataRebin); dataRebin = 0; } dataRebin += static_cast(dataSet->GetData()->at(j)); } histos.push_back(histo); } } // add histos to the DecayAnaModule folder for (UInt_t i=0; iAdd(histos[i]); // write file TFile *fout = new TFile(fln, "RECREATE", fln); if (fout == 0) { cerr << endl << "PRunDataHandler::WriteRootFile(): **ERROR** Couldn't create ROOT file '" << fln << "'" << endl; return false; } fout->cd(); runInfo->Write(); histosFolder->Write(); fout->Close(); // clean up for (UInt_t i=0; iuseStandardOutput && (fAny2ManyInfo->compressionTag == 0)) { // stream file to stdout ifstream is; int length=1024; char *buffer; is.open(fln.Data(), ios::binary); if (!is.is_open()) { cerr << endl << "PRunDataHandler::WriteRootFile(): **ERROR** Couldn't open the root-file for streaming." << endl; remove(fln.Data()); return false; } // get length of file is.seekg(0, ios::end); length = is.tellg(); is.seekg(0, ios::beg); if (length == -1) { cerr << endl << "PRunDataHandler::WriteRootFile(): **ERROR** Couldn't determine the root-file size." << endl; remove(fln.Data()); return false; } // allocate memory buffer = new char [length]; // read data as a block while (!is.eof()) { is.read(buffer, length); cout.write(buffer, length); } is.close(); delete [] buffer; // delete temporary root file remove(fln.Data()); } return true; } //-------------------------------------------------------------------------- // WriteNexusFile (private) //-------------------------------------------------------------------------- /** *

Write the nexus-file format. * * return: * - true on successful writting, * - otherwise false. * * \param fln file name. If empty, the routine will try to construct one */ Bool_t PRunDataHandler::WriteNexusFile(TString fln) { #ifdef PNEXUS_ENABLED Bool_t ok = false; fln = GenerateOutputFileName(fln, ".nxs", ok); if (!ok) return false; if (!fAny2ManyInfo->useStandardOutput) cout << endl << ">> PRunDataHandler::WriteNexusFile(): writing a NeXus data file (" << fln.Data() << ") ... " << endl; // create NeXus object PNeXus *nxs = new PNeXus(); if (nxs == 0) { cerr << endl << ">> PRunDataHandler::WriteNexusFile(): **ERROR** couldn't invoke the NeXus object." << endl; return false; } // set IDF version nxs->SetIdfVersion(fAny2ManyInfo->idf); if (fAny2ManyInfo->idf == 1) { // fill necessary data structures nxs->SetFileName(fln.Data()); // set file creating time time_t now; struct tm *tm; time(&now); tm = localtime(&now); string str(""); char cstr[128]; strftime(cstr, sizeof(cstr), "%FT%T", tm); str = string(cstr); nxs->SetFileTime(str); nxs->GetEntryIdf1()->SetProgramName("any2many"); nxs->GetEntryIdf1()->SetProgramVersion("$Id$"); nxs->GetEntryIdf1()->SetRunNumber(fData[0].GetRunNumber()); nxs->GetEntryIdf1()->SetTitle(fData[0].GetRunTitle()->Data()); nxs->GetEntryIdf1()->SetNotes("n/a"); nxs->GetEntryIdf1()->SetAnalysis("muonTD"); if (*fData[0].GetLaboratory() != "n/a") nxs->GetEntryIdf1()->SetLaboratory(fData[0].GetLaboratory()->Data()); if (*fData[0].GetBeamline() != "n/a") nxs->GetEntryIdf1()->SetBeamline(fData[0].GetBeamline()->Data()); str = string(fData[0].GetStartDate()->Data()) + string("T") + string(fData[0].GetStartTime()->Data()); nxs->GetEntryIdf1()->SetStartTime(str); str = string(fData[0].GetStopDate()->Data()) + string("T") + string(fData[0].GetStopTime()->Data()); nxs->GetEntryIdf1()->SetStopTime(str); nxs->GetEntryIdf1()->SetSwitchingState(1); nxs->GetEntryIdf1()->GetUser()->SetName("n/a"); nxs->GetEntryIdf1()->GetUser()->SetExperimentNumber("n/a"); nxs->GetEntryIdf1()->GetSample()->SetName(fData[0].GetSample()->Data()); nxs->GetEntryIdf1()->GetSample()->SetPhysProp("temperature", fData[0].GetTemperature(0), "Kelvin"); nxs->GetEntryIdf1()->GetSample()->SetPhysProp("magnetic_field", fData[0].GetField(), "Gauss"); nxs->GetEntryIdf1()->GetSample()->SetEnvironment(fData[0].GetSetup()->Data()); nxs->GetEntryIdf1()->GetSample()->SetShape("n/a"); nxs->GetEntryIdf1()->GetSample()->SetMagneticFieldVectorAvailable(0); if (*fData[0].GetInstrument() != "n/a") nxs->GetEntryIdf1()->GetInstrument()->SetName(fData[0].GetInstrument()->Data()); nxs->GetEntryIdf1()->GetInstrument()->GetDetector()->SetNumber(fData[0].GetNoOfHistos()); nxs->GetEntryIdf1()->GetInstrument()->GetCollimator()->SetType("n/a"); // calculate the total number of counts double total_counts = 0; PRawRunDataSet *dataSet = 0; for (unsigned int i=0; i> PRunDataHandler::WriteNexusFile: **ERROR** Couldn't get data set (idx=0" << i << ")"; cerr << endl << ">> something is really wrong!" << endl; return false; } for (unsigned int j=0; jGetData()->size(); j++) total_counts += dataSet->GetData()->at(j); } double total_counts_mev = (double) total_counts / 1.0e6; nxs->GetEntryIdf1()->GetInstrument()->GetBeam()->SetTotalCounts(total_counts_mev); nxs->GetEntryIdf1()->GetInstrument()->GetBeam()->SetUnits("Mev"); nxs->GetEntryIdf1()->GetData()->SetTimeResolution(fData[0].GetTimeResolution()*fAny2ManyInfo->rebin, "ns"); for (unsigned int i=0; iGetEntryIdf1()->GetData()->SetT0((Int_t)(dataSet->GetTimeZeroBin()/fAny2ManyInfo->rebin), i); nxs->GetEntryIdf1()->GetData()->SetFirstGoodBin((Int_t)(dataSet->GetFirstGoodBin()/fAny2ManyInfo->rebin), i); nxs->GetEntryIdf1()->GetData()->SetLastGoodBin((Int_t)(dataSet->GetLastGoodBin()/fAny2ManyInfo->rebin), i); } // feed histos PUIntVector data; UInt_t size = 0; if (fAny2ManyInfo->rebin == 1) { for (UInt_t i=0; i> PRunDataHandler::WriteNexusFile: **ERROR** Couldn't get data set (idx=" << i << ")"; cerr << endl << ">> something is really wrong!" << endl; return false; } size = dataSet->GetData()->size(); for (UInt_t j=0; jGetData()->at(j)); } nxs->GetEntryIdf1()->GetData()->SetHisto(data, i); data.clear(); } } else { // rebin > 1 UInt_t dataRebin = 0; UInt_t dataCount = 0; for (UInt_t i=0; i> PRunDataHandler::WriteNexusFile: **ERROR** Couldn't get data set (idx=" << i << ")"; cerr << endl << ">> something is really wrong!" << endl; return false; } size = dataSet->GetData()->size(); dataCount = 0; for (UInt_t j=0; j 0) && (j % fAny2ManyInfo->rebin == 0)) { dataCount++; data.push_back(dataRebin); dataRebin = 0; } dataRebin += static_cast(dataSet->GetData()->at(j)); } nxs->GetEntryIdf1()->GetData()->SetHisto(data, i); data.clear(); } } } else if (fAny2ManyInfo->idf == 2) { // fill necessary data structures nxs->SetFileName(fln.Data()); // set file creating time time_t now; struct tm *tm; time(&now); tm = localtime(&now); string str(""); char cstr[128]; strftime(cstr, sizeof(cstr), "%FT%T", tm); str = string(cstr); nxs->SetFileTime(str); // NXroot info nxs->SetCreator("PSI: any2many"); // NXentry info nxs->GetEntryIdf2()->SetDefinition("muonTD"); nxs->GetEntryIdf2()->SetProgramName("any2many"); nxs->GetEntryIdf2()->SetProgramVersion("$Id$"); nxs->GetEntryIdf2()->SetRunNumber(fData[0].GetRunNumber()); nxs->GetEntryIdf2()->SetTitle(fData[0].GetRunTitle()->Data()); str = string(fData[0].GetStartDate()->Data()) + string("T") + string(fData[0].GetStartTime()->Data()); nxs->GetEntryIdf2()->SetStartTime(str); str = string(fData[0].GetStopDate()->Data()) + string("T") + string(fData[0].GetStopTime()->Data()); nxs->GetEntryIdf2()->SetStopTime(str); nxs->GetEntryIdf2()->SetExperimentIdentifier("n/a"); // NXuser info nxs->GetEntryIdf2()->GetUser()->SetName("n/a"); // NXsample info nxs->GetEntryIdf2()->GetSample()->SetName(fData[0].GetSample()->Data()); nxs->GetEntryIdf2()->GetSample()->SetDescription("n/a"); nxs->GetEntryIdf2()->GetSample()->SetPhysProp("temperature_1", fData[0].GetTemperature(0), "Kelvin"); nxs->GetEntryIdf2()->GetSample()->SetPhysProp("magnetic_field_1", fData[0].GetField(), "Gauss"); nxs->GetEntryIdf2()->GetSample()->SetEnvironmentTemp(fData[0].GetSetup()->Data()); nxs->GetEntryIdf2()->GetSample()->SetEnvironmentField("n/a"); // here would be the information for NXinstrument. Currently there are not much information to feed this nxs->GetEntryIdf2()->GetInstrument()->SetName(fData[0].GetInstrument()->Data()); // NXinstrument/NXsource nxs->GetEntryIdf2()->GetInstrument()->GetSource()->SetName(fData[0].GetLaboratory()->Data()); nxs->GetEntryIdf2()->GetInstrument()->GetSource()->SetType(fData[0].GetMuonSource()->Data()); nxs->GetEntryIdf2()->GetInstrument()->GetSource()->SetProbe(fData[0].GetMuonSpecies()->Data()); // NXinstrument/NXbeamline nxs->GetEntryIdf2()->GetInstrument()->GetBeamline()->SetName(fData[0].GetBeamline()->Data()); // NXinstrument/NXdetector nxs->GetEntryIdf2()->GetInstrument()->GetDetector()->SetDescription(fData[0].GetInstrument()->Data()); // assume that this should be the instrument name nxs->GetEntryIdf2()->GetInstrument()->GetDetector()->SetNoOfPeriods(0); // currently red/green is not distinguished nxs->GetEntryIdf2()->GetInstrument()->GetDetector()->SetNoOfSpectra(fData[0].GetNoOfHistos()); PRawRunDataSet *dataSet = fData[0].GetDataSet(0, false); // i.e. the false means, that i is the index and NOT the histo number if (dataSet == 0) { // something is really wrong cerr << endl << ">> PRunDataHandler::WriteNeXusFile: **ERROR** Couldn't get data set (idx=0)"; cerr << endl << ">> something is really wrong!" << endl; return false; } nxs->GetEntryIdf2()->GetInstrument()->GetDetector()->SetNoOfBins((unsigned int)(dataSet->GetData()->size() / fAny2ManyInfo->rebin)); nxs->GetEntryIdf2()->GetInstrument()->GetDetector()->SetTimeResolution(fData[0].GetTimeResolution()*fAny2ManyInfo->rebin, "ns"); int *histo = 0; int idx = 0; if (fAny2ManyInfo->rebin == 1) { histo = new int[fData[0].GetNoOfHistos()*dataSet->GetData()->size()]; idx = 0; for (int i=0; iGetEntryIdf2()->GetInstrument()->GetDetector()->GetNoOfSpectra(); i++) { dataSet = fData[0].GetDataSet(i, false); // i.e. the false means, that i is the index and NOT the histo number if (dataSet == 0) { // something is really wrong cerr << endl << ">> PRunDataHandler::WriteNeXusFile: **ERROR** Couldn't get data set (idx=" << i << ")"; cerr << endl << ">> something is really wrong!" << endl; return false; } for (unsigned int j=0; jGetData()->size(); j++) { *(histo+idx++) = (int) dataSet->GetData()->at(j); } } nxs->GetEntryIdf2()->GetInstrument()->GetDetector()->SetHistos(histo); // clean up if (histo) { delete [] histo; histo = 0; } } else { // rebin > 1 histo = new int[fData[0].GetNoOfHistos()*(int)(dataSet->GetData()->size()/fAny2ManyInfo->rebin)]; int counts = 0; idx = 0; for (int i=0; iGetEntryIdf2()->GetInstrument()->GetDetector()->GetNoOfSpectra(); i++) { dataSet = fData[0].GetDataSet(i, false); // i.e. the false means, that i is the index and NOT the histo number if (dataSet == 0) { // something is really wrong cerr << endl << ">> PRunDataHandler::WriteNeXusFile: **ERROR** Couldn't get data set (idx=" << i << ")"; cerr << endl << ">> something is really wrong!" << endl; return false; } for (unsigned int j=0; jGetData()->size(); j++) { if ((j>0) && (j % fAny2ManyInfo->rebin == 0)) { *(histo+idx++) = counts; counts = 0; } counts += (int) dataSet->GetData()->at(j); } } nxs->GetEntryIdf2()->GetInstrument()->GetDetector()->SetHistos(histo); // clean up if (histo) { delete [] histo; histo = 0; } } // handle spectrum index for (int i=0; iGetEntryIdf2()->GetInstrument()->GetDetector()->GetNoOfSpectra(); i++) nxs->GetEntryIdf2()->GetInstrument()->GetDetector()->SetSpectrumIndex(i+1); // handle histogram resolution nxs->GetEntryIdf2()->GetInstrument()->GetDetector()->SetTimeResolution(fData[0].GetTimeResolution()*fAny2ManyInfo->rebin, "ns"); // handle raw time vector raw_time; UInt_t size = (unsigned int)(dataSet->GetData()->size() / fAny2ManyInfo->rebin); for (unsigned int i=0; irebin * 1.0e-3); // since time resolution is given in ns, the factor 1.0e-3 is needed to convert to us } nxs->GetEntryIdf2()->GetInstrument()->GetDetector()->SetRawTime(raw_time); nxs->GetEntryIdf2()->GetInstrument()->GetDetector()->SetRawTimeUnit("micro.second"); nxs->GetEntryIdf2()->GetInstrument()->GetDetector()->SetRawTimeName("time"); raw_time.clear(); // handle t0 nxs->GetEntryIdf2()->GetInstrument()->GetDetector()->SetT0Tag(2); // i.e. t0[#histo] format int *t0 = new int[fData[0].GetNoOfHistos()]; int *fgb = new int[fData[0].GetNoOfHistos()]; int *lgb = new int[fData[0].GetNoOfHistos()]; if ((t0==0) || (fgb==0) || (lgb==0)) { cerr << endl << ">> PRunDataHandler::WriteNeXusFile: **ERROR** Couldn't allocate memory for t0, fgb, lgb" << endl; return false; } for (unsigned int i=0; i> PRunDataHandler::WriteNeXusFile: **ERROR** Couldn't get data set (idx=0)"; cerr << endl << ">> something is really wrong!" << endl; return false; } t0[i] = (int)(dataSet->GetTimeZeroBin() / fAny2ManyInfo->rebin); fgb[i] = (int)(dataSet->GetFirstGoodBin() / fAny2ManyInfo->rebin); lgb[i] = (int)(dataSet->GetLastGoodBin() / fAny2ManyInfo->rebin); } nxs->GetEntryIdf2()->GetInstrument()->GetDetector()->SetT0(t0); nxs->GetEntryIdf2()->GetInstrument()->GetDetector()->SetFirstGoodBin(fgb); nxs->GetEntryIdf2()->GetInstrument()->GetDetector()->SetLastGoodBin(lgb); // clean up if (t0) delete [] t0; if (fgb) delete [] fgb; if (lgb) delete [] lgb; } else { // clean up if (nxs != 0) { delete nxs; nxs = 0; } return false; } // filter out the proper file type, i.e. HDF4, HDF5, or XML char fileType[32]; memset(fileType, '\0', 32); if (!fAny2ManyInfo->outFormat.CompareTo("nexus1-hdf4", TString::kIgnoreCase) || !fAny2ManyInfo->outFormat.CompareTo("nexus2-hdf4", TString::kIgnoreCase)) strncpy(fileType, "hdf4", sizeof(fileType)); else if (!fAny2ManyInfo->outFormat.CompareTo("nexus1-hdf5", TString::kIgnoreCase) || !fAny2ManyInfo->outFormat.CompareTo("nexus2-hdf5", TString::kIgnoreCase)) strncpy(fileType, "hdf5", sizeof(fileType)); else if (!fAny2ManyInfo->outFormat.CompareTo("nexus1-xml", TString::kIgnoreCase) || !fAny2ManyInfo->outFormat.CompareTo("nexus2-xml", TString::kIgnoreCase)) strncpy(fileType, "xml", sizeof(fileType)); else { cerr << endl << ">> PRunDataHandler::WriteNexusFile(): **ERROR** undefined output NeXus format " << fAny2ManyInfo->outFormat.Data() << " found."; cerr << endl << ">> Allowed are: hdf4, hdf5, xml" << endl; if (nxs != 0) { delete nxs; nxs = 0; } return false; } // write file nxs->WriteFile(fln, fileType, fAny2ManyInfo->idf); if (nxs != 0) { delete nxs; nxs = 0; } #else cout << endl << ">> PRunDataHandler::WriteNexusFile(): Sorry, not enabled at configuration level, i.e. --enable-NeXus when executing configure" << endl << endl; #endif return true; } //-------------------------------------------------------------------------- // WriteWkmFile (private) //-------------------------------------------------------------------------- /** *

Write the wkm-file format. * * return: * - true on successful writting, * - otherwise false. * * \param fln file name. If empty, the routine will try to construct one */ Bool_t PRunDataHandler::WriteWkmFile(TString fln) { // check if a LEM nemu file needs to be written bool lem_wkm_style = false; if (!fData[0].GetBeamline()->CompareTo("mue4", TString::kIgnoreCase)) lem_wkm_style = true; Bool_t ok = false; if (lem_wkm_style) fln = GenerateOutputFileName(fln, ".nemu", ok); else fln = GenerateOutputFileName(fln, ".wkm", ok); if (!ok) return false; TString fileName = fln; if (!fAny2ManyInfo->useStandardOutput) cout << endl << ">> PRunDataHandler::WriteWkmFile(): writing a wkm data file (" << fln.Data() << ") ... " << endl; // write ascii file ofstream fout; streambuf* strm_buffer = 0; if (!fAny2ManyInfo->useStandardOutput || (fAny2ManyInfo->compressionTag > 0)) { // open data-file fout.open(fln.Data(), ofstream::out); if (!fout.is_open()) { cerr << endl << ">> PRunDataHandler::WriteWkmFile **ERROR** Couldn't open data file (" << fln.Data() << ") for writing, sorry ..."; cerr << endl; return false; } // save output buffer of the stream strm_buffer = cout.rdbuf(); // redirect output into the file cout.rdbuf(fout.rdbuf()); } // write header cout << "- WKM data file converted with any2many"; if (lem_wkm_style) { cout << endl << "NEMU_Run: " << fData[0].GetRunNumber(); cout << endl << "nemu_Run: " << fileName.Data(); } else { cout << endl << "Run: " << fData[0].GetRunNumber(); } cout << endl << "Date: " << fData[0].GetStartTime()->Data() << " " << fData[0].GetStartDate()->Data() << " / " << fData[0].GetStopTime()->Data() << " " << fData[0].GetStopDate()->Data(); if (fData[0].GetRunTitle()->Length() > 0) cout << endl << "Title: " << fData[0].GetRunTitle()->Data(); if (fData[0].GetField() != PMUSR_UNDEFINED) { cout << endl << "Field: " << fData[0].GetField(); } else { cout << endl << "Field: ??"; } cout << endl << "Setup: " << fData[0].GetSetup()->Data(); if (fData[0].GetNoOfTemperatures() == 1) { cout << endl << "Temp: " << fData[0].GetTemperature(0); } else if (fData[0].GetNoOfTemperatures() > 1) { cout << endl << "Temp(meas1): " << fData[0].GetTemperature(0) << " +- " << fData[0].GetTempError(0); cout << endl << "Temp(meas2): " << fData[0].GetTemperature(1) << " +- " << fData[0].GetTempError(1); } else { cout << endl << "Temp: ??"; } if (lem_wkm_style) cout << endl << "TOF(M3S1): nocut"; cout << endl << "Groups: " << fData[0].GetNoOfHistos(); cout << endl << "Channels: " << static_cast(fData[0].GetDataBin(1)->size()/fAny2ManyInfo->rebin); cout.precision(10); cout << endl << "Resolution: " << fData[0].GetTimeResolution()*fAny2ManyInfo->rebin/1.0e3; // ns->us cout.setf(ios::fixed,ios::floatfield); // floatfield set to fixed // write data UInt_t no_of_bins_per_line = 16; if (lem_wkm_style) no_of_bins_per_line = 10; PRawRunDataSet *dataSet; if (fAny2ManyInfo->rebin == 1) { for (UInt_t i=0; iGetData()->size(); j++) { if ((j > 0) && (j % no_of_bins_per_line == 0)) cout << endl; if (lem_wkm_style) cout << setw(8) << static_cast(dataSet->GetData()->at(j)); else cout << static_cast(dataSet->GetData()->at(j)) << " "; } } } else { // rebin > 1 Int_t dataRebin = 0; UInt_t count = 0; for (UInt_t i=0; iGetData()->size(); j++) { if ((j > 0) && (j % fAny2ManyInfo->rebin == 0)) { if (lem_wkm_style) cout << setw(8) << dataRebin; else cout << dataRebin << " "; count++; dataRebin = 0; if ((count > 0) && (count % no_of_bins_per_line == 0) && (j != dataSet->GetData()->size()-1)) cout << endl; } else { dataRebin += static_cast(dataSet->GetData()->at(j)); } } } } if (!fAny2ManyInfo->useStandardOutput || (fAny2ManyInfo->compressionTag > 0)) { // restore old output buffer cout.rdbuf(strm_buffer); fout.close(); } return true; } //-------------------------------------------------------------------------- // WritePsiBinFile (private) //-------------------------------------------------------------------------- /** *

Write the psi-bin-file format. * * return: * - true on successful writting, * - otherwise false. * * \param fln file name. If empty, the routine will try to construct one */ Bool_t PRunDataHandler::WritePsiBinFile(TString fln) { Bool_t ok = false; fln = GenerateOutputFileName(fln, ".bin", ok); if (!ok) return false; if (!fAny2ManyInfo->useStandardOutput) cout << endl << ">> PRunDataHandler::WritePsiBinFile(): writing a psi-bin data file (" << fln.Data() << ") ... " << endl; MuSR_td_PSI_bin psibin; int status = 0; // fill header information // run number psibin.put_runNumber_int(fData[0].GetRunNumber()); // length of histograms psibin.put_histoLength_bin((int)(fData[0].GetDataBin(1)->size()/fAny2ManyInfo->rebin)); // number of histograms psibin.put_numberHisto_int((int)fData[0].GetNoOfHistos()); // run title = sample (10 char) / temp (10 char) / field (10 char) / orientation (10 char) char cstr[11]; // sample if (fData[0].GetSample()->Length() > 0) strncpy(cstr, fData[0].GetSample()->Data(), 10); else strcpy(cstr, "??"); cstr[10] = '\0'; psibin.put_sample(cstr); // temp if (fData[0].GetNoOfTemperatures() > 0) snprintf(cstr, 10, "%.1f K", fData[0].GetTemperature(0)); else strcpy(cstr, "?? K"); cstr[10] = '\0'; psibin.put_temp(cstr); // field if (fData[0].GetField() > 0) snprintf(cstr, 10, "%.1f G", fData[0].GetField()); else strcpy(cstr, "?? G"); cstr[10] = '\0'; psibin.put_field(cstr); // orientation if (fData[0].GetOrientation()->Length() > 0) strncpy(cstr, fData[0].GetOrientation()->Data(), 10); else strcpy(cstr, "??"); cstr[10] = '\0'; psibin.put_orient(cstr); // setup if (fData[0].GetSetup()->Length() > 0) strncpy(cstr, fData[0].GetSetup()->Data(), 10); else strcpy(cstr, "??"); cstr[10] = '\0'; psibin.put_setup(cstr); // handle PSI-BIN start/stop Time/Date. PSI-BIN requires: Time -> HH:MM:SS, and Date -> DD-MMM-YY // internally given: Time -> HH:MM:SS, and Date -> YYYY-MM-DD // run start date vector svec; TString str, date; TDatime dt; dt.Set(fData[0].GetStartDateTime()); date.Form("%02d-", dt.GetDay()); date.Append(GetMonth(dt.GetMonth())); date.Append("-"); date.Append(GetYear(dt.GetYear())); strncpy(cstr, date.Data(), 9); cstr[9] = '\0'; svec.push_back(cstr); // run start time strncpy(cstr, fData[0].GetStartTime()->Data(), 8); cstr[8] = '\0'; svec.push_back(cstr); psibin.put_timeStart_vector(svec); svec.clear(); // run stop date dt.Set(fData[0].GetStopDateTime()); date.Form("%02d-", dt.GetDay()); date.Append(GetMonth(dt.GetMonth())); date.Append("-"); date.Append(GetYear(dt.GetYear())); strncpy(cstr, date.Data(), 9); cstr[9] = '\0'; svec.push_back(cstr); // run stop time strncpy(cstr, fData[0].GetStopTime()->Data(), 8); cstr[8] = '\0'; svec.push_back(cstr); psibin.put_timeStop_vector(svec); svec.clear(); // number of measured temperatures psibin.put_numberTemperature_int(fData[0].GetNoOfTemperatures()); // mean temperatures vector dvec; for (UInt_t i=0; iData()); // write time resolution psibin.put_binWidth_ns(fData[0].GetTimeResolution()*fAny2ManyInfo->rebin); // write scaler dummies psibin.put_numberScaler_int(0); // feed detector related info like, histogram names, t0, fgb, lgb Int_t ival = 0; PRawRunDataSet *dataSet; UInt_t size = fData[0].GetNoOfHistos(); for (UInt_t i=0; i> PRunDataHandler::WritePsiBinFile: **ERROR** Couldn't get data set (idx=" << i << ")"; cerr << endl << ">> something is really wrong!" << endl; return false; } // detector name str = dataSet->GetName(); if (!str.CompareTo("n/a")) str.Form("Detector%3d", i+1); psibin.put_nameHisto(str.Data(), i); // time zero bin ival = (Int_t)(dataSet->GetTimeZeroBin()/fAny2ManyInfo->rebin); psibin.put_t0_int(i, ival); // first good bin ival = (Int_t)(dataSet->GetFirstGoodBin()/fAny2ManyInfo->rebin); psibin.put_firstGood_int(i, ival); // last good bin ival = (Int_t)(dataSet->GetLastGoodBin()/fAny2ManyInfo->rebin); psibin.put_lastGood_int(i, ival); } // feed histos vector< vector > histos; histos.resize(fData[0].GetNoOfHistos()); UInt_t length = 0; if (fAny2ManyInfo->rebin == 1) { for (UInt_t i=0; i> PRunDataHandler::WritePsiBinFile: **ERROR** Couldn't get data set (idx=" << i << ")"; cerr << endl << ">> something is really wrong!" << endl; return false; } length = dataSet->GetData()->size(); histos[i].resize(length); for (UInt_t j=0; jGetData()->at(j); } } } else { // rebin > 1 UInt_t dataRebin = 0; UInt_t dataCount = 0; for (UInt_t i=0; i> PRunDataHandler::WritePsiBinFile: **ERROR** Couldn't get data set (idx=" << i << ")"; cerr << endl << ">> something is really wrong!" << endl; return false; } length = dataSet->GetData()->size(); dataCount = 0; for (UInt_t j=0; j 0) && (j % fAny2ManyInfo->rebin == 0)) { dataCount++; histos[i].push_back(dataRebin); dataRebin = 0; } dataRebin += static_cast(dataSet->GetData()->at(j)); } } } status = psibin.put_histo_array_int(histos); if (status != 0) { cerr << endl << ">> PRunDataHandler::WritePsiBinFile(): " << psibin.ConsistencyStatus() << endl; return false; } if (!psibin.CheckDataConsistency()) { cerr << endl << ">> PRunDataHandler::WritePsiBinFile(): " << psibin.ConsistencyStatus() << endl; return false; } // write data to file status = psibin.write(fln.Data()); if (status != 0) { cerr << endl << ">> PRunDataHandler::WritePsiBinFile(): " << psibin.WriteStatus() << endl; return false; } return true; } //-------------------------------------------------------------------------- // WriteMudFile (private) //-------------------------------------------------------------------------- /** *

Write the mud-file format. * * return: * - true on successful writting, * - otherwise false. * * \param fln file name. If empty, the routine will try to construct one */ Bool_t PRunDataHandler::WriteMudFile(TString fln) { Bool_t ok = false; fln = GenerateOutputFileName(fln, ".msr", ok); if (!ok) return false; if (!fAny2ManyInfo->useStandardOutput) cout << endl << ">> PRunDataHandler::WriteMudFile(): writing a mud data file (" << fln.Data() << ") ... " << endl; // generate the mud data file int fd = MUD_openWrite((char*)fln.Data(), MUD_FMT_TRI_TD_ID); if (fd == -1) { cerr << endl << ">> PRunDataHandler::WriteMudFile(): **ERROR** couldn't open mud data file for write ..." << endl; return false; } // generate header information char dummy[32], info[128]; strcpy(dummy, "???"); MUD_setRunDesc(fd, MUD_SEC_GEN_RUN_DESC_ID); MUD_setExptNumber(fd, 0); MUD_setRunNumber(fd, fData[0].GetRunNumber()); Int_t ival = fData[0].GetStopDateTime()-fData[0].GetStartDateTime(); MUD_setElapsedSec(fd, ival); MUD_setTimeBegin(fd, fData[0].GetStartDateTime()); MUD_setTimeEnd(fd, fData[0].GetStopDateTime()); MUD_setTitle(fd, (char *)fData[0].GetRunTitle()->Data()); MUD_setLab(fd, (char *)fData[0].GetLaboratory()->Data()); MUD_setArea(fd, (char *)fData[0].GetBeamline()->Data()); MUD_setMethod(fd, (char *)fData[0].GetSetup()->Data()); MUD_setApparatus(fd, (char *)fData[0].GetInstrument()->Data()); MUD_setInsert(fd, dummy); MUD_setSample(fd, (char *)fData[0].GetSample()->Data()); MUD_setOrient(fd, (char *)fData[0].GetOrientation()->Data()); MUD_setDas(fd, dummy); MUD_setExperimenter(fd, dummy); sprintf(info, "%lf+-%lf (K)", fData[0].GetTemperature(0), fData[0].GetTempError(0)); MUD_setTemperature(fd, info); sprintf(info, "%lf", fData[0].GetField()); MUD_setField(fd, info); // generate the histograms MUD_setHists(fd, MUD_GRP_TRI_TD_HIST_ID, fData[0].GetNoOfHistos()); UInt_t *data, dataSize = fData[0].GetDataSet(0, false)->GetData()->size()/fAny2ManyInfo->rebin + 1; data = new UInt_t[dataSize]; if (data == 0) { cerr << endl << ">> PRunDataHandler::WriteMudFile(): **ERROR** couldn't allocate memory for the data ..." << endl; MUD_closeWrite(fd); return false; } UInt_t noOfEvents = 0, k = 0; ival = 0; PRawRunDataSet *dataSet; for (UInt_t i=0; i> PRunDataHandler::WriteMudFile: **ERROR** Couldn't get data set (idx=" << i << ")"; cerr << endl << ">> something is really wrong!" << endl; return false; } // fill data for (UInt_t j=0; jGetData()->size(); j++) { if ((j != 0) && (j % fAny2ManyInfo->rebin == 0)) { data[k] = ival; noOfEvents += ival; k++; ival = 0; } ival += static_cast(dataSet->GetData()->at(j)); } // feed data relevant information // the numbering of the histograms start from '1', hence i+1 needed!! MUD_setHistType(fd, i+1, MUD_GRP_TRI_TD_HIST_ID); MUD_setHistNumBytes(fd, i+1, sizeof(data)); MUD_setHistNumBins(fd, i+1, dataSize); MUD_setHistBytesPerBin(fd, i+1, 0); MUD_setHistFsPerBin(fd, i+1, static_cast(1.0e6*fAny2ManyInfo->rebin*fData[0].GetTimeResolution())); // time resolution is given in (ns) MUD_setHistT0_Ps(fd, i+1, static_cast(1.0e3*fData[0].GetTimeResolution()*((dataSet->GetTimeZeroBin()+fAny2ManyInfo->rebin/2)/fAny2ManyInfo->rebin))); MUD_setHistT0_Bin(fd, i+1, static_cast(dataSet->GetTimeZeroBin()/fAny2ManyInfo->rebin)); MUD_setHistGoodBin1(fd, i+1, static_cast(dataSet->GetFirstGoodBin()/fAny2ManyInfo->rebin)); MUD_setHistGoodBin2(fd, i+1, static_cast(dataSet->GetLastGoodBin()/fAny2ManyInfo->rebin)); MUD_setHistBkgd1(fd, i+1, 0); MUD_setHistBkgd2(fd, i+1, 0); MUD_setHistNumEvents(fd, i+1, (UINT32)noOfEvents); MUD_setHistTitle(fd, i+1, (char *)dataSet->GetName().Data()); REAL64 timeResolution = (fAny2ManyInfo->rebin*fData[0].GetTimeResolution())/1.0e9; // ns -> s MUD_setHistSecondsPerBin(fd, i+1, timeResolution); MUD_setHistData(fd, i+1, data); } MUD_closeWrite(fd); delete [] data; // check if mud file shall be streamed to stdout if (fAny2ManyInfo->useStandardOutput && (fAny2ManyInfo->compressionTag == 0)) { // stream file to stdout ifstream is; int length=1024; char *buffer; is.open(fln.Data(), ios::binary); if (!is.is_open()) { cerr << endl << "PRunDataHandler::WriteMudFile(): **ERROR** Couldn't open the mud-file for streaming." << endl; remove(fln.Data()); return false; } // get length of file is.seekg(0, ios::end); length = is.tellg(); is.seekg(0, ios::beg); if (length == -1) { cerr << endl << "PRunDataHandler::WriteMudFile(): **ERROR** Couldn't determine the mud-file size." << endl; remove(fln.Data()); return false; } // allocate memory buffer = new char [length]; // read data as a block while (!is.eof()) { is.read(buffer, length); cout.write(buffer, length); } is.close(); delete [] buffer; // delete temporary root file remove(fln.Data()); } return true; } //-------------------------------------------------------------------------- // WriteAsciiFile (private) //-------------------------------------------------------------------------- /** *

Write the ascii-file format. * * return: * - true on successful writting, * - otherwise false. * * \param fln file name. If empty, the routine will try to construct one */ Bool_t PRunDataHandler::WriteAsciiFile(TString fln) { Bool_t ok = false; fln = GenerateOutputFileName(fln, ".ascii", ok); if (!ok) return false; TString fileName = fln; if (!fAny2ManyInfo->useStandardOutput) cout << endl << ">> PRunDataHandler::WriteAsciiFile(): writing an ascii data file (" << fln.Data() << ") ... " << endl; // write ascii file ofstream fout; streambuf* strm_buffer = 0; if (!fAny2ManyInfo->useStandardOutput || (fAny2ManyInfo->compressionTag > 0)) { // open data-file fout.open(fln.Data(), ofstream::out); if (!fout.is_open()) { cerr << endl << ">> PRunDataHandler::WriteAsciiFile **ERROR** Couldn't open data file (" << fln.Data() << ") for writing, sorry ..."; cerr << endl; return false; } // save output buffer of the stream strm_buffer = cout.rdbuf(); // redirect output into the file cout.rdbuf(fout.rdbuf()); } // write header cout << "%*************************************************************************"; cout << endl << "% file name : " << fileName.Data(); if (fData[0].GetRunTitle()->Length() > 0) cout << endl << "% title : " << fData[0].GetRunTitle()->Data(); if (fData[0].GetRunNumber() >= 0) cout << endl << "% run number : " << fData[0].GetRunNumber(); if (fData[0].GetSetup()->Length() > 0) cout << endl << "% setup : " << fData[0].GetSetup()->Data(); cout << endl << "% field : " << fData[0].GetField() << " (G)"; if (fData[0].GetStartTime()->Length() > 0) cout << endl << "% date : " << fData[0].GetStartTime()->Data() << " " << fData[0].GetStartDate()->Data() << " / " << fData[0].GetStopTime()->Data() << " " << fData[0].GetStopDate()->Data(); if (fData[0].GetNoOfTemperatures() > 0) { cout << endl << "% temperature : "; for (UInt_t i=0; irebin << " (ns)"; cout.setf(ios::fixed,ios::floatfield); // floatfield set to fixed } PRawRunDataSet *dataSet; cout << endl << "% t0 : "; for (UInt_t i=0; i(dataSet->GetTimeZeroBin()/fAny2ManyInfo->rebin) << ", "; } dataSet = fData[0].GetDataSet(fData[0].GetNoOfHistos()-1, false); // i.e. the false means, that i is the index and NOT the histo number cout << static_cast(dataSet->GetTimeZeroBin()/fAny2ManyInfo->rebin); cout << endl << "% # histos : " << fData[0].GetNoOfHistos(); dataSet = fData[0].GetDataSet(0, false); // i.e. the false means, that i is the index and NOT the histo number cout << endl << "% # of bins : " << static_cast(dataSet->GetData()->size()/fAny2ManyInfo->rebin); cout << endl << "%*************************************************************************"; // write data UInt_t length = fData[0].GetDataSet(0,false)->GetData()->size(); if (fAny2ManyInfo->rebin == 1) { for (UInt_t i=0; i(dataSet->GetData()->at(i)); } } } else { PUIntVector dataRebin(fData[0].GetNoOfHistos()); // initialize the dataRebin vector for (UInt_t i=0; i(dataSet->GetData()->at(0)); } for (UInt_t i=0; irebin) == 0) { cout << endl; for (UInt_t j=0; j(dataSet->GetData()->at(i)); } } else { for (UInt_t j=0; j(dataSet->GetData()->at(i)); } } } } cout << endl; if (!fAny2ManyInfo->useStandardOutput || (fAny2ManyInfo->compressionTag > 0)) { // restore old output buffer cout.rdbuf(strm_buffer); fout.close(); } return true; } //-------------------------------------------------------------------------- // StripWhitespace (private) //-------------------------------------------------------------------------- /** *

Strip white spaces from a string. The hope is that future TString * implementations of ROOT will make this routine obsolate. * * \param str string to be stripped. It will be modified directly on success. * * return: * - true at successful reading, * - otherwise false. */ Bool_t PRunDataHandler::StripWhitespace(TString &str) { Char_t *s = 0; Char_t *subs = 0; Int_t i; Int_t start; Int_t end; Int_t size; size = (Int_t)str.Length(); s = new Char_t[size+1]; if (!s) return false; for (Int_t i=0; i Check if a string consists only of white spaces, i.e. spaces and/or * ctrl-characters. * * return: * - true at successful reading, * - otherwise false. * * \param str string to be checked */ Bool_t PRunDataHandler::IsWhitespace(const Char_t *str) { UInt_t i=0; while (isblank(str[i]) || iscntrl(str[i])) { if (str[i] == 0) break; i++; } if (i == strlen(str)) return true; else return false; } //-------------------------------------------------------------------------- // ToDouble (private) //-------------------------------------------------------------------------- /** *

Convert a string to a Double_t. * * return: * - returns the converted string * - otherwise 0.0 with ok==false * * \param str string to be converted * \param ok true on success, otherwise false. */ Double_t PRunDataHandler::ToDouble(TString &str, Bool_t &ok) { Char_t *s; Double_t value; Int_t size, status; ok = true; size = (Int_t)str.Length(); s = new Char_t[size+1]; if (!s) { ok = false; return 0.0; } // copy string; stupid way but it works for (Int_t i=0; i Convert a string to an Int_t. * * return: * - returns the converted string * - otherwise 0.0 with ok==false * * \param str string to be converted * \param ok true on success, otherwise false. */ Int_t PRunDataHandler::ToInt(TString &str, Bool_t &ok) { Char_t *s; Int_t value; Int_t size, status; ok = true; size = (Int_t)str.Length(); s = new Char_t[size+1]; if (!s) { ok = false; return 0; } // copy string; stupid way but it works for (Int_t i=0; i Checks if str is in a list of data tags * * return: * - if found returns the data tag index (from the dataTags vector), * - otherwise -1 * * \param str data tag string (see description of nonMusr db-data) * \param dataTags vector of all data tags */ Int_t PRunDataHandler::GetDataTagIndex(TString &str, const PStringVector* dataTags) { Int_t result = -1; // check all the other possible data tags for (UInt_t i=0; isize(); i++) { if (!dataTags->at(i).CompareTo(str, TString::kIgnoreCase)) { result = i; break; } } return result; } //-------------------------------------------------------------------------- // GenerateOutputFileName (private) //-------------------------------------------------------------------------- /** *

Generates the output file name (any2many). It also makes sure that the * generated output file name does not coincidentally is identical to an already * existing file. * * return: * - constructed file name * - empty string * * \param fileName * \param extension if the file name to be constructed * \param ok flag which is 'true' if the file name could be constructed, 'false' otherwise */ TString PRunDataHandler::GenerateOutputFileName(const TString fileName, const TString extension, Bool_t &ok) { TString fln = fileName; ok = true; // generate output file name if needed if (!fAny2ManyInfo->useStandardOutput || (fAny2ManyInfo->compressionTag > 0)) { if (fln.Length() == 0) { ok = false; fln = GetFileName(extension, ok); if (!ok) { fln = ""; return fln; } } else { fln.Prepend(fAny2ManyInfo->outPath); } // make sure that the file name doesn't already exist as a real file if (!gSystem->AccessPathName(fln)) { // file name already exists!! Int_t count = 1; TString newFln; do { newFln = fln; newFln.Insert(newFln.Last('.'), TString::Format(".%d", count++)); } while (!gSystem->AccessPathName(newFln)); cerr << endl << ">> PRunDataHandler::GenerateOutputFileName **WARNING** needed to modify output filename to " << newFln << ","; cerr << endl << ">> due to potential conflict with already existing files." << endl << endl; fln = newFln; } // keep the file name if compression is whished fAny2ManyInfo->outPathFileName.push_back(fln); } else { fln = fAny2ManyInfo->outPath + TString("__tmp.") + extension; } return fln; } //-------------------------------------------------------------------------- // GetFileName (private) //-------------------------------------------------------------------------- /** *

Construct the file name based on the any2many request. * * return: * - constructed file name * - empty string * * \param extension if the file name to be constructed * \param ok flag which is 'true' if the file name could be constructed, 'false' otherwise */ TString PRunDataHandler::GetFileName(const TString extension, Bool_t &ok) { TString fileName = ""; ok = true; Int_t start = fRunPathName.Last('/'); Int_t end = fRunPathName.Last('.'); if (end == -1) { cerr << endl << ">> PRunDataHandler::GetFileName(): **ERROR** couldn't generate the output file name ..." << endl; ok = false; return fileName; } // cut out the filename (get rid of the extension, and the path) Char_t str1[1024], str2[1024]; strncpy(str1, fRunPathName.Data(), sizeof(str1)); for (Int_t i=0; iinFormat == fAny2ManyInfo->outFormat) { // only rebinning TString rebinStr; rebinStr += fAny2ManyInfo->rebin; fileName = fAny2ManyInfo->outPath + str2 + "_rebin" + rebinStr + extension; } else { // real conversion fileName = fAny2ManyInfo->outPath + str2 + extension; } return fileName; } //-------------------------------------------------------------------------- // FileNameFromTemplate (private) //-------------------------------------------------------------------------- /** *

Will, based on the fileNameTemplate construct a file name. The file name template has a run tag * and a year tag. The run tag has the form [rrrr], whereas the number of 'r' defines the length of * this string part. If the run number is shorter, leading zeros will be filled, e.g. [rrrrrr] and run==123 * will lead to '000123'. The same is true for the year tag [yy], except that the length must agree. * For example: fileNameTemplate = d[yyyy]/deltat_tdc_gps_[rrrr].bin, run = 123, year = 2009 will result * in 'd2009/deltat_tdc_gps_0123.bin'. * * return: * - constructed file name from template, run number, and year * - empty string * * \param template template string * \param run run number * \param year year * \param ok true if operation went smooth, otherwise false */ TString PRunDataHandler::FileNameFromTemplate(TString &fileNameTemplate, Int_t run, TString &year, Bool_t &ok) { TString result(""); TObjArray *tok=0; TObjString *ostr; TString str; // check year string if ((year.Length() != 2) && (year.Length() != 4)) { cerr << endl << ">> PRunDataHandler::FileNameFromTemplate: **ERROR** year needs to be of the format"; cerr << endl << ">> 'yy' or 'yyyy', found " << year << endl; return result; } // make a short year version 'yy' and a long year version 'yyyy' TString yearShort="", yearLong=""; if (year.Length() == 2) { yearShort = year; yearLong = "20" ; yearLong += year; } else { yearShort = year[2]; yearShort += year[3]; yearLong = year; } // tokenize template string tok = fileNameTemplate.Tokenize("[]"); if (tok == 0) { cerr << endl << ">> PRunDataHandler::FileNameFromTemplate: **ERROR** couldn't tokenize template!" << endl; return result; } if (tok->GetEntries()==1) { cerr << endl << ">> PRunDataHandler::FileNameFromTemplate: **WARNING** template without tags." << endl; } // go through the tokens and generate the result string for (Int_t i=0; iGetEntries(); i++) { ostr = (TObjString*)tok->At(i); str = ostr->GetString(); // check tokens if (!str.CompareTo("yy", TString::kExact)) { // check for 'yy' result += yearShort; } else if (!str.CompareTo("yyyy", TString::kExact)) { // check for 'yyyy' result += yearLong; } else if (str.Contains("rr")) { // check for run // make sure ONLY 'r' are present Int_t idx; for (idx=0; idxIf possible converts a inDate, into a ISO8601 standard date. * *

return: true if conversion was successfull otherwise false. * * \param inDate input date which should be converted to an ISO 8601 date. * \param iso8601Date on success the converted iso8601Date, otherwise an empty string */ bool PRunDataHandler::DateToISO8601(string inDate, string &iso8601Date) { iso8601Date = string(""); struct tm tm; // 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 if (!strptime(inDate.c_str(), "%d-%b-%y", &tm)) // failed return false; TString str(""); str.Form("%04d-%02d-%02d", 1900+tm.tm_year, tm.tm_mon, tm.tm_mday); iso8601Date = str.Data(); return true; } //-------------------------------------------------------------------------- // SplitTimeData (private) //-------------------------------------------------------------------------- /** *

splits an ISO 8601 timeDate into seperate time and data. The flag ok * shows if it was successfull. * * \param timeData ISO 8601 timeData * \param time part of timeData * \param date part of timeData * \param ok flag showing if the splitting was successfull */ void PRunDataHandler::SplitTimeDate(TString timeData, TString &time, TString &date, Bool_t &ok) { struct tm tm; memset(&tm, 0, sizeof(tm)); strptime(timeData.Data(), "%Y-%m-%d %H:%M:S", &tm); if (tm.tm_year == 0) strptime(timeData.Data(), "%Y-%m-%dT%H:%M:S", &tm); if (tm.tm_year == 0) { ok = false; return; } time = TString::Format("%02d:%02d:%02d", tm.tm_hour, tm.tm_min, tm.tm_sec); date = TString::Format("%04d-%02d-%02d", tm.tm_year+1900, tm.tm_mon, tm.tm_mday); } //-------------------------------------------------------------------------- // GetMonth (private) //-------------------------------------------------------------------------- /** *

given the month as number, convert it to a 3 character month. * If month is out of range (i.e. not between 1 and 12) a '???' will * be returned. * * \param month as number */ TString PRunDataHandler::GetMonth(Int_t month) { TString monthString = "???"; switch (month) { case 1: monthString = "JAN"; break; case 2: monthString = "FEB"; break; case 3: monthString = "MAR"; break; case 4: monthString = "APR"; break; case 5: monthString = "MAY"; break; case 6: monthString = "JUN"; break; case 7: monthString = "JUL"; break; case 8: monthString = "AUG"; break; case 9: monthString = "SEP"; break; case 10: monthString = "OCT"; break; case 11: monthString = "NOV"; break; case 12: monthString = "DEC"; break; default: break; } return monthString; } //-------------------------------------------------------------------------- // GetYear (private) //-------------------------------------------------------------------------- /** *

given the year as number, convert it to a 2 character year. * If year is out of range '??' will be returned. This routine will * break in the year 2100 or later ;-) * * \param year as number */ TString PRunDataHandler::GetYear(Int_t year) { TString yearString = "??"; Int_t yy=0; if (year < 2000) { yy = year - 1900; if (yy > 0) yearString.Form("%02d", yy); } else { yy = year - 2000; if ((yy >= 0) && (yy <= 99)) yearString.Form("%02d", yy); } return yearString; }