switched to HDF4/HDF5 template loading in order to simplify the code.

This commit is contained in:
2026-02-04 09:26:49 +01:00
parent a6c9120d06
commit 867ac4895b
2 changed files with 216 additions and 166 deletions

View File

@@ -2248,172 +2248,8 @@ Bool_t PRunDataHandler::ReadNexusFile()
}
if (idf == 1) { // HDF4 IDF V1
// get header information
// get/set laboratory
sstr = "n/a";
if (nxs_file->HasDataset("/run/lab"))
sstr = nxs_file->GetDataset<std::string>("/run/lab").GetData()[0];
runData.SetLaboratory(sstr);
// get/set beamline
sstr = "n/a";
if (nxs_file->HasDataset("/run/beamline"))
sstr = nxs_file->GetDataset<std::string>("/run/beamline").GetData()[0];
runData.SetBeamline(sstr);
// get/set instrument
sstr = "n/a";
if (nxs_file->HasDataset("/run/instrument/name"))
sstr = nxs_file->GetDataset<std::string>("/run/instrument/name").GetData()[0];
runData.SetInstrument(sstr);
// get/set run title
str = "n/a";
if (nxs_file->HasDataset("/run/title"))
sstr = nxs_file->GetDataset<std::string>("/run/title").GetData()[0];
runData.SetRunTitle(sstr);
// get/set run number
ival = -1;
if (nxs_file->HasDataset("/run/number"))
ival = nxs_file->GetDataset<int>("/run/number").GetData()[0];
runData.SetRunNumber(ival);
// get/set temperature
dval = PMUSR_UNDEFINED;
sstr = "n/a";
if (nxs_file->HasDataset("/run/sample/temperature")) {
auto tmp_ds = nxs_file->GetDataset<float>("/run/sample/temperature");
dval = tmp_ds.GetData()[0];
if (tmp_ds.HasAttribute("units"))
sstr = std::any_cast<std::string>(tmp_ds.GetAttribute("units"));
if (sstr == "Celcius")
dval += 273.16;
}
runData.SetTemperature(0, dval, 0.0);
// get/set field
dval = PMUSR_UNDEFINED;
sstr = "n/a";
factor = 1.0;
if (nxs_file->HasDataset("/run/sample/magnetic_field")) {
auto mag_ds = nxs_file->GetDataset<float>("/run/sample/magnetic_field");
dval = mag_ds.GetData()[0];
if (mag_ds.HasAttribute("units"))
sstr = std::any_cast<std::string>(mag_ds.GetAttribute("units"));
if (sstr == "Tesla")
factor = 1.0e4;
}
runData.SetField(dval*factor);
// get/set implantation energy
runData.SetEnergy(PMUSR_UNDEFINED);
// get/set moderator HV
runData.SetTransport(PMUSR_UNDEFINED);
// get/set RA HV's (LEM specific)
for (UInt_t i=0; i<4; i++)
runData.SetRingAnode(i, PMUSR_UNDEFINED);
// get/set setup
sstr = "n/a";
if (nxs_file->HasDataset("/run/notes"))
sstr = nxs_file->GetDataset<std::string>("/run/notes").GetData()[0];
runData.SetSetup(sstr);
// get/set sample
sstr = "n/a";
if (nxs_file->HasDataset("/run/sample/name"))
sstr = nxs_file->GetDataset<std::string>("/run/sample/name").GetData()[0];
runData.SetSample(sstr);
// get/set orientation
runData.SetOrientation("??");
// get/set time resolution (ns)
dval = PMUSR_UNDEFINED;
sstr = "n/a";
factor = 1.0;
if (nxs_file->HasDataset("/run/histogram_data_1/resolution")) {
auto res_ds = nxs_file->GetDataset<int>("/run/histogram_data_1/resolution");
dval = res_ds.GetData()[0];
if (res_ds.HasAttribute("units"))
sstr = std::any_cast<std::string>(res_ds.GetAttribute("units"));
if ((sstr == "picoseconds") || (sstr == "pico.seconds"))
factor = 1.0e-3; // ps -> ns
}
runData.SetTimeResolution(dval*factor);
// get/set start/stop time
sstr = "n/a";
TString date{"n/a"}, time{"n/a"};
if (nxs_file->HasDataset("/run/start_time"))
sstr = nxs_file->GetDataset<std::string>("/run/start_time").GetData()[0];
str = sstr;
SplitTimeDate(str, time, date, ok);
if (ok) {
runData.SetStartTime(time);
runData.SetStartDate(date);
}
sstr = "n/a";
date = "n/a";
time = "n/a";
if (nxs_file->HasDataset("/run/stop_time"))
sstr = nxs_file->GetDataset<std::string>("/run/stop_time").GetData()[0];
str = sstr;
SplitTimeDate(str, time, date, ok);
if (ok) {
runData.SetStopTime(time);
runData.SetStopDate(date);
}
// data with its metadata
int t0_bin{-1}, fgb{-1}, lgb{-1}, noOfHistos{-1}, histoLength{-1};
if (nxs_file->HasDataset("/run/histogram_data_1/counts")) {
auto count_ds = nxs_file->GetDataset<int>("/run/histogram_data_1/counts");
auto count = count_ds.GetData();
// get all necessary attributes
if (count_ds.HasAttribute("t0_bin"))
t0_bin = std::any_cast<int>(count_ds.GetAttribute("t0_bin"));
if (count_ds.HasAttribute("first_good_bin"))
fgb = std::any_cast<int>(count_ds.GetAttribute("first_good_bin"));
if (count_ds.HasAttribute("last_good_bin"))
lgb = std::any_cast<int>(count_ds.GetAttribute("last_good_bin"));
if (count_ds.HasAttribute("number"))
noOfHistos = std::any_cast<int>(count_ds.GetAttribute("number"));
if (count_ds.HasAttribute("length"))
histoLength = std::any_cast<int>(count_ds.GetAttribute("length"));
if (count.size() != noOfHistos*histoLength) {
std::cerr << std::endl << "**ERROR** nxH4::PNeXus data size error! count.size()=" << count.size() << ", #histos=" << noOfHistos << ", length=" << histoLength << "." << std::endl;
return false;
}
// fill dataSet
PDoubleVector data;
for (unsigned int i=0; i<noOfHistos; i++) {
dataSet.Clear();
dataSet.SetHistoNo(i+1); // i.e. histo numbers start with 1
dataSet.SetTimeZeroBin(t0_bin);
dataSet.SetFirstGoodBin(fgb);
dataSet.SetLastGoodBin(lgb);
for (unsigned j=0; j<histoLength; j++)
data.push_back(count[i*histoLength+j]);
dataSet.SetData(data);
runData.SetDataSet(dataSet);
data.clear();
}
// keep run name from the msr-file
runData.SetRunName(fRunName);
// keep the information
fData.push_back(runData);
} else { // no data found
std::cerr << std::endl << "**ERROR** nxH4::PNeXus couldn't obtain data: '/run/histogram_data_1/counts' is missing." << std::endl;
if (!ReadNexusFileIdf1(nxs_file))
return false;
}
} else { // HDF4 IDF V2
// not yet implemented
}
@@ -2442,7 +2278,8 @@ Bool_t PRunDataHandler::ReadNexusFile()
}
if (idf == 1) { // HDF5 IDF V1
// not yet implemented
if (!ReadNexusFileIdf1(nxs_file))
return false;
} else { // HDF5 IDF V2
// not yet implemented
}

View File

@@ -30,6 +30,10 @@
#ifndef _PRUNDATAHANDLER_H_
#define _PRUNDATAHANDLER_H_
#include <any>
#include <iostream>
#include <string>
#include <TString.h>
#include "PMusr.h"
@@ -433,6 +437,8 @@ class PRunDataHandler
virtual Bool_t FileExistsCheck(const TString fileName);
virtual Bool_t ReadRootFile();
virtual Bool_t ReadNexusFile();
template <typename T> Bool_t ReadNexusFileIdf1(T& nxs_file);
template <typename T> Bool_t ReadNexusFileIdf2(T& nxs_file);
virtual Bool_t ReadWkmFile();
virtual Bool_t ReadPsiBinFile();
virtual Bool_t ReadMudFile();
@@ -464,4 +470,211 @@ class PRunDataHandler
virtual TString GetYear(Int_t month);
};
//--------------------------------------------------------------------------
// ReadNexusFileIdf1 (private)
//--------------------------------------------------------------------------
/**
* <p>Reads a NeXus file with IDF version 1 format.
*
* <p>Extracts run metadata (laboratory, beamline, instrument, run title,
* run number, temperature, field, sample info, time resolution, start/stop
* times) and histogram data from the NeXus file structure.
*
* @tparam T NeXus file handler type (std::unique_ptr<nxH4::PNeXus> and std::unique_ptr<nxH5::PNeXus>)
* @param nxs_file reference to the NeXus file handler
*
* <b>return:</b>
* - true at successful reading,
* - otherwise false.
*/
template <typename T>
Bool_t PRunDataHandler::ReadNexusFileIdf1(T& nxs_file)
{
PRawRunData runData;
PRawRunDataSet dataSet;
TString str;
std::string sstr;
Int_t ival;
Double_t dval, factor;
bool ok;
// get header information
// get/set laboratory
sstr = "n/a";
if (nxs_file->HasDataset("/run/lab"))
sstr = nxs_file->template GetDataset<std::string>("/run/lab").GetData()[0];
runData.SetLaboratory(sstr);
// get/set beamline
sstr = "n/a";
if (nxs_file->HasDataset("/run/beamline"))
sstr = nxs_file->template GetDataset<std::string>("/run/beamline").GetData()[0];
runData.SetBeamline(sstr);
// get/set instrument
sstr = "n/a";
if (nxs_file->HasDataset("/run/instrument/name"))
sstr = nxs_file->template GetDataset<std::string>("/run/instrument/name").GetData()[0];
runData.SetInstrument(sstr);
// get/set run title
str = "n/a";
if (nxs_file->HasDataset("/run/title"))
sstr = nxs_file->template GetDataset<std::string>("/run/title").GetData()[0];
runData.SetRunTitle(sstr);
// get/set run number
ival = -1;
if (nxs_file->HasDataset("/run/number"))
ival = nxs_file->template GetDataset<int>("/run/number").GetData()[0];
runData.SetRunNumber(ival);
// get/set temperature
dval = PMUSR_UNDEFINED;
sstr = "n/a";
if (nxs_file->HasDataset("/run/sample/temperature")) {
auto tmp_ds = nxs_file->template GetDataset<float>("/run/sample/temperature");
dval = tmp_ds.GetData()[0];
if (tmp_ds.HasAttribute("units"))
sstr = std::any_cast<std::string>(tmp_ds.GetAttribute("units"));
if (sstr == "Celcius")
dval += 273.16;
}
runData.SetTemperature(0, dval, 0.0);
// get/set field
dval = PMUSR_UNDEFINED;
sstr = "n/a";
factor = 1.0;
if (nxs_file->HasDataset("/run/sample/magnetic_field")) {
auto mag_ds = nxs_file->template GetDataset<float>("/run/sample/magnetic_field");
dval = mag_ds.GetData()[0];
if (mag_ds.HasAttribute("units"))
sstr = std::any_cast<std::string>(mag_ds.GetAttribute("units"));
if (sstr == "Tesla")
factor = 1.0e4;
}
runData.SetField(dval*factor);
// get/set implantation energy
runData.SetEnergy(PMUSR_UNDEFINED);
// get/set moderator HV
runData.SetTransport(PMUSR_UNDEFINED);
// get/set RA HV's (LEM specific)
for (UInt_t i=0; i<4; i++)
runData.SetRingAnode(i, PMUSR_UNDEFINED);
// get/set setup
sstr = "n/a";
if (nxs_file->HasDataset("/run/notes"))
sstr = nxs_file->template GetDataset<std::string>("/run/notes").GetData()[0];
runData.SetSetup(sstr);
// get/set sample
sstr = "n/a";
if (nxs_file->HasDataset("/run/sample/name"))
sstr = nxs_file->template GetDataset<std::string>("/run/sample/name").GetData()[0];
runData.SetSample(sstr);
// get/set orientation
runData.SetOrientation("??");
// get/set time resolution (ns)
dval = PMUSR_UNDEFINED;
sstr = "n/a";
factor = 1.0;
if (nxs_file->HasDataset("/run/histogram_data_1/resolution")) {
auto res_ds = nxs_file->template GetDataset<int>("/run/histogram_data_1/resolution");
dval = res_ds.GetData()[0];
if (res_ds.HasAttribute("units"))
sstr = std::any_cast<std::string>(res_ds.GetAttribute("units"));
if ((sstr == "picoseconds") || (sstr == "pico.seconds"))
factor = 1.0e-3; // ps -> ns
}
runData.SetTimeResolution(dval*factor);
// get/set start/stop time
sstr = "n/a";
TString date{"n/a"}, time{"n/a"};
if (nxs_file->HasDataset("/run/start_time"))
sstr = nxs_file->template GetDataset<std::string>("/run/start_time").GetData()[0];
str = sstr;
SplitTimeDate(str, time, date, ok);
if (ok) {
runData.SetStartTime(time);
runData.SetStartDate(date);
}
sstr = "n/a";
date = "n/a";
time = "n/a";
if (nxs_file->HasDataset("/run/stop_time"))
sstr = nxs_file->template GetDataset<std::string>("/run/stop_time").GetData()[0];
str = sstr;
SplitTimeDate(str, time, date, ok);
if (ok) {
runData.SetStopTime(time);
runData.SetStopDate(date);
}
// data with its metadata
int t0_bin{-1}, fgb{-1}, lgb{-1}, noOfHistos{-1}, histoLength{-1};
if (nxs_file->HasDataset("/run/histogram_data_1/counts")) {
auto count_ds = nxs_file->template GetDataset<int>("/run/histogram_data_1/counts");
auto count = count_ds.GetData();
// get all necessary attributes
if (count_ds.HasAttribute("t0_bin"))
t0_bin = std::any_cast<int>(count_ds.GetAttribute("t0_bin"));
if (count_ds.HasAttribute("first_good_bin"))
fgb = std::any_cast<int>(count_ds.GetAttribute("first_good_bin"));
if (count_ds.HasAttribute("last_good_bin"))
lgb = std::any_cast<int>(count_ds.GetAttribute("last_good_bin"));
if (count_ds.HasAttribute("number"))
noOfHistos = std::any_cast<int>(count_ds.GetAttribute("number"));
if (count_ds.HasAttribute("length"))
histoLength = std::any_cast<int>(count_ds.GetAttribute("length"));
if (static_cast<int>(count.size()) != noOfHistos*histoLength) {
std::cerr << std::endl << "**ERROR** PNeXus data size error! count.size()=" << count.size() << ", #histos=" << noOfHistos << ", length=" << histoLength << "." << std::endl;
return false;
}
// fill dataSet
PDoubleVector data;
for (int i=0; i<noOfHistos; i++) {
dataSet.Clear();
dataSet.SetHistoNo(i+1); // i.e. histo numbers start with 1
dataSet.SetTimeZeroBin(t0_bin);
dataSet.SetFirstGoodBin(fgb);
dataSet.SetLastGoodBin(lgb);
for (int j=0; j<histoLength; j++)
data.push_back(count[i*histoLength+j]);
dataSet.SetData(data);
runData.SetDataSet(dataSet);
data.clear();
}
// keep run name from the msr-file
runData.SetRunName(fRunName);
// keep the information
fData.push_back(runData);
} else { // no data found
std::cerr << std::endl << "**ERROR** PNeXus couldn't obtain data: '/run/histogram_data_1/counts' is missing." << std::endl;
return false;
}
return true;
}
//--------------------------------------------------------------------------
// ReadNexusFileIdf2 (private)
//--------------------------------------------------------------------------
template <typename T>
Bool_t PRunDataHandler::ReadNexusFileIdf2(T& nxs_file)
{
return true;
}
#endif // _PRUNDATAHANDLER_H_