add Red/Green mode handling for NeXus HDF5 IDF V2. See also the musrfit docu.

This commit is contained in:
2026-07-15 10:34:59 +02:00
parent dae2c8ada8
commit e2a42eadd5
3 changed files with 146 additions and 87 deletions
+1 -1
View File
@@ -6,7 +6,7 @@ if (CMAKE_VERSION GREATER_EQUAL "3.3")
cmake_policy(SET CMP0167 NEW)
endif ()
project(musrfit VERSION 1.11.2 LANGUAGES C CXX)
project(musrfit VERSION 1.11.3 LANGUAGES C CXX)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
+6
View File
@@ -12,6 +12,12 @@ or
https://bitbucket.org/muonspin/musrfit
Release of V1.11.3, 2026/07/15
==============================
Add Red/Green mode handling for NeXus, especially HDF5 IDF V2. Offset between the
routed histograms is 10000 (for LEM it is 20).
Release of V1.11.2, 2026/06/27
==============================
+139 -86
View File
@@ -871,95 +871,148 @@ Bool_t PRunDataHandler::ReadNexusFileIdf2(T& nxs_file)
ival = nxs_file->template GetDataset<int>("/raw_data_1/run_number").GetData()[0];
runData.SetRunNumber(ival);
// get/set temperature
dval = PMUSR_UNDEFINED;
sstr = "n/a";
if (nxs_file->HasDataset("/raw_data_1/sample/temperature")) {
auto tmp_ds = nxs_file->template GetDataset<float>("/raw_data_1/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;
// get/set temperature
dval = PMUSR_UNDEFINED;
sstr = "n/a";
if (nxs_file->HasDataset("/raw_data_1/sample/temperature")) {
auto tmp_ds = nxs_file->template GetDataset<float>("/raw_data_1/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("/raw_data_1/sample/magnetic_field")) {
auto mag_ds = nxs_file->template GetDataset<float>("/raw_data_1/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 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";
runData.SetSetup(str);
// get/set sample
sstr = "n/a";
if (nxs_file->HasDataset("/raw_data_1/sample/name"))
sstr = nxs_file->template GetDataset<std::string>("/raw_data_1/sample/name").GetData()[0];
runData.SetSample(sstr);
// get/set orientation
runData.SetOrientation("n/a");
// get/set time resolution (ns)
dval = PMUSR_UNDEFINED;
sstr = "n/a";
factor = 1.0;
if (nxs_file->HasDataset("/raw_data_1/instrument/detector_1/resolution")) {
auto res_ds = nxs_file->template GetDataset<int>("/raw_data_1/instrument/detector_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("/raw_data_1/start_time"))
sstr = nxs_file->template GetDataset<std::string>("/raw_data_1/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("/raw_data_1/end_time"))
sstr = nxs_file->template GetDataset<std::string>("/raw_data_1/end_time").GetData()[0];
str = sstr;
SplitTimeDate(str, time, date, ok);
if (ok) {
runData.SetStopTime(time);
runData.SetStopDate(date);
}
// get/set deadtime relevant parameters
if (nxs_file->HasDataset("/raw_data_1/instrument/detector_1/dead_time")) {
std::vector<float> dt;
dt = nxs_file->template GetDataset<float>("/raw_data_1/instrument/detector_1/dead_time").GetData();
runData.SetDeadTimeParam(dt);
}
if (nxs_file->HasDataset("/raw_data_1/good_frames")) {
ival = nxs_file->template GetDataset<int>("/raw_data_1/good_frames").GetData()[0];
runData.SetNumberOfGoodFrames(ival);
}
// data with its metadata
if (nxs_file->HasDataset("/raw_data_1/instrument/detector_1/counts")) {
int t0_bin{-1}, fgb{-1}, lgb{-1}, noOfPeriods{-1}, noOfHistos{-1}, histoLength{-1};
auto count_ds = nxs_file->template GetDataset<int>("/raw_data_1/instrument/detector_1/counts");
auto count = count_ds.GetData();
auto dims = count_ds.GetDimensions();
if (dims.size() < 3) {
std::cerr << std::endl << "**ERROR** PNeXus data dimension error! dims.size()=" << dims.size() << ", expecting == 3." << std::endl;
return false;
}
runData.SetTemperature(0, dval, 0.0);
// get/set field
dval = PMUSR_UNDEFINED;
sstr = "n/a";
factor = 1.0;
if (nxs_file->HasDataset("/raw_data_1/sample/magnetic_field")) {
auto mag_ds = nxs_file->template GetDataset<float>("/raw_data_1/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 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";
runData.SetSetup(str);
// get/set sample
sstr = "n/a";
if (nxs_file->HasDataset("/raw_data_1/sample/name"))
sstr = nxs_file->template GetDataset<std::string>("/raw_data_1/sample/name").GetData()[0];
runData.SetSample(sstr);
// get/set orientation
runData.SetOrientation("n/a");
// get/set time resolution (ns)
dval = PMUSR_UNDEFINED;
sstr = "n/a";
factor = 1.0;
if (nxs_file->HasDataset("/raw_data_1/instrument/detector_1/resolution")) {
auto res_ds = nxs_file->template GetDataset<int>("/raw_data_1/instrument/detector_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("/raw_data_1/start_time"))
sstr = nxs_file->template GetDataset<std::string>("/raw_data_1/start_time").GetData()[0];
str = sstr;
SplitTimeDate(str, time, date, ok);
if (ok) {
runData.SetStartTime(time);
runData.SetStartDate(date);
noOfPeriods = dims[0];
noOfHistos = dims[1];
histoLength = dims[2];
// 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 (static_cast<int>(count.size()) != noOfPeriods*noOfHistos*histoLength) {
std::cerr << std::endl << "**ERROR** PNeXus data size error! count.size()=" << count.size() << ", #periods=" << noOfPeriods << ", #histos=" << noOfHistos << ", length=" << histoLength << "." << std::endl;
return false;
}
sstr = "n/a";
date = "n/a";
time = "n/a";
if (nxs_file->HasDataset("/raw_data_1/end_time"))
sstr = nxs_file->template GetDataset<std::string>("/raw_data_1/end_time").GetData()[0];
str = sstr;
SplitTimeDate(str, time, date, ok);
if (ok) {
runData.SetStopTime(time);
runData.SetStopDate(date);
// fill dataSet
PDoubleVector data;
for (int i=0; i<noOfPeriods; i++) {
for (int j=0; j<noOfHistos; j++) {
dataSet.Clear();
dataSet.SetHistoNo(i*10000+j+1); // i.e. histo numbers start with 1
dataSet.SetTimeZeroBin(t0_bin);
dataSet.SetFirstGoodBin(fgb);
dataSet.SetLastGoodBin(lgb);
for (int k=0; k<histoLength; k++)
data.push_back(count[i*noOfHistos*histoLength+j*histoLength+k]);
dataSet.SetData(data);
runData.SetDataSet(dataSet);
data.clear();
}
}
// get/set deadtime relevant parameters