From 3eea73f07aaae999bd9eecedbec828dbe1985e01 Mon Sep 17 00:00:00 2001 From: Andreas Suter Date: Sun, 25 Jan 2026 08:26:43 +0100 Subject: [PATCH] stub for new NeXus file handling. Not much is working yet. --- CMakeLists.txt | 2 +- doc/musrfit_dox.cfg | 2 +- src/classes/PRunDataHandler.cpp | 23 +- src/dump_header.cpp | 3 + src/external/nexus/CMakeLists.txt | 2 +- src/external/nexus/PNeXus.cpp | 5472 +---------------------------- src/external/nexus/PNeXus.h | 604 +--- 7 files changed, 59 insertions(+), 6049 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b1bfc1a6..f06d59c4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,7 +4,7 @@ cmake_minimum_required(VERSION 3.17) # cmake: use BoostConfig.cmake instead of FindBoost cmake_policy(SET CMP0167 NEW) -project(musrfit VERSION 1.9.10 LANGUAGES C CXX) +project(musrfit VERSION 1.9.11 LANGUAGES C CXX) #--- musrfit specific options ------------------------------------------------- option(nexus "build optional NeXus support. Needed for ISIS" OFF) diff --git a/doc/musrfit_dox.cfg b/doc/musrfit_dox.cfg index 53fb4cd8..238d8417 100644 --- a/doc/musrfit_dox.cfg +++ b/doc/musrfit_dox.cfg @@ -38,7 +38,7 @@ PROJECT_NAME = musrfit # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = 1.9.10 +PROJECT_NUMBER = 1.9.11 # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a diff --git a/src/classes/PRunDataHandler.cpp b/src/classes/PRunDataHandler.cpp index afb567fe..1436a4d7 100644 --- a/src/classes/PRunDataHandler.cpp +++ b/src/classes/PRunDataHandler.cpp @@ -59,6 +59,10 @@ #include "MuSR_td_PSI_bin.h" #include "mud.h" +#ifdef PNEXUS_ENABLED +#include "PNeXus.h" +#endif + #include "PRunDataHandler.h" #define PRH_MUSR_ROOT 0 @@ -2135,13 +2139,27 @@ Bool_t PRunDataHandler::ReadNexusFile() #ifdef PNEXUS_ENABLED std::cout << std::endl << ">> PRunDataHandler::ReadNexusFile(): Will read nexus file " << fRunPathName.Data() << " ..."; + nxs::HDFType type = nxs::checkHDFType(fRunPathName.Data()); + switch (type) { + case nxs::HDFType::HDF4: + std::cout << std::endl << ">> PRunDataHandler::ReadNexusFile(): HDF4 file." << std::endl; + break; + case nxs::HDFType::HDF5: + std::cout << std::endl << ">> PRunDataHandler::ReadNexusFile(): HDF5 file." << std::endl; + break; + case nxs::HDFType::Unknown: + std::cerr << std::endl << ">> PRunDataHandler::ReadNexusFile(): Not a valid NeXus file." << std::endl; + return false; + } + +/* //as35 PDoubleVector histoData; PRawRunData runData; PRawRunDataSet dataSet; TString str; std::string sstr; Double_t dval; - bool ok; + bool ok; std::unique_ptr nxs_file = std::make_unique(fRunPathName.Data()); if (!nxs_file->IsValid()) { @@ -2475,6 +2493,7 @@ Bool_t PRunDataHandler::ReadNexusFile() } else { std::cout << std::endl << ">> PRunDataHandler::ReadNexusFile(): IDF version " << nxs_file->GetIdfVersion() << ", not implemented." << std::endl; } +*/ //as35 #else std::cout << std::endl << ">> PRunDataHandler::ReadNexusFile(): Sorry, not enabled at configuration level, i.e. --enable-NeXus when executing configure" << std::endl << std::endl; #endif @@ -4999,6 +5018,7 @@ Bool_t PRunDataHandler::WriteRootFile(TString fln) Bool_t PRunDataHandler::WriteNexusFile(TString fln) { #ifdef PNEXUS_ENABLED +/* //as35 Bool_t ok = false; fln = GenerateOutputFileName(fln, ".nxs", ok); if (!ok) @@ -5308,6 +5328,7 @@ Bool_t PRunDataHandler::WriteNexusFile(TString fln) // write file nxs->WriteFile(fln, fileType, fAny2ManyInfo->idf); +*/ //as35 #else std::cout << std::endl << ">> PRunDataHandler::WriteNexusFile(): Sorry, not enabled at configuration level, i.e. --enable-NeXus when executing configure" << std::endl << std::endl; #endif diff --git a/src/dump_header.cpp b/src/dump_header.cpp index eca6ec01..811ead70 100644 --- a/src/dump_header.cpp +++ b/src/dump_header.cpp @@ -360,6 +360,8 @@ int dump_header_root(const std::string fileName, const bool summary, const bool int dump_header_nexus(const std::string fileName, const bool counts) { #ifdef PNEXUS_ENABLED + std::cout << std::endl << "new NeXus handling not yet implemented ..." << std::endl << std::endl; +/* //as35 std::unique_ptr nxs_file = std::make_unique(fileName.c_str()); if (nxs_file->IsValid(false)) { @@ -370,6 +372,7 @@ int dump_header_nexus(const std::string fileName, const bool counts) { std::cerr << std::endl; return 1; } +*/ //as35 #else std::cout << std::endl << "NeXus not enabled, hence the header information cannot be dumped." << std::endl << std::endl; #endif diff --git a/src/external/nexus/CMakeLists.txt b/src/external/nexus/CMakeLists.txt index 592576ab..2dc2cf1f 100644 --- a/src/external/nexus/CMakeLists.txt +++ b/src/external/nexus/CMakeLists.txt @@ -7,7 +7,7 @@ set(prefix "${CMAKE_INSTALL_PREFIX}") set(exec_prefix "\$\{prefix\}") set(libdir "\$\{exec_prefix\}/lib") set(includedir "\$\{prefix\}/include") -set(PNEXUS_VERSION "0.9.0") +set(PNEXUS_VERSION "1.0.0") set(PNEXUS_LIBRARY_NAME "PNeXus") configure_file("PNeXus.pc.in" "PNeXus.pc" @ONLY) diff --git a/src/external/nexus/PNeXus.cpp b/src/external/nexus/PNeXus.cpp index c7f2897c..672170f0 100644 --- a/src/external/nexus/PNeXus.cpp +++ b/src/external/nexus/PNeXus.cpp @@ -27,5468 +27,44 @@ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ -#include -#include -#include -#include - #include -#include +#include +#include #include "PNeXus.h" -#ifndef SIZE_FLOAT32 -# define SIZE_FLOAT32 4 -# define SIZE_FLOAT64 8 -# define SIZE_INT8 1 -# define SIZE_UINT8 1 -# define SIZE_INT16 2 -# define SIZE_UINT16 2 -# define SIZE_INT32 4 -# define SIZE_UINT32 4 -# define SIZE_INT64 8 -# define SIZE_UINT64 8 -# define SIZE_CHAR8 1 -# define SIZE_CHAR 1 -# define SIZE_UCHAR8 1 -# define SIZE_UCHAR 1 -# define SIZE_CHAR16 2 -# define SIZE_UCHAR16 2 -#endif /* SIZE_FLOAT32 */ +nxs::HDFType nxs::checkHDFType(const std::string& filename) { -//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - -//------------------------------------------------------------------------------------------ -// PNeXusProp Constructor -//------------------------------------------------------------------------------------------ -/** - *

- */ -PNeXusProp::PNeXusProp() -{ - fName = "n/a"; - fUnit = "n/a"; - fValue = 1.0e99; -} - -//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - -//------------------------------------------------------------------------------------------ -// IsValid (public) -//------------------------------------------------------------------------------------------ -/** - *

Validates the NXbeam data. - * - * \param strict flag if true a strict NeXus validation is performed. - */ -bool PNeXusBeam1::IsValid(bool strict) -{ - bool valid = true; - - if (fTotalCounts == 0) { - std::cerr << ">> **WARNING** NXbeam total_counts not given" << std::endl; - } else if (!fUnits.compare("n/a")) { - std::cerr << ">> **WARNING** NXbeam total_counts units not given" << std::endl; - } - - return valid; -} - -//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - -//------------------------------------------------------------------------------------------ -// IsValid (public) -//------------------------------------------------------------------------------------------ -/** - *

Validates the NXdetector data. - * - * \param strict flag if true a strict NeXus validation is performed. - */ -bool PNeXusDetector1::IsValid(bool strict) -{ - bool valid = true; - - if (fNumber == 0) { - std::cerr << ">> **WARNING** NXdetector number of detectors not given" << std::endl; - } - - return valid; -} - -//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - -//------------------------------------------------------------------------------------------ -// IsValid (public) -//------------------------------------------------------------------------------------------ -/** - *

Validates the NXinstrument data. - * - * \param strict flag if true a strict NeXus validation is performed. - */ -bool PNeXusInstrument1::IsValid(bool strict) -{ - bool valid = true; - - if (!fName.compare("n/a")) { - std::cerr << ">> **ERROR** NXinstrument name not given" << std::endl; - valid = false; - } else if (!fDetector.IsValid(strict)) { - valid = false; - } else if (!fCollimator.IsValid(strict)) { - valid = false; - } else if (!fBeam.IsValid(strict)) { - valid = false; - } - - return valid; -} - -//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - -//------------------------------------------------------------------------------------------ -// PNeXusSample1 Constructor -//------------------------------------------------------------------------------------------ -/** - *

- */ -PNeXusSample1::PNeXusSample1() -{ - fName = "n/a"; - fShape = "n/a"; - fMagneticFieldState = "n/a"; - fEnvironment = "n/a"; - fMagneticFieldVectorAvailable = -1; - fMagneticFieldVectorUnits = "n/a"; - fMagneticFieldVectorCoordinateSystem = "n/a"; -} - -//------------------------------------------------------------------------------------------ -// PNeXusSample1 Destructor -//------------------------------------------------------------------------------------------ -/** - *

- */ -PNeXusSample1::~PNeXusSample1() -{ - fPhysProp.clear(); - fMagneticFieldVector.clear(); -} - -//------------------------------------------------------------------------------------------ -// IsValid (public) -//------------------------------------------------------------------------------------------ -/** - *

Validates the NXsample data. - * - * \param strict flag if true a strict NeXus validation is performed. - */ -bool PNeXusSample1::IsValid(bool strict) -{ - bool valid = true; - - if (!fName.compare("n/a")) { - std::cerr << ">> **ERROR** NXsample name not given." << std::endl; - valid = false; - } else if (!fShape.compare("n/a")) { - std::cerr << ">> **WARNING** NXsample shape not given." << std::endl; - } - - int count=0; // at the end count holds the number of required physiscal properties. Currently these are: temperature, magnetic_field - for (unsigned int i=0; i> **ERROR** NXsample temperature unit not given." << std::endl; - valid = false; - } - if (fPhysProp[i].GetValue() == 1.0e99) { - std::cerr << ">> **ERROR** NXsample temperature value not given." << std::endl; - valid = false; - } - } - if (!fPhysProp[i].GetName().compare("magnetic_field")) { - count++; - if (!fPhysProp[i].GetUnit().compare("n/a")) { - std::cerr << ">> **ERROR** NXsample magnetic_field unit not given." << std::endl; - valid = false; - } - if (fPhysProp[i].GetValue() == 1.0e99) { - std::cerr << ">> **ERROR** NXsample magnetic_field value not given." << std::endl; - valid = false; - } - } - } - if (count < 2) { - std::cerr << ">> **ERROR** not all required physical properties (e.g. temperature, magnetic_field) are given." << std::endl; - valid = false; - } - - return valid; -} - -//------------------------------------------------------------------------------------------ -// GetPhysPropValue (public) -//------------------------------------------------------------------------------------------ -/** - *

- * - * \param name - * \param ok - */ -double PNeXusSample1::GetPhysPropValue(std::string name, bool &ok) -{ - double dval=0.0; - ok = false; - - for (unsigned int i=0; i - * - * \param name - * \param ok - */ -void PNeXusSample1::GetPhysPropUnit(std::string name, std::string &unit, bool &ok) -{ - unit = "n/a"; - ok = false; - - for (unsigned int i=0; iSet the physical property with 'name' and 'value' at index 'idx'. If idx==-1 add it at the - * end, otherwise set it at index idx. - * - * \param name of the physical property - * \param value of the physical property - * \param idx index where to set the physical property - */ -void PNeXusSample1::SetPhysProp(std::string name, double value, std::string unit, int idx) -{ - PNeXusProp prop; - - prop.SetName(name); - prop.SetValue(value); - prop.SetUnit(unit); - - if (idx == -1) { - fPhysProp.push_back(prop); - } else if (idx >= (int)fPhysProp.size()) { - fPhysProp.resize(idx+1); - fPhysProp[idx] = prop; - } else { - fPhysProp[idx] = prop; - } -} - -//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - -//------------------------------------------------------------------------------------------ -// PNeXusUser1 Constructor -//------------------------------------------------------------------------------------------ -/** - *

- */ -PNeXusUser1::PNeXusUser1() -{ - fName = "n/a"; - fExperimentNumber = "n/a"; -} - -//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - -//------------------------------------------------------------------------------------------ -// PNeXusEntry1 Constructor -//------------------------------------------------------------------------------------------ -/** - *

- */ -PNeXusEntry1::PNeXusEntry1() -{ - fProgramName = "n/a"; - fProgramVersion = "n/a"; - fRunNumber = -1; - fTitle = "n/a"; - fNotes = "n/a"; - fAnalysis = "n/a"; - fLaboratory = "n/a"; - fBeamline = "n/a"; - fStartTime = "n/a"; - fStopTime = "n/a"; - fSwitchingState = -1; -} - -//------------------------------------------------------------------------------------------ -// IsValid (public) -//------------------------------------------------------------------------------------------ -/** - *

Validates the NXentry data. - * - * \param strict flag if true a strict NeXus validation is performed. - */ -bool PNeXusEntry1::IsValid(bool strict) -{ - if (!fProgramName.compare("n/a")) { - std::cerr << ">> **WARNING** NXentry: program_name not given." << std::endl; - } else if (!fProgramVersion.compare("n/a")) { - std::cerr << ">> **WARNING** NXentry: program_name/version not given." << std::endl; - } else if (fRunNumber == -1) { - std::cerr << ">> **ERROR** NXentry: number (i.e. run number) not given." << std::endl; - return false; - } else if (!fTitle.compare("n/a")) { - std::cerr << ">> **ERROR** NXentry: title not given." << std::endl; - return false; - } else if (!fNotes.compare("n/a")) { - std::cerr << ">> **WARNING** NXentry: notes not given." << std::endl; - } else if (!fAnalysis.compare("n/a")) { - std::cerr << ">> **ERROR** NXentry: analysis (i.e. type of muon experiment like 'TF', 'ALC', ...) not given." << std::endl; - return false; - } else if (!fLaboratory.compare("n/a")) { - std::cerr << ">> **ERROR** NXentry: lab (e.g. 'PSI') not given." << std::endl; - return false; - } else if (!fBeamline.compare("n/a")) { - std::cerr << ">> **ERROR** NXentry: beamline (e.g. 'piE3') not given." << std::endl; - return false; - } else if (!fStartTime.compare("n/a")) { - std::cerr << ">> **ERROR** NXentry: start_time not given." << std::endl; - return false; - } else if (!fStopTime.compare("n/a")) { - std::cerr << ">> **ERROR** NXentry: stop_time not given." << std::endl; - return false; - } else if (fSwitchingState == -1) { - std::cerr << ">> **ERROR** NXentry: switching_state (i.e. '1' normal data taking, '2' red/green mode) not given." << std::endl; - return false; - } else if (!fUser.IsValid(strict)) { - return false; - } else if (!fSample.IsValid(strict)) { - return false; - } else if (!fInstrument.IsValid(strict)) { - return false; - } else if (!fData.IsValid(strict)) { - return false; - } - - return true; -} - -//------------------------------------------------------------------------------------------ -// SetStartTime (public) -//------------------------------------------------------------------------------------------ -/** - *

Set the start time std::string and check that it is ISO 8601 conform. - * - * \param time start time std::string - */ -int PNeXusEntry1::SetStartTime(std::string time) -{ - struct tm tm; - memset(&tm, 0, sizeof(tm)); - strptime(time.c_str(), "%Y-%m-%d %H:%M:S", &tm); - if (tm.tm_year == 0) - strptime(time.c_str(), "%Y-%m-%dT%H:%M:S", &tm); - if (tm.tm_year == 0) - return NX_ERROR; - - fStartTime = time; - - return NX_OK; -} - -//------------------------------------------------------------------------------------------ -// SetStopTime (public) -//------------------------------------------------------------------------------------------ -/** - *

Set the stop time std::string and check that it is ISO 8601 conform. - * - * \param time stop time std::string - */ -int PNeXusEntry1::SetStopTime(std::string time) -{ - struct tm tm; - memset(&tm, 0, sizeof(tm)); - strptime(time.c_str(), "%Y-%m-%d %H:%M:S", &tm); - if (tm.tm_year == 0) - strptime(time.c_str(), "%Y-%m-%dT%H:%M:S", &tm); - if (tm.tm_year == 0) - return NX_ERROR; - - fStopTime = time; - - return NX_OK; -} - -//------------------------------------------------------------------------------------------ -// SetSwitchingState (public) -//------------------------------------------------------------------------------------------ -/** - *

Set the switching state tag. '1' normal data collection, '2' Red/Green mode - * - * \param state switching state tag - */ -int PNeXusEntry1::SetSwitchingState(int state) -{ - if ((state != 1) && (state != 2)) - return NX_ERROR; - - fSwitchingState = state; - - return NX_OK; -} - -//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - -//------------------------------------------------------------------------------------------ -// PNeXusAlpha1 Constructor -//------------------------------------------------------------------------------------------ -/** - *

- */ -PNeXusAlpha1::PNeXusAlpha1() -{ - fGroupFirst=0; - fGroupSecond=0; - fAlphaVal=0.0; -} - -//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - -//------------------------------------------------------------------------------------------ -// PNeXusData1 Destructor -//------------------------------------------------------------------------------------------ -/** - *

- */ -PNeXusData1::~PNeXusData1() -{ - fT0.clear(); - fFirstGoodBin.clear(); - fLastGoodBin.clear(); - fHistoName.clear(); - for (unsigned int i=0; iValidates the NXbeam data. - * - * \param strict flag if true a strict NeXus validation is performed. - */ -bool PNeXusData1::IsValid(bool strict) -{ - if (GetNoOfHistos() == 0) { - std::cerr << ">> **ERROR** NXdata no histograms given." << std::endl; - return false; - } else if (fTimeResolution == 0.0) { - std::cerr << ">> **ERROR** NXdata time resolution not given." << std::endl; - return false; - } else if (fT0.size() == 0) { - std::cerr << ">> **WARNING** NXdata t0 not given." << std::endl; - } else if (fFirstGoodBin.size() == 0) { - std::cerr << ">> **WARNING** NXdata first good bin not given." << std::endl; - } else if (fLastGoodBin.size() == 0) { - std::cerr << ">> **WARNING** NXdata last good bin not given." << std::endl; - } - - return true; -} - - -//------------------------------------------------------------------------------------------ -// GetTimeResolution (public) -//------------------------------------------------------------------------------------------ -/** - *

Get time resolution in the requested units. Allowed units are 'fs', 'ps', 'ns', 'us'. - * If unsupported time units are given, a time resolution == 0.0 is returned. Internally the - * time resolution is stored in 'ps'. - * - * \param units requested units for the time resolution. - */ -double PNeXusData1::GetTimeResolution(std::string units) -{ - double result=0.0; - - if (!units.compare("fs")) - result = fTimeResolution * 1.0e3; - else if (!units.compare("ps")) - result = fTimeResolution; - else if (!units.compare("ns")) - result = fTimeResolution * 1.0e-3; - else if (!units.compare("us")) - result = fTimeResolution * 1.0e-6; - else - result = 0.0; - - return result; -} - -//------------------------------------------------------------------------------------------ -// GetT0 (public) -//------------------------------------------------------------------------------------------ -/** - *

Returns the t0 at index 'idx' or -1 if the index is out of range. - * - * \param idx index of the requested t0 - */ -int PNeXusData1::GetT0(unsigned int idx) -{ - if (idx >= fT0.size()) - return -1; - - return (int)fT0[idx]; -} - -//------------------------------------------------------------------------------------------ -// GetFirstGoodBin (public) -//------------------------------------------------------------------------------------------ -/** - *

Returns the first good bin at index 'idx' or -1 if the index is out of range. - * - * \param idx index of the requested first good bin - */ -int PNeXusData1::GetFirstGoodBin(unsigned int idx) -{ - if (idx >= fFirstGoodBin.size()) - return -1; - - return (int)fFirstGoodBin[idx]; -} - -//------------------------------------------------------------------------------------------ -// GetLastGoodBin (public) -//------------------------------------------------------------------------------------------ -/** - *

Returns the last good bin at index 'idx' or -1 if the index is out of range. - * - * \param idx index of the requested last good bin - */ -int PNeXusData1::GetLastGoodBin(unsigned int idx) -{ - if (idx >= fLastGoodBin.size()) - return -1; - - return (int)fLastGoodBin[idx]; -} - - -//------------------------------------------------------------------------------------------ -// GetHistoName (public) -//------------------------------------------------------------------------------------------ -/** - *

Extract the histogram name at position 'idx'. If 'idx' is out of range, the 'ok' flag - * is set to 'false' in which case the 'name' is undefined. - * - * \param idx index of the requested histogram name. - * \param name histogram name if idx is within range - * \param ok =true if idx was within range, otherwise false - */ -void PNeXusData1::GetHistoName(unsigned int idx, std::string &name, bool &ok) -{ - if (idx >= fHistoName.size()) { - ok = false; - } else { - ok = true; - name = fHistoName[idx]; - } -} - -//------------------------------------------------------------------------------------------ -// GetHistoLength (public) -//------------------------------------------------------------------------------------------ -/** - *

Returns the length of histogram histoNo, or 0 if histoNo is out of bound. - * - * \param histoNo index of the histogram for which the size needs to be determined. - */ -unsigned int PNeXusData1::GetHistoLength(unsigned int histoNo) -{ - if (histoNo >= fHisto.size()) - return 0; - - return fHisto[histoNo].size(); -} - -//------------------------------------------------------------------------------------------ -// GetHistoLength (public) -//------------------------------------------------------------------------------------------ -unsigned int PNeXusData1::GetHistoCounts(unsigned int histoNo) -{ - if (histoNo >= fHisto.size()) - return 0; - - unsigned int counts=0; - for (unsigned int i=0; iReturns the histogram with index 'histoNo' or 0 if 'histoNo' is out of range. - * - * \param histoNo index of the requested histogram - */ -std::vector *PNeXusData1::GetHisto(unsigned int histoNo) -{ - if (histoNo >= fHisto.size()) - return 0; - - return &fHisto[histoNo]; -} - - -//------------------------------------------------------------------------------------------ -// SetTimeResolution (public) -//------------------------------------------------------------------------------------------ -/** - *

Set the time resolution. 'units' tells in which units 'val' is provided. Acteptable units - * are 'fs', 'ps', 'ns', 'us'. - * - * \param val time resolution value - * \param units time resolution units - */ -void PNeXusData1::SetTimeResolution(double val, std::string units) -{ - if (!units.compare("fs")) - fTimeResolution = val * 1.0e-3; - else if (!units.compare("ps")) - fTimeResolution = val; - else if (!units.compare("ns")) - fTimeResolution = val * 1.0e3; - else if (!units.compare("us")) - fTimeResolution = val * 1.0e6; -} - -//------------------------------------------------------------------------------------------ -// SetT0 (public) -//------------------------------------------------------------------------------------------ -/** - *

Set the t0 value at index 'idx'. If 'idx'==-1, the t0 value will be appended - * - * \param t0 bin value - * \param idx index where to set t0 bin value - */ -void PNeXusData1::SetT0(unsigned int t0, int idx) -{ - if (idx == -1) { - fT0.push_back(t0); - } else if (idx >= (int)fT0.size()) { - fT0.resize(idx+1); - fT0[idx] = t0; - } else { - fT0[idx] = t0; - } -} - -//------------------------------------------------------------------------------------------ -// SetFirstGoodBin (public) -//------------------------------------------------------------------------------------------ -/** - *

Set the first good bin value at index 'idx'. If 'idx'==-1, the first good bin value will be appended - * - * \param fgb first good bin value - * \param idx index where to set first good bin value - */ -void PNeXusData1::SetFirstGoodBin(unsigned int fgb, int idx) -{ - if (idx == -1) { - fFirstGoodBin.push_back(fgb); - } else if (idx >= (int)fFirstGoodBin.size()) { - fFirstGoodBin.resize(idx+1); - fFirstGoodBin[idx] = fgb; - } else { - fFirstGoodBin[idx] = fgb; - } -} - -//------------------------------------------------------------------------------------------ -// SetLastGoodBin (public) -//------------------------------------------------------------------------------------------ -/** - *

Set the last good bin value at index 'idx'. If 'idx'==-1, the last good bin value will be appended - * - * \param lgb last good bin value - * \param idx index where to set last good bin value - */ -void PNeXusData1::SetLastGoodBin(unsigned int lgb, int idx) -{ - if (idx == -1) { - fLastGoodBin.push_back(lgb); - } else if (idx >= (int)fLastGoodBin.size()) { - fLastGoodBin.resize(idx+1); - fLastGoodBin[idx] = lgb; - } else { - fLastGoodBin[idx] = lgb; - } -} - -//------------------------------------------------------------------------------------------ -// FlushHistos (public) -//------------------------------------------------------------------------------------------ -/** - *

Flushes all previously allocated histograms. - * - */ -void PNeXusData1::FlushHistos() -{ - for (unsigned int i=0; iSet a histogram at index 'histoNo'. If 'histoNo'==-1, the histogram will be appended - * - * \param data histogram vector - * \param histoNo index where to set the histogram - */ -void PNeXusData1::SetHisto(std::vector &data, int histoNo) -{ - if (histoNo == -1) { - fHisto.push_back(data); - } else if (histoNo >= (int)fHisto.size()) { - fHisto.resize(histoNo+1); - fHisto[histoNo] = data; - } else { - fHisto[histoNo] = data; - } -} - -//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - -//------------------------------------------------------------------------------------------ -// IsValid (public) -//------------------------------------------------------------------------------------------ -/** - *

Validates the NXbeamline data. - * - * \param strict flag if true a strict NeXus validation is performed. - */ -bool PNeXusBeamline2::IsValid(bool strict) -{ - std::string msg(""); - - if (!fName.compare("n/a")) { - msg = "IDF2 NXbeamline 'name' not set."; - if (strict) { - std::cerr << ">> **ERROR** " << msg << std::endl; - return false; - } else { - std::cerr << ">> **WARNING** " << msg << std::endl; - } - } - - return true; -} - -//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - -//------------------------------------------------------------------------------------------ -// PNeXusDetector2 Constructor -//------------------------------------------------------------------------------------------ -/** - *

- */ -PNeXusDetector2::PNeXusDetector2() -{ - fErrorMsg = ""; - - fDescription = "n/a"; - fTimeResolution = 0; - fNoOfPeriods = -1; - fNoOfSpectra = -1; - fNoOfBins = -1; - - fT0Tag = -1; - fT0 = nullptr; - fFirstGoodBin = nullptr; - fLastGoodBin = nullptr; - fHisto = nullptr; -} - -//------------------------------------------------------------------------------------------ -// PNeXusDetector2 Destructor -//------------------------------------------------------------------------------------------ -/** - *

- */ -PNeXusDetector2::~PNeXusDetector2() -{ - fSpectrumIndex.clear(); - fRawTime.clear(); - - if (fT0) { - delete [] fT0; - fT0 = nullptr; - } - if (fFirstGoodBin) { - delete [] fFirstGoodBin; - fFirstGoodBin = nullptr; - } - if (fLastGoodBin) { - delete [] fLastGoodBin; - fLastGoodBin = nullptr; - } - if (fHisto) { - delete [] fHisto; - fHisto = nullptr; - } -} - -//------------------------------------------------------------------------------------------ -// IsValid (public) -//------------------------------------------------------------------------------------------ -/** - *

Validates the NXdetector data. - * - * \param strict flag if true a strict NeXus validation is performed. - */ -bool PNeXusDetector2::IsValid(bool strict) -{ - std::string msg(""); - - if (!fDescription.compare("n/a")) { - msg = "IDF2 NXdetector 'description' not set."; - if (strict) { - std::cerr << ">> **ERROR** " << msg << std::endl; - return false; - } else { - std::cerr << ">> **WARNING** " << msg << std::endl; - } - } - - if (fTimeResolution == 0.0) { - std::cerr << ">> **ERROR** IDF2 NXdetector 'histogram_resolution' is not set." << std::endl; - return false; - } - - if (fSpectrumIndex.size() == 0) { - std::cerr << ">> **ERROR** IDF2 NXdetector 'spectrum_index' is not set." << std::endl; - return false; - } - - if ((fT0Tag != 1) && (fT0Tag !=2)) { - std::cerr << ">> **ERROR** IDF2 NXdetector problem with t0/first_good_bin/last_good_bin/counts settings (tagging)." << std::endl; - return false; - } - - if (fT0 == 0) { - std::cerr << ">> **ERROR** IDF2 NXdetector t0 settings pointer is null." << std::endl; - return false; - } - - if (fHisto == 0) { - std::cerr << ">> **ERROR** IDF2 NXdetector counts settings pointer is null." << std::endl; - return false; - } - - if (fNoOfBins == -1) { - std::cerr << ">> **ERROR** IDF2 NXdetector fNoOfBins==-1." << std::endl; - return false; - } - - return true; -} - -//------------------------------------------------------------------------------------------ -// GetT0 (public) -//------------------------------------------------------------------------------------------ -/** - *

Get T0 bin if present, otherwise return -1. - * - * \param idxp period index - * \param idxs spectrum index - */ -int PNeXusDetector2::GetT0(int idxp, int idxs) -{ - int result = -1; - - if (fT0Tag == 1) { // there is only ONE t0 present - if (fT0 != nullptr) - result = *fT0; - return result; - } - - if ((idxp < 0) && (idxs < 0)) { // assumption: there is only ONE t0 for all spectra - if (fT0 != nullptr) { - result = *fT0; - } - } else if ((idxp < 0) && (idxs >= 0)) { // assumption: t0's are represented as t0[ns] - if (idxs < fNoOfSpectra) { - result = *(fT0+idxs); - } - } else if ((idxp >= 0) && (idxs >= 0)) { // assumption: t0's are represented as t0[np][ns] - if ((idxp < fNoOfPeriods) || (idxs < fNoOfSpectra)) { - result = *(fT0+idxp*fNoOfSpectra+idxs); - } - } else { - result = -1; - } - - return result; -} - -//------------------------------------------------------------------------------------------ -// SetT0 (public) -//------------------------------------------------------------------------------------------ -/** - *

Set T0s. - * - *

return: - * -1 of everything is OK, - * -0 if there was an error, in which case GetErrorMsg() will give the internal error message. - * - * \param t0 pointer to t0's. - */ -int PNeXusDetector2::SetT0(int *t0) -{ - if (t0 == 0) { - fErrorMsg = "PNeXusDetector2::SetT0(int *t0): t0 pointer is null."; - return 0; - } - - int result = 1; - unsigned int size=0; - std::stringstream ss; - - switch (fT0Tag) { - case -1: - ss << "PNeXusDetector2::SetT0(int *t0): unkown fT0tag: " << fT0Tag << "!"; - fErrorMsg = ss.str(); - result = 0; - break; - case 1: // just one single t0 - size = 1; - break; - case 2: // t0[#histos] - if (fNoOfSpectra <= 0) { - fErrorMsg = "PNeXusDetector2::SetT0(int *t0): ask for t0 vector (ns), but ns <= 0!"; - result = 0; - } else { - size = fNoOfSpectra; - } - break; - case 3: // t0[np][#histos] - if ((fNoOfPeriods <= 0) || (fNoOfSpectra <= 0)) { - fErrorMsg = "PNeXusDetector2::SetT0(int *t0): ask for t0 vector (np, ns), but either np or ns <= 0!"; - result = 0; - } else { - size = fNoOfPeriods * fNoOfSpectra; - } - break; - default: - ss << "PNeXusDetector2::SetT0(int *t0): unkown fT0tag: " << fT0Tag << "!"; - fErrorMsg = ss.str(); - result = 0; - break; - } - - // check for error - if (!result) - return result; - - // make sure fT0 memory is cleaned up before filled - if (fT0) { - delete [] fT0; - fT0 = 0; - } - - // allocate memory - fT0 = new int[size]; - if (fT0 == 0) { - fErrorMsg = "PNeXusDetector2::SetT0(int *t0): couldn't allocate necessary memory."; - result = 0; - } else { - for (unsigned int i=0; iGet first good bin if present, otherwise return -1. - * - * \param idxp period index - * \param idxs spectrum index - */ -int PNeXusDetector2::GetFirstGoodBin(int idxp, int idxs) -{ - int result = -1; - - if (fT0Tag == 1) { // there is only ONE t0 present - if (fT0 != nullptr) - result = *fFirstGoodBin; - return result; - } - - if ((idxp < 0) && (idxs < 0)) { // assumption: there is only ONE t0 for all spectra - if (fFirstGoodBin != nullptr) { - result = *fFirstGoodBin; - } - } else if ((idxp < 0) && (idxs >= 0)) { // assumptions: fgb's are represented as fgb[ns] - if ((idxs < fNoOfSpectra) && (fFirstGoodBin != nullptr)) { - result = *(fFirstGoodBin+idxs); - } - } else if ((idxp >= 0) && (idxs >= 0)) { // assumption: fgb's are represented as fgb[np][ns] - if ((idxp < fNoOfPeriods) || (idxs < fNoOfSpectra)) { - if (fFirstGoodBin != nullptr) - result = *(fFirstGoodBin+idxp*fNoOfSpectra+idxs); - } - } else { - result = -1; - } - - return result; -} - -//------------------------------------------------------------------------------------------ -// SetFirstGoodBin (public) -//------------------------------------------------------------------------------------------ -/** - *

Set first good bins. - * - *

return: - * -1 of everything is OK, - * -0 if there was an error, in which case GetErrorMsg() will give the internal error message. - * - * \param fgb is the pointer to the first good bin array. - */ -int PNeXusDetector2::SetFirstGoodBin(int *fgb) -{ - if (fgb == 0) { - fErrorMsg = "PNeXusDetector2::SetFirstGoodBin(int *fgb): fgb pointer is null."; - return 0; - } - - int result = 1; - unsigned int size=0; - std::stringstream ss; - - switch (fT0Tag) { - case -1: - ss << "PNeXusDetector2::SetFirstGoodBin(int *fgb): unkown fT0tag: " << fT0Tag << "!"; - fErrorMsg = ss.str(); - result = 0; - break; - case 1: // single fgb - size = 1; - break; - case 2: // fgb[#histos] - if (fNoOfSpectra <= 0) { - fErrorMsg = "PNeXusDetector2::SetFirstGoodBin(int *fgb): ask for fgb vector (ns), but ns <= 0!"; - result = 0; - } else { - size = fNoOfSpectra; - } - break; - case 3: // fgb[np][#histos] - if ((fNoOfPeriods <= 0) || (fNoOfSpectra <= 0)) { - fErrorMsg = "PNeXusDetector2::SetFirstGoodBin(int *fgb): ask for fgb vector (np, ns), but either np or ns <= 0!"; - result = 0; - } else { - size = fNoOfPeriods * fNoOfSpectra; - } - break; - default: - ss << "PNeXusDetector2::SetFirstGoodBin(int *fgb): unkown fT0tag: " << fT0Tag << "!"; - fErrorMsg = ss.str(); - result = 0; - break; - } - - // check for error - if (!result) - return result; - - // make sure fFirstGoodBin memory is cleaned up before filled - if (fFirstGoodBin) { - delete [] fFirstGoodBin; - fFirstGoodBin = 0; - } - - // allocate memory - fFirstGoodBin = new int[size]; - if (fFirstGoodBin == 0) { - fErrorMsg = "PNeXusDetector2::SetFirstGoodBin(int *fgb): couldn't allocate necessary memory."; - result = 0; - } else { - for (unsigned int i=0; iGet last good bin if present, otherwise return -1. - * - * \param idxp period index - * \param idxs spectrum index - */ -int PNeXusDetector2::GetLastGoodBin(int idxp, int idxs) -{ - int result = -1; - - if (fT0Tag == 1) { // there is only ONE t0 present - if (fT0 != nullptr) - result = *fLastGoodBin; - return result; - } - - if ((idxp < 0) && (idxs < 0)) { // assumption: there is only ONE t0 for all spectra - if (fLastGoodBin != nullptr) { - result = *fLastGoodBin; - } - } else if ((idxp < 0) && (idxs >= 0)) { // assumption: lgb's are represented as lgb[ns] - if ((idxs < fNoOfSpectra) && (fLastGoodBin != nullptr)) { - result = *(fLastGoodBin+idxs); - } - } else if ((idxp >= 0) && (idxs >= 0)) { // assumption: lgb's are represented as lgb[np][ns] - if ((idxp < fNoOfPeriods) || (idxs < fNoOfSpectra)) { - if (fLastGoodBin != nullptr) - result = *(fLastGoodBin+idxp*fNoOfSpectra+idxs); - } - } else { - result = -1; - } - - return result; -} - -//------------------------------------------------------------------------------------------ -// SetLastGoodBin (public) -//------------------------------------------------------------------------------------------ -/** - *

Set last good bins. - * - *

return: - * -1 of everything is OK, - * -0 if there was an error, in which case GetErrorMsg() will give the internal error message. - * - * \param lgb is the pointer to the first good bin array. - */ -int PNeXusDetector2::SetLastGoodBin(int *lgb) -{ - if (lgb == 0) { - fErrorMsg = "PNeXusDetector2::SetLastGoodBin(int *lgb): fgb pointer is null."; - return 0; - } - - int result = 1; - unsigned int size=0; - std::stringstream ss; - - switch (fT0Tag) { - case -1: - ss << "PNeXusDetector2::SetLastGoodBin(int *lgb): unkown fT0tag: " << fT0Tag << "!"; - fErrorMsg = ss.str(); - result = 0; - break; - case 1: // single lgb only - size = 1; - break; - case 2: // lgb[#histos] - if (fNoOfSpectra <= 0) { - fErrorMsg = "PNeXusDetector2::SetLastGoodBin(int *lgb): ask for lgb vector (ns), but ns <= 0!"; - result = 0; - } else { - size = fNoOfSpectra; - } - break; - case 3: // lgb[np][#histos] - if ((fNoOfPeriods <= 0) || (fNoOfSpectra <= 0)) { - fErrorMsg = "PNeXusDetector2::SetLastGoodBin(int *lgb): ask for lgb vector (np, ns), but either np or ns <= 0!"; - result = 0; - } else { - size = fNoOfPeriods * fNoOfSpectra; - } - break; - default: - ss << "PNeXusDetector2::SetLastGoodBin(int *lgb): unkown fT0tag: " << fT0Tag << "!"; - fErrorMsg = ss.str(); - result = 0; - break; - } - - // check for error - if (!result) - return result; - - // make sure fLastGoodBin memory is cleaned up before filled - if (fLastGoodBin) { - delete [] fLastGoodBin; - fLastGoodBin = 0; - } - - // allocate memory - fLastGoodBin = new int[size]; - if (fLastGoodBin == 0) { - fErrorMsg = "PNeXusDetector2::SetLastGoodBin(int *lgb): couldn't allocate necessary memory."; - result = 0; - } else { - for (unsigned int i=0; iGet number of counts in a given histogram histoNo - * - * \param idx_p period index - * \param idx_s spectrum index - * - * \return the number of entries in the selected histogram histoNo, or 0 if the histoNo is out of scope. - */ -unsigned int PNeXusDetector2::GetHistoCounts(int idx_p, int idx_s) -{ - unsigned counts = 0; - - if (idx_p > 0) - if (idx_p > fNoOfPeriods) - return counts; - - if (idx_s > 0) - if (idx_s > fNoOfSpectra) - return counts; - - for (int i=0; iGet histogram value. If any of the indices is out of range, -1 is returned. Since the - * histogram can have the structures: histo[][][], histo[][], or histo[] - * - * \param idx_p period index - * \param idx_s spectrum index - * \param idx_b histogram bin index - */ -int PNeXusDetector2::GetHistoValue(int idx_p, int idx_s, int idx_b) -{ - int value = -1; - - if ((idx_b < 0) || (idx_b >= fNoOfBins)) { // make sure that idx_b is within proper bounds - return -1; - } - - if (fNoOfSpectra > 0) { // make sure that idx_s is within proper bounds if there are different spectra - if ((idx_s < 0) || (idx_s >= fNoOfSpectra)) { - return -1; - } - } - - if (fNoOfPeriods > 0) { // make sure that idx_p is within proper bounds if there are different periods - if ((idx_p < 0) || (idx_p >= fNoOfPeriods)) { - return -1; - } - } - - if (fNoOfPeriods > 0) { - value = *(fHisto+idx_p*fNoOfSpectra*fNoOfBins+idx_s*fNoOfBins+idx_b); - } else { - if (fNoOfSpectra > 0) { - value = *(fHisto+idx_s*fNoOfBins+idx_b); - } else { - value = *(fHisto+idx_b); - } - } - - return value; -} - -//------------------------------------------------------------------------------------------ -// SetHistos (public) -//------------------------------------------------------------------------------------------ -/** - *

Set values of all histograms. - * - *

return: - * - 1 if everything is OK. - * - 0 something is wrong, check the internal error message via GetErrorMsg(). - * - * \param histo pointer to the data. - */ -int PNeXusDetector2::SetHistos(int *histo) -{ - // make sure that histos are cleaned up before filled - if (fHisto) { - delete [] fHisto; - fHisto = 0; - } - - // check needed size and its consistency - unsigned int size = 0; - if (fNoOfPeriods > 0) { // (np, ns, nb) - if ((fNoOfSpectra <= 0) || (fNoOfBins <= 0)) { // error - fErrorMsg = "PNeXusDetector2::SetHistos(int *histo): claims format (np, ns, nb), but ns or nb < 0."; - return 0; - } - size = fNoOfPeriods * fNoOfSpectra * fNoOfBins; - } else { // (ns, nb) or (nb) - if (fNoOfSpectra > 0) { // (ns, nb) - if (fNoOfBins <= 0) { // error - fErrorMsg = "PNeXusDetector2::SetHistos(int *histo): claims format (ns, nb), but nb < 0."; - return 0; - } - size = fNoOfSpectra * fNoOfBins; - } else { // (nb) - if (fNoOfBins <= 0) { - fErrorMsg = "PNeXusDetector2::SetHistos(int *histo): claims format (nb), but nb < 0."; - return 0; - } - size = fNoOfBins; - } - } - - // allocate memory for fHisto - fHisto = new int[size]; - if (fHisto == 0) { - fErrorMsg = "PNeXusDetector2::SetHistos(int *histo): couldn't allocate necessary memory for fHisto."; - return 0; - } - - for (unsigned int i=0; iGet time resolution in the requested units. Allowed units are 'fs', 'ps', 'ns', 'us'. - * If unsupported time units are given, a time resolution == 0.0 is returned. Internally the - * time resolution is stored in 'ps'. - * - * \param units requested units for the time resolution. - */ -double PNeXusDetector2::GetTimeResolution(std::string units) -{ - double result=0.0; - - if (!units.compare("fs") || !units.compare("femto.second") || !units.compare("femto second") || !units.compare("femtoseconds")) - result = fTimeResolution * 1.0e3; - else if (!units.compare("ps") || !units.compare("pico.second") || !units.compare("pico second") || !units.compare("picoseconds")) - result = fTimeResolution; - else if (!units.compare("ns") || !units.compare("nano.second") || !units.compare("nano second") || !units.compare("nanoseconds")) - result = fTimeResolution * 1.0e-3; - else if (!units.compare("us") || !units.compare("micro.second") || !units.compare("micro second") || !units.compare("microseconds")) - result = fTimeResolution * 1.0e-6; - else - result = 0.0; - - return result; -} - -//------------------------------------------------------------------------------------------ -// SetTimeResolution (public) -//------------------------------------------------------------------------------------------ -/** - *

Set the time resolution. 'units' tells in which units 'val' is provided. Acteptable units - * are 'fs', 'ps', 'ns', 'us'. - * - * \param val time resolution value - * \param units time resolution units - */ -void PNeXusDetector2::SetTimeResolution(double val, std::string units) -{ - if (!units.compare("fs") || !units.compare("femto.second") || !units.compare("femto second") || !units.compare("femtoseconds")) - fTimeResolution = val * 1.0e-3; - else if (!units.compare("ps") || !units.compare("pico.second") || !units.compare("pico second") || !units.compare("picoseconds")) - fTimeResolution = val; - else if (!units.compare("ns") || !units.compare("nano.second") || !units.compare("nano second") || !units.compare("nanoseconds")) - fTimeResolution = val * 1.0e3; - else if (!units.compare("us") || !units.compare("micro.second") || !units.compare("micro second") || !units.compare("microseconds")) - fTimeResolution = val * 1.0e6; -} - -//------------------------------------------------------------------------------------------ -// SetRawTime (public) -//------------------------------------------------------------------------------------------ -/** - *

sets the raw time (deep copy). - * - * \param rawTime raw time vector. - */ -void PNeXusDetector2::SetRawTime(std::vector &rawTime) -{ - for (unsigned int i=0; ireturns the global spectrum index of index idx. - * - * \param idx spectrum index idx - */ -int PNeXusDetector2::GetSpectrumIndex(unsigned int idx) -{ - if (idx >= fSpectrumIndex.size()) - return -1; - - return fSpectrumIndex[idx]; -} - -//------------------------------------------------------------------------------------------ -// SetSpectrumIndex (public) -//------------------------------------------------------------------------------------------ -/** - *

set the global spectrum index of index idx. - * - * \param spectIdx spectrum index value - * \param idx spectrum index idx - */ -void PNeXusDetector2::SetSpectrumIndex(int spectIdx, int idx) -{ - if (idx < 0) { - fSpectrumIndex.push_back(spectIdx); - } else if (idx >= (int)fSpectrumIndex.size()) { - fSpectrumIndex.resize(idx+1); - fSpectrumIndex[idx] = spectIdx; - } else { - fSpectrumIndex[idx] = spectIdx; - } -} - -//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - -//------------------------------------------------------------------------------------------ -// IsValid (public) -//------------------------------------------------------------------------------------------ -/** - *

Validates the NXinstrument data. - * - * \param strict flag if true a strict NeXus validation is performed. - */ -bool PNeXusInstrument2::IsValid(bool strict) -{ - std::string msg(""); - - if (!fName.compare("n/a")) { - msg = "IDF2 NXinstrument 'name' not set."; - if (strict) { - std::cerr << ">> **ERROR** " << msg << std::endl; - return false; - } else { - std::cerr << ">> **WARNING** " << msg << std::endl; - } - } - - if (!fSource.IsValid(strict)) - return false; - - if (!fBeamline.IsValid(strict)) - return false; - - if (!fDetector.IsValid(strict)) - return false; - - return true; -} - -//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - -//------------------------------------------------------------------------------------------ -// PNeXusSource2 Constructor -//------------------------------------------------------------------------------------------ -/** - *

- */ -PNeXusSource2::PNeXusSource2() -{ - fName = "n/a"; - fType = "n/a"; - fProbe = "n/a"; -} - -//------------------------------------------------------------------------------------------ -// IsValid (public) -//------------------------------------------------------------------------------------------ -/** - *

Validates the NXsource data. - * - * \param strict flag if true a strict NeXus validation is performed. - */ -bool PNeXusSource2::IsValid(bool strict) -{ - std::string msg(""); - - if (!fName.compare("n/a")) { - msg = "IDF2 NXsample 'name' not set."; - if (strict) { - std::cerr << ">> **ERROR** " << msg << std::endl; - return false; - } else { - std::cerr << ">> **WARNING** " << msg << std::endl; - } - } - - if (!fType.compare("n/a")) { - msg = "IDF2 NXsample 'type' not set."; - if (strict) { - std::cerr << ">> **ERROR** " << msg << std::endl; - return false; - } else { - std::cerr << ">> **WARNING** " << msg << std::endl; - } - } - - if (!fProbe.compare("n/a")) { - msg = "IDF2 NXsample 'probe' not set."; - if (strict) { - std::cerr << ">> **ERROR** " << msg << std::endl; - return false; - } else { - std::cerr << ">> **WARNING** " << msg << std::endl; - } - } - - return true; -} - -//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - -//------------------------------------------------------------------------------------------ -// PNeXusSample2 Constructor -//------------------------------------------------------------------------------------------ -/** - *

- */ -PNeXusSample2::PNeXusSample2() -{ - fName = "n/a"; - fDescription = "n/a"; - fMagneticFieldState = "n/a"; - fEnvironmentTemp = "n/a"; - fEnvironmentField = "n/a"; -} - -//------------------------------------------------------------------------------------------ -// PNeXusSample2 Destructor -//------------------------------------------------------------------------------------------ -/** - *

- */ -PNeXusSample2::~PNeXusSample2() -{ - fPhysProp.clear(); -} - -//------------------------------------------------------------------------------------------ -// IsValid (public) -//------------------------------------------------------------------------------------------ -/** - *

Validates the NXsample data. - * - * \param strict flag if true a strict NeXus validation is performed. - */ -bool PNeXusSample2::IsValid(bool strict) -{ - std::string msg(""); - - if (!fName.compare("n/a")) { - std::cerr << ">> **WARNING** IDF2 NXsample 'name' not set." << msg << std::endl; - } - - if (!fDescription.compare("n/a")) { - std::cerr << std::endl << ">> **WARNING** IDF2 NXsample 'description' not set." << std::endl; - } - - if (!fMagneticFieldState.compare("n/a")) { - std::cerr << std::endl << ">> **WARNING** IDF2 NXsample 'magnetic_field_state' not set." << std::endl; - } - - if (!fEnvironmentTemp.compare("n/a")) { - std::cerr << std::endl << ">> **WARNING** IDF2 NXsample 'temperature_1_env' not set." << std::endl; - } - - if (!fEnvironmentField.compare("n/a")) { - std::cerr << std::endl << ">> **WARNING** IDF2 NXsample 'magnetic_field_1_env' not set." << std::endl; - } - - bool ok; - double dummy; - - dummy = GetPhysPropValue("temperature_1", ok); - if (!ok) { - std::cerr << std::endl << ">> **WARNING** IDF2 NXsample 'temperature_1' not set." << std::endl; - } - - dummy = GetPhysPropValue("magnetic_field_1", ok); - if (!ok) { - std::cerr << std::endl << ">> **WARNING** IDF2 NXsample 'magnetic_field_1' not set." << std::endl; - } - - return true; -} - -//------------------------------------------------------------------------------------------ -// GetPhysPropValue (public) -//------------------------------------------------------------------------------------------ -/** - *

- * - * \param name - * \param ok - */ -double PNeXusSample2::GetPhysPropValue(std::string name, bool &ok) -{ - double dval=0.0; - ok = false; - - for (unsigned int i=0; i - * - * \param name - * \param ok - */ -void PNeXusSample2::GetPhysPropUnit(std::string name, std::string &unit, bool &ok) -{ - unit = "n/a"; - ok = false; - - for (unsigned int i=0; iSet the physical property with 'name' and 'value' at index 'idx'. If idx==-1 add it at the - * end, otherwise set it at index idx. - * - * \param name of the physical property - * \param value of the physical property - * \param idx index where to set the physical property - */ -void PNeXusSample2::SetPhysProp(std::string name, double value, std::string unit, int idx) -{ - PNeXusProp prop; - - prop.SetName(name); - prop.SetValue(value); - prop.SetUnit(unit); - - if (idx == -1) { - fPhysProp.push_back(prop); - } else if (idx >= (int)fPhysProp.size()) { - fPhysProp.resize(idx+1); - fPhysProp[idx] = prop; - } else { - fPhysProp[idx] = prop; - } -} - -//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - -//------------------------------------------------------------------------------------------ -// PNeXusEntry2 Constructor -//------------------------------------------------------------------------------------------ -/** - *

- */ -PNeXusEntry2::PNeXusEntry2() -{ - fErrorMsg = ""; - fDefinition = "n/a"; - fProgramName = "n/a"; - fProgramVersion = "n/a"; - fRunNumber = -1; - fTitle = "n/a"; - fStartTime = "n/a"; - fStopTime = "n/a"; - fExperimentIdentifier = "n/a"; -} - -//------------------------------------------------------------------------------------------ -// IsValid (public) -//------------------------------------------------------------------------------------------ -/** - *

Validates the NXentry data. - * - * \param strict flag if true a strict NeXus validation is performed. - */ -bool PNeXusEntry2::IsValid(bool strict) -{ - std::string msg(""); - - if (!fDefinition.compare("n/a")) { - msg = "IDF2 NXentry definition not set."; - if (strict) { - std::cerr << std::endl << ">> **ERROR** " << msg << std::endl; - return false; - } else { - std::cerr << std::endl << ">> **WARNING** " << msg << std::endl; - } - } - - if (fRunNumber == -1) { - msg = "run number not set."; - if (strict) { - std::cerr << std::endl << ">> **ERROR** " << msg << std::endl; - return false; - } else { - std::cerr << std::endl << ">> **WARNING** " << msg << std::endl; - } - } - - if (!fTitle.compare("n/a")) { - msg = "run title not set."; - if (strict) { - std::cerr << std::endl << ">> **ERROR** " << msg << std::endl; - return false; - } else { - std::cerr << std::endl << ">> **WARNING** " << msg << std::endl; - } - } - - if (!fStartTime.compare("n/a")) { - msg = "start time not set."; - if (strict) { - std::cerr << std::endl << ">> **ERROR** " << msg << std::endl; - return false; - } else { - std::cerr << std::endl << ">> **WARNING** " << msg << std::endl; - } - } - - if (!fStopTime.compare("n/a")) { - msg = "end time not set."; - if (strict) { - std::cerr << std::endl << ">> **ERROR** " << msg << std::endl; - return false; - } else { - std::cerr << std::endl << ">> **WARNING** " << msg << std::endl; - } - } - - if (!fExperimentIdentifier.compare("n/a")) { - msg = "experiment identifier not set."; - if (strict) { - std::cerr << std::endl << ">> **ERROR** " << msg << std::endl; - return false; - } else { - std::cerr << std::endl << ">> **WARNING** " << msg << std::endl; - } - } - - if (!fUser.IsValid(strict)) - return false; - - if (!fSample.IsValid(strict)) - return false; - - if (!fInstrument.IsValid(strict)) - return false; - - return true; -} - -//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - -//------------------------------------------------------------------------------------------ -// SetStartTime (public) -//------------------------------------------------------------------------------------------ -/** - *

Set the start time std::string and check that it is ISO 8601 conform. - * - * \param time start time std::string - */ -int PNeXusEntry2::SetStartTime(std::string time) -{ - struct tm tm; - memset(&tm, 0, sizeof(tm)); - strptime(time.c_str(), "%Y-%m-%d %H:%M:S", &tm); - if (tm.tm_year == 0) - strptime(time.c_str(), "%Y-%m-%dT%H:%M:S", &tm); - if (tm.tm_year == 0) { - fErrorMsg = "PNeXusEntry2::SetStartTime(): get year zero!"; - return NX_ERROR; - } - - fStartTime = time; - - return NX_OK; -} - -//------------------------------------------------------------------------------------------ -// SetStopTime (public) -//------------------------------------------------------------------------------------------ -/** - *

Set the stop time std::string and check that it is ISO 8601 conform. - * - * \param time stop time std::string - */ -int PNeXusEntry2::SetStopTime(std::string time) -{ - struct tm tm; - memset(&tm, 0, sizeof(tm)); - strptime(time.c_str(), "%Y-%m-%d %H:%M:S", &tm); - if (tm.tm_year == 0) - strptime(time.c_str(), "%Y-%m-%dT%H:%M:S", &tm); - if (tm.tm_year == 0) { - fErrorMsg = "PNeXusEntry2::SetStopTime(): get year zero!"; - return NX_ERROR; - } - - fStopTime = time; - - return NX_OK; -} - -//------------------------------------------------------------------------------------------ -// PNeXus Constructor -//------------------------------------------------------------------------------------------ -/** - *

- */ -PNeXus::PNeXus() -{ - Init(); -} - -//------------------------------------------------------------------------------------------ -// PNeXus Constructor -//------------------------------------------------------------------------------------------ -/** - *

- * - * \param fileName - */ -PNeXus::PNeXus(const char* fileName) -{ - Init(); - - fFileName = fileName; - - if (ReadFile(fileName) != NX_OK) { - std::cerr << std::endl << fErrorMsg << " (error code=" << fErrorCode << ")" << std::endl << std::endl; - } else { - fValid = true; - } -} - -//------------------------------------------------------------------------------------------ -// PNeXus Destructor -//------------------------------------------------------------------------------------------ -/** - *

- */ -PNeXus::~PNeXus() -{ - for (unsigned int i=0; iDefine which IDF version shall be written/created. - * - * \param idf version number - */ -void PNeXus::SetIdfVersion(unsigned int idf) -{ - if ((idf != 1) && (idf != 2)) { - std::cerr << std::endl << ">> **ERROR** Only IDF versions 1 and 2 are supported." << std::endl; - return; - } - - fIdfVersion = idf; - - if (idf == 1) { // IDF 1 - fNxEntry2.reset(); - - fNxEntry1 = std::make_unique(); - if (fNxEntry1 == nullptr) { - std::cerr << std::endl << ">> **ERROR** couldn't invoke IDF 1 object PNeXusEntry1." << std::endl; - return; - } - } else { // IDF 2 - fNxEntry1.reset(); - - fNxEntry2 = std::make_unique(); - if (fNxEntry2 == nullptr) { - std::cerr << std::endl << ">> **ERROR** couldn't invoke IDF 2 object PNeXusEntry1." << std::endl; - return; - } - } -} - -//------------------------------------------------------------------------------------------ -// Init (public) -//------------------------------------------------------------------------------------------ -/** - *

Validates the NeXus data. A flag 'strict' controls the degree of validation. If 'strict' == true - * a full NeXus validation is done, otherwise a much sloppier validation is performed. This sloppier - * validation is needed when converting data. - * - * \param strict flag if true a strict NeXus validation is performed. - */ -bool PNeXus::IsValid(bool strict) -{ - bool valid = true; - - if (fIdfVersion == 1) // IDF Version 1 - valid = IsValidIdf1(strict); - else if (fIdfVersion == 2) // IDF Version 2 - valid = IsValidIdf2(strict); - else { - std::cerr << std::endl << ">> **ERROR** found IDF Version " << fIdfVersion << ", which is not implemented yet." << std::endl << std::endl; - valid = false; - } - - return valid; -} - -//------------------------------------------------------------------------------------------ -// GetGroupedHisto (public) -//------------------------------------------------------------------------------------------ -/** - *

Returns the grouped histogram if idx is within range, otherwise 0. - * - * \param idx index of the grouped histogram to be returned. - */ -std::vector* PNeXus::GetGroupedHisto(unsigned int idx) -{ - if (idx >= fGroupedHisto.size()) - return 0; - - return &fGroupedHisto[idx]; -} - -//------------------------------------------------------------------------------------------ -// ReadFile (public) -//------------------------------------------------------------------------------------------ -/** - *

Read the NeXus file 'fileName'. - * - * return: - * - NX_OK on successful reading - * - NX_ERROR on error. The error code/message will give the details. - * - * \param fileName file name of the nexus file to be read - */ -int PNeXus::ReadFile(const char *fileName) -{ - fFileName = fileName; - - // open file - NXstatus status; - status = NXopen(fileName, NXACC_READ, &fFileHandle); - if (status != NX_OK) { - fErrorCode = PNEXUS_FILE_OPEN_ERROR; - fErrorMsg = "PNeXus::ReadFile() **ERROR** Couldn't open file "+std::string(fileName)+"!"; - return NX_ERROR; - } - - // get idf in order to decide which read routine needs to be used. - bool found = false; - NXname nxname, nxclass; - int dataType; - // 1) get the first NXentry - if (!SearchInGroup("NXentry", "class", nxname, nxclass, dataType)) { - fErrorCode = PNEXUS_NXENTRY_NOT_FOUND; - fErrorMsg = "PNeXus::ReadFile() **ERROR** Couldn't find any NXentry!"; - return NX_ERROR; - } - // 2) open the NXentry group to obtain the IDF - status = NXopengroup(fFileHandle, nxname, "NXentry"); - if (status != NX_OK) { - fErrorCode = PNEXUS_GROUP_OPEN_ERROR; - fErrorMsg = "PNeXus::ReadFile() **ERROR** Couldn't open the NeXus group '" + std::string(nxname) + "'!"; - return NX_ERROR; - } - // 3) get the IDF - // IDF - found = false; - do { - status = NXgetnextentry(fFileHandle, nxname, nxclass, &dataType); - if ((strstr(nxname, "IDF_version") != NULL) || (strstr(nxname, "idf_version") != NULL)) - found = true; - } while (!found || (status == NX_EOD)); - - if (!ErrorHandler(NXopendata(fFileHandle, nxname), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'IDF_version' nor 'idf_version' data!!")) return NX_ERROR; - if (!ErrorHandler(NXgetdata(fFileHandle, &fIdfVersion), PNEXUS_GET_DATA_ERROR, "couldn't read 'idf_version' data!")) return NX_ERROR; - if (!ErrorHandler(NXclosedata(fFileHandle), PNEXUS_CLOSE_DATA_ERROR, "couldn't close 'IDF_version' data")) return NX_ERROR; - // close group NXentry - NXclosegroup(fFileHandle); - - // close file - NXclose(&fFileHandle); - - std::stringstream ss; - switch (fIdfVersion) { - case 0: - fErrorCode = PNEXUS_IDF_NOT_IMPLEMENTED; - ss << ">> **ERROR** update of the HDF4/HDF5 libs without recompilation of the NeXus lib?"; - fErrorMsg = ss.str(); - status = NX_ERROR; - break; - case 1: - status = ReadFileIdf1(); - if (status != NX_OK) { - fErrorCode = PNEXUS_VAILD_READ_IDF1_FILE; - fErrorMsg = ">> **ERROR** while reading IDF Version 1 file '" + fFileName + "'."; - } - break; - case 2: - status = ReadFileIdf2(); - if (status != NX_OK) { - fErrorCode = PNEXUS_VAILD_READ_IDF2_FILE; - fErrorMsg = ">> **ERROR** while reading IDF Version 2 file '" + fFileName + "'."; - } - break; - default: - fErrorCode = PNEXUS_IDF_NOT_IMPLEMENTED; - ss << ">> **ERROR** idf_version=" << fIdfVersion << " not yet implemented."; - fErrorMsg = ss.str(); - status = NX_ERROR; - break; - } - - return status; -} - -//------------------------------------------------------------------------------------------ -// WriteFile (public) -//------------------------------------------------------------------------------------------ -/** - *

Write the NeXus file 'fileName', with the 'fileType' (HDF4 | HDF5 | XML) and the instrument - * definition (1 | 2). - * - * return: - * - NX_OK on successfull reading - * - NX_ERROR on error. The error code/message will give the details. - * - * \param fileName file name of the nexus file to be written - * \param fileType = HDF4 | HDF5 | XML - * \param idf = 1 or 2 - */ -int PNeXus::WriteFile(const char *fileName, const char *fileType, const unsigned int idf) -{ - if (!IsValid()) { - return NX_ERROR; - } - - int status = NX_OK; - NXaccess access=NXACC_CREATE4; - - if (!strcmp(fileType, "hdf4")) - access=NXACC_CREATE4; - else if (!strcmp(fileType, "hdf5")) - access=NXACC_CREATE5; - else if (!strcmp(fileType, "xml")) - access=NXACC_CREATEXML; - else - access=NXACC_CREATE4; - - switch (idf) { - case 1: - status = WriteFileIdf1(fileName, access); - break; - case 2: - status = WriteFileIdf2(fileName, access); - break; - default: - break; - } - - return status; -} - -//------------------------------------------------------------------------------------------ -// Dump (public) -//------------------------------------------------------------------------------------------ -/** - *

Write the content of the NeXus file to stdout. Used for debugging purposes. - * - * \param counts flag, if true, also dump the counts for all the histograms - */ -void PNeXus::Dump(const bool counts) -{ - double dval; - std::string str; - bool ok; - - if (fIdfVersion == 1) { - std::cout << std::endl << "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"; - std::cout << std::endl << "NXfile:"; - std::cout << std::endl << " NeXus_version : " << fNeXusVersion; - std::cout << std::endl << " file format ver: " << fFileFormatVersion; - std::cout << std::endl << " file name : " << fFileName; - std::cout << std::endl << " file time : " << fFileTime; - std::cout << std::endl << " user : " << fCreator; - std::cout << std::endl << "NXentry:"; - std::cout << std::endl << " idf version : " << fIdfVersion; - std::cout << std::endl << " program name : " << fNxEntry1->GetProgramName() << ", version: " << fNxEntry1->GetProgramVersion(); - std::cout << std::endl << " run number : " << fNxEntry1->GetRunNumber(); - std::cout << std::endl << " title : " << fNxEntry1->GetTitle(); - std::cout << std::endl << " notes : " << fNxEntry1->GetNotes(); - std::cout << std::endl << " analysis : " << fNxEntry1->GetAnalysis(); - std::cout << std::endl << " laboratory : " << fNxEntry1->GetLaboratory(); - std::cout << std::endl << " beamline : " << fNxEntry1->GetBeamline(); - std::cout << std::endl << " start time : " << fNxEntry1->GetStartTime(); - std::cout << std::endl << " stop time : " << fNxEntry1->GetStopTime(); - std::cout << std::endl << " switching state: " << fNxEntry1->GetSwitchingState() << ", '1' normal data collection, '2' Red/Green mode"; - std::cout << std::endl << "NXuser:"; - std::cout << std::endl << " name : " << fNxEntry1->GetUser()->GetName(); - std::cout << std::endl << " exp.number : " << fNxEntry1->GetUser()->GetExperimentNumber(); - std::cout << std::endl << "NXsample:"; - std::cout << std::endl << " name : " << fNxEntry1->GetSample()->GetName(); - dval = fNxEntry1->GetSample()->GetPhysPropValue("temperature", ok); - if (ok) - std::cout << std::endl << " temperature : " << dval; - fNxEntry1->GetSample()->GetPhysPropUnit("temperature", str, ok); - if (ok) - std::cout << " (" << str << ")"; - dval = fNxEntry1->GetSample()->GetPhysPropValue("magnetic_field", ok); - if (ok) - std::cout << std::endl << " magnetic_field : " << dval; - fNxEntry1->GetSample()->GetPhysPropUnit("magnetic_field", str, ok); - if (ok) - std::cout << " (" << str << ")"; - std::cout << std::endl << " shape : " << fNxEntry1->GetSample()->GetShape(); - std::cout << std::endl << " mag.field state: " << fNxEntry1->GetSample()->GetMagneticFieldState(); - std::cout << std::endl << " environment : " << fNxEntry1->GetSample()->GetEnvironment(); - if (fNxEntry1->GetSample()->IsMagneticFieldVectorAvailable()) { - std::cout << std::endl << " magnetic field vector: "; - for (unsigned int i=0; iGetSample()->GetMagneticFieldVector().size(); i++) { - std::cout << fNxEntry1->GetSample()->GetMagneticFieldVector().at(i) << ", "; - } - std::cout << "(" << fNxEntry1->GetSample()->GetMagneticFieldVectorUnits() << "), "; - std::cout << fNxEntry1->GetSample()->GetMagneticFieldVectorCoordinateSystem(); - } - std::cout << std::endl << "NXinstrument:"; - std::cout << std::endl << " name : " << fNxEntry1->GetInstrument()->GetName(); - std::cout << std::endl << " NXdetector:"; - std::cout << std::endl << " number of detectors: " << fNxEntry1->GetInstrument()->GetDetector()->GetNumber(); - std::cout << std::endl << " NXcollimator:"; - std::cout << std::endl << " type : " << fNxEntry1->GetInstrument()->GetCollimator()->GetType(); - std::cout << std::endl << " Nxbeam:"; - std::cout << std::endl << " total_counts : " << fNxEntry1->GetInstrument()->GetBeam()->GetTotalCounts() << " (" << fNxEntry1->GetInstrument()->GetBeam()->GetUnits() << ")"; - std::cout << std::endl << "NXdata:"; - std::cout << std::endl << " number of histos : " << fNxEntry1->GetData()->GetNoOfHistos(); - std::cout << std::endl << " time resolution : " << fNxEntry1->GetData()->GetTimeResolution("ns") << " (ns)"; - if (fNxEntry1->GetData()->GetGrouping()->size() != 0) { - std::cout << std::endl << " grouping : "; - for (unsigned int i=0; iGetData()->GetGrouping()->size(); i++) { - std::cout << "(" << i << "/" << fNxEntry1->GetData()->GetGrouping()->at(i) << "), "; - } - } else { - std::cout << std::endl << " grouping : not available"; - } - if (fNxEntry1->GetData()->GetT0s()->size() == 0) { - std::cout << std::endl << " t0's : not available"; - } else { - std::cout << std::endl << " t0's : "; - for (unsigned int i=0; iGetData()->GetT0s()->size(); i++) { - std::cout << fNxEntry1->GetData()->GetT0(i) << ", "; - } - } - if (fNxEntry1->GetData()->GetFirstGoodBins()->size() == 0) { - std::cout << std::endl << " first good bins : not available"; - } else { - std::cout << std::endl << " first good bins : "; - for (unsigned int i=0; iGetData()->GetFirstGoodBins()->size(); i++) { - std::cout << fNxEntry1->GetData()->GetFirstGoodBin(i) << ", "; - } - } - if (fNxEntry1->GetData()->GetLastGoodBins()->size() == 0) { - std::cout << std::endl << " last good bins : not available"; - } else { - std::cout << std::endl << " last good bins : "; - for (unsigned int i=0; iGetData()->GetLastGoodBins()->size(); i++) { - std::cout << fNxEntry1->GetData()->GetLastGoodBin(i) << ", "; - } - } - if (fNxEntry1->GetData()->GetNoOfHistos() == 0) { - std::cout << std::endl << " historgrams : not available"; - } else { - std::cout << std::endl << " historgrams : +++++++++++++"; - for (unsigned int i=0; iGetData()->GetNoOfHistos(); i++) { - std::cout << std::endl << " histo " << i+1 << ": "; - for (unsigned int j=0; j<15; j++) { - std::cout << fNxEntry1->GetData()->GetHisto(i)->at(j) << ", "; - } - std::cout << "..."; - if (counts) - std::cout << " total no of entries: " << fNxEntry1->GetData()->GetHistoCounts(i); - } - } - if (fNxEntry1->GetData()->GetAlpha()->size() == 0) { - std::cout << std::endl << " alpha : not available"; - } else { - std::cout << std::endl << " alpha : "; - for (unsigned int i=0; iGetData()->GetAlpha()->size(); i++) - std::cout << "(" << fNxEntry1->GetData()->GetAlpha()->at(i).GetGroupFirst() << "/" << fNxEntry1->GetData()->GetAlpha()->at(i).GetGroupSecond() << "/" << fNxEntry1->GetData()->GetAlpha()->at(i).GetAlpha() << "), "; - } - if (fGroupedHisto.size() == 0) { - std::cout << std::endl << " grouped historgrams : not available"; - } else { - std::cout << std::endl << " grouped historgrams : +++++++++++++"; - for (unsigned int i=0; iGetDefinition(); - if (!fNxEntry2->GetProgramName().empty()) - std::cout << std::endl << " program name : " << fNxEntry2->GetProgramName() << ", version: " << fNxEntry2->GetProgramVersion(); - std::cout << std::endl << " run_number : " << fNxEntry2->GetRunNumber(); - std::cout << std::endl << " run_title : " << fNxEntry2->GetTitle(); - std::cout << std::endl << " start_time : " << fNxEntry2->GetStartTime(); - std::cout << std::endl << " end_time : " << fNxEntry2->GetStopTime(); - std::cout << std::endl << " exp.identifier : " << fNxEntry2->GetExperimentIdentifier(); - std::cout << std::endl << " NXuser:"; - std::cout << std::endl << " name : " << fNxEntry2->GetUser()->GetName(); - std::cout << std::endl << " NXsample:"; - std::cout << std::endl << " name : " << fNxEntry2->GetSample()->GetName(); - std::cout << std::endl << " description : " << fNxEntry2->GetSample()->GetDescription(); - std::cout << std::endl << " mag.field state : " << fNxEntry2->GetSample()->GetMagneticFieldState(); - dval = fNxEntry2->GetSample()->GetPhysPropValue("temperature_1", ok); - if (ok) - std::cout << std::endl << " temperature : " << dval; - fNxEntry2->GetSample()->GetPhysPropUnit("temperature_1", str, ok); - if (ok) - std::cout << " (" << str << ")"; - std::cout << std::endl << " temp.environment : " << fNxEntry2->GetSample()->GetEnvironmentTemp(); - dval = fNxEntry2->GetSample()->GetPhysPropValue("magnetic_field_1", ok); - if (ok) - std::cout << std::endl << " magnetic_field : " << dval; - fNxEntry2->GetSample()->GetPhysPropUnit("magnetic_field_1", str, ok); - if (ok) - std::cout << " (" << str << ")"; - std::cout << std::endl << " mag. field env. : " << fNxEntry2->GetSample()->GetEnvironmentField(); - std::cout << std::endl << " NXinstrument:"; - std::cout << std::endl << " name : " << fNxEntry2->GetInstrument()->GetName(); - std::cout << std::endl << " NXsource:"; - std::cout << std::endl << " name : " << fNxEntry2->GetInstrument()->GetSource()->GetName(); - std::cout << std::endl << " type : " << fNxEntry2->GetInstrument()->GetSource()->GetType(); - std::cout << std::endl << " probe : " << fNxEntry2->GetInstrument()->GetSource()->GetProbe(); - std::cout << std::endl << " NXbeamline:"; - std::cout << std::endl << " name : " << fNxEntry2->GetInstrument()->GetBeamline()->GetName(); - std::cout << std::endl << " NXdetector:"; - std::cout << std::endl << " description : " << fNxEntry2->GetInstrument()->GetDetector()->GetDescription(); - std::cout << std::endl << " time resolution : " << fNxEntry2->GetInstrument()->GetDetector()->GetTimeResolution("ns") << " (ns)"; - if (fNxEntry2->GetInstrument()->GetDetector()->IsT0Present()) { - if (fNxEntry2->GetInstrument()->GetDetector()->GetT0Tag() == 1) { // only one t0 for all histograms - std::cout << std::endl << " t0 : " << fNxEntry2->GetInstrument()->GetDetector()->GetT0(); - } else if (fNxEntry2->GetInstrument()->GetDetector()->GetT0Tag() == 2) { // t0[ns] - std::cout << std::endl << " t0 (idx_s/t0) : "; - for (int i=0; iGetInstrument()->GetDetector()->GetNoOfSpectra(); i++) { - std::cout << "(" << i+1 << "/" << fNxEntry2->GetInstrument()->GetDetector()->GetT0(-1, i) << "), "; - } - } else { // t0 vector of the form t0[np][ns] - std::cout << std::endl << " t0 (idx_p/idx_s/t0): "; - for (int i=0; iGetInstrument()->GetDetector()->GetNoOfPeriods(); i++) { - for (int j=0; jGetInstrument()->GetDetector()->GetNoOfSpectra(); j++) { - std::cout << "(" << i+1 << "/" << j+1 << "/" << fNxEntry2->GetInstrument()->GetDetector()->GetT0(i,j) << "), "; - } - } - } - } else { - std::cout << std::endl << " t0 : n/a"; - } - if (fNxEntry2->GetInstrument()->GetDetector()->IsFirstGoodBinPresent()) { - if (fNxEntry2->GetInstrument()->GetDetector()->GetT0Tag() == 1) { // only one fgb for all histograms - std::cout << std::endl << " first good bin : " << fNxEntry2->GetInstrument()->GetDetector()->GetFirstGoodBin(); - } else if (fNxEntry2->GetInstrument()->GetDetector()->GetT0Tag() == 2) { // fgb[ns] - std::cout << std::endl << " fgb (idx_s/fgb) : "; - for (int i=0; iGetInstrument()->GetDetector()->GetNoOfSpectra(); i++) { - std::cout << "(" << i+1 << "/" << fNxEntry2->GetInstrument()->GetDetector()->GetFirstGoodBin(-1,i) << ") , "; - } - } else { // fgb vector of the form fgb[np][ns] - std::cout << std::endl << " fgb (idx_p/idx_s/fgb): "; - for (int i=0; iGetInstrument()->GetDetector()->GetNoOfPeriods(); i++) { - for (int j=0; jGetInstrument()->GetDetector()->GetNoOfSpectra(); j++) { - std::cout << "(" << i+1 << "/" << j+1 << "/" << fNxEntry2->GetInstrument()->GetDetector()->GetFirstGoodBin(i,j); - } - } - } - } else { - std::cout << std::endl << " first good bin : n/a"; - } - if (fNxEntry2->GetInstrument()->GetDetector()->IsLastGoodBinPresent()) { - if (fNxEntry2->GetInstrument()->GetDetector()->GetT0Tag() == 1) { // only one lgb for all histograms - std::cout << std::endl << " last good bin : " << fNxEntry2->GetInstrument()->GetDetector()->GetLastGoodBin(); - } else if (fNxEntry2->GetInstrument()->GetDetector()->GetT0Tag() == 2) { // lgb[ns] - std::cout << std::endl << " lgb (idx_s/lgb) : "; - for (int i=0; iGetInstrument()->GetDetector()->GetNoOfSpectra(); i++) { - std::cout << "(" << i+1 << "/" << fNxEntry2->GetInstrument()->GetDetector()->GetLastGoodBin(-1,i) << "), "; - } - } else { // lgb vector of the form lgb[np][ns] - std::cout << std::endl << " lgb (idx_p/idx_s/lgb): "; - for (int i=0; iGetInstrument()->GetDetector()->GetNoOfPeriods(); i++) { - for (int j=0; jGetInstrument()->GetDetector()->GetNoOfSpectra(); j++) { - std::cout << "(" << i+1 << "/" << j+1 << "/" << fNxEntry2->GetInstrument()->GetDetector()->GetLastGoodBin(i,j) << "), "; - } - } - } - } else { - std::cout << std::endl << " last good bin : n/a"; - } - std::cout << std::endl << " spectrum_index : "; - for (unsigned int i=0; iGetInstrument()->GetDetector()->GetSpectrumIndexSize(); i++) - std::cout << fNxEntry2->GetInstrument()->GetDetector()->GetSpectrumIndex(i) << ", "; - - // dump data - int maxDump = 15; - std::cout << std::endl << " counts : "; - if (fNxEntry2->GetInstrument()->GetDetector()->GetNoOfPeriods() > 0) { // counts[np][ns][ntc] - for (int i=0; iGetInstrument()->GetDetector()->GetNoOfPeriods(); i++) { - std::cout << std::endl << " period : " << i+1; - for (int j=0; jGetInstrument()->GetDetector()->GetNoOfSpectra(); j++) { - std::cout << std::endl << " spectrum : " << j+1 << ", (#bins=" << fNxEntry2->GetInstrument()->GetDetector()->GetNoOfBins() << ")"; - if (maxDump > fNxEntry2->GetInstrument()->GetDetector()->GetNoOfBins()) - maxDump = fNxEntry2->GetInstrument()->GetDetector()->GetNoOfBins(); - std::cout << std::endl << " "; - for (int k=0; kGetInstrument()->GetDetector()->GetHistoValue(i,j,k) << ", "; - } - std::cout << "..."; - if (counts) - std::cout << " total number of entries: " << fNxEntry2->GetInstrument()->GetDetector()->GetHistoCounts(i,j); - } - } - } else { - if (fNxEntry2->GetInstrument()->GetDetector()->GetNoOfSpectra() > 0) { // counts[ns][ntc] - for (int j=0; jGetInstrument()->GetDetector()->GetNoOfSpectra(); j++) { - std::cout << std::endl << " spectrum : " << j+1 << ", (#bins=" << fNxEntry2->GetInstrument()->GetDetector()->GetNoOfBins() << ")"; - if (maxDump > fNxEntry2->GetInstrument()->GetDetector()->GetNoOfBins()) - maxDump = fNxEntry2->GetInstrument()->GetDetector()->GetNoOfBins(); - std::cout << std::endl << " "; - for (int k=0; kGetInstrument()->GetDetector()->GetHistoValue(0,j,k) << ", "; - } - std::cout << "..."; - if (counts) - std::cout << " total number of entries: " << fNxEntry2->GetInstrument()->GetDetector()->GetHistoCounts(0,j); - } - } else { // counts[ntc] - std::cout << std::endl << " (#bins=" << fNxEntry2->GetInstrument()->GetDetector()->GetNoOfBins() << ")"; - if (maxDump > fNxEntry2->GetInstrument()->GetDetector()->GetNoOfBins()) - maxDump = fNxEntry2->GetInstrument()->GetDetector()->GetNoOfBins(); - std::cout << std::endl << " "; - for (int k=0; kGetInstrument()->GetDetector()->GetHistoValue(0,0,k) << ", "; - } - std::cout << "..."; - if (counts) - std::cout << " total number of entries: " << fNxEntry2->GetInstrument()->GetDetector()->GetHistoCounts(0,0); - } - } - std::cout << std::endl << "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"; - std::cout << std::endl << "that's all!"; - std::cout << std::endl << std::endl; - } -} - -//------------------------------------------------------------------------------------------ -// Init (private) -//------------------------------------------------------------------------------------------ -/** - *

- */ -void PNeXus::Init() -{ - fValid = false; - fErrorCode = PNEXUS_NO_ERROR; - fErrorMsg = "n/a"; - fNeXusVersion = NEXUS_VERSION; - fFileFormatVersion = "n/a"; - fIdfVersion = 0; - fFileName = "n/a"; - fFileTime = "n/a"; - fCreator = "n/a"; -} - -//----------------------------------------------------------------------------------------------------- -// ErrorHandler (private) -//----------------------------------------------------------------------------------------------------- -/** - *

- * - * return: - * - true of no error occurred - * - false on error - * - * \param status of the calling routine - * \param errCode will set the fErrorCode of the class - * \param errMsg will set the fErrorMsg of the class - */ -bool PNeXus::ErrorHandler(NXstatus status, int errCode, const std::string &errMsg) -{ - if (status != NX_OK) { - fErrorCode = errCode; - fErrorMsg = errMsg; - std::cerr << std::endl << ">> **ERROR** " << fErrorMsg << std::endl; - if (fFileHandle != 0) { - NXclose(&fFileHandle); - } - return false; - } - return true; -} - -//----------------------------------------------------------------------------------------------------- -// GetStringData (private) -//----------------------------------------------------------------------------------------------------- -/** - *

- * - * return: - * - NX_OK on success - * - NX_ERROR otherwiese - * - * \param str std::string to be fed - */ -NXstatus PNeXus::GetStringData(std::string &str) -{ - int i, status, rank, type, dims[32]; - char cstr[1024]; - NXname data_value; - - status = NXgetinfo(fFileHandle, &rank, dims, &type); - if (status != NX_OK) { - std::cerr << std::endl << ">> **ERROR** in NXgetinfo: couldn't get meta info!" << std::endl; - fErrorCode = PNEXUS_GET_META_INFO_ERROR; - fErrorMsg = "PNeXus::GetStringData() **ERROR** couldn't get meta info!"; - return NX_ERROR; - } - - if ((type != NX_CHAR) || (rank > 1) || (dims[0] >= (int)sizeof(cstr))) { - std::cerr << std::endl << ">> **ERROR** in NXgetinfo: found wrong meta info!" << std::endl; - fErrorCode = PNEXUS_WRONG_META_INFO; - fErrorMsg = "PNeXus::GetStringData() **ERROR** found wrong meta info!"; - return NX_ERROR; - } - - status = NXgetdata(fFileHandle, data_value); - if (status != NX_OK) { - std::cerr << std::endl << ">> **ERROR** in routine NXgetdata: couldn't get data for '" << str << "'!" << std::endl; - fErrorCode = PNEXUS_GET_DATA_ERROR; - fErrorMsg = "couldn't get data!"; - return NX_ERROR; - } - - for (i = 0; i < dims[0]; i++) - cstr[i] = *(data_value + i); - cstr[i] = '\0'; - - str = cstr; - - return NX_OK; -} - -//----------------------------------------------------------------------------------------------------- -// GetStringAttr (private) -//----------------------------------------------------------------------------------------------------- -/** - *

- * - * return: - * - NX_OK on success - * - NX_ERROR otherwiese - * - * \param attr attribute tag - * \param str std::string to be fed - */ -NXstatus PNeXus::GetStringAttr(std::string attr, std::string &str) -{ - int i, status, attlen, atttype; - char cstr[VGNAMELENMAX]; - NXname data_value; - - attlen = VGNAMELENMAX - 1; - atttype = NX_CHAR; - status = NXgetattr(fFileHandle, (char *)attr.c_str(), data_value, &attlen, &atttype); - if (status != NX_OK) { - std::cerr << std::endl << ">> **ERROR** in routine NXgetattr: couldn't get attribute '" << attr << "'! status=" << status << std::endl << std::endl; - fErrorCode = PNEXUS_GET_ATTR_ERROR; - fErrorMsg = "couldn't get std::string attribute data!"; - return NX_ERROR; - } - - for (i = 0; i < attlen; i++) - cstr[i] = *(data_value + i); - cstr[i] = '\0'; - - str = cstr; - - return NX_OK; -} - -//----------------------------------------------------------------------------------------------------- -// GetDataSize (private) -//----------------------------------------------------------------------------------------------------- -/** - *

- * - * return: - * - size in bytes of the given type - * - 0 if the type is not recognized - * - * \param type - */ -int PNeXus::GetDataSize(int type) -{ - int size; - - switch (type) { - case NX_CHAR: - size = SIZE_CHAR8; - break; - case NX_FLOAT32: - size = SIZE_FLOAT32; - break; - case NX_FLOAT64: - size = SIZE_FLOAT64; - break; - case NX_INT8: - size = SIZE_INT8; - break; - case NX_UINT8: - size = SIZE_UINT8; - break; - case NX_INT16: - size = SIZE_INT16; - break; - case NX_UINT16: - size = SIZE_UINT16; - break; - case NX_INT32: - size = SIZE_INT32; - break; - case NX_UINT32: - size = SIZE_UINT32; - break; - default: - size = 0; - break; - } - - return size; -} - -//----------------------------------------------------------------------------------------------------- -// GetDoubleVectorData (private) -//----------------------------------------------------------------------------------------------------- -/** - *

- * - * return: - * - NX_OK on success - * - NX_ERROR otherwiese - * - * \param data - */ -NXstatus PNeXus::GetDoubleVectorData(std::vector &data) -{ - // get information of the current nexus entity - int rank, type, dims[32], size, noOfElements; - if (!ErrorHandler(NXgetinfo(fFileHandle, &rank, dims, &type), PNEXUS_GET_META_INFO_ERROR, "couldn't get data info!")) - return NX_ERROR; - - // calculate the needed size - size = dims[0]; - for (int i=1; i - * - * return: - * - NX_OK on success - * - NX_ERROR otherwiese - * - * \param data - */ -NXstatus PNeXus::GetIntVectorData(std::vector &data) -{ - // get information of the current nexus entity - int rank, type, dims[32], size, noOfElements; - if (!ErrorHandler(NXgetinfo(fFileHandle, &rank, dims, &type), PNEXUS_GET_META_INFO_ERROR, "couldn't get data info!")) - return NX_ERROR; - - // calculate the needed size - size = dims[0]; - for (int i=1; iRead the NeXus file of type IDF Version 1. - * - * return: - * - NX_OK on successfull reading - * - NX_ERROR on error. The error code/message will give the details. - */ -int PNeXus::ReadFileIdf1() -{ - std::cout << std::endl << ">> reading NeXus IDF Version 1 file ..." << std::endl; - - // create first the necessary NXentry object for IDF Version 1 - fNxEntry1 = std::make_unique(); - if (fNxEntry1 == nullptr) { - fErrorCode = PNEXUS_OBJECT_INVOK_ERROR; - fErrorMsg = ">> **ERROR** couldn't invoke PNeXusEntry1 object."; - return NX_ERROR; - } - - std::string str; - char cstr[128]; - int ival; - float fval; - int attlen, atttype, rank, dims[32]; - NXname data_value, nxAttrName; - - // open file - NXstatus status; - status = NXopen(fFileName.c_str(), NXACC_READ, &fFileHandle); - if (status != NX_OK) { - fErrorCode = PNEXUS_FILE_OPEN_ERROR; - fErrorMsg = "PNeXus::ReadFile() **ERROR** Couldn't open file '"+fFileName+"' !"; - return NX_ERROR; - } - - // collect the NXroot attribute information - do { - status = NXgetnextattra(fFileHandle, nxAttrName, &rank, dims, &atttype); - if (status == NX_OK) { - if (!strcmp(nxAttrName, "HDF_version")) { - attlen = VGNAMELENMAX - 1; - atttype = NX_CHAR; - status = NXgetattr(fFileHandle, nxAttrName, data_value, &attlen, &atttype); - if (status == NX_OK) { - fFileFormatVersion = std::string(data_value); - } - } else if (!strcmp(nxAttrName, "HDF5_Version")) { - attlen = VGNAMELENMAX - 1; - atttype = NX_CHAR; - status = NXgetattr(fFileHandle, nxAttrName, data_value, &attlen, &atttype); - if (status == NX_OK) { - fFileFormatVersion = std::string("HDF5: ")+std::string(data_value); - } - } else if (!strcmp(nxAttrName, "XML_version")) { - attlen = VGNAMELENMAX - 1; - atttype = NX_CHAR; - status = NXgetattr(fFileHandle, nxAttrName, data_value, &attlen, &atttype); - if (status == NX_OK) { - fFileFormatVersion = std::string(data_value); - } - } else if (!strcmp(nxAttrName, "file_name")) { - if (!ErrorHandler(GetStringAttr("file_name", str), PNEXUS_GET_ATTR_ERROR, "couldn't read NXroot 'file_name' attribute!")) return NX_ERROR; - fFileName = str; - } else if (!strcmp(nxAttrName, "file_time")) { - if (!ErrorHandler(GetStringAttr("file_time", str), PNEXUS_GET_ATTR_ERROR, "couldn't read NXroot 'file_time' attribute!")) return NX_ERROR; - fFileTime = str; - } else if (!strcmp(nxAttrName, "user")) { - if (!ErrorHandler(GetStringAttr("user", str), PNEXUS_GET_ATTR_ERROR, "couldn't read NXroot 'user' attribute!")) return NX_ERROR; - fCreator = str; - } - } - } while (status == NX_OK); - - // look for the first occurring NXentry - bool found = false; - NXname nxname, nxclass; - int dataType; - do { - status = NXgetnextentry(fFileHandle, nxname, nxclass, &dataType); - if (strstr(nxclass, "NXentry") != NULL) - found = true; - } while (!found || (status == NX_EOD)); - // make sure any NXentry has been found - if (!found) { - fErrorCode = PNEXUS_NXENTRY_NOT_FOUND; - fErrorMsg = ">> **ERROR** Couldn't find any NXentry!"; - return NX_ERROR; - } - // open the NXentry group to obtain the necessary stuff - status = NXopengroup(fFileHandle, nxname, "NXentry"); - if (status != NX_OK) { - fErrorCode = PNEXUS_GROUP_OPEN_ERROR; - fErrorMsg = "PNeXus::ReadFile() **ERROR** Couldn't open the NeXus group '" + std::string(nxname) + "'!"; - return NX_ERROR; - } - - // program_name - if (!ErrorHandler(NXopendata(fFileHandle, "program_name"), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'program_name' data in NXentry!")) return NX_ERROR; - if (!ErrorHandler(GetStringData(str), PNEXUS_GET_DATA_ERROR, "couldn't read 'program_name' data in NXentry!")) return NX_ERROR; - fNxEntry1->SetProgramName(str); - if (!ErrorHandler(GetStringAttr("version", str), PNEXUS_GET_ATTR_ERROR, "couldn't read 'program_name' attribute in NXentry!")) return NX_ERROR; - fNxEntry1->SetProgramVersion(str); - if (!ErrorHandler(NXclosedata(fFileHandle), PNEXUS_CLOSE_DATA_ERROR, "couldn't close 'program_name' data in NXentry!")) return NX_ERROR; - - // run number - if (!ErrorHandler(NXopendata(fFileHandle, "number"), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'number' data in NXentry!")) return NX_ERROR; - if (!ErrorHandler(NXgetdata(fFileHandle, &ival), PNEXUS_GET_DATA_ERROR, "couldn't read 'number' data in NXentry!")) return NX_ERROR; - fNxEntry1->SetRunNumber(ival); - if (!ErrorHandler(NXclosedata(fFileHandle), PNEXUS_CLOSE_DATA_ERROR, "couldn't close 'number' data in NXentry!")) return NX_ERROR; - - // title - if (!ErrorHandler(NXopendata(fFileHandle, "title"), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'title' data in NXentry!")) return NX_ERROR; - if (!ErrorHandler(GetStringData(str), PNEXUS_GET_DATA_ERROR, "couldn't read 'title' data in NXentry!")) return NX_ERROR; - fNxEntry1->SetTitle(str); - if (!ErrorHandler(NXclosedata(fFileHandle), PNEXUS_CLOSE_DATA_ERROR, "couldn't close 'title' data in NXentry!")) return NX_ERROR; - - // notes - if (!ErrorHandler(NXopendata(fFileHandle, "notes"), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'notes' data in NXentry!")) return NX_ERROR; - if (!ErrorHandler(GetStringData(str), PNEXUS_GET_DATA_ERROR, "couldn't read 'notes' data in NXentry!")) return NX_ERROR; - fNxEntry1->SetNotes(str); - if (!ErrorHandler(NXclosedata(fFileHandle), PNEXUS_CLOSE_DATA_ERROR, "couldn't close 'notes' data in NXentry!")) return NX_ERROR; - - // analysis tag - if (!ErrorHandler(NXopendata(fFileHandle, "analysis"), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'analysis' data in NXentry!")) return NX_ERROR; - if (!ErrorHandler(GetStringData(str), PNEXUS_GET_DATA_ERROR, "couldn't read 'analysis' data in NXentry!")) return NX_ERROR; - fNxEntry1->SetAnalysis(str); - if (!ErrorHandler(NXclosedata(fFileHandle), PNEXUS_CLOSE_DATA_ERROR, "couldn't close 'analysis' data in NXentry!")) return NX_ERROR; - - // lab - if (!ErrorHandler(NXopendata(fFileHandle, "lab"), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'lab' data in NXentry!")) return NX_ERROR; - if (!ErrorHandler(GetStringData(str), PNEXUS_GET_DATA_ERROR, "couldn't read 'lab' data in NXentry!")) return NX_ERROR; - fNxEntry1->SetLaboratory(str); - if (!ErrorHandler(NXclosedata(fFileHandle), PNEXUS_CLOSE_DATA_ERROR, "couldn't close 'lab' data in NXentry!")) return NX_ERROR; - - // beamline - if (!ErrorHandler(NXopendata(fFileHandle, "beamline"), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'beamline' data in NXentry!")) return NX_ERROR; - if (!ErrorHandler(GetStringData(str), PNEXUS_GET_DATA_ERROR, "couldn't read 'beamline' data in NXentry!")) return NX_ERROR; - fNxEntry1->SetBeamline(str); - if (!ErrorHandler(NXclosedata(fFileHandle), PNEXUS_CLOSE_DATA_ERROR, "couldn't close 'beamline' data in NXentry!")) return NX_ERROR; - - // start time - if (!ErrorHandler(NXopendata(fFileHandle, "start_time"), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'start_time' data in NXentry!")) return NX_ERROR; - if (!ErrorHandler(GetStringData(str), PNEXUS_GET_DATA_ERROR, "couldn't read 'start_time' data in NXentry!")) return NX_ERROR; - if (!ErrorHandler(NXclosedata(fFileHandle), PNEXUS_CLOSE_DATA_ERROR, "couldn't close 'start_time' data in NXentry!")) return NX_ERROR; - if (fNxEntry1->SetStartTime(str) != NX_OK) { - fErrorCode = PNEXUS_TIME_FORMAT_ERROR; - fErrorMsg = "start time format is not ISO 8601 conform."; - } - - // stop time - if (!ErrorHandler(NXopendata(fFileHandle, "stop_time"), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'start_time' data in NXentry!")) return NX_ERROR; - if (!ErrorHandler(GetStringData(str), PNEXUS_GET_DATA_ERROR, "couldn't read 'start_time' data in NXentry!")) return NX_ERROR; - if (!ErrorHandler(NXclosedata(fFileHandle), PNEXUS_CLOSE_DATA_ERROR, "couldn't close 'start_time' data in NXentry!")) return NX_ERROR; - if (fNxEntry1->SetStopTime(str) != NX_OK) { - fErrorCode = PNEXUS_TIME_FORMAT_ERROR; - fErrorMsg = "stop time format is not ISO 8601 conform.."; - } - - // switching state (red/green mode) - if (!ErrorHandler(NXopendata(fFileHandle, "switching_states"), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'switching_states' data in NXentry!")) return NX_ERROR; - if (!ErrorHandler(NXgetdata(fFileHandle, &ival), PNEXUS_GET_DATA_ERROR, "couldn't read 'switching_states' data in NXentry!")) return NX_ERROR; - if (!ErrorHandler(NXclosedata(fFileHandle), PNEXUS_CLOSE_DATA_ERROR, "couldn't close 'switching_states' data in NXentry!")) return NX_ERROR; - if (fNxEntry1->SetSwitchingState(ival)) { - fErrorCode = PNEXUS_DATA_ERROR; - fErrorMsg = "unkown switching state found."; - } - - // open group NXuser - if (!ErrorHandler(NXopengroup(fFileHandle, "user", "NXuser"), PNEXUS_GROUP_OPEN_ERROR, "couldn't open NeXus subgroup 'user'!")) return NX_ERROR; - - // change to subgroup - if (!ErrorHandler(NXinitgroupdir(fFileHandle), PNEXUS_INIT_GROUPDIR_ERROR, "couldn't init group directory")) return NX_ERROR; - int numItems = 0; - NXname groupName, className; - if (!ErrorHandler(NXgetgroupinfo(fFileHandle, &numItems, groupName, className), PNEXUS_GET_GROUP_INFO_ERROR, "couldn't get user group info")) return NX_ERROR; - - // get all the user info - // go through the user list and filter out the required items - NXname nx_label; - int nx_dataType; - for (int i=0; iGetUser()->SetName(str); - } - if (!strcmp(nx_label, "experiment_number")) { - if (!ErrorHandler(GetStringData(str), PNEXUS_GET_DATA_ERROR, "couldn't get user name")) return NX_ERROR; - fNxEntry1->GetUser()->SetExperimentNumber(str); - } - if (!ErrorHandler(NXclosedata(fFileHandle), PNEXUS_CLOSE_DATA_ERROR, "couldn't close data")) return NX_ERROR; - } - - // close group NXuser - NXclosegroup(fFileHandle); - - // open group NXsample - if (SearchInGroup("NXsample", "class", nxname, nxclass, dataType)) { - if (!ErrorHandler(NXopengroup(fFileHandle, "sample", "NXsample"), PNEXUS_GROUP_OPEN_ERROR, "couldn't open NeXus subgroup 'sample'!")) return NX_ERROR; - } else { - std::cout << std::endl << ">> **WARNING** unable to open subgroup NXsample, will try NXSample." << std::endl; - if (!ErrorHandler(NXopengroup(fFileHandle, "sample", "NXSample"), PNEXUS_GROUP_OPEN_ERROR, "couldn't open NeXus subgroup 'sample'!")) return NX_ERROR; - } - - // read sample name - if (!ErrorHandler(NXopendata(fFileHandle, "name"), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'name' data in sample group!")) return NX_ERROR; - if (!ErrorHandler(GetStringData(str), PNEXUS_GET_DATA_ERROR, "couldn't read 'name' data in sample group!")) return NX_ERROR; - if (!ErrorHandler(NXclosedata(fFileHandle), PNEXUS_CLOSE_DATA_ERROR, "couldn't close 'name' data in sample group")) return NX_ERROR; - fNxEntry1->GetSample()->SetName(str); - - // read sample temperature - if (!ErrorHandler(NXopendata(fFileHandle, "temperature"), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'temperature' data in sample group!")) return NX_ERROR; - if (!ErrorHandler(NXgetdata(fFileHandle, &fval), PNEXUS_GET_DATA_ERROR, "couldn't read 'temperature' data in sample group!")) return NX_ERROR; - if (!ErrorHandler(GetStringAttr("units", str), PNEXUS_GET_ATTR_ERROR, "couldn't read temperature units!")) return NX_ERROR; - if (!ErrorHandler(NXclosedata(fFileHandle), PNEXUS_CLOSE_DATA_ERROR, "couldn't close 'temperature' data in sample group")) return NX_ERROR; - fNxEntry1->GetSample()->SetPhysProp("temperature", (double)fval, str); - - // read sample magnetic field - if (!ErrorHandler(NXopendata(fFileHandle, "magnetic_field"), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'magnetic_field' data in sample group!")) return NX_ERROR; - if (!ErrorHandler(NXgetdata(fFileHandle, &fval), PNEXUS_GET_DATA_ERROR, "couldn't read 'magnetic_field' data in sample group!")) return NX_ERROR; - if (!ErrorHandler(GetStringAttr("units", str), PNEXUS_GET_ATTR_ERROR, "couldn't read magnetic_field units!")) return NX_ERROR; - if (!ErrorHandler(NXclosedata(fFileHandle), PNEXUS_CLOSE_DATA_ERROR, "couldn't close 'magnetic_field' data in sample group")) return NX_ERROR; - fNxEntry1->GetSample()->SetPhysProp("magnetic_field", (double)fval, str); - - // read sample shape, e.g. powder, single crystal, etc (THIS IS AN OPTIONAL ENTRY) - if (SearchInGroup("shape", "name", nxname, nxclass, dataType)) { - if (!ErrorHandler(NXopendata(fFileHandle, "shape"), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'shape' data in sample group!")) return NX_ERROR; - if (!ErrorHandler(GetStringData(str), PNEXUS_GET_DATA_ERROR, "couldn't read 'shape' data in sample group!")) return NX_ERROR; - if (!ErrorHandler(NXclosedata(fFileHandle), PNEXUS_CLOSE_DATA_ERROR, "couldn't close 'shape' data in sample group")) return NX_ERROR; - fNxEntry1->GetSample()->SetShape(str); - } - - // read magnetic field state, e.g. TF, LF, ZF - if (!ErrorHandler(NXopendata(fFileHandle, "magnetic_field_state"), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'magnetic_field_state' data in sample group!")) return NX_ERROR; - if (!ErrorHandler(GetStringData(str), PNEXUS_GET_DATA_ERROR, "couldn't read 'magnetic_field_state' data in sample group!")) return NX_ERROR; - if (!ErrorHandler(NXclosedata(fFileHandle), PNEXUS_CLOSE_DATA_ERROR, "couldn't close 'magnetic_field_state' data in sample group")) return NX_ERROR; - fNxEntry1->GetSample()->SetMagneticFieldState(str); - - // read 'magnetic_field_vector' and 'coordinate_system' attribute - if (!ErrorHandler(NXopendata(fFileHandle, "magnetic_field_vector"), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'magnetic_field_vector' data in sample group!")) return NX_ERROR; - int attLen = 1, attType = NX_INT32; - memset(cstr, '\0', sizeof(cstr)); - strncpy(cstr, "available", sizeof(cstr)); - if (!ErrorHandler(NXgetattr(fFileHandle, cstr, &ival, &attLen, &attType), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'magnetic_field_vector available' data in sample group!")) return NX_ERROR; - fNxEntry1->GetSample()->SetMagneticFieldVectorAvailable(ival); - if (fNxEntry1->GetSample()->IsMagneticFieldVectorAvailable()) { - std::vector magVec; - if (!ErrorHandler(GetDoubleVectorData(magVec), PNEXUS_GET_DATA_ERROR, "couldn't get 'magnetic_field_vector' data!")) return NX_ERROR; - fNxEntry1->GetSample()->SetMagneticFieldVector(magVec); - magVec.clear(); - if (!ErrorHandler(GetStringAttr("coordinate_system", str), PNEXUS_GET_ATTR_ERROR, "couldn't read magnetic field coordinate_system!")) return NX_ERROR; - fNxEntry1->GetSample()->SetMagneticFieldVectorCoordinateSystem(str); - - // workaround since not all ISIS IDF 1 files have the 'units' entry!! - memset(cstr, '\0', sizeof(cstr)); - strncpy(cstr, "units", sizeof(cstr)); - if (SearchAttrInData(cstr, attLen, attType)) { - status = NXgetattr(fFileHandle, cstr, data_value, &attLen, &attType); - if (status == NX_OK) { - strncpy(cstr, data_value, sizeof(cstr)); - str = cstr; - } else { - str = std::string("Gauss"); - } - } else { - str = std::string("Gauss"); - } - fNxEntry1->GetSample()->SetMagneticFieldUnits(str); - } - if (!ErrorHandler(NXclosedata(fFileHandle), PNEXUS_CLOSE_DATA_ERROR, "couldn't close 'magnetic_field_vector' data in sample group")) return NX_ERROR; - - // read sample environment, e.g. CCR, LowTemp-2, etc. - if (!ErrorHandler(NXopendata(fFileHandle, "environment"), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'environment' data in sample group!")) return NX_ERROR; - if (!ErrorHandler(GetStringData(str), PNEXUS_GET_DATA_ERROR, "couldn't read 'environment' data in sample group!")) return NX_ERROR; - if (!ErrorHandler(NXclosedata(fFileHandle), PNEXUS_CLOSE_DATA_ERROR, "couldn't close 'environment' data in sample group")) return NX_ERROR; - fNxEntry1->GetSample()->SetEnvironment(str); - - // close group NXsample - NXclosegroup(fFileHandle); - - // get required instrument information - // open subgroup NXinstrument with subgroups detector, collimator, beam - if (!ErrorHandler(NXopengroup(fFileHandle, "instrument", "NXinstrument"), PNEXUS_GROUP_OPEN_ERROR, "couldn't open NeXus subgroup instrument!")) return NX_ERROR; - - // get instrument name - if (!ErrorHandler(NXopendata(fFileHandle, "name"), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'name' data in instrument group!")) return NX_ERROR; - if (!ErrorHandler(GetStringData(str), PNEXUS_GET_DATA_ERROR, "couldn't read 'name' data in instrument group!")) return NX_ERROR; - if (!ErrorHandler(NXclosedata(fFileHandle), PNEXUS_CLOSE_DATA_ERROR, "couldn't close 'name' data in instrument group")) return NX_ERROR; - fNxEntry1->GetInstrument()->SetName(str); - - // open subgroup NXdetector - if (!ErrorHandler(NXopengroup(fFileHandle, "detector", "NXdetector"), PNEXUS_GROUP_OPEN_ERROR, "couldn't open NeXus subgroup detector!")) return NX_ERROR; - - // get number of detectors - if (!ErrorHandler(NXopendata(fFileHandle, "number"), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'number' data in detector group!")) return NX_ERROR; - if (!ErrorHandler(NXgetdata(fFileHandle, &ival), PNEXUS_GET_DATA_ERROR, "couldn't read 'number' data in detector group!")) return NX_ERROR; - if (!ErrorHandler(NXclosedata(fFileHandle), PNEXUS_CLOSE_DATA_ERROR, "couldn't close 'number' data in detector group")) return NX_ERROR; - fNxEntry1->GetInstrument()->GetDetector()->SetNumber(ival); - - // close subgroup NXdetector - NXclosegroup(fFileHandle); - - // open subgroup NXcollimator - if (!ErrorHandler(NXopengroup(fFileHandle, "collimator", "NXcollimator"), PNEXUS_GROUP_OPEN_ERROR, "couldn't open NeXus subgroup collimator!")) return NX_ERROR; - - // get collimator type - if (!ErrorHandler(NXopendata(fFileHandle, "type"), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'type' data in collimator group!")) return NX_ERROR; - if (!ErrorHandler(GetStringData(str), PNEXUS_GET_DATA_ERROR, "couldn't read 'type' data in collimator group!")) return NX_ERROR; - if (!ErrorHandler(NXclosedata(fFileHandle), PNEXUS_CLOSE_DATA_ERROR, "couldn't close 'type' data in collimator group")) return NX_ERROR; - fNxEntry1->GetInstrument()->GetCollimator()->SetType(str); - - // close subgroup NXcollimator - NXclosegroup(fFileHandle); - - // open subgroup NXbeam - if (!ErrorHandler(NXopengroup(fFileHandle, "beam", "NXbeam"), PNEXUS_GROUP_OPEN_ERROR, "couldn't open NeXus subgroup beam!")) return NX_ERROR; - - // get the total counts - if (!ErrorHandler(NXopendata(fFileHandle, "total_counts"), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'total_counts' data in beam group!")) return NX_ERROR; - if (!ErrorHandler(NXgetdata(fFileHandle, &fval), PNEXUS_GET_DATA_ERROR, "couldn't read 'total_counts' data in beam group!")) return NX_ERROR; - fNxEntry1->GetInstrument()->GetBeam()->SetTotalCounts((double)fval); - if (!ErrorHandler(GetStringAttr("units", str), PNEXUS_GET_ATTR_ERROR, "couldn't read total_counts units!")) return NX_ERROR; - fNxEntry1->GetInstrument()->GetBeam()->SetUnits(str); - if (!ErrorHandler(NXclosedata(fFileHandle), PNEXUS_CLOSE_DATA_ERROR, "couldn't close 'total_counts' data in beam group")) return NX_ERROR; - - // close subgroup NXbeam - NXclosegroup(fFileHandle); - - // close subgroup NXinstrument - NXclosegroup(fFileHandle); - - // find the first occuring NXdata class - found = false; - do { - status = NXgetnextentry(fFileHandle, nxname, nxclass, &dataType); - if (strstr(nxclass, "NXdata") != NULL) - found = true; - } while (!found || (status == NX_EOD)); - // make sure any NXentry has been found - if (!found) { - fErrorCode = PNEXUS_GROUP_OPEN_ERROR; - fErrorMsg = ">> **ERROR** Couldn't find any NXdata!"; - return NX_ERROR; - } - - // open subgroup NXdata (this is for Version 1, only and is subject to change in the near future!) - memset(cstr, '\0', sizeof(cstr)); - snprintf(cstr, sizeof(cstr), "couldn't open NeXus subgroup %s!", nxname); - if (!ErrorHandler(NXopengroup(fFileHandle, nxname, "NXdata"), PNEXUS_GROUP_OPEN_ERROR, cstr)) return NX_ERROR; - - // get time resolution - if (!ErrorHandler(NXopendata(fFileHandle, "resolution"), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'resolution' data in NXdata group!")) return NX_ERROR; - if (!ErrorHandler(NXgetdata(fFileHandle, &ival), PNEXUS_GET_DATA_ERROR, "couldn't read 'resolution' data in NXdata group!")) return NX_ERROR; - if (!ErrorHandler(GetStringAttr("units", str), PNEXUS_GET_ATTR_ERROR, "couldn't read 'resolution' units!")) return NX_ERROR; - if (!ErrorHandler(NXclosedata(fFileHandle), PNEXUS_CLOSE_DATA_ERROR, "couldn't close 'resolution' data in NXdata group")) return NX_ERROR; - if (!strcmp(str.c_str(), "picoseconds")) { - fNxEntry1->GetData()->SetTimeResolution((double)ival, "ps"); - } else if (!strcmp(str.c_str(), "femtoseconds")) { - fNxEntry1->GetData()->SetTimeResolution((double)ival, "fs"); - } - - // get data, t0, first good bin, last good bin, data - if (!ErrorHandler(NXopendata(fFileHandle, "counts"), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'counts' data in NXdata group!")) return NX_ERROR; - int histoLength=0; - int noOfHistos=0; - - // get number of histos - attLen = 1; - attType = NX_INT32; - memset(cstr, '\0', sizeof(cstr)); - strncpy(cstr, "number", sizeof(cstr)); - if (!ErrorHandler(NXgetattr(fFileHandle, cstr, &noOfHistos, &attLen, &attType), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'number' data in NXdata group!")) return NX_ERROR; - - // get histo length - attLen = 1; - attType = NX_INT32; - memset(cstr, '\0', sizeof(cstr)); - strncpy(cstr, "length", sizeof(cstr)); - if (!ErrorHandler(NXgetattr(fFileHandle, cstr, &histoLength, &attLen, &attType), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'length' data in NXdata group!")) return NX_ERROR; - - // get t0 - attLen = 1; - attType = NX_INT32; - memset(cstr, '\0', sizeof(cstr)); - strncpy(cstr, "T0_bin", sizeof(cstr)); - if (SearchAttrInData(cstr, attLen, attType)) { - if (!ErrorHandler(NXgetattr(fFileHandle, cstr, &ival, &attLen, &attType), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'T0_bin' data in NXdata group!")) return NX_ERROR; - } else { - std::cout << std::endl << ">> **WARNING** didn't find attribute 'T0_bin' in NXdata/counts, will try 't0_bin'." << std::endl; - memset(cstr, '\0', sizeof(cstr)); - strncpy(cstr, "t0_bin", sizeof(cstr)); - if (!ErrorHandler(NXgetattr(fFileHandle, cstr, &ival, &attLen, &attType), PNEXUS_OPEN_DATA_ERROR, "couldn't open 't0_bin' data in NXdata group!")) return NX_ERROR; - } - fNxEntry1->GetData()->SetT0(ival); - - // get first good bin - attLen = 1; - attType = NX_INT32; - memset(cstr, '\0', sizeof(cstr)); - strncpy(cstr, "first_good_bin", sizeof(cstr)); - if (!ErrorHandler(NXgetattr(fFileHandle, cstr, &ival, &attLen, &attType), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'first_good_bin' data in NXdata group!")) return NX_ERROR; - fNxEntry1->GetData()->SetFirstGoodBin(ival); - - // get last good bin - attLen = 1; - attType = NX_INT32; - memset(cstr, '\0', sizeof(cstr)); - strncpy(cstr, "last_good_bin", sizeof(cstr)); - if (!ErrorHandler(NXgetattr(fFileHandle, cstr, &ival, &attLen, &attType), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'last_good_bin' data in NXdata group!")) return NX_ERROR; - fNxEntry1->GetData()->SetLastGoodBin(ival); - - // get data - - // get information of the current nexus entity - int type, size, noOfElements; - if (!ErrorHandler(NXgetinfo(fFileHandle, &rank, dims, &type), PNEXUS_GET_META_INFO_ERROR, "couldn't get data info!")) return NX_ERROR; - - // calculate the needed size - size = dims[0]; - for (int i=1; iGetData()->FlushHistos(); - std::vector data; - for (int i=0; i0)) { - fNxEntry1->GetData()->SetHisto(data); - data.clear(); - data.push_back(*(i_data_ptr+i)); - } else { - data.push_back(*(i_data_ptr+i)); - } - } - fNxEntry1->GetData()->SetHisto(data); - data.clear(); - - // clean up - if (data_ptr) { - delete [] data_ptr; - } - - if (!ErrorHandler(NXclosedata(fFileHandle), PNEXUS_CLOSE_DATA_ERROR, "couldn't close 'counts' data in NXdata group")) return NX_ERROR; - - // get grouping - if (!ErrorHandler(NXopendata(fFileHandle, "grouping"), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'grouping' data in NXdata group!")) return NX_ERROR; - attLen = 1; - attType = NX_INT32; - memset(cstr, '\0', sizeof(cstr)); - strncpy(cstr, "available", sizeof(cstr)); - if (!ErrorHandler(NXgetattr(fFileHandle, cstr, &ival, &attLen, &attType), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'grouping available' data in NXdata group!")) return NX_ERROR; - if (ival) { - std::vector grouping; - if (!ErrorHandler(GetIntVectorData(grouping), PNEXUS_GET_DATA_ERROR, "couldn't read 'grouping' data in NXdata group!")) return NX_ERROR; - fNxEntry1->GetData()->SetGrouping(grouping); - grouping.clear(); - } - if (!ErrorHandler(NXclosedata(fFileHandle), PNEXUS_CLOSE_DATA_ERROR, "couldn't close 'grouping' data in NXdata group")) return NX_ERROR; - - // if grouping has been available check for consistency - bool ok=true; - if (ival) { // i.e. grouping is available (see a few lines further up) - // check grouping vector for consistency - if (fNxEntry1->GetData()->GetGrouping()->size() != fNxEntry1->GetData()->GetNoOfHistos()) { - fNxEntry1->GetData()->FlushGrouping(); - std::cerr << std::endl << ">> **WARNING** grouping vector size (" << fNxEntry1->GetData()->GetGrouping()->size()<< ") != no of histograms (" << fNxEntry1->GetData()->GetNoOfHistos() << ") which doesn't make sence, hence grouping will be ignored." << std::endl; - } - // check that the grouping values do make sense, i.e. allowed range is grouping value > 0 and grouping value <= # of histos - for (unsigned int i=0; iGetData()->GetGrouping()->size(); i++) { - if ((fNxEntry1->GetData()->GetGrouping()->at(i) == 0) || (fNxEntry1->GetData()->GetGrouping()->at(i) > (int)fNxEntry1->GetData()->GetNoOfHistos())) { - std::cerr << std::endl << ">> **WARNING** found grouping entry '" << fNxEntry1->GetData()->GetGrouping()->at(i) << "' which doesn't make sense, hence grouping will be ignored." << std::endl; - ok = false; - break; - } - } - if (!ok) - fNxEntry1->GetData()->FlushGrouping(); - } - - // get alpha - if (!ErrorHandler(NXopendata(fFileHandle, "alpha"), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'alpha' data in NXdata group!")) return NX_ERROR; - attLen = 1; - attType = NX_INT32; - memset(cstr, '\0', sizeof(cstr)); - strncpy(cstr, "available", sizeof(cstr)); - if (!ErrorHandler(NXgetattr(fFileHandle, cstr, &ival, &attLen, &attType), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'alpha available' data in NXdata group!")) return NX_ERROR; - if (ival) { - if (!ErrorHandler(NXgetinfo(fFileHandle, &rank, dims, &type), PNEXUS_GET_META_INFO_ERROR, "couldn't get alpha info!")) return NX_ERROR; - // calculate the needed size - size = dims[0]; - for (int i=1; i> **ERROR** " << fErrorMsg << std::endl; - return NX_ERROR; - } - - // allocate locale memory to get the data - char *data_ptr = new char[size]; - if (data_ptr == nullptr) { - return NX_ERROR; - } - - // get the data - float *f_data_ptr = (float*) data_ptr; - status = NXgetdata(fFileHandle, f_data_ptr); - if (status != NX_OK) { - return NX_ERROR; - } - - // copy the data into the vector - fNxEntry1->GetData()->FlushAlpha(); - PNeXusAlpha1 alpha; - std::vector alphaVec; - for (int i=0; iGetData()->SetAlpha(alphaVec); - - // clean up - alphaVec.clear(); - if (data_ptr) { - delete [] data_ptr; - } - } - if (!ErrorHandler(NXclosedata(fFileHandle), PNEXUS_CLOSE_DATA_ERROR, "couldn't close 'alpha' data in NXdata group")) return NX_ERROR; - - // close subgroup NXdata - NXclosegroup(fFileHandle); - - // close group NXentry - NXclosegroup(fFileHandle); - - // close file - NXclose(&fFileHandle); - - GroupHistoData(); - - fValid = true; - - return NX_OK; -} - -//------------------------------------------------------------------------------------------ -// ReadFileIdf2 (private) -//------------------------------------------------------------------------------------------ -/** - *

Read the NeXus file of type IDF Version 2. - * - * return: - * - NX_OK on successfull reading - * - NX_ERROR on error. The error code/message will give the details. - */ -int PNeXus::ReadFileIdf2() -{ - std::cout << std::endl << ">> reading NeXus IDF Version 2 file ..." << std::endl; - - // create first the necessary NXentry object for IDF Version 2 - fNxEntry2 = std::make_unique(); - if (fNxEntry2 == nullptr) { - fErrorCode = PNEXUS_OBJECT_INVOK_ERROR; - fErrorMsg = ">> **ERROR** couldn't invoke PNeXusEntry2 object."; - return NX_ERROR; - } - - std::string str; - int ival, attlen, atttype; - float fval; - NXname data_value, nxAttrName; - int rank, type, dims[32], size, noOfElements; - - // open file - NXstatus status; - status = NXopen(fFileName.c_str(), NXACC_READ, &fFileHandle); - if (status != NX_OK) { - fErrorCode = PNEXUS_FILE_OPEN_ERROR; - fErrorMsg = "PNeXus::ReadFileIdf2() **ERROR** Couldn't open file '"+fFileName+"' !"; - return NX_ERROR; - } - - // collect the NXroot attribute information - do { - status = NXgetnextattra(fFileHandle, nxAttrName, &rank, dims, &atttype); - if (status == NX_OK) { - if (!strcmp(nxAttrName, "HDF_version")) { - attlen = VGNAMELENMAX - 1; - atttype = NX_CHAR; - status = NXgetattr(fFileHandle, nxAttrName, data_value, &attlen, &atttype); - if (status == NX_OK) { - fFileFormatVersion = std::string(data_value); - } - } else if (!strcmp(nxAttrName, "HDF5_Version")) { - attlen = VGNAMELENMAX - 1; - atttype = NX_CHAR; - status = NXgetattr(fFileHandle, nxAttrName, data_value, &attlen, &atttype); - if (status == NX_OK) { - fFileFormatVersion = std::string("HDF5: ")+std::string(data_value); - } - } else if (!strcmp(nxAttrName, "XML_version")) { - attlen = VGNAMELENMAX - 1; - atttype = NX_CHAR; - status = NXgetattr(fFileHandle, nxAttrName, data_value, &attlen, &atttype); - if (status == NX_OK) { - fFileFormatVersion = std::string(data_value); - } - } else if (!strcmp(nxAttrName, "file_name")) { - if (!ErrorHandler(GetStringAttr("file_name", str), PNEXUS_GET_ATTR_ERROR, "couldn't read NXroot 'file_name' attribute!")) return NX_ERROR; - fFileName = str; - } else if (!strcmp(nxAttrName, "file_time")) { - if (!ErrorHandler(GetStringAttr("file_time", str), PNEXUS_GET_ATTR_ERROR, "couldn't read NXroot 'file_time' attribute!")) return NX_ERROR; - fFileTime = str; - } else if (!strcmp(nxAttrName, "creator")) { - if (!ErrorHandler(GetStringAttr("creator", str), PNEXUS_GET_ATTR_ERROR, "couldn't read NXroot 'creator' attribute!")) return NX_ERROR; - fCreator = str; - } - } - } while (status == NX_OK); - - // look for the first occurring NXentry which name ends on "_1" - NXname nxname, nxclass; - int dataType; - bool found = false; - size_t pos; - do { - status = NXgetnextentry(fFileHandle, nxname, nxclass, &dataType); - if (!strcmp(nxclass, "NXentry")) { - str = nxname; - pos = str.find_last_of("_1"); - if (pos != str.npos) - found = true; - } - } while (!found && (status == NX_OK)); - if (!found) { - fErrorCode = PNEXUS_NXENTRY_NOT_FOUND; - fErrorMsg = ">> **ERROR** Couldn't find any NXentry on NXroot level!"; - return NX_ERROR; - } - - // open the NXentry group to obtain the necessary stuff - status = NXopengroup(fFileHandle, nxname, "NXentry"); - if (status != NX_OK) { - fErrorCode = PNEXUS_GROUP_OPEN_ERROR; - fErrorMsg = "PNeXus::ReadFileIdf2() **ERROR** Couldn't open the NeXus group '" + std::string(nxname) + "'!"; - return NX_ERROR; - } - - // beamline - if (SearchInGroup("beamline", "name", nxname, nxclass, dataType)) { - if (!ErrorHandler(NXopendata(fFileHandle, "beamline"), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'beamline' data in NXentry!")) return NX_ERROR; - if (!ErrorHandler(GetStringData(str), PNEXUS_GET_DATA_ERROR, "couldn't read 'beamline' data in NXentry!")) return NX_ERROR; - if (!ErrorHandler(NXclosedata(fFileHandle), PNEXUS_CLOSE_DATA_ERROR, "couldn't close 'beamline' data in NXentry!")) return NX_ERROR; - fNxEntry2->GetInstrument()->GetBeamline()->SetName(str); - } - - // definition - if (!ErrorHandler(NXopendata(fFileHandle, "definition"), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'definition' data in NXentry!")) return NX_ERROR; - if (!ErrorHandler(GetStringData(str), PNEXUS_GET_DATA_ERROR, "couldn't read 'definition' data in NXentry!")) return NX_ERROR; - if (!ErrorHandler(NXclosedata(fFileHandle), PNEXUS_CLOSE_DATA_ERROR, "couldn't close 'definition' data in NXentry!")) return NX_ERROR; - fNxEntry2->SetDefinition(str); - - // program_name and version - if (SearchInGroup("program_name", "name", nxname, nxclass, dataType)) { - if (!ErrorHandler(NXopendata(fFileHandle, "program_name"), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'program_name' data in NXentry!")) return NX_ERROR; - if (!ErrorHandler(GetStringData(str), PNEXUS_GET_DATA_ERROR, "couldn't read 'program_name' data in NXentry!")) return NX_ERROR; - fNxEntry2->SetProgramName(str); - if (!ErrorHandler(GetStringAttr("version", str), PNEXUS_GET_ATTR_ERROR, "couldn't read 'program_name' attribute in NXentry!")) return NX_ERROR; - fNxEntry2->SetProgramVersion(str); - if (!ErrorHandler(NXclosedata(fFileHandle), PNEXUS_CLOSE_DATA_ERROR, "couldn't close 'program_name' data in NXentry!")) return NX_ERROR; - } - - // run number - if (!ErrorHandler(NXopendata(fFileHandle, "run_number"), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'run_number' data in NXentry!")) return NX_ERROR; - if (!ErrorHandler(NXgetdata(fFileHandle, &ival), PNEXUS_GET_DATA_ERROR, "couldn't read 'run_number' data in NXentry!")) return NX_ERROR; - if (!ErrorHandler(NXclosedata(fFileHandle), PNEXUS_CLOSE_DATA_ERROR, "couldn't close 'run_number' data in NXentry!")) return NX_ERROR; - fNxEntry2->SetRunNumber(ival); - - // title - if (!ErrorHandler(NXopendata(fFileHandle, "title"), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'title' data in NXentry!")) return NX_ERROR; - if (!ErrorHandler(GetStringData(str), PNEXUS_GET_DATA_ERROR, "couldn't read 'title' data in NXentry!")) return NX_ERROR; - if (!ErrorHandler(NXclosedata(fFileHandle), PNEXUS_CLOSE_DATA_ERROR, "couldn't close 'title' data in NXentry!")) return NX_ERROR; - fNxEntry2->SetTitle(str); - - // start time - if (!ErrorHandler(NXopendata(fFileHandle, "start_time"), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'start_time' data in NXentry!")) return NX_ERROR; - if (!ErrorHandler(GetStringData(str), PNEXUS_GET_DATA_ERROR, "couldn't read 'start_time' data in NXentry!")) return NX_ERROR; - if (!ErrorHandler(NXclosedata(fFileHandle), PNEXUS_CLOSE_DATA_ERROR, "couldn't close 'start_time' data in NXentry!")) return NX_ERROR; - if (fNxEntry2->SetStartTime(str) != NX_OK) { - fErrorCode = PNEXUS_TIME_FORMAT_ERROR; - fErrorMsg = "start time format is not ISO 8601 conform."; - } - - // end time - if (!ErrorHandler(NXopendata(fFileHandle, "end_time"), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'end_time' data in NXentry!")) return NX_ERROR; - if (!ErrorHandler(GetStringData(str), PNEXUS_GET_DATA_ERROR, "couldn't read 'end_time' data in NXentry!")) return NX_ERROR; - if (!ErrorHandler(NXclosedata(fFileHandle), PNEXUS_CLOSE_DATA_ERROR, "couldn't close 'end_time' data in NXentry!")) return NX_ERROR; - if (fNxEntry2->SetStopTime(str) != NX_OK) { - fErrorCode = PNEXUS_TIME_FORMAT_ERROR; - fErrorMsg = "stop time format is not ISO 8601 conform.."; - } - - // experiment identifier - if (!ErrorHandler(NXopendata(fFileHandle, "experiment_identifier"), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'experiment_identifier' data in NXentry!")) return NX_ERROR; - if (!ErrorHandler(GetStringData(str), PNEXUS_GET_DATA_ERROR, "couldn't read 'experiment_identifier' data in NXentry!")) return NX_ERROR; - if (!ErrorHandler(NXclosedata(fFileHandle), PNEXUS_CLOSE_DATA_ERROR, "couldn't close 'experiment_identifier' data in NXentry!")) return NX_ERROR; - fNxEntry2->SetExperimentIdentifier(str); - - // find entry for NXuser - if (SearchInGroup("NXuser", "class", nxname, nxclass, dataType)) { - // open the NXuser - status = NXopengroup(fFileHandle, nxname, "NXuser"); - if (status != NX_OK) { - fErrorCode = PNEXUS_GROUP_OPEN_ERROR; - fErrorMsg = "PNeXus::ReadFileIdf2() **ERROR** Couldn't open NXuser '" + std::string(nxname) + "' in NXentry!"; - return NX_ERROR; - } - - // user name - if (!ErrorHandler(NXopendata(fFileHandle, "name"), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'name' data in NXuser!")) return NX_ERROR; - if (!ErrorHandler(GetStringData(str), PNEXUS_GET_DATA_ERROR, "couldn't read 'name' data in NXuser!")) return NX_ERROR; - if (!ErrorHandler(NXclosedata(fFileHandle), PNEXUS_CLOSE_DATA_ERROR, "couldn't close 'name' data in NXuser!")) return NX_ERROR; - fNxEntry2->GetUser()->SetName(str); - - // close group NXuser - NXclosegroup(fFileHandle); - } - - // find entry for NXsample - if (SearchInGroup("NXsample", "class", nxname, nxclass, dataType)) { - // open group NXsample - if (!ErrorHandler(NXopengroup(fFileHandle, "sample", "NXsample"), PNEXUS_GROUP_OPEN_ERROR, "couldn't open NeXus subgroup sample!")) return NX_ERROR; - - // sample name - if (!ErrorHandler(NXopendata(fFileHandle, "name"), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'name' data in NXsample!")) return NX_ERROR; - if (!ErrorHandler(GetStringData(str), PNEXUS_GET_DATA_ERROR, "couldn't read 'name' data in NXsample!")) return NX_ERROR; - if (!ErrorHandler(NXclosedata(fFileHandle), PNEXUS_CLOSE_DATA_ERROR, "couldn't close 'name' data in NXsample!")) return NX_ERROR; - fNxEntry2->GetSample()->SetName(str); - - // sample description - if (SearchInGroup("description", "name", nxname, nxclass, dataType)) { - if (!ErrorHandler(NXopendata(fFileHandle, "description"), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'description' data in NXsample!")) return NX_ERROR; - if (!ErrorHandler(GetStringData(str), PNEXUS_GET_DATA_ERROR, "couldn't read 'description' data in NXsample!")) return NX_ERROR; - if (!ErrorHandler(NXclosedata(fFileHandle), PNEXUS_CLOSE_DATA_ERROR, "couldn't close 'description' data in NXsample!")) return NX_ERROR; - fNxEntry2->GetSample()->SetDescription(str); - } - - // temperature - if (SearchInGroup("temperature_1", "name", nxname, nxclass, dataType)) { - if (!ErrorHandler(NXopendata(fFileHandle, "temperature_1"), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'temperature_1' data in NXsample!")) return NX_ERROR; - if (!ErrorHandler(NXgetdata(fFileHandle, &fval), PNEXUS_GET_DATA_ERROR, "couldn't read 'temperature_1' data in NXsample!")) return NX_ERROR; - if (!ErrorHandler(GetStringAttr("units", str), PNEXUS_GET_ATTR_ERROR, "couldn't read temperature units in NXsample!")) return NX_ERROR; - if (!ErrorHandler(NXclosedata(fFileHandle), PNEXUS_CLOSE_DATA_ERROR, "couldn't close 'temperature_1' data in NXsample!")) return NX_ERROR; - fNxEntry2->GetSample()->SetPhysProp("temperature_1", fval, str); - } - - // temperature environment - if (SearchInGroup("temperature_1_env", "name", nxname, nxclass, dataType)) { - if (!ErrorHandler(NXopengroup(fFileHandle, "temperature_1_env", "NXenvironment"), PNEXUS_GROUP_OPEN_ERROR, "couldn't open NeXus subgroup NXenvironment!")) return NX_ERROR; - // temperature environment name - if (!ErrorHandler(NXopendata(fFileHandle, "name"), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'name' data in NXenvironment!")) return NX_ERROR; - if (!ErrorHandler(GetStringData(str), PNEXUS_GET_DATA_ERROR, "couldn't read 'name' data in NXenvironment!")) return NX_ERROR; - if (!ErrorHandler(NXclosedata(fFileHandle), PNEXUS_CLOSE_DATA_ERROR, "couldn't close 'name' data in NXenvironment!")) return NX_ERROR; - fNxEntry2->GetSample()->SetEnvironmentTemp(str); - // close group NXenvironment - NXclosegroup(fFileHandle); - } - - // magnetic_field - if (SearchInGroup("magnetic_field_1", "name", nxname, nxclass, dataType)) { - if (!ErrorHandler(NXopendata(fFileHandle, "magnetic_field_1"), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'magnetic_field_1' data in NXsample!")) return NX_ERROR; - if (!ErrorHandler(NXgetdata(fFileHandle, &fval), PNEXUS_GET_DATA_ERROR, "couldn't read 'magnetic_field_1' data in NXsample!")) return NX_ERROR; - if (!ErrorHandler(GetStringAttr("units", str), PNEXUS_GET_ATTR_ERROR, "couldn't read magnetic field units in NXsample!")) return NX_ERROR; - if (!ErrorHandler(NXclosedata(fFileHandle), PNEXUS_CLOSE_DATA_ERROR, "couldn't close 'magnetic_field_1' data in NXsample!")) return NX_ERROR; - fNxEntry2->GetSample()->SetPhysProp("magnetic_field_1", fval, str); - } - - // magnetic field state - if (SearchInGroup("magnetic_field_state", "name", nxname, nxclass, dataType)) { - if (!ErrorHandler(NXopendata(fFileHandle, "magnetic_field_state"), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'magnetic_field_state' data in NXsample!")) return NX_ERROR; - if (!ErrorHandler(GetStringData(str), PNEXUS_GET_DATA_ERROR, "couldn't read 'magnetic_field_state' data in NXsample!")) return NX_ERROR; - if (!ErrorHandler(NXclosedata(fFileHandle), PNEXUS_CLOSE_DATA_ERROR, "couldn't close 'magnetic_field_state' data in NXsample!")) return NX_ERROR; - fNxEntry2->GetSample()->SetMagneticFieldState(str); - } - - // magnetic field environment - if (SearchInGroup("magnetic_field_1_env", "name", nxname, nxclass, dataType)) { - if (!ErrorHandler(NXopengroup(fFileHandle, "magnetic_field_1_env", "NXenvironment"), PNEXUS_GROUP_OPEN_ERROR, "couldn't open NeXus subgroup NXenvironment!")) return NX_ERROR; - // magnetic field environment name - if (!ErrorHandler(NXopendata(fFileHandle, "name"), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'name' data in NXenvironment!")) return NX_ERROR; - if (!ErrorHandler(GetStringData(str), PNEXUS_GET_DATA_ERROR, "couldn't read 'name' data in NXenvironment!")) return NX_ERROR; - if (!ErrorHandler(NXclosedata(fFileHandle), PNEXUS_CLOSE_DATA_ERROR, "couldn't close 'name' data in NXenvironment!")) return NX_ERROR; - fNxEntry2->GetSample()->SetEnvironmentField(str); - // close group NXenvironment - NXclosegroup(fFileHandle); - } - - // close group NXsample - NXclosegroup(fFileHandle); - } - - // open group NXinstrument - if (!ErrorHandler(NXopengroup(fFileHandle, "instrument", "NXinstrument"), PNEXUS_GROUP_OPEN_ERROR, "couldn't open NeXus subgroup instrument in NXentry!")) return NX_ERROR; - - // name - if (!ErrorHandler(NXopendata(fFileHandle, "name"), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'name' data in NXinstrument!")) return NX_ERROR; - if (!ErrorHandler(GetStringData(str), PNEXUS_GET_DATA_ERROR, "couldn't read 'name' data in NXinstrument!")) return NX_ERROR; - if (!ErrorHandler(NXclosedata(fFileHandle), PNEXUS_CLOSE_DATA_ERROR, "couldn't close 'name' data in NXinstrument!")) return NX_ERROR; - fNxEntry2->GetInstrument()->SetName(str); - - // open group NXsource - if (!ErrorHandler(NXopengroup(fFileHandle, "source", "NXsource"), PNEXUS_GROUP_OPEN_ERROR, "couldn't open NeXus subgroup instrument in NXinstrument!")) return NX_ERROR; - - // name - if (!ErrorHandler(NXopendata(fFileHandle, "name"), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'name' data in NXsource!")) return NX_ERROR; - if (!ErrorHandler(GetStringData(str), PNEXUS_GET_DATA_ERROR, "couldn't read 'name' data in NXsource!")) return NX_ERROR; - if (!ErrorHandler(NXclosedata(fFileHandle), PNEXUS_CLOSE_DATA_ERROR, "couldn't close 'name' data in NXsource!")) return NX_ERROR; - fNxEntry2->GetInstrument()->GetSource()->SetName(str); - - // type - if (!ErrorHandler(NXopendata(fFileHandle, "type"), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'type' data in NXsource!")) return NX_ERROR; - if (!ErrorHandler(GetStringData(str), PNEXUS_GET_DATA_ERROR, "couldn't read 'type' data in NXsource!")) return NX_ERROR; - if (!ErrorHandler(NXclosedata(fFileHandle), PNEXUS_CLOSE_DATA_ERROR, "couldn't close 'type' data in NXsource!")) return NX_ERROR; - fNxEntry2->GetInstrument()->GetSource()->SetType(str); - - // probe - if (!ErrorHandler(NXopendata(fFileHandle, "probe"), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'probe' data in NXsource!")) return NX_ERROR; - if (!ErrorHandler(GetStringData(str), PNEXUS_GET_DATA_ERROR, "couldn't read 'probe' data in NXsource!")) return NX_ERROR; - if (!ErrorHandler(NXclosedata(fFileHandle), PNEXUS_CLOSE_DATA_ERROR, "couldn't close 'probe' data in NXsource!")) return NX_ERROR; - fNxEntry2->GetInstrument()->GetSource()->SetProbe(str); - - // close group NXsource - NXclosegroup(fFileHandle); - - - // open group NXbeamline - if (SearchInGroup("beamline", "name", nxname, nxclass, dataType)) { - if (!ErrorHandler(NXopengroup(fFileHandle, "beamline", "NXbeamline"), PNEXUS_GROUP_OPEN_ERROR, "couldn't open NeXus subgroup beamline in NXinstrument!")) return NX_ERROR; - - // beamline name - if (!ErrorHandler(NXopendata(fFileHandle, "beamline"), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'beamline' data in NXbeamline!")) return NX_ERROR; - if (!ErrorHandler(GetStringData(str), PNEXUS_GET_DATA_ERROR, "couldn't read 'beamline' data in NXbeamline!")) return NX_ERROR; - if (!ErrorHandler(NXclosedata(fFileHandle), PNEXUS_CLOSE_DATA_ERROR, "couldn't close 'beamline' data in NXbeamline!")) return NX_ERROR; - fNxEntry2->GetInstrument()->GetBeamline()->SetName(str); - - // close group NXbeamline - NXclosegroup(fFileHandle); - } else { - std::cerr << "**WARNING** in class NXinstrument the object NXbeamline with name 'beamline' is missing!" << std::endl; - std::cerr << " Complain at the facility where you got this data file from!" << std::endl; - } - - // open group NXdetector in instrument (NXinstrument) - if (!ErrorHandler(NXopengroup(fFileHandle, "detector_1", "NXdetector"), PNEXUS_GROUP_OPEN_ERROR, "couldn't open NeXus subgroup detector_1 in NXinstrument!")) return NX_ERROR; - - // description - if (SearchInGroup("description", "name", nxname, nxclass, dataType)) { - if (!ErrorHandler(NXopendata(fFileHandle, "description"), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'description' data in NXdetector!")) return NX_ERROR; - if (!ErrorHandler(GetStringData(str), PNEXUS_GET_DATA_ERROR, "couldn't read 'description' data in NXdetector!")) return NX_ERROR; - if (!ErrorHandler(NXclosedata(fFileHandle), PNEXUS_CLOSE_DATA_ERROR, "couldn't close 'description' data in NXdetector!")) return NX_ERROR; - fNxEntry2->GetInstrument()->GetDetector()->SetDescription(str); - } else { - std::cerr << "**WARNING** in class NXdetector to object NX_CHAR with name 'description' is missing!" << std::endl; - std::cerr << " Complain at the facility where you got this data file from!" << std::endl; - } - - // get the time resolution. This is a little bit complicated since it is either present as 'histogram_resolution' or needs to be extracted from the 'raw_time' vector - // 1st check if 'histogram_resolution' is found - if (SearchInGroup("histogram_resolution", "name", nxname, nxclass, dataType)) { - if (!ErrorHandler(NXopendata(fFileHandle, "histogram_resolution"), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'histogram_resolution' data in NXdetector!")) return NX_ERROR; - if (!ErrorHandler(NXgetdata(fFileHandle, &fval), PNEXUS_GET_DATA_ERROR, "couldn't read 'histogram_resolution' data in NXdetector!")) return NX_ERROR; - if (!ErrorHandler(GetStringAttr("units", str), PNEXUS_GET_ATTR_ERROR, "couldn't read time resolution units in NXdetector!")) return NX_ERROR; - if (!ErrorHandler(NXclosedata(fFileHandle), PNEXUS_CLOSE_DATA_ERROR, "couldn't close 'histogram_resolution' data in NXdetector!")) return NX_ERROR; - fNxEntry2->GetInstrument()->GetDetector()->SetTimeResolution((double)fval, str); - } else if (SearchInGroup("resolution", "name", nxname, nxclass, dataType)) { // 2nd check if 'resolution' is found - if (!ErrorHandler(NXopendata(fFileHandle, "resolution"), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'resolution' data in NXdetector!")) return NX_ERROR; - if (!ErrorHandler(NXgetdata(fFileHandle, &ival), PNEXUS_GET_DATA_ERROR, "couldn't read 'resolution' data in NXdetector!")) return NX_ERROR; - if (!ErrorHandler(GetStringAttr("units", str), PNEXUS_GET_ATTR_ERROR, "couldn't read time resolution units in NXdetector!")) return NX_ERROR; - if (!ErrorHandler(NXclosedata(fFileHandle), PNEXUS_CLOSE_DATA_ERROR, "couldn't close 'resolution' data in NXdetector!")) return NX_ERROR; - fNxEntry2->GetInstrument()->GetDetector()->SetTimeResolution((double)ival, str); - } else { // 3nd 'histogram_resolution' is not present, hence extract the time resolution from the 'raw_time' vector - if (!ErrorHandler(NXopendata(fFileHandle, "raw_time"), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'raw_time' data in NXdetector!")) return NX_ERROR; - std::vector rawTime; - if (!ErrorHandler(GetDoubleVectorData(rawTime), PNEXUS_GET_DATA_ERROR, "couldn't get 'raw_time' data in NXdetector!")) return NX_ERROR; - if (!ErrorHandler(GetStringAttr("units", str), PNEXUS_GET_ATTR_ERROR, "couldn't read 'raw_time' units in NXdetector!")) return NX_ERROR; - if (!ErrorHandler(NXclosedata(fFileHandle), PNEXUS_CLOSE_DATA_ERROR, "couldn't close 'raw_time' data in NXdetector!")) return NX_ERROR; - fNxEntry2->GetInstrument()->GetDetector()->SetTimeResolution(rawTime[1]-rawTime[0], str); - rawTime.clear(); - } - - // get counts - if (!ErrorHandler(NXopendata(fFileHandle, "counts"), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'counts' data in NXdetector!")) return NX_ERROR; - // check the dimensions of 'counts' - if (!ErrorHandler(NXgetinfo(fFileHandle, &rank, dims, &type), PNEXUS_GET_META_INFO_ERROR, "couldn't get 'counts' info in NXdetector!")) return NX_ERROR; - - // check if last_good_bin, first_good_bin, and t0_bins are defined as attributes - int attLen = 1, attType = NX_INT32; - if (SearchAttrInData("first_good_bin", attLen, attType)) { - char cstr[1204]; - memset(cstr, '\0', sizeof(cstr)); - strncpy(cstr, "first_good_bin", sizeof(cstr)); - status = NXgetattr(fFileHandle, cstr, (void*)&ival, &attLen, &attType); - - fNxEntry2->GetInstrument()->GetDetector()->SetT0Tag(1); // a single set for t0, fgb, lgb is likely given - int *i_data_ptr = new int; - *i_data_ptr = ival; - if (!fNxEntry2->GetInstrument()->GetDetector()->SetFirstGoodBin(i_data_ptr)) { - std::cerr << std::endl << ">> **ERROR** " << fNxEntry2->GetInstrument()->GetDetector()->GetErrorMsg() << std::endl; - return NX_ERROR; - } + std::ifstream file(filename, std::ios::binary); + if (!file.is_open()) { + std::cerr << "Error: Cannot open file '" << filename << "'" << std::endl; + return nxs::HDFType::Unknown; } - if (SearchAttrInData("last_good_bin", attLen, attType)) { - char cstr[1204]; - memset(cstr, '\0', sizeof(cstr)); - strncpy(cstr, "last_good_bin", sizeof(cstr)); - status = NXgetattr(fFileHandle, cstr, (void*)&ival, &attLen, &attType); - fNxEntry2->GetInstrument()->GetDetector()->SetT0Tag(1); // a single set for t0, fgb, lgb is likely given - int *i_data_ptr = new int; - *i_data_ptr = ival; - if (!fNxEntry2->GetInstrument()->GetDetector()->SetLastGoodBin(i_data_ptr)) { - std::cerr << std::endl << ">> **ERROR** " << fNxEntry2->GetInstrument()->GetDetector()->GetErrorMsg() << std::endl; - return NX_ERROR; - } - } - if (SearchAttrInData("t0_bin", attLen, attType)) { - char cstr[1204]; - memset(cstr, '\0', sizeof(cstr)); - strncpy(cstr, "t0_bin", sizeof(cstr)); - status = NXgetattr(fFileHandle, cstr, (void*)&ival, &attLen, &attType); - - fNxEntry2->GetInstrument()->GetDetector()->SetT0Tag(1); // a single set for t0, fgb, lgb is likely given - int *i_data_ptr = new int; - *i_data_ptr = ival; - if (!fNxEntry2->GetInstrument()->GetDetector()->SetT0(i_data_ptr)) { - std::cerr << std::endl << ">> **ERROR** " << fNxEntry2->GetInstrument()->GetDetector()->GetErrorMsg() << std::endl; - return NX_ERROR; - } - } - - // calculate the needed size - size = dims[0]; - for (int i=1; iGetInstrument()->GetDetector()->SetNoOfPeriods(dims[0]); - fNxEntry2->GetInstrument()->GetDetector()->SetNoOfSpectra(dims[1]); - fNxEntry2->GetInstrument()->GetDetector()->SetNoOfBins(dims[2]); - } else if (rank == 2) { // i.e. ns, ntc - fNxEntry2->GetInstrument()->GetDetector()->SetNoOfPeriods(-1); - fNxEntry2->GetInstrument()->GetDetector()->SetNoOfSpectra(dims[0]); - fNxEntry2->GetInstrument()->GetDetector()->SetNoOfBins(dims[1]); - } else if (rank == 1) { // i.e. ntc only - fNxEntry2->GetInstrument()->GetDetector()->SetNoOfPeriods(-1); - fNxEntry2->GetInstrument()->GetDetector()->SetNoOfSpectra(1); - fNxEntry2->GetInstrument()->GetDetector()->SetNoOfBins(dims[0]); - } else { - fNxEntry2->GetInstrument()->GetDetector()->SetNoOfPeriods(-1); - fNxEntry2->GetInstrument()->GetDetector()->SetNoOfSpectra(-1); - fNxEntry2->GetInstrument()->GetDetector()->SetNoOfBins(-1); - std::cerr << std::endl << ">> **ERROR** found rank=" << rank << " for NXinstrument:NXdetector:counts! Allowed ranks are 1, 2, or 3." << std::endl; - return NX_ERROR; - } - - if (!fNxEntry2->GetInstrument()->GetDetector()->SetHistos(i_data_ptr)) { - std::cerr << std::endl << ">> **ERROR** " << fNxEntry2->GetInstrument()->GetDetector()->GetErrorMsg() << std::endl; - return NX_ERROR; - } - - // clean up - if (data_ptr) { - delete [] data_ptr; - data_ptr = nullptr; - } - - if (!ErrorHandler(NXclosedata(fFileHandle), PNEXUS_CLOSE_DATA_ERROR, "couldn't close 'counts' data in NXdetector!")) return NX_ERROR; - - // handle spectrum_index - if (!ErrorHandler(NXopendata(fFileHandle, "spectrum_index"), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'spectrum_index' data in NXdetector!")) return NX_ERROR; - // check the dimensions of 'spectrum_index' - if (!ErrorHandler(NXgetinfo(fFileHandle, &rank, dims, &type), PNEXUS_GET_META_INFO_ERROR, "couldn't get 'spectrum_index' info in NXdetector!")) return NX_ERROR; - if (rank > 1) { - std::cerr << std::endl << ">> **ERROR** found rank=" << rank << " of spectrum_index in NXdetector. Rank needs to be == 1!" << std::endl; - return NX_ERROR; - } - if (dims[0] != fNxEntry2->GetInstrument()->GetDetector()->GetNoOfSpectra()) { - std::cerr << std::endl << ">> **ERROR** found spectrum_index dimension=" << dims[0] << " inconsistent with counts (" << fNxEntry2->GetInstrument()->GetDetector()->GetNoOfSpectra() << "!" << std::endl; - return NX_ERROR; - } - // allocate locale memory to get the data - data_ptr = new char[dims[0]*GetDataSize(type)]; - if (data_ptr == nullptr) { - return NX_ERROR; - } - // get the data - i_data_ptr = (int*) data_ptr; - status = NXgetdata(fFileHandle, i_data_ptr); - if (status != NX_OK) { - return NX_ERROR; - } - for (int i=0; iGetInstrument()->GetDetector()->SetSpectrumIndex(*(i_data_ptr+i), i); - - // clean up - if (data_ptr) { - delete [] data_ptr; - data_ptr = nullptr; - } - - if (!ErrorHandler(NXclosedata(fFileHandle), PNEXUS_CLOSE_DATA_ERROR, "couldn't close 'spectrum_index' data in NXdetector!")) return NX_ERROR; - - // only handle t0, fgb, lgb, if they are not already set as an attribute of /raw_data_1/instrument/detector_1/counts - if (fNxEntry2->GetInstrument()->GetDetector()->GetT0Tag() == -1) { - // handle t0's - if (SearchInGroup("time_zero_bin", "name", nxname, nxclass, dataType)) { // check for 'time_zero_bin' - if (!ErrorHandler(NXopendata(fFileHandle, "time_zero_bin"), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'time_zero_bin' data in NXdetector!")) return NX_ERROR; - - // check the dimensions of the 'time_zero_bin' vector - if (!ErrorHandler(NXgetinfo(fFileHandle, &rank, dims, &type), PNEXUS_GET_META_INFO_ERROR, "couldn't get 'time_zero_bin' info in NXdetector!")) return NX_ERROR; - - if ((rank == 1) && (dims[0] == 1)) { // single t0 entry - fNxEntry2->GetInstrument()->GetDetector()->SetT0Tag(1); - } else if ((rank == 1) && (dims[0] > 1)) { // t0 of the form t0[ns] - fNxEntry2->GetInstrument()->GetDetector()->SetT0Tag(2); - } else if (rank == 2) { // t0 of the form t0[np][ns] - fNxEntry2->GetInstrument()->GetDetector()->SetT0Tag(3); - } else { - std::cerr << std::endl << ">> **ERROR** found 'time_zero_bin' info in NXdetector with rank=" << rank << ". Do not know how to handle." << std::endl; - return NX_ERROR; - } - - // calculate the needed size - size = dims[0]; - for (int i=1; iGetInstrument()->GetDetector()->SetT0(i_data_ptr)) { - std::cerr << std::endl << ">> **ERROR** " << fNxEntry2->GetInstrument()->GetDetector()->GetErrorMsg() << std::endl; - return NX_ERROR; - } - - // clean up - if (data_ptr) { - delete [] data_ptr; - data_ptr = nullptr; - } - - if (!ErrorHandler(NXclosedata(fFileHandle), PNEXUS_CLOSE_DATA_ERROR, "couldn't close 'time_zero_bin' data in NXdetector!")) return NX_ERROR; - } else if (SearchInGroup("time_zero", "name", nxname, nxclass, dataType)) { // check for 'time_zero' - if (!ErrorHandler(NXopendata(fFileHandle, "time_zero"), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'time_zero' data in NXdetector!")) return NX_ERROR; - // check the dimensions of the 'time_zero' vector - if (!ErrorHandler(NXgetinfo(fFileHandle, &rank, dims, &type), PNEXUS_GET_META_INFO_ERROR, "couldn't get 'time_zero' info in NXdetector!")) return NX_ERROR; - - if ((rank == 1) && (dims[0] == 1)) { // single t0 entry - fNxEntry2->GetInstrument()->GetDetector()->SetT0Tag(1); - } else if ((rank == 1) && (dims[0] > 1)) { // t0 of the form t0[ns] - fNxEntry2->GetInstrument()->GetDetector()->SetT0Tag(2); - } else if (rank == 2) { // t0 of the form t0[np][ns] - fNxEntry2->GetInstrument()->GetDetector()->SetT0Tag(3); - } else { - std::cerr << std::endl << ">> **ERROR** found 'time_zero' info in NXdetector with rank=" << rank << ". Do not know how to handle." << std::endl; - return NX_ERROR; - } - - // calculate the needed size - size = dims[0]; - for (int i=1; iGetInstrument()->GetDetector()->GetTimeResolution(str) == 0.0) { - std::cerr << std::endl << ">> **ERROR** trying to set T0's based on 'time_zero'. Need a valid time resolution to do so, but this is not given." << std::endl; - return NX_ERROR; - } - // set the t0's based on the t0 time stamp and the time resolution - int *pt0 = nullptr; - if (rank == 1) { - pt0 = new int; - *pt0 = (int)(*f_data_ptr / (float)fNxEntry2->GetInstrument()->GetDetector()->GetTimeResolution(str)); - } else { // rank == 2 - pt0 = new int[noOfElements]; - for (int i=0; iGetInstrument()->GetDetector()->GetTimeResolution(str)); - } - } - - if (!fNxEntry2->GetInstrument()->GetDetector()->SetT0(pt0)) { - std::cerr << std::endl << ">> **ERROR** " << fNxEntry2->GetInstrument()->GetDetector()->GetErrorMsg() << std::endl; - return NX_ERROR; - } - - // clean up - if (data_ptr) { - delete [] data_ptr; - data_ptr = nullptr; - } - - std::cerr << std::endl << ">> **WARNING** found only 'time_zero' will convert it to 'time_zero_bin' values" << std::endl; - if (!ErrorHandler(NXclosedata(fFileHandle), PNEXUS_CLOSE_DATA_ERROR, "couldn't close 'time_zero' data in NXdetector!")) return NX_ERROR; - } else { - std::cerr << std::endl << ">> **WARNING** found neither 'time_zero_bin' nor 'time_zero' values ..." << std::endl; - } - - // handle first good bin - if (SearchInGroup("first_good_bin", "name", nxname, nxclass, dataType)) { - if (!ErrorHandler(NXopendata(fFileHandle, "first_good_bin"), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'first_good_bin' data in NXdetector!")) return NX_ERROR; - - // check the dimensions of the 'first_good_bin' vector - if (!ErrorHandler(NXgetinfo(fFileHandle, &rank, dims, &type), PNEXUS_GET_META_INFO_ERROR, "couldn't get 'first_good_bin' info in NXdetector!")) return NX_ERROR; - - // calculate the needed size - size = dims[0]; - for (int i=1; iGetInstrument()->GetDetector()->SetFirstGoodBin(i_data_ptr)) { - std::cerr << std::endl << ">> **ERROR** " << fNxEntry2->GetInstrument()->GetDetector()->GetErrorMsg() << std::endl; - return NX_ERROR; - } - - if (data_ptr) { - delete [] data_ptr; - data_ptr = nullptr; - } - - if (!ErrorHandler(NXclosedata(fFileHandle), PNEXUS_CLOSE_DATA_ERROR, "couldn't close 'first_good_bin' data in NXdetector!")) return NX_ERROR; - } else if (SearchInGroup("first_good_time", "name", nxname, nxclass, dataType)) { - if (!ErrorHandler(NXopendata(fFileHandle, "first_good_time"), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'first_good_time' data in NXdetector!")) return NX_ERROR; - - // check the dimensions of the 'first_good_time' vector - if (!ErrorHandler(NXgetinfo(fFileHandle, &rank, dims, &type), PNEXUS_GET_META_INFO_ERROR, "couldn't get 'first_good_time' info in NXdetector!")) return NX_ERROR; - - // calculate the needed size - size = dims[0]; - for (int i=1; iGetInstrument()->GetDetector()->GetTimeResolution(str)); - } else { // rank == 2 - p_fgb = new int[noOfElements]; - for (int i=0; iGetInstrument()->GetDetector()->GetTimeResolution(str)); - } - } - - if (!fNxEntry2->GetInstrument()->GetDetector()->SetFirstGoodBin(p_fgb)) { - std::cerr << std::endl << ">> **ERROR** " << fNxEntry2->GetInstrument()->GetDetector()->GetErrorMsg() << std::endl; - return NX_ERROR; - } - - // clean up - if (p_fgb) { - delete [] p_fgb; - p_fgb = 0; - } - if (data_ptr) { - delete [] data_ptr; - data_ptr = nullptr; - } - - if (!ErrorHandler(NXclosedata(fFileHandle), PNEXUS_CLOSE_DATA_ERROR, "couldn't close 'first_good_time' data in NXdetector!")) return NX_ERROR; - } else { - std::cerr << std::endl << ">> **WARNING** found neither 'first_good_bin' nor 'first_good_time' values ..." << std::endl; - } - - // handle last good bin - if (SearchInGroup("last_good_bin", "name", nxname, nxclass, dataType)) { - if (!ErrorHandler(NXopendata(fFileHandle, "last_good_bin"), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'last_good_bin' data in NXdetector!")) return NX_ERROR; - - // check the dimensions of the 'last_good_bin' vector - if (!ErrorHandler(NXgetinfo(fFileHandle, &rank, dims, &type), PNEXUS_GET_META_INFO_ERROR, "couldn't get 'last_good_bin' info in NXdetector!")) return NX_ERROR; - - // calculate the needed size - size = dims[0]; - for (int i=1; iGetInstrument()->GetDetector()->SetLastGoodBin(i_data_ptr)) { - std::cerr << std::endl << ">> **ERROR** " << fNxEntry2->GetInstrument()->GetDetector()->GetErrorMsg() << std::endl; - return NX_ERROR; - } - - // clean up - if (data_ptr) { - delete [] data_ptr; - data_ptr = nullptr; - } - - if (!ErrorHandler(NXclosedata(fFileHandle), PNEXUS_CLOSE_DATA_ERROR, "couldn't close 'last_good_bin' data in NXdetector!")) return NX_ERROR; - } else if (SearchInGroup("last_good_time", "name", nxname, nxclass, dataType)) { - if (!ErrorHandler(NXopendata(fFileHandle, "last_good_time"), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'last_good_time' data in NXdetector!")) return NX_ERROR; - - // check the dimensions of the 'last_good_time' vector - if (!ErrorHandler(NXgetinfo(fFileHandle, &rank, dims, &type), PNEXUS_GET_META_INFO_ERROR, "couldn't get 'last_good_time' info in NXdetector!")) return NX_ERROR; - - // calculate the needed size - size = dims[0]; - for (int i=1; iGetInstrument()->GetDetector()->GetTimeResolution(str)); - } else { // rank == 2 - p_lgb = new int[noOfElements]; - for (int i=0; iGetInstrument()->GetDetector()->GetTimeResolution(str)); - } - } - - if (fNxEntry2->GetInstrument()->GetDetector()->SetFirstGoodBin(p_lgb)) { - std::cerr << std::endl << ">> **ERROR** " << fNxEntry2->GetInstrument()->GetDetector()->GetErrorMsg() << std::endl; - return NX_ERROR; - } - - // clean up - if (p_lgb) { - delete [] p_lgb; - p_lgb = 0; - } - if (data_ptr) { - delete [] data_ptr; - data_ptr = nullptr; - } - - if (!ErrorHandler(NXclosedata(fFileHandle), PNEXUS_CLOSE_DATA_ERROR, "couldn't close 'last_good_time' data in NXdetector!")) return NX_ERROR; - } else { - std::cerr << std::endl << ">> **WARNING** found neither 'last_good_bin' nor 'last_good_time' values ..." << std::endl; - } - } - - // close group NXdetector - NXclosegroup(fFileHandle); - - // close group NXinstrument - NXclosegroup(fFileHandle); - - // GET DATA : STILL MISSING : The real data are found under NXentry:NXinstrument:NXdetector - // CHECK if it is necessary to read ANY of these data - - // close group NXentry - NXclosegroup(fFileHandle); - - // close file - NXclose(&fFileHandle); - - fValid = true; - - return NX_OK; -} - -//------------------------------------------------------------------------------------------ -// GroupHistoData (private) -//------------------------------------------------------------------------------------------ -/** - *

Feed the grouped histo data, based on the grouping vector and the raw histo data. - */ -NXstatus PNeXus::GroupHistoData() -{ - if (fIdfVersion == 1) { - // check if NO grouping is whished - if (fNxEntry1->GetData()->GetGrouping()->size() == 0) { - return NX_OK; - } - - // check that the grouping size is equal to the number of histograms - if (fNxEntry1->GetData()->GetGrouping()->size() != fNxEntry1->GetData()->GetNoOfHistos()) { - fErrorCode = PNEXUS_HISTO_ERROR; - fErrorMsg = "grouping vector size is unequal to the number of histos present!"; - return NX_ERROR; - } - - // make a vector of all grouping present - std::vector groupingValue; - bool newGroup = true; - for (unsigned int i=0; iGetData()->GetGrouping()->size(); i++) { - newGroup = true; - for (unsigned int j=0; jGetData()->GetGrouping()->at(i)) { - newGroup = false; - break; - } - } - if (newGroup) - groupingValue.push_back(fNxEntry1->GetData()->GetGrouping()->at(i)); - } - - // check that none of the grouping values is outside of the valid range - for (unsigned int i=0; i= fNxEntry1->GetData()->GetNoOfHistos()) { - fErrorCode = PNEXUS_HISTO_ERROR; - fErrorMsg = "grouping values out of range"; - return NX_ERROR; - } - } - - // set fGroupedHisto to the proper size - fGroupedHisto.clear(); - fGroupedHisto.resize(groupingValue.size()); - for (unsigned int i=0; iGetData()->GetHisto(0)->size()); - } - - for (unsigned int i=0; iGetData()->GetNoOfHistos(); i++) { - for (unsigned int j=0; jGetData()->GetHisto(i)->size(); j++) { - fGroupedHisto[fNxEntry1->GetData()->GetGrouping()->at(i)-1][j] += fNxEntry1->GetData()->GetHisto(i)->at(j); - } - } - - // cleanup - groupingValue.clear(); - } else if (fIdfVersion == 2) { - // will probably do nothing here - } else { - fErrorCode = PNEXUS_HISTO_ERROR; - fErrorMsg = "unsupported IDF"; - return NX_ERROR; - } - - return NX_OK; -} - -//------------------------------------------------------------------------------------------ -// WriteFileIdf1 (private) -//------------------------------------------------------------------------------------------ -/** - *

Write the NeXus file of type IDF Version 1. - * - * return: - * - NX_OK on successfull writting - * - NX_ERROR on error. The error code/message will give the details. - * - * \param fileName file name - * \param access flag needed to know in which format (HDF4, HDF5, or XML) the file shall be written. - */ -int PNeXus::WriteFileIdf1(const char* fileName, const NXaccess access) -{ - std::string str; - char cstr[1204]; - bool ok = false; - int size, idata; - float fdata; - - memset(cstr, '\0', sizeof(cstr)); - snprintf(cstr, sizeof(cstr), "couldn't open file '%s' for writing", fileName); - if (!ErrorHandler(NXopen(fileName, access, &fFileHandle), PNEXUS_FILE_OPEN_ERROR, cstr)) return NX_ERROR; - - // write NXfile attribute NeXus_version - memset(cstr, '\0', sizeof(cstr)); - strncpy(cstr, NEXUS_VERSION, sizeof(cstr)); - if (!ErrorHandler(NXputattr(fFileHandle, "NeXus_version", cstr, strlen(cstr), NX_CHAR), PNEXUS_SET_ATTR_ERROR, "couldn't set NXfile attribute 'NeXus_version'")) return NX_ERROR; - - memset(cstr, '\0', sizeof(cstr)); - strncpy(cstr, fNxEntry1->GetUser()->GetName().c_str(), sizeof(cstr)); - if (!ErrorHandler(NXputattr(fFileHandle, "user", cstr, strlen(cstr), NX_CHAR), PNEXUS_SET_ATTR_ERROR, "couldn't set NXfile attributes")) return NX_ERROR; - - // make group 'run' - if (!ErrorHandler(NXmakegroup(fFileHandle, "run", "NXentry"), PNEXUS_CREATE_GROUP_ERROR, "couldn't create group 'NXfile/run'.")) return NX_ERROR; - // open group 'run' - if (!ErrorHandler(NXopengroup(fFileHandle, "run", "NXentry"), PNEXUS_GROUP_OPEN_ERROR, "couldn't open group 'NXfile/run' for writting.")) return NX_ERROR; - - // write IDF_version - size = 1; - if (!ErrorHandler(NXmakedata(fFileHandle, "IDF_version", NX_INT32, 1, &size), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'NXentry/IDF_version'.")) return NX_ERROR; - if (!ErrorHandler(NXopendata(fFileHandle, "IDF_version"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'NXentry/IDF_version' for writting.")) return NX_ERROR; - idata = fIdfVersion; - if (!ErrorHandler(NXputdata(fFileHandle, &idata), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'NXentry/IDF_version'.")) return NX_ERROR; - NXclosedata(fFileHandle); - - // write program_name, and attribute version - size = fNxEntry1->GetProgramName().length(); - if (!ErrorHandler(NXmakedata(fFileHandle, "program_name", NX_CHAR, 1, &size), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'NXentry/program_name'.")) return NX_ERROR; - if (!ErrorHandler(NXopendata(fFileHandle, "program_name"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'NXentry/program_name' for writting.")) return NX_ERROR; - memset(cstr, '\0', sizeof(cstr)); - strncpy(cstr, fNxEntry1->GetProgramName().c_str(), sizeof(cstr)); - if (!ErrorHandler(NXputdata(fFileHandle, cstr), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'NXentry/program_name'.")) return NX_ERROR; - memset(cstr, '\0', sizeof(cstr)); - strncpy(cstr, fNxEntry1->GetProgramVersion().c_str(), sizeof(cstr)); - if (!ErrorHandler(NXputattr(fFileHandle, "version", cstr, strlen(cstr), NX_CHAR), PNEXUS_PUT_ATTR_ERROR, "couldn't put attribute 'version' for 'NXentry/program_name'")) return NX_ERROR; - NXclosedata(fFileHandle); - - // write run 'number' - size = 1; - if (!ErrorHandler(NXmakedata(fFileHandle, "number", NX_INT32, 1, &size), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'NXentry/number'.")) return NX_ERROR; - if (!ErrorHandler(NXopendata(fFileHandle, "number"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'NXentry/number' for writting.")) return NX_ERROR; - idata = fNxEntry1->GetRunNumber(); - if (!ErrorHandler(NXputdata(fFileHandle, &idata), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'NXentry/number'.")) return NX_ERROR; - NXclosedata(fFileHandle); - - // write run 'title' - size = fNxEntry1->GetTitle().length(); - if (!ErrorHandler(NXmakedata(fFileHandle, "title", NX_CHAR, 1, &size), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'NXentry/title'.")) return NX_ERROR; - if (!ErrorHandler(NXopendata(fFileHandle, "title"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'NXentry/title' for writting.")) return NX_ERROR; - memset(cstr, '\0', sizeof(cstr)); - strncpy(cstr, fNxEntry1->GetTitle().c_str(), sizeof(cstr)); - if (!ErrorHandler(NXputdata(fFileHandle, cstr), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'NXentry/title'.")) return NX_ERROR; - NXclosedata(fFileHandle); - - // write run 'notes' - size = fNxEntry1->GetNotes().length(); - if (!ErrorHandler(NXmakedata(fFileHandle, "notes", NX_CHAR, 1, &size), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'NXentry/notes'.")) return NX_ERROR; - if (!ErrorHandler(NXopendata(fFileHandle, "notes"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'NXentry/notes' for writting.")) return NX_ERROR; - memset(cstr, '\0', sizeof(cstr)); - strncpy(cstr, fNxEntry1->GetNotes().c_str(), sizeof(cstr)); - if (!ErrorHandler(NXputdata(fFileHandle, cstr), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'NXentry/notes'.")) return NX_ERROR; - NXclosedata(fFileHandle); - - // write run 'analysis' - size = fNxEntry1->GetAnalysis().length(); - if (!ErrorHandler(NXmakedata(fFileHandle, "analysis", NX_CHAR, 1, &size), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'NXentry/analysis'.")) return NX_ERROR; - if (!ErrorHandler(NXopendata(fFileHandle, "analysis"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'NXentry/analysis' for writting.")) return NX_ERROR; - memset(cstr, '\0', sizeof(cstr)); - strncpy(cstr, fNxEntry1->GetAnalysis().c_str(), sizeof(cstr)); - if (!ErrorHandler(NXputdata(fFileHandle, cstr), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'NXentry/analysis'.")) return NX_ERROR; - NXclosedata(fFileHandle); - - // write run 'lab' - size = fNxEntry1->GetLaboratory().length(); - if (!ErrorHandler(NXmakedata(fFileHandle, "lab", NX_CHAR, 1, &size), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'NXentry/lab'.")) return NX_ERROR; - if (!ErrorHandler(NXopendata(fFileHandle, "lab"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'NXentry/lab' for writting.")) return NX_ERROR; - memset(cstr, '\0', sizeof(cstr)); - strncpy(cstr, fNxEntry1->GetLaboratory().c_str(), sizeof(cstr)); - if (!ErrorHandler(NXputdata(fFileHandle, cstr), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'NXentry/lab'.")) return NX_ERROR; - NXclosedata(fFileHandle); - - // write run 'beamline' - size = fNxEntry1->GetBeamline().length(); - if (!ErrorHandler(NXmakedata(fFileHandle, "beamline", NX_CHAR, 1, &size), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'NXentry/beamline'.")) return NX_ERROR; - if (!ErrorHandler(NXopendata(fFileHandle, "beamline"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'NXentry/beamline' for writting.")) return NX_ERROR; - memset(cstr, '\0', sizeof(cstr)); - strncpy(cstr, fNxEntry1->GetBeamline().c_str(), sizeof(cstr)); - if (!ErrorHandler(NXputdata(fFileHandle, cstr), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'NXentry/beamline'.")) return NX_ERROR; - NXclosedata(fFileHandle); - - // write run 'start_time' - memset(cstr, '\0', sizeof(cstr)); - strncpy(cstr, fNxEntry1->GetStartTime().c_str(), sizeof(cstr)); - size = strlen(cstr); - if (!ErrorHandler(NXmakedata(fFileHandle, "start_time", NX_CHAR, 1, &size), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'NXentry/start_time'.")) return NX_ERROR; - if (!ErrorHandler(NXopendata(fFileHandle, "start_time"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'NXentry/start_time' for writting.")) return NX_ERROR; - if (!ErrorHandler(NXputdata(fFileHandle, cstr), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'NXentry/start_time'.")) return NX_ERROR; - NXclosedata(fFileHandle); - - // write run 'stop_time' - memset(cstr, '\0', sizeof(cstr)); - strncpy(cstr, fNxEntry1->GetStopTime().c_str(), sizeof(cstr)); - size = strlen(cstr); - if (!ErrorHandler(NXmakedata(fFileHandle, "stop_time", NX_CHAR, 1, &size), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'NXentry/stop_time'.")) return NX_ERROR; - if (!ErrorHandler(NXopendata(fFileHandle, "stop_time"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'NXentry/stop_time' for writting.")) return NX_ERROR; - if (!ErrorHandler(NXputdata(fFileHandle, cstr), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'NXentry/stop_time'.")) return NX_ERROR; - NXclosedata(fFileHandle); - - // write run 'switching_states' - size = 1; - if (!ErrorHandler(NXmakedata(fFileHandle, "switching_states", NX_INT32, 1, &size), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'NXentry/switching_states'.")) return NX_ERROR; - if (!ErrorHandler(NXopendata(fFileHandle, "switching_states"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'NXentry/switching_states' for writting.")) return NX_ERROR; - idata = fNxEntry1->GetSwitchingState(); - if (!ErrorHandler(NXputdata(fFileHandle, &idata), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'NXentry/switching_states'.")) return NX_ERROR; - NXclosedata(fFileHandle); - - // make group 'user' - if (!ErrorHandler(NXmakegroup(fFileHandle, "user", "NXuser"), PNEXUS_CREATE_GROUP_ERROR, "couldn't create group 'NXuser/user'.")) return NX_ERROR; - // open group 'user' - if (!ErrorHandler(NXopengroup(fFileHandle, "user", "NXuser"), PNEXUS_GROUP_OPEN_ERROR, "couldn't open group 'NXuser/user' for writting.")) return NX_ERROR; - - // write user 'name' - size = fNxEntry1->GetUser()->GetName().length(); - if (!ErrorHandler(NXmakedata(fFileHandle, "name", NX_CHAR, 1, &size), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'NXuser/name'.")) return NX_ERROR; - if (!ErrorHandler(NXopendata(fFileHandle, "name"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'NXuser/name' for writting.")) return NX_ERROR; - memset(cstr, '\0', sizeof(cstr)); - strncpy(cstr, fNxEntry1->GetUser()->GetName().c_str(), sizeof(cstr)); - if (!ErrorHandler(NXputdata(fFileHandle, cstr), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'NXuser/name'.")) return NX_ERROR; - NXclosedata(fFileHandle); - - // write user 'experiment_number' - size = fNxEntry1->GetUser()->GetExperimentNumber().length(); - if (!ErrorHandler(NXmakedata(fFileHandle, "experiment_number", NX_CHAR, 1, &size), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'NXuser/experiment_number'.")) return NX_ERROR; - if (!ErrorHandler(NXopendata(fFileHandle, "experiment_number"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'NXuser/experiment_number' for writting.")) return NX_ERROR; - memset(cstr, '\0', sizeof(cstr)); - strncpy(cstr, fNxEntry1->GetUser()->GetExperimentNumber().c_str(), sizeof(cstr)); - if (!ErrorHandler(NXputdata(fFileHandle, cstr), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'NXuser/experiment_number'.")) return NX_ERROR; - NXclosedata(fFileHandle); - - // close group 'user' - NXclosegroup(fFileHandle); - - // make group 'sample' - if (!ErrorHandler(NXmakegroup(fFileHandle, "sample", "NXsample"), PNEXUS_CREATE_GROUP_ERROR, "couldn't create group 'NXsample/sample'.")) return NX_ERROR; - // open group 'sample' - if (!ErrorHandler(NXopengroup(fFileHandle, "sample", "NXsample"), PNEXUS_GROUP_OPEN_ERROR, "couldn't open group 'NXsample/sample' for writting.")) return NX_ERROR; - - // write sample 'name' - size = fNxEntry1->GetSample()->GetName().length(); - if (!ErrorHandler(NXmakedata(fFileHandle, "name", NX_CHAR, 1, &size), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'NXsample/name'.")) return NX_ERROR; - if (!ErrorHandler(NXopendata(fFileHandle, "name"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'NXsample/name' for writting.")) return NX_ERROR; - memset(cstr, '\0', sizeof(cstr)); - strncpy(cstr, fNxEntry1->GetSample()->GetName().c_str(), sizeof(cstr)); - if (!ErrorHandler(NXputdata(fFileHandle, cstr), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'NXsample/name'.")) return NX_ERROR; - NXclosedata(fFileHandle); - - // write sample 'temperature' - size = 1; - if (!ErrorHandler(NXmakedata(fFileHandle, "temperature", NX_FLOAT32, 1, &size), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'NXsample/temperature'.")) return NX_ERROR; - if (!ErrorHandler(NXopendata(fFileHandle, "temperature"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'NXsample/temperature' for writting.")) return NX_ERROR; - fdata = (float)fNxEntry1->GetSample()->GetPhysPropValue(std::string("temperature"), ok); - if (!ErrorHandler(NXputdata(fFileHandle, &fdata), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'NXsample/temperature'.")) return NX_ERROR; - memset(cstr, '\0', sizeof(cstr)); - str = std::string("n/a"); - fNxEntry1->GetSample()->GetPhysPropUnit(std::string("temperature"), str, ok); - strncpy(cstr, str.c_str(), sizeof(cstr)); - if (!ErrorHandler(NXputattr(fFileHandle, "units", cstr, strlen(cstr), NX_CHAR), PNEXUS_PUT_ATTR_ERROR, "couldn't put attribute 'units' for 'NXsample/temperature'")) return NX_ERROR; - NXclosedata(fFileHandle); - - // write sample 'magnetic_field' - size = 1; - if (!ErrorHandler(NXmakedata(fFileHandle, "magnetic_field", NX_FLOAT32, 1, &size), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'NXsample/magnetic_field'.")) return NX_ERROR; - if (!ErrorHandler(NXopendata(fFileHandle, "magnetic_field"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'NXsample/magnetic_field' for writting.")) return NX_ERROR; - fdata = (float)fNxEntry1->GetSample()->GetPhysPropValue(std::string("magnetic_field"), ok); - if (!ErrorHandler(NXputdata(fFileHandle, &fdata), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'NXsample/magnetic_field'.")) return NX_ERROR; - memset(cstr, '\0', sizeof(cstr)); - str = std::string("n/a"); - fNxEntry1->GetSample()->GetPhysPropUnit(std::string("magnetic_field"), str, ok); - memset(cstr, '\0', sizeof(cstr)); - strncpy(cstr, str.c_str(), sizeof(cstr)); - if (!ErrorHandler(NXputattr(fFileHandle, "units", cstr, strlen(cstr), NX_CHAR), PNEXUS_PUT_ATTR_ERROR, "couldn't put attribute 'units' for 'NXsample/magnetic_field'")) return NX_ERROR; - NXclosedata(fFileHandle); - - // write sample 'shape' only if populated with something different than 'n/a' - if (fNxEntry1->GetSample()->GetShape() != "n/a") { - size = fNxEntry1->GetSample()->GetShape().length(); - if (!ErrorHandler(NXmakedata(fFileHandle, "shape", NX_CHAR, 1, &size), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'NXsample/shape'.")) return NX_ERROR; - if (!ErrorHandler(NXopendata(fFileHandle, "shape"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'NXsample/shape' for writting.")) return NX_ERROR; - strncpy(cstr, fNxEntry1->GetSample()->GetShape().c_str(), sizeof(cstr)); - if (!ErrorHandler(NXputdata(fFileHandle, cstr), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'NXsample/shape'.")) return NX_ERROR; - NXclosedata(fFileHandle); - } - - // write sample 'magnetic_field_state' - size = fNxEntry1->GetSample()->GetMagneticFieldState().length(); - if (!ErrorHandler(NXmakedata(fFileHandle, "magnetic_field_state", NX_CHAR, 1, &size), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'NXsample/magnetic_field_state'.")) return NX_ERROR; - if (!ErrorHandler(NXopendata(fFileHandle, "magnetic_field_state"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'NXsample/magnetic_field_state' for writting.")) return NX_ERROR; - memset(cstr, '\0', sizeof(cstr)); - strncpy(cstr, fNxEntry1->GetSample()->GetMagneticFieldState().c_str(), sizeof(cstr)); - if (!ErrorHandler(NXputdata(fFileHandle, cstr), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'NXsample/magnetic_field_state'.")) return NX_ERROR; - NXclosedata(fFileHandle); - - // write sample 'magnetic_field_vector' - float *magFieldVec; - if (fNxEntry1->GetSample()->IsMagneticFieldVectorAvailable()) { - idata = 1; - size = fNxEntry1->GetSample()->GetMagneticFieldVector().size(); - magFieldVec = new float[size]; - for (int i=0; iGetSample()->GetMagneticFieldVector().at(i); - } else { - idata = 0; - size = 3; - magFieldVec = new float[size]; - for (int i=0; iGetSample()->GetMagneticFieldVectorCoordinateSystem().c_str(), sizeof(cstr)); - if (!ErrorHandler(NXputattr(fFileHandle, "coordinate_system", cstr, strlen(cstr), NX_CHAR), PNEXUS_PUT_ATTR_ERROR, "couldn't put attribute 'coordinate_system' for 'NXsample/magnetic_field_vector'")) return NX_ERROR; - memset(cstr, '\0', sizeof(cstr)); - strncpy(cstr, fNxEntry1->GetSample()->GetMagneticFieldVectorUnits().c_str(), sizeof(cstr)); - if (!ErrorHandler(NXputattr(fFileHandle, "units", cstr, strlen(cstr), NX_CHAR), PNEXUS_PUT_ATTR_ERROR, "couldn't put attribute 'units' for 'NXsample/magnetic_field_vector'")) return NX_ERROR; - if (!ErrorHandler(NXputattr(fFileHandle, "available", &idata, 1, NX_INT32), PNEXUS_PUT_ATTR_ERROR, "couldn't put attribute 'available' for 'NXsample/magnetic_field_vector'")) return NX_ERROR; - NXclosedata(fFileHandle); - if (magFieldVec) { - delete [] magFieldVec; - magFieldVec = 0; - } - - // write sample 'environment' - size = fNxEntry1->GetSample()->GetEnvironment().length(); - if (!ErrorHandler(NXmakedata(fFileHandle, "environment", NX_CHAR, 1, &size), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'NXsample/environment'.")) return NX_ERROR; - if (!ErrorHandler(NXopendata(fFileHandle, "environment"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'NXsample/environment' for writting.")) return NX_ERROR; - memset(cstr, '\0', sizeof(cstr)); - strncpy(cstr, fNxEntry1->GetSample()->GetEnvironment().c_str(), sizeof(cstr)); - if (!ErrorHandler(NXputdata(fFileHandle, cstr), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'NXsample/environment'.")) return NX_ERROR; - NXclosedata(fFileHandle); - - // close group 'sample' - NXclosegroup(fFileHandle); - - // make group 'instrument' - if (!ErrorHandler(NXmakegroup(fFileHandle, "instrument", "NXinstrument"), PNEXUS_CREATE_GROUP_ERROR, "couldn't create group 'NXinstrument/instrument'.")) return NX_ERROR; - // open group 'instrument' - if (!ErrorHandler(NXopengroup(fFileHandle, "instrument", "NXinstrument"), PNEXUS_GROUP_OPEN_ERROR, "couldn't open group 'NXinstrument/instrument' for writting.")) return NX_ERROR; - - // write instrument 'name' - size = fNxEntry1->GetInstrument()->GetName().length(); - if (!ErrorHandler(NXmakedata(fFileHandle, "name", NX_CHAR, 1, &size), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'NXinstrument/name'.")) return NX_ERROR; - if (!ErrorHandler(NXopendata(fFileHandle, "name"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'NXinstrument/name' for writting.")) return NX_ERROR; - memset(cstr, '\0', sizeof(cstr)); - strncpy(cstr, fNxEntry1->GetInstrument()->GetName().c_str(), sizeof(cstr)); - if (!ErrorHandler(NXputdata(fFileHandle, cstr), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'NXinstrument/name'.")) return NX_ERROR; - NXclosedata(fFileHandle); - - // make group 'detector' - if (!ErrorHandler(NXmakegroup(fFileHandle, "detector", "NXdetector"), PNEXUS_CREATE_GROUP_ERROR, "couldn't create group 'NXdetector/detector'.")) return NX_ERROR; - // open group 'detector' - if (!ErrorHandler(NXopengroup(fFileHandle, "detector", "NXdetector"), PNEXUS_GROUP_OPEN_ERROR, "couldn't open group 'NXdetector/detector' for writting.")) return NX_ERROR; - - // write detector 'number' - size = 1; - if (!ErrorHandler(NXmakedata(fFileHandle, "number", NX_INT32, 1, &size), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'NXdetector/number'.")) return NX_ERROR; - if (!ErrorHandler(NXopendata(fFileHandle, "number"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'NXdetector/number' for writting.")) return NX_ERROR; - idata = fNxEntry1->GetInstrument()->GetDetector()->GetNumber(); - if (!ErrorHandler(NXputdata(fFileHandle, &idata), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'NXdetector/number'.")) return NX_ERROR; - NXclosedata(fFileHandle); + // Read first 8 bytes (enough for both signatures) + unsigned char header[8]; + file.read(reinterpret_cast(header), 8); - // close group 'detector' - NXclosegroup(fFileHandle); - - // make group 'collimator' - if (!ErrorHandler(NXmakegroup(fFileHandle, "collimator", "NXcollimator"), PNEXUS_CREATE_GROUP_ERROR, "couldn't create group 'NXcollimator/collimator'.")) return NX_ERROR; - // open group 'collimator' - if (!ErrorHandler(NXopengroup(fFileHandle, "collimator", "NXcollimator"), PNEXUS_GROUP_OPEN_ERROR, "couldn't open group 'NXcollimator/collimator' for writting.")) return NX_ERROR; - - // write collimator 'type' - size = fNxEntry1->GetInstrument()->GetCollimator()->GetType().length(); - if (!ErrorHandler(NXmakedata(fFileHandle, "type", NX_CHAR, 1, &size), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'NXcollimator/type'.")) return NX_ERROR; - if (!ErrorHandler(NXopendata(fFileHandle, "type"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'NXcollimator/type' for writting.")) return NX_ERROR; - memset(cstr, '\0', sizeof(cstr)); - strncpy(cstr, fNxEntry1->GetInstrument()->GetCollimator()->GetType().c_str(), sizeof(cstr)); - if (!ErrorHandler(NXputdata(fFileHandle, cstr), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'NXcollimator/type'.")) return NX_ERROR; - NXclosedata(fFileHandle); - - // close group 'collimator' - NXclosegroup(fFileHandle); - - // make group 'beam' - if (!ErrorHandler(NXmakegroup(fFileHandle, "beam", "NXbeam"), PNEXUS_CREATE_GROUP_ERROR, "couldn't create group 'NXbeam/beam'.")) return NX_ERROR; - // open group 'beam' - if (!ErrorHandler(NXopengroup(fFileHandle, "beam", "NXbeam"), PNEXUS_GROUP_OPEN_ERROR, "couldn't open group 'NXbeam/beam' for writting.")) return NX_ERROR; - - size = 1; - if (!ErrorHandler(NXmakedata(fFileHandle, "total_counts", NX_FLOAT32, 1, &size), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'NXbeam/total_counts'.")) return NX_ERROR; - if (!ErrorHandler(NXopendata(fFileHandle, "total_counts"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'NXbeam/total_counts' for writting.")) return NX_ERROR; - fdata = (float)fNxEntry1->GetInstrument()->GetBeam()->GetTotalCounts(); - if (!ErrorHandler(NXputdata(fFileHandle, &fdata), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'NXbeam/total_counts'.")) return NX_ERROR; - memset(cstr, '\0', sizeof(cstr)); - strncpy(cstr, fNxEntry1->GetInstrument()->GetBeam()->GetUnits().c_str(), sizeof(cstr)); - if (!ErrorHandler(NXputattr(fFileHandle, "units", cstr, strlen(cstr), NX_CHAR), PNEXUS_PUT_ATTR_ERROR, "couldn't put attribute 'units' for 'NXbeam/total_counts'")) return NX_ERROR; - NXclosedata(fFileHandle); - - // close group 'beam' - NXclosegroup(fFileHandle); - - // close group 'instrument' - NXclosegroup(fFileHandle); - - // make group 'histogram_data_1' - if (!ErrorHandler(NXmakegroup(fFileHandle, "histogram_data_1", "NXdata"), PNEXUS_CREATE_GROUP_ERROR, "couldn't create group 'NXdata/histogram_data_1'.")) return NX_ERROR; - // open group 'histogram_data_1' - if (!ErrorHandler(NXopengroup(fFileHandle, "histogram_data_1", "NXdata"), PNEXUS_GROUP_OPEN_ERROR, "couldn't open group 'NXdata/histogram_data_1' for writting.")) return NX_ERROR; - - // write data 'counts' - int *histo_data=0; - int histo_size[2]; - if (fNxEntry1->GetData()->GetNoOfHistos() == 0) { - histo_data = new int[1]; - histo_data[0] = -1; - histo_size[0] = 1; - histo_size[1] = 1; - } else { - int noOfHistos = fNxEntry1->GetData()->GetNoOfHistos(); - int histoLength = fNxEntry1->GetData()->GetHisto(0)->size(); - histo_data = new int[noOfHistos*histoLength]; - for (int i=0; iGetData()->GetHisto(i)->at(j); - histo_size[0] = noOfHistos; - histo_size[1] = histoLength; - } - - if (!ErrorHandler(NXcompmakedata(fFileHandle, "counts", NX_INT32, 2, histo_size, NX_COMP_LZW, histo_size), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'NXdata/counts'.")) return NX_ERROR; - if (!ErrorHandler(NXopendata(fFileHandle, "counts"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'NXdata/counts' for writting.")) return NX_ERROR; - if (!ErrorHandler(NXputdata(fFileHandle, (void*)histo_data), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'NXdata/counts'.")) return NX_ERROR; - memset(cstr, '\0', sizeof(cstr)); - strncpy(cstr, "counts", sizeof(cstr)); - if (!ErrorHandler(NXputattr(fFileHandle, "units", cstr, strlen(cstr), NX_CHAR), PNEXUS_PUT_ATTR_ERROR, "couldn't put attribute 'units' for 'NXdata/counts'")) return NX_ERROR; - idata = 1; - if (!ErrorHandler(NXputattr(fFileHandle, "signal", &idata, 1, NX_INT32), PNEXUS_PUT_ATTR_ERROR, "couldn't put attribute 'signal' for 'NXdata/counts'")) return NX_ERROR; - idata = fNxEntry1->GetData()->GetNoOfHistos(); - if (!ErrorHandler(NXputattr(fFileHandle, "number", &idata, 1, NX_INT32), PNEXUS_PUT_ATTR_ERROR, "couldn't put attribute 'number' for 'NXdata/counts'")) return NX_ERROR; - idata = fNxEntry1->GetData()->GetHistoLength(); - if (!ErrorHandler(NXputattr(fFileHandle, "length", &idata, 1, NX_INT32), PNEXUS_PUT_ATTR_ERROR, "couldn't put attribute 'length' for 'NXdata/counts'")) return NX_ERROR; - idata = fNxEntry1->GetData()->GetT0(0); - if (!ErrorHandler(NXputattr(fFileHandle, "t0_bin", &idata, 1, NX_INT32), PNEXUS_PUT_ATTR_ERROR, "couldn't put attribute 'T0_bin' for 'NXdata/counts'")) return NX_ERROR; - idata = fNxEntry1->GetData()->GetFirstGoodBin(0); - if (!ErrorHandler(NXputattr(fFileHandle, "first_good_bin", &idata, 1, NX_INT32), PNEXUS_PUT_ATTR_ERROR, "couldn't put attribute 'first_good_bin' for 'NXdata/counts'")) return NX_ERROR; - idata = fNxEntry1->GetData()->GetLastGoodBin(0); - if (!ErrorHandler(NXputattr(fFileHandle, "last_good_bin", &idata, 1, NX_INT32), PNEXUS_PUT_ATTR_ERROR, "couldn't put attribute 'last_good_bin' for 'NXdata/counts'")) return NX_ERROR; - fdata = (float)fNxEntry1->GetData()->GetTimeResolution("ps")/2.0; - if (!ErrorHandler(NXputattr(fFileHandle, "offset", &fdata, 1, NX_FLOAT32), PNEXUS_PUT_ATTR_ERROR, "couldn't put attribute 'offset' for 'NXdata/counts'")) return NX_ERROR; - NXclosedata(fFileHandle); - - if (histo_data) { - delete [] histo_data; - } - - // write data 'resolution' - size = 1; - if (!ErrorHandler(NXmakedata(fFileHandle, "resolution", NX_INT32, 1, &size), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'NXdata/resolution'.")) return NX_ERROR; - if (!ErrorHandler(NXopendata(fFileHandle, "resolution"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'NXdata/resolution' for writting.")) return NX_ERROR; - fdata = fNxEntry1->GetData()->GetTimeResolution("fs"); - idata = (int)fdata; - if (!ErrorHandler(NXputdata(fFileHandle, &idata), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'NXdata/resolution'.")) return NX_ERROR; - memset(cstr, '\0', sizeof(cstr)); - strncpy(cstr, "femtoseconds", sizeof(cstr)); - if (!ErrorHandler(NXputattr(fFileHandle, "units", cstr, strlen(cstr), NX_CHAR), PNEXUS_PUT_ATTR_ERROR, "couldn't put attribute 'units' for 'NXdata/resolution'")) return NX_ERROR; - NXclosedata(fFileHandle); - - // write data 'time_zero' based on t0_bin which is the master! - size = 1; - if (!ErrorHandler(NXmakedata(fFileHandle, "time_zero", NX_FLOAT32, 1, &size), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'NXdata/time_zero'.")) return NX_ERROR; - if (!ErrorHandler(NXopendata(fFileHandle, "time_zero"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'NXdata/time_zero' for writting.")) return NX_ERROR; - fdata = (float)fNxEntry1->GetData()->GetT0(0) * (float)fNxEntry1->GetData()->GetTimeResolution("us"); - if (!ErrorHandler(NXputdata(fFileHandle, &fdata), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'NXdata/time_zero'.")) return NX_ERROR; - memset(cstr, '\0', sizeof(cstr)); - strncpy(cstr, "microseconds", sizeof(cstr)); - if (!ErrorHandler(NXputattr(fFileHandle, "units", cstr, strlen(cstr), NX_CHAR), PNEXUS_PUT_ATTR_ERROR, "couldn't put attribute 'units' for 'NXdata/time_zero'")) return NX_ERROR; - idata = 1; - if (!ErrorHandler(NXputattr(fFileHandle, "available", &idata, 1, NX_INT32), PNEXUS_PUT_ATTR_ERROR, "couldn't put attribute 'available' for 'NXdata/time_zero'")) return NX_ERROR; - NXclosedata(fFileHandle); - - // write data 'raw_time' - int noOfHistos = fNxEntry1->GetData()->GetNoOfHistos(); - int histoLength = fNxEntry1->GetData()->GetHisto(0)->size(); - if (noOfHistos == 0) { - fErrorCode = PNEXUS_HISTO_ERROR; - fErrorMsg = "no data for writing present."; - return NX_ERROR; - } - float *raw_time = new float[histoLength]; - for (int i=0; iGetData()->GetTimeResolution("us") * (float)i; // raw time in (us) - } - size = histoLength; - if (!ErrorHandler(NXmakedata(fFileHandle, "raw_time", NX_FLOAT32, 1, &size), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'NXdata/raw_time'.")) return NX_ERROR; - if (!ErrorHandler(NXopendata(fFileHandle, "raw_time"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'NXdata/raw_time' for writting.")) return NX_ERROR; - if (!ErrorHandler(NXputdata(fFileHandle, raw_time), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'NXdata/raw_time'.")) return NX_ERROR; - idata = 1; - if (!ErrorHandler(NXputattr(fFileHandle, "axis", &idata, 1, NX_INT32), PNEXUS_PUT_ATTR_ERROR, "couldn't put attribute 'axis' for 'NXdata/raw_time'")) return NX_ERROR; - idata = 1; - if (!ErrorHandler(NXputattr(fFileHandle, "primary", &idata, 1, NX_INT32), PNEXUS_PUT_ATTR_ERROR, "couldn't put attribute 'primary' for 'NXdata/raw_time'")) return NX_ERROR; - memset(cstr, '\0', sizeof(cstr)); - strncpy(cstr, "microseconds", sizeof(cstr)); - if (!ErrorHandler(NXputattr(fFileHandle, "units", cstr, strlen(cstr), NX_CHAR), PNEXUS_PUT_ATTR_ERROR, "couldn't put attribute 'units' for 'NXdata/raw_time'")) return NX_ERROR; - NXclosedata(fFileHandle); - if (raw_time) { - delete [] raw_time; - raw_time = 0; - } - - // write data 'corrected_time' - float *corrected_time = new float[histoLength]; - for (int i=0; iGetData()->GetTimeResolution("us") * (float)((int)i-(int)fNxEntry1->GetData()->GetT0(0)+1); // raw time in (us) - } - size = histoLength; - if (!ErrorHandler(NXmakedata(fFileHandle, "corrected_time", NX_FLOAT32, 1, &size), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'NXdata/corrected_time'.")) return NX_ERROR; - if (!ErrorHandler(NXopendata(fFileHandle, "corrected_time"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'NXdata/corrected_time' for writting.")) return NX_ERROR; - if (!ErrorHandler(NXputdata(fFileHandle, corrected_time), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'NXdata/corrected_time'.")) return NX_ERROR; - idata = 1; - if (!ErrorHandler(NXputattr(fFileHandle, "axis", &idata, 1, NX_INT32), PNEXUS_PUT_ATTR_ERROR, "couldn't put attribute 'axis' for 'NXdata/corrected_time'")) return NX_ERROR; - memset(cstr, '\0', sizeof(cstr)); - strncpy(cstr, "microseconds", sizeof(cstr)); - if (!ErrorHandler(NXputattr(fFileHandle, "units", cstr, strlen(cstr), NX_CHAR), PNEXUS_PUT_ATTR_ERROR, "couldn't put attribute 'units' for 'NXdata/corrected_time'")) return NX_ERROR; - NXclosedata(fFileHandle); - if (corrected_time) { - delete [] corrected_time; - corrected_time = 0; - } - - // write data 'grouping' - int *grouping = new int[noOfHistos]; - std::vector groupNo; // keep the number of different groupings - if (noOfHistos == (int)fNxEntry1->GetData()->GetGrouping()->size()) { // grouping vector seems to be properly defined - bool found; - groupNo.push_back(fNxEntry1->GetData()->GetGrouping()->at(0)); - for (int i=0; iGetData()->GetGrouping()->at(i); - found = false; - for (unsigned int j=0; jGetData()->GetGrouping()->at(i) == groupNo[j]) { - found = true; - break; - } - } - if (!found) { - groupNo.push_back(fNxEntry1->GetData()->GetGrouping()->at(i)); - } - } - } else { // grouping vector not available - for (int i=0; iGetData()->GetAlpha()->size() == 0) { - alpha = new float[3]; - alpha[0] = -1.0; - alpha[1] = -1.0; - alpha[2] = -1.0; - array_size[0] = 1; - array_size[1] = 3; - } else { - alpha = new float[fNxEntry1->GetData()->GetAlpha()->size()*3]; - for (unsigned int i=0; iGetData()->GetAlpha()->size(); i++) { - alpha[i] = (float)fNxEntry1->GetData()->GetAlpha()->at(i).GetGroupFirst(); - alpha[i+1] = (float)fNxEntry1->GetData()->GetAlpha()->at(i).GetGroupSecond(); - alpha[i+2] = (float)(float)fNxEntry1->GetData()->GetAlpha()->at(i).GetAlpha(); - } - array_size[0] = fNxEntry1->GetData()->GetAlpha()->size(); - array_size[1] = 3; - } - if (!ErrorHandler(NXmakedata(fFileHandle, "alpha", NX_FLOAT32, 2, array_size), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'NXdata/alpha'.")) return NX_ERROR; - if (!ErrorHandler(NXopendata(fFileHandle, "alpha"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'NXdata/alpha' for writting.")) return NX_ERROR; - if (!ErrorHandler(NXputdata(fFileHandle, (void*)alpha), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'NXdata/alpha'.")) return NX_ERROR; - idata = fNxEntry1->GetData()->GetAlpha()->size(); - if (!ErrorHandler(NXputattr(fFileHandle, "available", &idata, 1, NX_INT32), PNEXUS_PUT_ATTR_ERROR, "couldn't put attribute 'available' for 'NXdata/alpha'")) return NX_ERROR; - if (alpha) { - delete [] alpha; - } - - // close group 'histogram_data_1' - NXclosegroup(fFileHandle); - - // close group 'run' - NXclosegroup(fFileHandle); - - NXclose(&fFileHandle); - - return NX_OK; -} - -//------------------------------------------------------------------------------------------ -// WriteFileIdf2 (private) -//------------------------------------------------------------------------------------------ -/** - *

Write the NeXus file of type IDF Version 2. - * - * return: - * - NX_OK on successfull writting - * - NX_ERROR on error. The error code/message will give the details. - * - * \param fileName file name - * \param access flag needed to know in which format (HDF4, HDF5, or XML) the file shall be written. - */ -int PNeXus::WriteFileIdf2(const char* fileName, const NXaccess access) -{ - std::string str; - char cstr[1204]; - bool ok = false; - int size, idata; - float fdata; - double dval; - NXlink nxLink; - std::vector nxLinkVec; - - memset(cstr, '\0', sizeof(cstr)); - snprintf(cstr, sizeof(cstr), "couldn't open file '%s' for writing", fileName); - if (!ErrorHandler(NXopen(fileName, access, &fFileHandle), PNEXUS_FILE_OPEN_ERROR, cstr)) return NX_ERROR; - - // write NXroot attribute 'file_name' - memset(cstr, '\0', sizeof(cstr)); - strncpy(cstr, fileName, sizeof(cstr)); - if (!ErrorHandler(NXputattr(fFileHandle, "file_name", cstr, strlen(cstr), NX_CHAR), PNEXUS_SET_ATTR_ERROR, "couldn't set NXroot attribute 'file_name'")) return NX_ERROR; - - // write NXroot attribute 'creator' - memset(cstr, '\0', sizeof(cstr)); - strncpy(cstr, fCreator.c_str(), sizeof(cstr)); - if (!ErrorHandler(NXputattr(fFileHandle, "creator", cstr, strlen(cstr), NX_CHAR), PNEXUS_SET_ATTR_ERROR, "couldn't set NXroot attribute 'creator'")) return NX_ERROR; - - // make group 'raw_data_1' - if (!ErrorHandler(NXmakegroup(fFileHandle, "raw_data_1", "NXentry"), PNEXUS_CREATE_GROUP_ERROR, "couldn't create group 'raw_data_1' in NXroot.")) return NX_ERROR; - // open group 'raw_data_1' - if (!ErrorHandler(NXopengroup(fFileHandle, "raw_data_1", "NXentry"), PNEXUS_GROUP_OPEN_ERROR, "couldn't open group 'raw_data_1' in NXroot for writting.")) return NX_ERROR; - - // write idf_version - size = 1; - if (!ErrorHandler(NXmakedata(fFileHandle, "idf_version", NX_INT32, 1, &size), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'idf_version' in NXentry.")) return NX_ERROR; - if (!ErrorHandler(NXopendata(fFileHandle, "idf_version"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'idf_version' in NXentry for writting.")) return NX_ERROR; - idata = fIdfVersion; - if (!ErrorHandler(NXputdata(fFileHandle, &idata), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'idf_version' in NXentry.")) return NX_ERROR; - NXclosedata(fFileHandle); - - // write run 'definition' - size = fNxEntry2->GetDefinition().length(); - if (!ErrorHandler(NXmakedata(fFileHandle, "definition", NX_CHAR, 1, &size), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'definition' in NXentry.")) return NX_ERROR; - if (!ErrorHandler(NXopendata(fFileHandle, "definition"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'definition' in NXentry for writting.")) return NX_ERROR; - memset(cstr, '\0', sizeof(cstr)); - strncpy(cstr, fNxEntry2->GetDefinition().c_str(), sizeof(cstr)); - if (!ErrorHandler(NXputdata(fFileHandle, cstr), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'definition' in NXentry.")) return NX_ERROR; - NXclosedata(fFileHandle); - - // write 'program_name' if present - if (!fNxEntry2->GetProgramName().empty()) { - size = fNxEntry2->GetProgramName().length(); - if (!ErrorHandler(NXmakedata(fFileHandle, "program_name", NX_CHAR, 1, &size), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'program_name' in NXentry.")) return NX_ERROR; - if (!ErrorHandler(NXopendata(fFileHandle, "program_name"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'program_name' in NXentry for writting.")) return NX_ERROR; - memset(cstr, '\0', sizeof(cstr)); - strncpy(cstr, fNxEntry2->GetProgramName().c_str(), sizeof(cstr)); - if (!ErrorHandler(NXputdata(fFileHandle, cstr), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'program_name' in NXentry.")) return NX_ERROR; - memset(cstr, '\0', sizeof(cstr)); - strncpy(cstr, fNxEntry2->GetProgramVersion().c_str(), sizeof(cstr)); - if (!ErrorHandler(NXputattr(fFileHandle, "version", cstr, strlen(cstr), NX_CHAR), PNEXUS_PUT_ATTR_ERROR, "couldn't put attribute 'version' for 'program_name' in NXentry.")) return NX_ERROR; - NXclosedata(fFileHandle); - } - - // write run 'run_number' - size = 1; - if (!ErrorHandler(NXmakedata(fFileHandle, "run_number", NX_INT32, 1, &size), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'run_number' in NXentry.")) return NX_ERROR; - if (!ErrorHandler(NXopendata(fFileHandle, "run_number"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'run_number' in NXentry for writting.")) return NX_ERROR; - idata = fNxEntry2->GetRunNumber(); - if (!ErrorHandler(NXputdata(fFileHandle, &idata), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'run_number' in NXentry.")) return NX_ERROR; - NXclosedata(fFileHandle); - - // write run 'title' - size = fNxEntry2->GetTitle().length(); - if (!ErrorHandler(NXmakedata(fFileHandle, "title", NX_CHAR, 1, &size), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'title' in NXentry.")) return NX_ERROR; - if (!ErrorHandler(NXopendata(fFileHandle, "title"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'title' in NXentry for writting.")) return NX_ERROR; - memset(cstr, '\0', sizeof(cstr)); - strncpy(cstr, fNxEntry2->GetTitle().c_str(), sizeof(cstr)); - if (!ErrorHandler(NXputdata(fFileHandle, cstr), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'title' in NXentry.")) return NX_ERROR; - NXclosedata(fFileHandle); - - // write run 'start_time' - size = fNxEntry2->GetStartTime().length(); - if (!ErrorHandler(NXmakedata(fFileHandle, "start_time", NX_CHAR, 1, &size), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'start_time' in NXentry.")) return NX_ERROR; - if (!ErrorHandler(NXopendata(fFileHandle, "start_time"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'start_time' in NXentry for writting.")) return NX_ERROR; - memset(cstr, '\0', sizeof(cstr)); - strncpy(cstr, fNxEntry2->GetStartTime().c_str(), sizeof(cstr)); - if (!ErrorHandler(NXputdata(fFileHandle, cstr), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'start_time' in NXentry.")) return NX_ERROR; - NXclosedata(fFileHandle); - - // write run 'end_time' - size = fNxEntry2->GetStopTime().length(); - if (!ErrorHandler(NXmakedata(fFileHandle, "end_time", NX_CHAR, 1, &size), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'end_time' in NXentry.")) return NX_ERROR; - if (!ErrorHandler(NXopendata(fFileHandle, "end_time"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'end_time' in NXentry for writting.")) return NX_ERROR; - memset(cstr, '\0', sizeof(cstr)); - strncpy(cstr, fNxEntry2->GetStopTime().c_str(), sizeof(cstr)); - if (!ErrorHandler(NXputdata(fFileHandle, cstr), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'end_time' in NXentry.")) return NX_ERROR; - NXclosedata(fFileHandle); - - // write run 'experiment_identifier' - size = fNxEntry2->GetExperimentIdentifier().length(); - if (!ErrorHandler(NXmakedata(fFileHandle, "experiment_identifier", NX_CHAR, 1, &size), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'experiment_identifier' in NXentry.")) return NX_ERROR; - if (!ErrorHandler(NXopendata(fFileHandle, "experiment_identifier"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'experiment_identifier' in NXentry for writting.")) return NX_ERROR; - memset(cstr, '\0', sizeof(cstr)); - strncpy(cstr, fNxEntry2->GetExperimentIdentifier().c_str(), sizeof(cstr)); - if (!ErrorHandler(NXputdata(fFileHandle, cstr), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'experiment_identifier' in NXentry.")) return NX_ERROR; - NXclosedata(fFileHandle); - - // user_1 (NXuser) will only be written if there is at least a user name present - if (fNxEntry2->GetUser()->GetName() != "n/a") { - // make group 'user_1' - if (!ErrorHandler(NXmakegroup(fFileHandle, "user_1", "NXuser"), PNEXUS_CREATE_GROUP_ERROR, "couldn't create group 'user_1' in NXentry.")) return NX_ERROR; - // open group 'user' - if (!ErrorHandler(NXopengroup(fFileHandle, "user_1", "NXuser"), PNEXUS_GROUP_OPEN_ERROR, "couldn't open group 'user_1' in NXentry for writting.")) return NX_ERROR; - - // write user 'name' - size = fNxEntry2->GetUser()->GetName().length(); - if (!ErrorHandler(NXmakedata(fFileHandle, "name", NX_CHAR, 1, &size), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'name' in NXuser.")) return NX_ERROR; - if (!ErrorHandler(NXopendata(fFileHandle, "name"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'name' in NXuser for writting.")) return NX_ERROR; - memset(cstr, '\0', sizeof(cstr)); - strncpy(cstr, fNxEntry2->GetUser()->GetName().c_str(), sizeof(cstr)); - if (!ErrorHandler(NXputdata(fFileHandle, cstr), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'name' in NXuser.")) return NX_ERROR; - NXclosedata(fFileHandle); - - // close group 'user_1' - NXclosegroup(fFileHandle); - } - - // make group 'sample' - if (!ErrorHandler(NXmakegroup(fFileHandle, "sample", "NXsample"), PNEXUS_CREATE_GROUP_ERROR, "couldn't create group 'sample' in NXentry.")) return NX_ERROR; - // open group 'sample' - if (!ErrorHandler(NXopengroup(fFileHandle, "sample", "NXsample"), PNEXUS_GROUP_OPEN_ERROR, "couldn't open group 'sample' in NXentry for writting.")) return NX_ERROR; - - // write sample 'name' - size = fNxEntry2->GetSample()->GetName().length(); - if (!ErrorHandler(NXmakedata(fFileHandle, "name", NX_CHAR, 1, &size), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'name' in NXsample.")) return NX_ERROR; - if (!ErrorHandler(NXopendata(fFileHandle, "name"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'name' in NXsample for writting.")) return NX_ERROR; - memset(cstr, '\0', sizeof(cstr)); - strncpy(cstr, fNxEntry2->GetSample()->GetName().c_str(), sizeof(cstr)); - if (!ErrorHandler(NXputdata(fFileHandle, cstr), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'name' in NXsample.")) return NX_ERROR; - NXclosedata(fFileHandle); - - // check if description is present - if (fNxEntry2->GetSample()->GetDescription().compare("n/a")) { - // write sample 'description' - size = fNxEntry2->GetSample()->GetDescription().length(); - if (!ErrorHandler(NXmakedata(fFileHandle, "description", NX_CHAR, 1, &size), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'description' in NXsample.")) return NX_ERROR; - if (!ErrorHandler(NXopendata(fFileHandle, "description"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'description' in NXsample for writting.")) return NX_ERROR; - memset(cstr, '\0', sizeof(cstr)); - strncpy(cstr, fNxEntry2->GetSample()->GetDescription().c_str(), sizeof(cstr)); - if (!ErrorHandler(NXputdata(fFileHandle, cstr), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'description' in NXsample.")) return NX_ERROR; - NXclosedata(fFileHandle); - } - - // check if temperature is present and if yes, write it into the file - ok=false; - dval = fNxEntry2->GetSample()->GetPhysPropValue("temperature_1", ok); - if (ok) { - fdata = (float)dval; - fNxEntry2->GetSample()->GetPhysPropUnit("temperature_1", str, ok); - } - if (ok) { - size = 1; - if (!ErrorHandler(NXmakedata(fFileHandle, "temperature_1", NX_FLOAT32, 1, &size), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'temperature_1' in NXsample.")) return NX_ERROR; - if (!ErrorHandler(NXopendata(fFileHandle, "temperature_1"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'temperature_1' in NXsample for writting.")) return NX_ERROR; - if (!ErrorHandler(NXputdata(fFileHandle, (void*)&fdata), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'temperature_1' in NXsample.")) return NX_ERROR; - memset(cstr, '\0', sizeof(cstr)); - strncpy(cstr, str.c_str(), sizeof(cstr)); - if (!ErrorHandler(NXputattr(fFileHandle, "units", cstr, strlen(cstr), NX_CHAR), PNEXUS_PUT_ATTR_ERROR, "couldn't put attribute 'units' for 'temperature_1' in NXsample.")) return NX_ERROR; - NXclosedata(fFileHandle); - } - - // check if temperature environment info is present - if (fNxEntry2->GetSample()->GetEnvironmentTemp().compare("n/a")) { - // make group 'temperature_1_env' - if (!ErrorHandler(NXmakegroup(fFileHandle, "temperature_1_env", "NXenvironment"), PNEXUS_CREATE_GROUP_ERROR, "couldn't create group 'temperature_1_env' in NXsample.")) return NX_ERROR; - // open group 'temperature_1_env' - if (!ErrorHandler(NXopengroup(fFileHandle, "temperature_1_env", "NXenvironment"), PNEXUS_GROUP_OPEN_ERROR, "couldn't open group 'NXenvironment' in NXsample for writting.")) return NX_ERROR; - // write sample 'temperature_1_env' - size = fNxEntry2->GetSample()->GetEnvironmentTemp().length(); - if (!ErrorHandler(NXmakedata(fFileHandle, "name", NX_CHAR, 1, &size), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'name' in 'temperature_1_env' in NXsample.")) return NX_ERROR; - if (!ErrorHandler(NXopendata(fFileHandle, "name"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'name' in 'temperature_1_env' in NXsample for writting.")) return NX_ERROR; - memset(cstr, '\0', sizeof(cstr)); - strncpy(cstr, fNxEntry2->GetSample()->GetEnvironmentTemp().c_str(), sizeof(cstr)); - if (!ErrorHandler(NXputdata(fFileHandle, cstr), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'temperature_1_env' in NXsample.")) return NX_ERROR; - NXclosedata(fFileHandle); - // close group 'temperature_1_env' - NXclosegroup(fFileHandle); - } - - // check if magnetic field is present and if yes, write it into the file - ok=false; - dval = fNxEntry2->GetSample()->GetPhysPropValue("magnetic_field_1", ok); - if (ok) { - fdata = (float)dval; - fNxEntry2->GetSample()->GetPhysPropUnit("magnetic_field_1", str, ok); - } - if (ok) { - size = 1; - if (!ErrorHandler(NXmakedata(fFileHandle, "magnetic_field_1", NX_FLOAT32, 1, &size), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'magnetic_field_1' in NXsample.")) return NX_ERROR; - if (!ErrorHandler(NXopendata(fFileHandle, "magnetic_field_1"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'magnetic_field_1' in NXsample for writting.")) return NX_ERROR; - if (!ErrorHandler(NXputdata(fFileHandle, (void*)&fdata), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'magnetic_field_1' in NXsample.")) return NX_ERROR; - memset(cstr, '\0', sizeof(cstr)); - strncpy(cstr, str.c_str(), sizeof(cstr)); - if (!ErrorHandler(NXputattr(fFileHandle, "units", cstr, strlen(cstr), NX_CHAR), PNEXUS_PUT_ATTR_ERROR, "couldn't put attribute 'units' for 'magnetic_field_1' in NXsample.")) return NX_ERROR; - NXclosedata(fFileHandle); - } - - // check if magnetic field environment info is present - if (fNxEntry2->GetSample()->GetEnvironmentField().compare("n/a")) { - // make group 'magnetic_field_1_env' - if (!ErrorHandler(NXmakegroup(fFileHandle, "magnetic_field_1_env", "NXenvironment"), PNEXUS_CREATE_GROUP_ERROR, "couldn't create group 'magnetic_field_1_env' in NXsample.")) return NX_ERROR; - // open group 'magnetic_field_1_env' - if (!ErrorHandler(NXopengroup(fFileHandle, "magnetic_field_1_env", "NXenvironment"), PNEXUS_GROUP_OPEN_ERROR, "couldn't open group 'NXenvironment' in NXsample for writting.")) return NX_ERROR; - // write sample 'magnetic_field_1_env' - size = fNxEntry2->GetSample()->GetEnvironmentField().length(); - if (!ErrorHandler(NXmakedata(fFileHandle, "magnetic_field_1_env", NX_CHAR, 1, &size), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'magnetic_field_1_env' in NXsample.")) return NX_ERROR; - if (!ErrorHandler(NXopendata(fFileHandle, "magnetic_field_1_env"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'magnetic_field_1_env' in NXsample for writting.")) return NX_ERROR; - memset(cstr, '\0', sizeof(cstr)); - strncpy(cstr, fNxEntry2->GetSample()->GetEnvironmentField().c_str(), sizeof(cstr)); - if (!ErrorHandler(NXputdata(fFileHandle, cstr), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'magnetic_field_1_env' in NXsample.")) return NX_ERROR; - NXclosedata(fFileHandle); - // close group 'magnetic_field_1_env' - NXclosegroup(fFileHandle); + if (file.gcount() < 4) { + std::cerr << "**Error**: File too small to be HDF4 or HDF5" << std::endl; + return nxs::HDFType::Unknown; } - // check if magnetic field state info is present - if (fNxEntry2->GetSample()->GetMagneticFieldState().compare("n/a")) { - // write sample 'magnetic_field_state' - size = fNxEntry2->GetSample()->GetMagneticFieldState().length(); - if (!ErrorHandler(NXmakedata(fFileHandle, "magnetic_field_state", NX_CHAR, 1, &size), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'magnetic_field_state' in NXsample.")) return NX_ERROR; - if (!ErrorHandler(NXopendata(fFileHandle, "magnetic_field_state"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'magnetic_field_state' in NXsample for writting.")) return NX_ERROR; - memset(cstr, '\0', sizeof(cstr)); - strncpy(cstr, fNxEntry2->GetSample()->GetMagneticFieldState().c_str(), sizeof(cstr)); - if (!ErrorHandler(NXputdata(fFileHandle, cstr), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'magnetic_field_state' in NXsample.")) return NX_ERROR; - NXclosedata(fFileHandle); - } - - // close group 'sample' - NXclosegroup(fFileHandle); - - - // make group 'instrument' - if (!ErrorHandler(NXmakegroup(fFileHandle, "instrument", "NXinstrument"), PNEXUS_CREATE_GROUP_ERROR, "couldn't create group 'instrument' in NXentry.")) return NX_ERROR; - // open group 'instrument' - if (!ErrorHandler(NXopengroup(fFileHandle, "instrument", "NXinstrument"), PNEXUS_GROUP_OPEN_ERROR, "couldn't open group 'instrument' in NXentry for writting.")) return NX_ERROR; - - // write instrument 'name' - size = fNxEntry2->GetInstrument()->GetName().length(); - if (!ErrorHandler(NXmakedata(fFileHandle, "name", NX_CHAR, 1, &size), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'name' in NXinstrument.")) return NX_ERROR; - if (!ErrorHandler(NXopendata(fFileHandle, "name"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'name' in NXinstrument for writting.")) return NX_ERROR; - memset(cstr, '\0', sizeof(cstr)); - strncpy(cstr, fNxEntry2->GetInstrument()->GetName().c_str(), sizeof(cstr)); - if (!ErrorHandler(NXputdata(fFileHandle, cstr), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'name' in NXinstrument.")) return NX_ERROR; - NXclosedata(fFileHandle); - - // make group 'source' - if (!ErrorHandler(NXmakegroup(fFileHandle, "source", "NXsource"), PNEXUS_CREATE_GROUP_ERROR, "couldn't create group 'source' in NXinstrument.")) return NX_ERROR; - // open group 'source' - if (!ErrorHandler(NXopengroup(fFileHandle, "source", "NXsource"), PNEXUS_GROUP_OPEN_ERROR, "couldn't open group 'source' in NXentry for NXinstrument.")) return NX_ERROR; - - // write instrument 'name' - size = fNxEntry2->GetInstrument()->GetSource()->GetName().length(); - if (!ErrorHandler(NXmakedata(fFileHandle, "name", NX_CHAR, 1, &size), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'name' in NXsource.")) return NX_ERROR; - if (!ErrorHandler(NXopendata(fFileHandle, "name"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'name' in NXsource for writting.")) return NX_ERROR; - memset(cstr, '\0', sizeof(cstr)); - strncpy(cstr, fNxEntry2->GetInstrument()->GetSource()->GetName().c_str(), sizeof(cstr)); - if (!ErrorHandler(NXputdata(fFileHandle, cstr), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'name' in NXsource.")) return NX_ERROR; - NXclosedata(fFileHandle); - - // write instrument 'type' - size = fNxEntry2->GetInstrument()->GetSource()->GetType().length(); - if (!ErrorHandler(NXmakedata(fFileHandle, "type", NX_CHAR, 1, &size), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'type' in NXsource.")) return NX_ERROR; - if (!ErrorHandler(NXopendata(fFileHandle, "type"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'type' in NXsource for writting.")) return NX_ERROR; - memset(cstr, '\0', sizeof(cstr)); - strncpy(cstr, fNxEntry2->GetInstrument()->GetSource()->GetType().c_str(), sizeof(cstr)); - if (!ErrorHandler(NXputdata(fFileHandle, cstr), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'type' in NXsource.")) return NX_ERROR; - NXclosedata(fFileHandle); - - // write instrument 'probe' - size = fNxEntry2->GetInstrument()->GetSource()->GetProbe().length(); - if (!ErrorHandler(NXmakedata(fFileHandle, "probe", NX_CHAR, 1, &size), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'probe' in NXsource.")) return NX_ERROR; - if (!ErrorHandler(NXopendata(fFileHandle, "probe"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'probe' in NXsource for writting.")) return NX_ERROR; - memset(cstr, '\0', sizeof(cstr)); - strncpy(cstr, fNxEntry2->GetInstrument()->GetSource()->GetProbe().c_str(), sizeof(cstr)); - if (!ErrorHandler(NXputdata(fFileHandle, cstr), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'probe' in NXsource.")) return NX_ERROR; - NXclosedata(fFileHandle); - - // close group 'source' - NXclosegroup(fFileHandle); - - // make group 'beamline' - if (!ErrorHandler(NXmakegroup(fFileHandle, "beamline", "NXbeamline"), PNEXUS_CREATE_GROUP_ERROR, "couldn't create group 'beamline' in NXinstrument.")) return NX_ERROR; - // open group 'beamline' - if (!ErrorHandler(NXopengroup(fFileHandle, "beamline", "NXbeamline"), PNEXUS_GROUP_OPEN_ERROR, "couldn't open group 'beamline' in NXentry for NXinstrument.")) return NX_ERROR; - - // write beamline 'beamline' - size = fNxEntry2->GetInstrument()->GetBeamline()->GetName().length(); - if (!ErrorHandler(NXmakedata(fFileHandle, "beamline", NX_CHAR, 1, &size), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'beamline' in NXbeamline.")) return NX_ERROR; - if (!ErrorHandler(NXopendata(fFileHandle, "beamline"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'beamline' in NXbeamline for writting.")) return NX_ERROR; - memset(cstr, '\0', sizeof(cstr)); - strncpy(cstr, fNxEntry2->GetInstrument()->GetBeamline()->GetName().c_str(), sizeof(cstr)); - if (!ErrorHandler(NXputdata(fFileHandle, cstr), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'beamline' in NXbeamline.")) return NX_ERROR; - NXclosedata(fFileHandle); - - // close group 'beamline' - NXclosegroup(fFileHandle); - - // make group 'detector_1' - if (!ErrorHandler(NXmakegroup(fFileHandle, "detector_1", "NXdetector"), PNEXUS_CREATE_GROUP_ERROR, "couldn't create group 'detector_1' in NXinstrument.")) return NX_ERROR; - // open group 'detector_1' - if (!ErrorHandler(NXopengroup(fFileHandle, "detector_1", "NXdetector"), PNEXUS_GROUP_OPEN_ERROR, "couldn't open group 'detector_1' in NXinstrument.")) return NX_ERROR; - - // write detector_1 'description' - size = fNxEntry2->GetInstrument()->GetDetector()->GetDescription().length(); - if (!ErrorHandler(NXmakedata(fFileHandle, "description", NX_CHAR, 1, &size), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'description' in NXdetector.")) return NX_ERROR; - if (!ErrorHandler(NXopendata(fFileHandle, "description"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'description' in NXdetector for writting.")) return NX_ERROR; - memset(cstr, '\0', sizeof(cstr)); - strncpy(cstr, fNxEntry2->GetInstrument()->GetDetector()->GetDescription().c_str(), sizeof(cstr)); - if (!ErrorHandler(NXputdata(fFileHandle, cstr), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'description' in NXdetector.")) return NX_ERROR; - NXclosedata(fFileHandle); - - // write detector_1 'counts' - int dims[3]; - if (fNxEntry2->GetInstrument()->GetDetector()->GetNoOfPeriods() > 0) { // counts[][][] - dims[0] = fNxEntry2->GetInstrument()->GetDetector()->GetNoOfPeriods(); - dims[1] = fNxEntry2->GetInstrument()->GetDetector()->GetNoOfSpectra(); - dims[2] = fNxEntry2->GetInstrument()->GetDetector()->GetNoOfBins(); - if (!ErrorHandler(NXcompmakedata(fFileHandle, "counts", NX_INT32, 3, dims, NX_COMP_LZW, dims), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'counts' in NXdetector.")) return NX_ERROR; - } else { - if (fNxEntry2->GetInstrument()->GetDetector()->GetNoOfSpectra() > 0) { // counts[][] - dims[0] = fNxEntry2->GetInstrument()->GetDetector()->GetNoOfSpectra(); - dims[1] = fNxEntry2->GetInstrument()->GetDetector()->GetNoOfBins(); - if (!ErrorHandler(NXcompmakedata(fFileHandle, "counts", NX_INT32, 2, dims, NX_COMP_LZW, dims), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'counts' in NXdetector.")) return NX_ERROR; - } else { // counts[] - dims[0] = fNxEntry2->GetInstrument()->GetDetector()->GetNoOfBins(); - if (!ErrorHandler(NXcompmakedata(fFileHandle, "counts", NX_INT32, 1, dims, NX_COMP_LZW, dims), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'counts' in NXdetector.")) return NX_ERROR; - } - } - if (!ErrorHandler(NXopendata(fFileHandle, "counts"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'counts' in NXdetector for writting.")) return NX_ERROR; - if (!ErrorHandler(NXputdata(fFileHandle, (void*)fNxEntry2->GetInstrument()->GetDetector()->GetHistos()), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'counts' in NXdetector.")) return NX_ERROR; - - // write 'counts' attributes - idata = 1; - if (!ErrorHandler(NXputattr(fFileHandle, "signal", &idata, 1, NX_INT32), PNEXUS_PUT_ATTR_ERROR, "couldn't put attribute 'signal' for 'counts' in NXdetector.")) return NX_ERROR; - - memset(cstr, '\0', sizeof(cstr)); - if (fNxEntry2->GetInstrument()->GetDetector()->GetNoOfPeriods() > 0) { // counts[][][] - strncpy(cstr, "[period_index, spectrum_index, raw_time_bin]", sizeof(cstr)); - } else { - if (fNxEntry2->GetInstrument()->GetDetector()->GetNoOfSpectra() > 0) { // counts[][] - strncpy(cstr, "[spectrum_index, raw_time_bin]", sizeof(cstr)); - } else { // counts[] - strncpy(cstr, "[raw_time_bin]", sizeof(cstr)); - } - } - if (!ErrorHandler(NXputattr(fFileHandle, "axes", cstr, strlen(cstr), NX_CHAR), PNEXUS_PUT_ATTR_ERROR, "couldn't put attribute 'axes' for 'counts' in NXdetector.")) return NX_ERROR; - - memset(cstr, '\0', sizeof(cstr)); - if (!fNxEntry2->GetInstrument()->GetSource()->GetProbe().compare("positive muons")) { - strncpy(cstr, "positron counts", sizeof(cstr)); - } else if (!fNxEntry2->GetInstrument()->GetSource()->GetProbe().compare("negative muons")) { - strncpy(cstr, "electron counts", sizeof(cstr)); - } else { - strncpy(cstr, "n/a", sizeof(cstr)); - } - if (!ErrorHandler(NXputattr(fFileHandle, "long_name", cstr, strlen(cstr), NX_CHAR), PNEXUS_PUT_ATTR_ERROR, "couldn't put attribute 'long_name' for 'counts' in NXdetector.")) return NX_ERROR; - // create link of 'counts' for NXdata - if (!ErrorHandler(NXgetdataID(fFileHandle, &nxLink), PNEXUS_LINKING_ERROR, "couldn't obtain link of 'counts' in NXdetector.")) return NX_ERROR; - nxLinkVec.push_back(nxLink); - NXclosedata(fFileHandle); - - // write time resolution - fdata = (float)fNxEntry2->GetInstrument()->GetDetector()->GetTimeResolution("ns"); - size = 1; - if (!ErrorHandler(NXmakedata(fFileHandle, "histogram_resolution", NX_FLOAT32, 1, &size), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'histogram_resolution' in NXdetector.")) return NX_ERROR; - if (!ErrorHandler(NXopendata(fFileHandle, "histogram_resolution"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'histogram_resolution' in NXdetector for writting.")) return NX_ERROR; - if (!ErrorHandler(NXputdata(fFileHandle, (void*)&fdata), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'histogram_resolution' in NXdetector.")) return NX_ERROR; - memset(cstr, '\0', sizeof(cstr)); - strncpy(cstr, "nano.second", sizeof(cstr)); - if (!ErrorHandler(NXputattr(fFileHandle, "units", cstr, strlen(cstr), NX_CHAR), PNEXUS_PUT_ATTR_ERROR, "couldn't put attribute 'units' for 'histogram_resolution' in NXdetector.")) return NX_ERROR; - // create link of 'histogram_resolution' for NXdata - if (!ErrorHandler(NXgetdataID(fFileHandle, &nxLink), PNEXUS_LINKING_ERROR, "couldn't obtain link of 'histogram_resolution' in NXdetector.")) return NX_ERROR; - nxLinkVec.push_back(nxLink); - NXclosedata(fFileHandle); - - // write detector_1 'raw_time' - size = (int)fNxEntry2->GetInstrument()->GetDetector()->GetRawTime()->size(); - float *p_fdata = new float[size]; - assert(p_fdata); - for (int i=0; iGetInstrument()->GetDetector()->GetRawTime()->at(i); - if (!ErrorHandler(NXmakedata(fFileHandle, "raw_time", NX_FLOAT32, 1, &size), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'raw_time' in NXdetector.")) return NX_ERROR; - if (!ErrorHandler(NXopendata(fFileHandle, "raw_time"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'raw_time' in NXdetector for writting.")) return NX_ERROR; - if (!ErrorHandler(NXputdata(fFileHandle, (void*)p_fdata), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'raw_time' in NXdetector.")) return NX_ERROR; - strncpy(cstr, fNxEntry2->GetInstrument()->GetDetector()->GetRawTimeUnit().c_str(), sizeof(cstr)); - if (!ErrorHandler(NXputattr(fFileHandle, "units", cstr, strlen(cstr), NX_CHAR), PNEXUS_PUT_ATTR_ERROR, "couldn't put attribute 'units' for 'raw_time' in NXdetector.")) return NX_ERROR; - strncpy(cstr, fNxEntry2->GetInstrument()->GetDetector()->GetRawTimeName().c_str(), sizeof(cstr)); - if (!ErrorHandler(NXputattr(fFileHandle, "long_name", cstr, strlen(cstr), NX_CHAR), PNEXUS_PUT_ATTR_ERROR, "couldn't put attribute 'long_name' for 'raw_time' in NXdetector.")) return NX_ERROR; - // create link of 'raw_time' for NXdata - if (!ErrorHandler(NXgetdataID(fFileHandle, &nxLink), PNEXUS_LINKING_ERROR, "couldn't obtain link of 'raw_time' in NXdetector.")) return NX_ERROR; - nxLinkVec.push_back(nxLink); - NXclosedata(fFileHandle); - // clean up - if (p_fdata) { - delete [] p_fdata; - p_fdata = 0; - } - - // write detector_1 'spectrum_index' - size = fNxEntry2->GetInstrument()->GetDetector()->GetSpectrumIndexSize(); - int *p_idata = new int[size]; - assert(p_idata); - for (int i=0; iGetInstrument()->GetDetector()->GetSpectrumIndex(i); - if (!ErrorHandler(NXmakedata(fFileHandle, "spectrum_index", NX_INT32, 1, &size), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'spectrum_index' in NXdetector.")) return NX_ERROR; - if (!ErrorHandler(NXopendata(fFileHandle, "spectrum_index"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'spectrum_index' in NXdetector for writting.")) return NX_ERROR; - if (!ErrorHandler(NXputdata(fFileHandle, (void*)p_idata), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'spectrum_index' in NXdetector.")) return NX_ERROR; - // create link of 'spectrum_index' for NXdata - if (!ErrorHandler(NXgetdataID(fFileHandle, &nxLink), PNEXUS_LINKING_ERROR, "couldn't obtain link of 'spectrum_index' in NXdetector.")) return NX_ERROR; - nxLinkVec.push_back(nxLink); - NXclosedata(fFileHandle); - if (p_idata) { - delete [] p_idata; - p_idata = 0; - } - - // write detector_1 'time_zero_bin' if present - if (fNxEntry2->GetInstrument()->GetDetector()->IsT0Present()) { - if (fNxEntry2->GetInstrument()->GetDetector()->GetT0Tag() == 1) { - size = 1; - idata = fNxEntry2->GetInstrument()->GetDetector()->GetT0(); - if (!ErrorHandler(NXmakedata(fFileHandle, "time_zero_bin", NX_INT32, 1, &size), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'time_zero_bin' in NXdetector.")) return NX_ERROR; - if (!ErrorHandler(NXopendata(fFileHandle, "time_zero_bin"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'time_zero_bin' in NXdetector for writting.")) return NX_ERROR; - if (!ErrorHandler(NXputdata(fFileHandle, (void*)&idata), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'time_zero_bin' in NXdetector.")) return NX_ERROR; - NXclosedata(fFileHandle); - } else if (fNxEntry2->GetInstrument()->GetDetector()->GetT0Tag() == 2) { - int dims[1]; - dims[0] = fNxEntry2->GetInstrument()->GetDetector()->GetNoOfSpectra(); - if (!ErrorHandler(NXmakedata(fFileHandle, "time_zero_bin", NX_INT32, 1, dims), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'time_zero_bin' in NXdetector.")) return NX_ERROR; - if (!ErrorHandler(NXopendata(fFileHandle, "time_zero_bin"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'time_zero_bin' in NXdetector for writting.")) return NX_ERROR; - if (!ErrorHandler(NXputdata(fFileHandle, (void*)fNxEntry2->GetInstrument()->GetDetector()->GetT0s()), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'time_zero_bin' in NXdetector.")) return NX_ERROR; - NXclosedata(fFileHandle); - } else if (fNxEntry2->GetInstrument()->GetDetector()->GetT0Tag() == 3) { - int dims[2]; - dims[0] = fNxEntry2->GetInstrument()->GetDetector()->GetNoOfPeriods(); - dims[1] = fNxEntry2->GetInstrument()->GetDetector()->GetNoOfSpectra(); - if (!ErrorHandler(NXmakedata(fFileHandle, "time_zero_bin", NX_INT32, 2, dims), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'time_zero_bin' in NXdetector.")) return NX_ERROR; - if (!ErrorHandler(NXopendata(fFileHandle, "time_zero_bin"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'time_zero_bin' in NXdetector for writting.")) return NX_ERROR; - if (!ErrorHandler(NXputdata(fFileHandle, (void*)fNxEntry2->GetInstrument()->GetDetector()->GetT0s()), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'time_zero_bin' in NXdetector.")) return NX_ERROR; - NXclosedata(fFileHandle); - } else { - std::cerr << std::endl << ">> **WARNING** time_zero_bin with rank " << fNxEntry2->GetInstrument()->GetDetector()->GetT0Tag() << " requested. Do not know how to handle." << std::endl; - } - } - - // write detector_1 'first_good_bin' if present - if (fNxEntry2->GetInstrument()->GetDetector()->IsFirstGoodBinPresent()) { - if (fNxEntry2->GetInstrument()->GetDetector()->GetT0Tag() == 1) { - size = 1; - idata = fNxEntry2->GetInstrument()->GetDetector()->GetFirstGoodBin(); - if (!ErrorHandler(NXmakedata(fFileHandle, "first_good_bin", NX_INT32, 1, &size), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'first_good_bin' in NXdetector.")) return NX_ERROR; - if (!ErrorHandler(NXopendata(fFileHandle, "first_good_bin"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'first_good_bin' in NXdetector for writting.")) return NX_ERROR; - if (!ErrorHandler(NXputdata(fFileHandle, (void*)&idata), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'first_good_bin' in NXdetector.")) return NX_ERROR; - NXclosedata(fFileHandle); - } else if (fNxEntry2->GetInstrument()->GetDetector()->GetT0Tag() == 2) { - int dims[1]; - dims[0] = fNxEntry2->GetInstrument()->GetDetector()->GetNoOfSpectra(); - if (!ErrorHandler(NXmakedata(fFileHandle, "first_good_bin", NX_INT32, 1, dims), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'first_good_bin' in NXdetector.")) return NX_ERROR; - if (!ErrorHandler(NXopendata(fFileHandle, "first_good_bin"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'first_good_bin' in NXdetector for writting.")) return NX_ERROR; - if (!ErrorHandler(NXputdata(fFileHandle, (void*)fNxEntry2->GetInstrument()->GetDetector()->GetFirstGoodBins()), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'first_good_bin' in NXdetector.")) return NX_ERROR; - NXclosedata(fFileHandle); - } else if (fNxEntry2->GetInstrument()->GetDetector()->GetT0Tag() == 3) { - int dims[2]; - dims[0] = fNxEntry2->GetInstrument()->GetDetector()->GetNoOfPeriods(); - dims[1] = fNxEntry2->GetInstrument()->GetDetector()->GetNoOfSpectra(); - if (!ErrorHandler(NXmakedata(fFileHandle, "first_good_bin", NX_INT32, 2, dims), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'first_good_bin' in NXdetector.")) return NX_ERROR; - if (!ErrorHandler(NXopendata(fFileHandle, "first_good_bin"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'first_good_bin' in NXdetector for writting.")) return NX_ERROR; - if (!ErrorHandler(NXputdata(fFileHandle, (void*)fNxEntry2->GetInstrument()->GetDetector()->GetFirstGoodBins()), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'first_good_bin' in NXdetector.")) return NX_ERROR; - NXclosedata(fFileHandle); - } else { - std::cerr << std::endl << ">> **WARNING** first_good_bin with rank " << fNxEntry2->GetInstrument()->GetDetector()->GetT0Tag() << " requested. Do not know how to handle." << std::endl; - } - } - - // write detector_1 'last_good_bin' if present - if (fNxEntry2->GetInstrument()->GetDetector()->IsLastGoodBinPresent()) { - if (fNxEntry2->GetInstrument()->GetDetector()->GetT0Tag() == 1) { - size = 1; - idata = fNxEntry2->GetInstrument()->GetDetector()->GetLastGoodBin(); - if (!ErrorHandler(NXmakedata(fFileHandle, "last_good_bin", NX_INT32, 1, &size), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'last_good_bin' in NXdetector.")) return NX_ERROR; - if (!ErrorHandler(NXopendata(fFileHandle, "last_good_bin"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'last_good_bin' in NXdetector for writting.")) return NX_ERROR; - if (!ErrorHandler(NXputdata(fFileHandle, (void*)&idata), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'last_good_bin' in NXdetector.")) return NX_ERROR; - NXclosedata(fFileHandle); - } else if (fNxEntry2->GetInstrument()->GetDetector()->GetT0Tag() == 2) { - int dims[1]; - dims[0] = fNxEntry2->GetInstrument()->GetDetector()->GetNoOfSpectra(); - if (!ErrorHandler(NXmakedata(fFileHandle, "last_good_bin", NX_INT32, 1, dims), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'last_good_bin' in NXdetector.")) return NX_ERROR; - if (!ErrorHandler(NXopendata(fFileHandle, "last_good_bin"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'last_good_bin' in NXdetector for writting.")) return NX_ERROR; - if (!ErrorHandler(NXputdata(fFileHandle, (void*)fNxEntry2->GetInstrument()->GetDetector()->GetLastGoodBins()), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'last_good_bin' in NXdetector.")) return NX_ERROR; - NXclosedata(fFileHandle); - } else if (fNxEntry2->GetInstrument()->GetDetector()->GetT0Tag() == 3) { - int dims[2]; - dims[0] = fNxEntry2->GetInstrument()->GetDetector()->GetNoOfPeriods(); - dims[1] = fNxEntry2->GetInstrument()->GetDetector()->GetNoOfSpectra(); - if (!ErrorHandler(NXmakedata(fFileHandle, "last_good_bin", NX_INT32, 2, dims), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'last_good_bin' in NXdetector.")) return NX_ERROR; - if (!ErrorHandler(NXopendata(fFileHandle, "last_good_bin"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'last_good_bin' in NXdetector for writting.")) return NX_ERROR; - if (!ErrorHandler(NXputdata(fFileHandle, (void*)fNxEntry2->GetInstrument()->GetDetector()->GetLastGoodBins()), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'last_good_bin' in NXdetector.")) return NX_ERROR; - NXclosedata(fFileHandle); - } else { - std::cerr << std::endl << ">> **WARNING** last_good_bin with rank " << fNxEntry2->GetInstrument()->GetDetector()->GetT0Tag() << " requested. Do not know how to handle." << std::endl; - } - } - - // close group 'detector_1' - NXclosegroup(fFileHandle); - - // close group 'instrument' - NXclosegroup(fFileHandle); - - // make group 'detector_1' NXdata - if (!ErrorHandler(NXmakegroup(fFileHandle, "detector_1", "NXdata"), PNEXUS_CREATE_GROUP_ERROR, "couldn't create group 'detector_1' in NXroot.")) return NX_ERROR; - // open group 'detector_1' NXdata - if (!ErrorHandler(NXopengroup(fFileHandle, "detector_1", "NXdata"), PNEXUS_GROUP_OPEN_ERROR, "couldn't open group 'detector_1' in NXroot.")) return NX_ERROR; - - for (unsigned int i=0; iChecks if the given data are representing a valid IDF Version 1. - * - * return: - * - true if a valid IDF Version 1 representation is present - * - false otherwise - * - * \param strict flag if true a strict NeXus validation is performed. - */ -bool PNeXus::IsValidIdf1(bool strict) -{ - bool valid = true; - - if (fIdfVersion != 1) { - std::cerr << std::endl << ">> **ERROR** wrong IDF version found, namely IDF " << fIdfVersion << ", instead of IDF 1" << std::endl; - return false; - } - - if (!fNxEntry1->IsValid(strict)) - valid = false; + // HDF5 signature: 0x89 'H' 'D' 'F' 0x0d 0x0a 0x1a 0x0a + const unsigned char hdf5_sig[8] = {0x89, 0x48, 0x44, 0x46, 0x0d, 0x0a, 0x1a, 0x0a}; - return valid; -} - -//------------------------------------------------------------------------------------------ -// IsValidIdf2 (private) -//------------------------------------------------------------------------------------------ -/** - *

Checks if the given data are representing a valid IDF Version 2. - * - * return: - * - true if a valid IDF Version 2 representation is present - * - false otherwise - * - * \param strict flag if true a strict NeXus validation is performed. - */ -bool PNeXus::IsValidIdf2(bool strict) -{ - if (fIdfVersion != 2) { - std::cerr << std::endl << ">> **ERROR** wrong IDF version found, namely IDF " << fIdfVersion << ", instead of IDF 2" << std::endl; - return false; - } - - if (!fCreator.compare("n/a")) { - if (strict) { - std::cerr << std::endl << ">> **ERROR** creator not set." << std::endl; - return false; - } else { - std::cerr << std::endl << ">> **WARNING** creator not set." << std::endl; - } - } - - if (!fFileName.compare("n/a")) { - if (strict) { - std::cerr << std::endl << ">> **ERROR** file name not given." << std::endl; - return false; - } else { - std::cerr << std::endl << ">> **WARNING** file name not given." << std::endl; - } - } + // HDF4 signature: 0x0e 0x03 0x13 0x01 + const unsigned char hdf4_sig[4] = {0x0e, 0x03, 0x13, 0x01}; - if (!fFileTime.compare("n/a")) { - if (strict) { - std::cerr << std::endl << ">> **ERROR** no file creation time is given." << std::endl; - return false; - } else { - std::cerr << std::endl << ">> **WARNING** no file creation time is given." << std::endl; - } + // Check HDF5 first (needs 8 bytes) + if (file.gcount() >= 8 && std::memcmp(header, hdf5_sig, 8) == 0) { + return nxs::HDFType::HDF5; } - if (!fNxEntry2->IsValid(strict)) { - return false; + // Check HDF4 (needs 4 bytes) + if (std::memcmp(header, hdf4_sig, 4) == 0) { + return nxs::HDFType::HDF4; } - return true; -} - -//------------------------------------------------------------------------------------------ -// SearchInGroup (private) -//------------------------------------------------------------------------------------------ -/** - *

Searches an entry (labelled by str) in the currently open group. If the tag=='name' - * a label is looked for, if the tag=='class' a class is looked for. - * - * return: - * - true if entry 'str' is found in the currently open group. nxname, nxclass keeps than the entry information. - * - false otherwise - * - * \param str label/class of the entry to be looked for - * \param tag either 'name' or 'class' - * \param nxname 'name' of the entry if entry is found - * \param nxclass 'class name' of the entry if entry is found - * \param dataType of the entry if entry is found - */ -bool PNeXus::SearchInGroup(std::string str, std::string tag, NXname &nxname, NXname &nxclass, int &dataType) -{ - bool found = false; - int status; - - NXinitgroupdir(fFileHandle); - do { - status = NXgetnextentry(fFileHandle, nxname, nxclass, &dataType); - if (!tag.compare("name")) { - if (!str.compare(nxname)) { - found = true; - break; - } - } else if (!tag.compare("class")) { - if (!str.compare(nxclass)) { - found = true; - break; - } - } else { - std::cerr << std::endl << ">> **ERROR** found tag='" << tag << "' which is not handled!" << std::endl; - break; - } - } while (!found && (status == NX_OK)); - - return found; -} - -//------------------------------------------------------------------------------------------ -// SearchAttrInData (private) -//------------------------------------------------------------------------------------------ -/** - *

Searches an attribute (labelled by str) in the currently open data set. - * - * return: - * - true if attribute 'str' is found in the currently open data set. nxname, nxclass keeps than the entry information. - * - false otherwise - * - * \param str label of the attribute to be looked for - * \param length of the attribute data if entry is found - * \param dataType of the entry if entry is found - */ -bool PNeXus::SearchAttrInData(std::string str, int &length, int &dataType) -{ - bool found = false; - int status, rank, dims[32]; - char name[128]; - - memset(name, 0, sizeof(name)); - - NXinitattrdir(fFileHandle); - do { - status = NXgetnextattra(fFileHandle, name, &rank, dims, &dataType); - if (!str.compare(name)) { - if (rank == 1) - length = dims[0]; - found = true; - break; - } - } while (!found && (status == NX_OK)); - - return found; + return nxs::HDFType::Unknown; } diff --git a/src/external/nexus/PNeXus.h b/src/external/nexus/PNeXus.h index 768120a2..c855900a 100644 --- a/src/external/nexus/PNeXus.h +++ b/src/external/nexus/PNeXus.h @@ -31,607 +31,17 @@ #define _PNEXUS_H_ #include -#include -#include -#include "napi.h" +namespace nxs { -#ifndef VGNAMELENMAX -#define VGNAMELENMAX 64 -#endif /* VGNAMELENMAX */ - -#define PNEXUS_NO_ERROR 0 -#define PNEXUS_NXENTRY_NOT_FOUND 1 -#define PNEXUS_FILE_OPEN_ERROR 2 -#define PNEXUS_GROUP_OPEN_ERROR 3 -#define PNEXUS_OPEN_DATA_ERROR 4 -#define PNEXUS_GET_DATA_ERROR 5 -#define PNEXUS_GET_ATTR_ERROR 6 -#define PNEXUS_CLOSE_DATA_ERROR 7 -#define PNEXUS_GET_META_INFO_ERROR 8 -#define PNEXUS_WRONG_META_INFO 9 -#define PNEXUS_WRONG_DATE_FORMAT 10 -#define PNEXUS_WRONG_TIME_FORMAT 11 -#define PNEXUS_INIT_GROUPDIR_ERROR 12 -#define PNEXUS_GET_GROUP_INFO_ERROR 13 -#define PNEXUS_GET_NEXT_ENTRY_ERROR 14 -#define PNEXUS_HISTO_ERROR 15 -#define PNEXUS_SET_ATTR_ERROR 16 -#define PNEXUS_CREATE_GROUP_ERROR 17 -#define PNEXUS_MAKE_DATA_ERROR 18 -#define PNEXUS_PUT_DATA_ERROR 19 -#define PNEXUS_PUT_ATTR_ERROR 20 -#define PNEXUS_IDF_NOT_IMPLEMENTED 21 -#define PNEXUS_VAILD_READ_IDF1_FILE 22 -#define PNEXUS_VAILD_READ_IDF2_FILE 23 -#define PNEXUS_OBJECT_INVOK_ERROR 24 -#define PNEXUS_TIME_FORMAT_ERROR 25 -#define PNEXUS_DATA_ERROR 26 -#define PNEXUS_NXUSER_NOT_FOUND 27 -#define PNEXUS_LINKING_ERROR 28 - -class PNeXusProp { - public: - PNeXusProp(); - virtual ~PNeXusProp() {} - - virtual std::string GetName() { return fName; } - virtual double GetValue() { return fValue; } - virtual std::string GetUnit() { return fUnit; } - - virtual void SetName(std::string name) { fName = name; } - virtual void SetValue(double val) { fValue = val; } - virtual void SetUnit(std::string unit) { fUnit = unit; } - - private: - std::string fName; - double fValue; - std::string fUnit; +enum class HDFType { + HDF4, + HDF5, + Unknown }; -class PNeXusBeam1 { - public: - PNeXusBeam1() { fTotalCounts = 0; fUnits = "n/a"; } - virtual ~PNeXusBeam1() {} +HDFType checkHDFType(const std::string& filename); - virtual bool IsValid(bool strict); - - virtual double GetTotalCounts() { return fTotalCounts; } - virtual std::string GetUnits() { return fUnits; } - - virtual void SetTotalCounts(double counts) { fTotalCounts = counts; } - virtual void SetUnits(std::string units) { fUnits = units; } - - private: - double fTotalCounts; ///< total number of counts - std::string fUnits; ///< 'units' in which total counts is given, e.g. 'Mev' -}; - -class PNeXusCollimator1 { - public: - PNeXusCollimator1() { fType = "n/a"; } - virtual ~PNeXusCollimator1() {} - - virtual bool IsValid(bool strict) { return true; } // currently only a dummy - - virtual std::string GetType() { return fType; } - virtual void SetType(std::string type) { fType = type; } - - private: - std::string fType; -}; - -class PNeXusDetector1 { - public: - PNeXusDetector1() { fNumber = 0; } - virtual ~PNeXusDetector1() {} - - virtual bool IsValid(bool strict); - - virtual int GetNumber() { return fNumber; } - virtual void SetNumber(int number) { fNumber = number; } - - private: - int fNumber; -}; - -class PNeXusInstrument1 { - public: - PNeXusInstrument1() { fName = "n/a"; } - virtual ~PNeXusInstrument1() {} - - virtual bool IsValid(bool strict); - - virtual std::string GetName() { return fName; } - virtual PNeXusDetector1* GetDetector() { return &fDetector; } - virtual PNeXusCollimator1* GetCollimator() { return &fCollimator; } - virtual PNeXusBeam1* GetBeam() { return &fBeam; } - - virtual void SetName(std::string name) { fName = name; } - virtual void SetDetector(PNeXusDetector1 &detector) { fDetector = detector; } - virtual void SetCollimator(PNeXusCollimator1 &collimator) { fCollimator = collimator; } - virtual void SetBeam(PNeXusBeam1 &beam) { fBeam = beam; } - - private: - std::string fName; ///< instrument name - PNeXusDetector1 fDetector; - PNeXusCollimator1 fCollimator; - PNeXusBeam1 fBeam; -}; - -class PNeXusSample1 { - public: - PNeXusSample1(); - virtual ~PNeXusSample1(); - - virtual bool IsValid(bool strict); - - virtual std::string GetName() { return fName; } - virtual std::string GetShape() { return fShape; } - virtual std::string GetMagneticFieldState() { return fMagneticFieldState; } - virtual std::string GetEnvironment() { return fEnvironment; } - virtual double GetPhysPropValue(std::string name, bool &ok); - virtual void GetPhysPropUnit(std::string name, std::string &unit, bool &ok); - virtual int IsMagneticFieldVectorAvailable() { return fMagneticFieldVectorAvailable; } - virtual std::vector GetMagneticFieldVector() { return fMagneticFieldVector; } - virtual std::string GetMagneticFieldVectorUnits() { return fMagneticFieldVectorUnits; } - virtual std::string GetMagneticFieldVectorCoordinateSystem() { return fMagneticFieldVectorCoordinateSystem; } - - virtual void SetName(std::string name) { fName = name; } - virtual void SetShape(std::string shape) { fShape = shape; } - virtual void SetMagneticFieldState(std::string magFieldState) { fMagneticFieldState = magFieldState; } - virtual void SetEnvironment(std::string env) { fEnvironment = env; } - virtual void SetPhysProp(std::string name, double value, std::string unit, int idx=-1); - virtual void SetMagneticFieldVectorAvailable(int avail) { fMagneticFieldVectorAvailable = avail; } - virtual void SetMagneticFieldVector(std::vector &magVec) { fMagneticFieldVector = magVec; } - virtual void SetMagneticFieldVectorCoordinateSystem(std::string coord) { fMagneticFieldVectorCoordinateSystem = coord; } - virtual void SetMagneticFieldUnits(std::string units) { fMagneticFieldVectorUnits = units; } - - private: - std::string fName; ///< sample name - std::string fShape; ///< sample orientation - std::string fMagneticFieldState; ///< magnetic field state, e.g. TF, ZF, ... - std::string fEnvironment; ///< sample environment, e.g. CCR, Konti-1, ... - std::vector fPhysProp; ///< collects the temperature, magnetic field - - int fMagneticFieldVectorAvailable; ///< flag '0' magnetic field vector not available, '1' magnetic field vector available - std::vector fMagneticFieldVector; ///< magnetic field vector - std::string fMagneticFieldVectorUnits; ///< units in which the magnetic field vector is given - std::string fMagneticFieldVectorCoordinateSystem; ///< coordinate system, e.g. 'cartesian' -}; - -class PNeXusUser1 { - public: - PNeXusUser1(); - virtual ~PNeXusUser1() {} - - virtual bool IsValid(bool strict) { return true; } // currently only a dummy - - virtual std::string GetName() { return fName; } - virtual std::string GetExperimentNumber() { return fExperimentNumber; } - - virtual void SetName(std::string name) { fName = name; } - virtual void SetExperimentNumber(std::string expNum) { fExperimentNumber = expNum; } - - private: - std::string fName; ///< user name - std::string fExperimentNumber; ///< experiment number, RB number at ISIS -}; - -class PNeXusAlpha1 { - public: - PNeXusAlpha1(); - virtual ~PNeXusAlpha1() {} - - virtual unsigned int GetGroupFirst() { return fGroupFirst; } - virtual unsigned int GetGroupSecond() { return fGroupSecond; } - virtual double GetAlpha() { return fAlphaVal; } - - virtual void SetGroupFirst(unsigned int val) { fGroupFirst = val; } - virtual void SetGroupSecond(unsigned int val) { fGroupSecond = val; } - virtual void SetAlpha(double val) { fAlphaVal = val; } - - private: - unsigned int fGroupFirst; - unsigned int fGroupSecond; - double fAlphaVal; -}; - -class PNeXusData1 { - public: - PNeXusData1() { fTimeResolution = 0.0; } - virtual ~PNeXusData1(); - - virtual bool IsValid(bool strict); - - virtual double GetTimeResolution(std::string units); - virtual std::vector *GetT0s() { return &fT0; } - virtual int GetT0(unsigned int idx); - virtual std::vector *GetFirstGoodBins() { return &fFirstGoodBin; } - virtual int GetFirstGoodBin(unsigned int idx); - virtual std::vector *GetLastGoodBins() { return &fLastGoodBin; } - virtual int GetLastGoodBin(unsigned int idx); - virtual std::vector *GetHistoNames() { return &fHistoName; } - virtual void GetHistoName(unsigned int idx, std::string &name, bool &ok); - virtual unsigned int GetNoOfHistos() { return fHisto.size(); } - virtual unsigned int GetHistoLength(unsigned int histoNo=0); - virtual unsigned int GetHistoCounts(unsigned int histoNo=0); - virtual std::vector *GetHisto(unsigned int histoNo); - virtual std::vector *GetGrouping() { return &fGrouping; } - virtual std::vector *GetAlpha() { return &fAlpha; } - - virtual void SetTimeResolution(double val, std::string units); - virtual void SetT0(unsigned int t0, int idx=-1); - virtual void SetFirstGoodBin(unsigned int fgb, int idx=-1); - virtual void SetLastGoodBin(unsigned int lgb, int idx=-1); - virtual void FlushHistos(); - virtual void SetHisto(std::vector &data, int histoNo=-1); - virtual void FlushGrouping() { fGrouping.clear(); } - virtual void SetGrouping(std::vector &grouping) { fGrouping = grouping; } - virtual void FlushAlpha() { fAlpha.clear(); } - virtual void SetAlpha(std::vector &alpha) { fAlpha = alpha; } - - private: - double fTimeResolution; ///< time resolution in (ps) - std::vector fT0; - std::vector fFirstGoodBin; - std::vector fLastGoodBin; - std::vector fHistoName; - std::vector< std::vector > fHisto; - std::vector fGrouping; - std::vector fAlpha; -}; - -class PNeXusEntry1 { - public: - PNeXusEntry1(); - virtual ~PNeXusEntry1() {} - - virtual bool IsValid(bool strict); - - virtual std::string GetProgramName() { return fProgramName; } - virtual std::string GetProgramVersion() { return fProgramVersion; } - virtual int GetRunNumber() { return fRunNumber; } - virtual std::string GetTitle() { return fTitle; } - virtual std::string GetNotes() { return fNotes; } - virtual std::string GetAnalysis() { return fAnalysis; } - virtual std::string GetLaboratory() { return fLaboratory; } - virtual std::string GetBeamline() { return fBeamline; } - virtual std::string GetStartTime() { return fStartTime; } - virtual std::string GetStopTime() { return fStopTime; } - virtual int GetSwitchingState() { return fSwitchingState; } - virtual PNeXusUser1* GetUser() { return &fUser; } - virtual PNeXusSample1* GetSample() { return &fSample; } - virtual PNeXusInstrument1* GetInstrument() { return &fInstrument; } - virtual PNeXusData1* GetData() { return &fData; } - - virtual void SetProgramName(std::string name) { fProgramName = name; } - virtual void SetProgramVersion(std::string version) { fProgramVersion = version; } - virtual void SetRunNumber(int number) { fRunNumber = number; } - virtual void SetTitle(std::string title) { fTitle = title; } - virtual void SetNotes(std::string notes) { fNotes = notes; } - virtual void SetAnalysis(std::string analysis) { fAnalysis = analysis; } - virtual void SetLaboratory(std::string lab) { fLaboratory = lab; } - virtual void SetBeamline(std::string beamline) { fBeamline = beamline; } - virtual int SetStartTime(std::string time); - virtual int SetStopTime(std::string time); - virtual int SetSwitchingState(int state); - virtual void SetUser(PNeXusUser1 &user) { fUser = user; } - virtual void SetSample(PNeXusSample1 &sample) { fSample = sample; } - virtual void SetInstrument(PNeXusInstrument1 &instrument) { fInstrument = instrument; } - virtual void SetData(PNeXusData1 &data) { fData = data; } - - private: - std::string fProgramName; ///< name of the creating program - std::string fProgramVersion; ///< version of the creating program - int fRunNumber; ///< run number - std::string fTitle; ///< string containing the run title - std::string fNotes; ///< comments - std::string fAnalysis; ///< type of muon experiment "muonTD", "ALC", ... - std::string fLaboratory; ///< name of the laboratory where the data are taken, e.g. PSI, triumf, ISIS, J-Parc - std::string fBeamline; ///< name of the beamline used for the experiment, e.g. muE4 - std::string fStartTime; ///< start date/time of the run - std::string fStopTime; ///< stop date/time of the run - int fSwitchingState; ///< '1' normal data collection, '2' Red/Green mode - PNeXusUser1 fUser; ///< NXuser info IDF Version 1 - PNeXusSample1 fSample; ///< NXsample info IDF Version 1 - PNeXusInstrument1 fInstrument; ///< NXinstrument info IDF Version 1 - PNeXusData1 fData; ///< NXdata info IDF Version 1 -}; - -class PNeXusSource2 { - public: - PNeXusSource2(); - virtual ~PNeXusSource2() {} - - virtual bool IsValid(bool strict); - - virtual std::string GetName() { return fName; } - virtual std::string GetType() { return fType; } - virtual std::string GetProbe() { return fProbe; } - - virtual void SetName(std::string name) { fName = name; } - virtual void SetType(std::string type) { fType = type; } - virtual void SetProbe(std::string probe) { fProbe = probe; } - - private: - std::string fName; ///< facility name - std::string fType; ///< continous muon source, pulsed muon source, low energy muon source, ... - std::string fProbe; ///< positive muon, negative muon -}; - -class PNeXusBeamline2 { - public: - PNeXusBeamline2() { fName = "n/a"; } - virtual ~PNeXusBeamline2() {} - - virtual bool IsValid(bool strict); - - virtual std::string GetName() { return fName; } - - virtual void SetName(std::string name) { fName = name; } - - private: - std::string fName; -}; - -class PNeXusDetector2 { - public: - PNeXusDetector2(); - virtual ~PNeXusDetector2(); - - virtual bool IsValid(bool strict); - virtual std::string GetErrorMsg() { return fErrorMsg; } - - virtual std::string GetDescription() { return fDescription; } - virtual double GetTimeResolution(std::string units); - virtual std::vector *GetRawTime() { return &fRawTime; } - virtual std::string GetRawTimeName() { return fRawTimeName; } - virtual std::string GetRawTimeUnit() { return fRawTimeUnit; } - virtual bool IsT0Present() { return (fT0 == nullptr) ? false : true; } - virtual int GetT0Tag() { return fT0Tag; } - virtual int GetT0(int idxp=-1, int idxs=-1); - virtual int* GetT0s() { return fT0; } - virtual bool IsFirstGoodBinPresent() { return (fFirstGoodBin == nullptr) ? false : true; } - virtual int GetFirstGoodBin(int idxp=-1, int idxs=-1); - virtual int* GetFirstGoodBins() { return fFirstGoodBin; } - virtual bool IsLastGoodBinPresent() { return (fLastGoodBin == nullptr) ? false : true; } - virtual int GetLastGoodBin(int idxp=-1, int idxs=-1); - virtual int* GetLastGoodBins() { return fLastGoodBin; } - virtual int GetNoOfPeriods() { return fNoOfPeriods; } - virtual int GetNoOfSpectra() { return fNoOfSpectra; } - virtual int GetNoOfBins() { return fNoOfBins; } - virtual unsigned int GetHistoCounts(int idx_p, int idx_s); - virtual int GetHistoValue(int idx_p, int idx_s, int idx_b); - virtual int* GetHistos() { return fHisto; } - virtual unsigned int GetSpectrumIndexSize() { return fSpectrumIndex.size(); } - virtual std::vector *GetSpectrumIndex() { return &fSpectrumIndex; } - virtual int GetSpectrumIndex(unsigned int idx); - - virtual void SetDescription(std::string description) { fDescription = description; } - virtual void SetTimeResolution(double val, std::string units); - virtual void SetRawTime(std::vector &rawTime); - virtual void SetRawTimeName(std::string rawTimeName) { fRawTimeName = rawTimeName; } - virtual void SetRawTimeUnit(std::string rawTimeUnit) { fRawTimeUnit = rawTimeUnit; } - virtual void SetT0Tag(int tag) { fT0Tag = tag; } - virtual int SetT0(int *t0); - virtual int SetFirstGoodBin(int *fgb); - virtual int SetLastGoodBin(int *lgb); - virtual void SetNoOfPeriods(int val) { fNoOfPeriods = val; } - virtual void SetNoOfSpectra(int val) { fNoOfSpectra = val; } - virtual void SetNoOfBins(int val) { fNoOfBins = val; } - virtual int SetHistos(int *histo); - virtual void SetSpectrumIndex(std::vector spectIdx) { fSpectrumIndex = spectIdx; } - virtual void SetSpectrumIndex(int spectIdx, int idx=-1); - - private: - std::string fErrorMsg; ///< internal error message - std::string fDescription; ///< description of the detector - double fTimeResolution; ///< keeps the time resolution in (ps) - std::vector fSpectrumIndex; ///< list of global spectra - std::vector fRawTime; ///< keeps a raw time vector - std::string fRawTimeName; ///< name of the raw time vector - std::string fRawTimeUnit; ///< unit of the raw time vector - - int fNoOfPeriods; ///< number of periods or -1 if not defined - int fNoOfSpectra; ///< number of spectra or -1 if not defined - int fNoOfBins; ///< number of bins of a spectrum or -1 if not defined - - int fT0Tag; ///< tag for t0, fgb, lgb structure. -1==not present, 1==NX_INT, 2==NX_INT[ns], 3==NX_INT[np][ns] - int *fT0; - int *fFirstGoodBin; - int *fLastGoodBin; - int *fHisto; -}; - -class PNeXusInstrument2 { - public: - PNeXusInstrument2() { fName = "n/a"; } - virtual ~PNeXusInstrument2() {} - - virtual bool IsValid(bool strict); - - virtual std::string GetName() { return fName; } - virtual PNeXusSource2* GetSource() { return &fSource; } - virtual PNeXusBeamline2* GetBeamline() { return &fBeamline; } - virtual PNeXusDetector2* GetDetector() { return &fDetector; } - - virtual void SetName(std::string name) { fName = name; } - virtual void SetSource(PNeXusSource2 &source) { fSource = source; } - virtual void SetBeamline(PNeXusBeamline2 &beamline) { fBeamline = beamline; } - virtual void SetDetector(PNeXusDetector2 &detector) { fDetector = detector; } - - private: - std::string fName; ///< name of the instrument - PNeXusSource2 fSource; ///< details of the muon source used - PNeXusBeamline2 fBeamline; ///< beamline description - PNeXusDetector2 fDetector; ///< details of the detectors which also includes the data!! -}; - -class PNeXusSample2 { - public: - PNeXusSample2(); - virtual ~PNeXusSample2(); - - virtual bool IsValid(bool strict); - - virtual std::string GetName() { return fName; } - virtual std::string GetDescription() { return fDescription; } - virtual std::string GetMagneticFieldState() { return fMagneticFieldState; } - virtual std::string GetEnvironmentTemp() { return fEnvironmentTemp; } - virtual std::string GetEnvironmentField() { return fEnvironmentField; } - virtual double GetPhysPropValue(std::string name, bool &ok); - virtual void GetPhysPropUnit(std::string name, std::string &unit, bool &ok); - - virtual void SetName(std::string name) { fName = name; } - virtual void SetDescription(std::string description) { fDescription = description; } - virtual void SetMagneticFieldState(std::string magFieldState) { fMagneticFieldState = magFieldState; } - virtual void SetEnvironmentTemp(std::string env) { fEnvironmentTemp = env; } - virtual void SetEnvironmentField(std::string env) { fEnvironmentField = env; } - virtual void SetPhysProp(std::string name, double value, std::string unit, int idx=-1); - - private: - std::string fName; ///< sample name - std::string fDescription; ///< sample description - std::string fMagneticFieldState; ///< magnetic field state, e.g. TF, ZF, ... - std::string fEnvironmentTemp; ///< sample environment related to temperature, e.g. CCR, Konti-1, ... - std::string fEnvironmentField; ///< sample environment related to field, e.g. WEW-Bruker - std::vector fPhysProp; ///< collects the temperature, magnetic field -}; - -class PNeXusUser2 { - public: - PNeXusUser2() { fName = "n/a"; } - virtual ~PNeXusUser2() {} - - virtual bool IsValid(bool strict) { return true; } // currently only a dummy - - virtual std::string GetName() { return fName; } - - virtual void SetName(std::string name) { fName = name; } - - private: - std::string fName; ///< user name -}; - -class PNeXusEntry2 { - public: - PNeXusEntry2(); - virtual ~PNeXusEntry2() {} - - virtual bool IsValid(bool strict); - - virtual std::string GetErrorMsg() { return fErrorMsg; } - virtual std::string GetDefinition() { return fDefinition; } - virtual std::string GetProgramName() { return fProgramName; } - virtual std::string GetProgramVersion() { return fProgramVersion; } - virtual int GetRunNumber() { return fRunNumber; } - virtual std::string GetTitle() { return fTitle; } - virtual std::string GetStartTime() { return fStartTime; } - virtual std::string GetStopTime() { return fStopTime; } - virtual std::string GetExperimentIdentifier() { return fExperimentIdentifier; } - virtual PNeXusUser2* GetUser() { return &fUser; } - virtual PNeXusSample2* GetSample() { return &fSample; } - virtual PNeXusInstrument2* GetInstrument() { return &fInstrument; } - - virtual void SetDefinition(std::string def) { fDefinition = def; } - virtual void SetProgramName(std::string name) { fProgramName = name; } - virtual void SetProgramVersion(std::string version) { fProgramVersion = version; } - virtual void SetRunNumber(int number) { fRunNumber = number; } - virtual void SetTitle(std::string title) { fTitle = title; } - virtual int SetStartTime(std::string time); - virtual int SetStopTime(std::string time); - virtual void SetExperimentIdentifier(std::string expId) { fExperimentIdentifier = expId; } - virtual void SetUser(PNeXusUser2 &user) { fUser = user; } - virtual void SetSample(PNeXusSample2 &sample) { fSample = sample; } - virtual void SetInstrument(PNeXusInstrument2 &instrument) { fInstrument = instrument; } - - private: - std::string fErrorMsg; ///< internal error message - std::string fDefinition; ///< the template (DTD name) on which the entry was based, e.g. 'pulsedTD' - std::string fProgramName; ///< name of the creating program - std::string fProgramVersion; ///< version of the creating program - int fRunNumber; ///< run number - std::string fTitle; ///< string containing the run title - std::string fStartTime; ///< start date/time of the run - std::string fStopTime; ///< stop date/time of the run - std::string fExperimentIdentifier; ///< experiment number, (for ISIS, the RB number) - PNeXusUser2 fUser; ///< NXuser info IDF Version 2 - PNeXusSample2 fSample; ///< NXsample info IDF Version 2 - PNeXusInstrument2 fInstrument; ///< NXinstrument inf IDF Version 2 -}; - -class PNeXus { - public: - PNeXus(); - PNeXus(const char* fileName); - virtual ~PNeXus(); - - virtual int GetIdfVersion() { return fIdfVersion; } - virtual std::string GetFileName() { return fFileName; } - virtual std::string GetFileTime() { return fFileTime; } - - virtual void SetIdfVersion(unsigned int idf); - virtual void SetFileName(std::string name) { fFileName = name; } - virtual void SetFileTime(std::string time) { fFileTime = time; } - - virtual PNeXusEntry1* GetEntryIdf1() { return fNxEntry1.get(); } - virtual PNeXusEntry2* GetEntryIdf2() { return fNxEntry2.get(); } - - virtual bool IsValid(bool strict=false); - virtual int GetErrorCode() { return fErrorCode; } - virtual std::string GetErrorMsg() { return fErrorMsg; } - - virtual std::vector* GetGroupedHisto(unsigned int idx); - - virtual int ReadFile(const char *fileName); - virtual int WriteFile(const char *fileName, const char *fileType="hdf4", const unsigned int idf=2); - - virtual void SetCreator(std::string str) { fCreator = str; } - - virtual void Dump(const bool counts); - - private: - bool fValid; - int fErrorCode; - std::string fErrorMsg; - - std::string fNeXusVersion; ///< version of the NeXus API used in writing the file - std::string fFileFormatVersion; ///< version of the HDF, HDF5, or XML library used to create the file (IDF 2 only) - - unsigned int fIdfVersion; ///< version of the instrument definition - std::string fFileName; ///< file name of the original NeXus file to assist identification if the external name has been changed - std::string fFileTime; ///< date and time of file creating (IDF 2 only) - NXhandle fFileHandle; - - std::string fCreator; ///< facility of program where the file originated - - std::unique_ptr fNxEntry1; ///< NXentry for IDF 1 - std::unique_ptr fNxEntry2; ///< NXentry for IDF 2 - - std::vector< std::vector > fGroupedHisto; - - virtual void Init(); - virtual bool ErrorHandler(NXstatus status, int errCode, const std::string &errMsg); - virtual NXstatus GetStringData(std::string &str); - virtual NXstatus GetStringAttr(std::string attr, std::string &str); - virtual int GetDataSize(int type); - virtual NXstatus GetDoubleVectorData(std::vector &data); - virtual NXstatus GetIntVectorData(std::vector &data); - - virtual int ReadFileIdf1(); - virtual int ReadFileIdf2(); - - virtual int WriteFileIdf1(const char* fileName, const NXaccess access); - virtual int WriteFileIdf2(const char* fileName, const NXaccess access); - - virtual NXstatus GroupHistoData(); - - virtual bool IsValidIdf1(bool strict); - virtual bool IsValidIdf2(bool strict); - - virtual bool SearchInGroup(std::string str, std::string tag, NXname &nxname, NXname &nxclass, int &dataType); - virtual bool SearchAttrInData(std::string str, int &length, int &dataType); -}; +} // end namespace nxs #endif // _PNEXUS_H_