more work on the NeXus write routines.

This commit is contained in:
2026-02-07 11:31:11 +01:00
parent fc478d27c7
commit 3bb004ea2d
2 changed files with 83 additions and 59 deletions

View File

@@ -4807,7 +4807,7 @@ Bool_t PRunDataHandler::WriteRootFile(TString fln)
Bool_t PRunDataHandler::WriteNexusFile(TString format, TString fln) Bool_t PRunDataHandler::WriteNexusFile(TString format, TString fln)
{ {
#ifdef PNEXUS_ENABLED #ifdef PNEXUS_ENABLED
std::string str{""};
Bool_t ok = false; Bool_t ok = false;
fln = GenerateOutputFileName(fln, ".nxs", ok); fln = GenerateOutputFileName(fln, ".nxs", ok);
if (!ok) if (!ok)
@@ -4837,8 +4837,89 @@ Bool_t PRunDataHandler::WriteNexusFile(TString format, TString fln)
nxs->AddGroupAttribute("/", "HDF_version", nxs->GetHdf5LibVersion()); nxs->AddGroupAttribute("/", "HDF_version", nxs->GetHdf5LibVersion());
// set file name // set file name
nxs->AddGroupAttribute("/", "file_name", std::string(fln.Data())); nxs->AddGroupAttribute("/", "file_name", std::string(fln.Data()));
// set creation time
std::string dt = nxs::getIso8601TimestampLocal();
nxs->AddGroupAttribute("/", "file_time", dt);
// set IDF version // set IDF version
nxs->AddDataset<int>("/run/IDF_version", {(int)fAny2ManyInfo->idf}, {1}, H5::PredType::NATIVE_INT32); nxs->AddDataset<int>("/run/IDF_version", {(int)fAny2ManyInfo->idf}, {1}, H5::PredType::NATIVE_INT32);
// set program name
nxs->AddDataset<std::string>("/run/program_name", {"any2many"}, {1}, H5::StrType(H5::PredType::C_S1, H5T_VARIABLE));
str="n/a";
#ifdef HAVE_CONFIG_H
str = PACKAGE_VERSION;
#endif
nxs->AddDatasetAttribute<std::string>("/run/program_name", "version", str);
// set run number
nxs->AddDataset<int>("/run/number", {fData[0].GetRunNumber()}, {1}, H5::PredType::NATIVE_INT32);
// set title
nxs->AddDataset<std::string>("/run/title", {fData[0].GetRunTitle()->Data()}, {1}, H5::StrType(H5::PredType::C_S1, H5T_VARIABLE));
// set notes
nxs->AddDataset<std::string>("/run/notes", {std::string("n/a")}, {1}, H5::StrType(H5::PredType::C_S1, H5T_VARIABLE));
// set analysis
nxs->AddDataset<std::string>("/run/notes", {std::string("muonTD")}, {1}, H5::StrType(H5::PredType::C_S1, H5T_VARIABLE));
// set lab
str = *fData[0].GetLaboratory();
nxs->AddDataset<std::string>("/run/lab", {str}, {1}, H5::StrType(H5::PredType::C_S1, H5T_VARIABLE));
// set beamline
str = *fData[0].GetBeamline();
nxs->AddDataset<std::string>("/run/beamline", {str}, {1}, H5::StrType(H5::PredType::C_S1, H5T_VARIABLE));
// set start time
str = std::string(fData[0].GetStartDate()->Data()) + std::string("T") + std::string(fData[0].GetStartTime()->Data());
nxs->AddDataset<std::string>("/run/start_time", {str}, {1}, H5::StrType(H5::PredType::C_S1, H5T_VARIABLE));
// set stop time
str = std::string(fData[0].GetStopDate()->Data()) + std::string("T") + std::string(fData[0].GetStopTime()->Data());
nxs->AddDataset<std::string>("/run/stop_time", {str}, {1}, H5::StrType(H5::PredType::C_S1, H5T_VARIABLE));
// set switching state
nxs->AddDataset<int>("/run/switching_states", {1}, {1}, H5::PredType::NATIVE_INT32);
// set user name
nxs->AddDataset<std::string>("/run/user/name", {std::string("n/a")}, {1}, H5::StrType(H5::PredType::C_S1, H5T_VARIABLE));
// set user experiment_number
nxs->AddDataset<std::string>("/run/user/experiment_number", {std::string("n/a")}, {1}, H5::StrType(H5::PredType::C_S1, H5T_VARIABLE));
// set sample name
nxs->AddDataset<std::string>("/run/sample/name", {fData[0].GetSample()->Data()}, {1}, H5::StrType(H5::PredType::C_S1, H5T_VARIABLE));
// set sample temperature
nxs->AddDataset<float>("/run/sample/temperature", {(float)fData[0].GetTemperature(0)}, {1}, H5::PredType::NATIVE_FLOAT);
nxs->AddDatasetAttribute<float>("/run/sample/temperature", "units", std::string("Kelvin"));
// set magnetic field
nxs->AddDataset<float>("/run/sample/magnetic_field", {(float)fData[0].GetField()}, {1}, H5::PredType::NATIVE_FLOAT);
nxs->AddDatasetAttribute<float>("/run/sample/magnetic_field", "units", std::string("Gauss"));
// set sample environment
nxs->AddDataset<std::string>("/run/sample/environment", {fData[0].GetSetup()->Data()}, {1}, H5::StrType(H5::PredType::C_S1, H5T_VARIABLE));
// set sample shape
nxs->AddDataset<std::string>("/run/sample/shape", {std::string("n/a")}, {1}, H5::StrType(H5::PredType::C_S1, H5T_VARIABLE));
// set magnetic field vector
nxs->AddDataset<float>("/run/sample/magnetic_field_vector", {1.0, 1.0, 1.0}, {3}, H5::PredType::NATIVE_FLOAT);
nxs->AddDatasetAttribute<float>("/run/sample/magnetic_field_vector", "coordinate_system", std::string("cartesian"));
nxs->AddDatasetAttribute<float>("/run/sample/magnetic_field_vector", "units", std::string("Gauss"));
nxs->AddDatasetAttribute<float>("/run/sample/magnetic_field_vector", "available", 0);
// set instrument name
str = *fData[0].GetInstrument();
nxs->AddDataset<std::string>("/run/instrument/name", {str}, {1}, H5::StrType(H5::PredType::C_S1, H5T_VARIABLE));
// set instrument number of detectors
nxs->AddDataset<int>("/run/instrument/detector/number", {(int)fData[0].GetNoOfHistos()}, {1}, H5::PredType::NATIVE_INT32);
// set instrument collimator
nxs->AddDataset<std::string>("/run/instrument/collimator/type", {std::string("n/a")}, {1}, H5::StrType(H5::PredType::C_S1, H5T_VARIABLE));
// set instrument beam total number of counts in Mev
// calculate the total number of counts
double total_counts = 0;
PRawRunDataSet *dataSet = nullptr;
for (unsigned int i=0; i<fData[0].GetNoOfHistos(); i++) {
dataSet = fData[0].GetDataSet(i, false); // i.e. the false means, that i is the index and NOT the histo number
if (dataSet == nullptr) { // something is really wrong
std::cerr << std::endl << ">> PRunDataHandler::WriteNexusFile: **ERROR** Couldn't get data set (idx=0" << i << ")";
std::cerr << std::endl << ">> something is really wrong!" << std::endl;
return false;
}
for (unsigned int j=0; j<dataSet->GetData()->size(); j++)
total_counts += dataSet->GetData()->at(j);
}
float total_counts_mev = (float) total_counts / 1.0e6;
nxs->AddDataset<float>("/run/instrument/beam/total_counts", {total_counts_mev}, {1}, H5::PredType::NATIVE_FLOAT);
nxs->AddDatasetAttribute<float>("/run/instrument/beam/total_counts", "units", std::string("MEv"));
// set time resolution (use FLOAT instead of INT)
float res = (float)(fData[0].GetTimeResolution()*fAny2ManyInfo->rebin*1.0e3);
nxs->AddDataset<float>("/run/histogram_data_1/resolution", {res}, {1}, H5::PredType::NATIVE_FLOAT);
nxs->AddDatasetAttribute<float>("/run/histogram_data_1/resolution", "units", std::string("picoseconds"));
} else { // IDF V2 } else { // IDF V2
// set IDF version // set IDF version
nxs->AddDataset<int>("/raw_data_1/IDF_version", {(int)fAny2ManyInfo->idf}, {1}, H5::PredType::NATIVE_INT32); nxs->AddDataset<int>("/raw_data_1/IDF_version", {(int)fAny2ManyInfo->idf}, {1}, H5::PredType::NATIVE_INT32);
@@ -4860,63 +4941,6 @@ Bool_t PRunDataHandler::WriteNexusFile(TString format, TString fln)
if (fAny2ManyInfo->idf == 1) { if (fAny2ManyInfo->idf == 1) {
// fill necessary data structures // fill necessary data structures
// set file creating time
time_t now;
struct tm *tm;
time(&now);
tm = localtime(&now);
std::string str("");
char cstr[128];
strftime(cstr, sizeof(cstr), "%FT%T", tm);
str = std::string(cstr);
nxs->SetFileTime(str);
nxs->GetEntryIdf1()->SetProgramName("any2many");
nxs->GetEntryIdf1()->SetProgramVersion("$Id$");
nxs->GetEntryIdf1()->SetRunNumber(fData[0].GetRunNumber());
nxs->GetEntryIdf1()->SetTitle(fData[0].GetRunTitle()->Data());
nxs->GetEntryIdf1()->SetNotes("n/a");
nxs->GetEntryIdf1()->SetAnalysis("muonTD");
if (*fData[0].GetLaboratory() != "n/a")
nxs->GetEntryIdf1()->SetLaboratory(fData[0].GetLaboratory()->Data());
if (*fData[0].GetBeamline() != "n/a")
nxs->GetEntryIdf1()->SetBeamline(fData[0].GetBeamline()->Data());
str = std::string(fData[0].GetStartDate()->Data()) + std::string("T") + std::string(fData[0].GetStartTime()->Data());
nxs->GetEntryIdf1()->SetStartTime(str);
str = std::string(fData[0].GetStopDate()->Data()) + std::string("T") + std::string(fData[0].GetStopTime()->Data());
nxs->GetEntryIdf1()->SetStopTime(str);
nxs->GetEntryIdf1()->SetSwitchingState(1);
nxs->GetEntryIdf1()->GetUser()->SetName("n/a");
nxs->GetEntryIdf1()->GetUser()->SetExperimentNumber("n/a");
nxs->GetEntryIdf1()->GetSample()->SetName(fData[0].GetSample()->Data());
nxs->GetEntryIdf1()->GetSample()->SetPhysProp("temperature", fData[0].GetTemperature(0), "Kelvin");
nxs->GetEntryIdf1()->GetSample()->SetPhysProp("magnetic_field", fData[0].GetField(), "Gauss");
nxs->GetEntryIdf1()->GetSample()->SetEnvironment(fData[0].GetSetup()->Data());
nxs->GetEntryIdf1()->GetSample()->SetShape("n/a");
nxs->GetEntryIdf1()->GetSample()->SetMagneticFieldVectorAvailable(0);
if (*fData[0].GetInstrument() != "n/a")
nxs->GetEntryIdf1()->GetInstrument()->SetName(fData[0].GetInstrument()->Data());
nxs->GetEntryIdf1()->GetInstrument()->GetDetector()->SetNumber(fData[0].GetNoOfHistos());
nxs->GetEntryIdf1()->GetInstrument()->GetCollimator()->SetType("n/a");
// calculate the total number of counts
double total_counts = 0;
PRawRunDataSet *dataSet = nullptr;
for (unsigned int i=0; i<fData[0].GetNoOfHistos(); i++) {
dataSet = fData[0].GetDataSet(i, false); // i.e. the false means, that i is the index and NOT the histo number
if (dataSet == nullptr) { // something is really wrong
std::cerr << std::endl << ">> PRunDataHandler::WriteNexusFile: **ERROR** Couldn't get data set (idx=0" << i << ")";
std::cerr << std::endl << ">> something is really wrong!" << std::endl;
return false;
}
for (unsigned int j=0; j<dataSet->GetData()->size(); j++)
total_counts += dataSet->GetData()->at(j);
}
double total_counts_mev = (double) total_counts / 1.0e6;
nxs->GetEntryIdf1()->GetInstrument()->GetBeam()->SetTotalCounts(total_counts_mev);
nxs->GetEntryIdf1()->GetInstrument()->GetBeam()->SetUnits("Mev");
nxs->GetEntryIdf1()->GetData()->SetTimeResolution(fData[0].GetTimeResolution()*fAny2ManyInfo->rebin, "ns");
for (unsigned int i=0; i<fData[0].GetNoOfHistos(); i++) { for (unsigned int i=0; i<fData[0].GetNoOfHistos(); i++) {
dataSet = fData[0].GetDataSet(i, false); // i.e. the false means, that i is the index and NOT the histo number dataSet = fData[0].GetDataSet(i, false); // i.e. the false means, that i is the index and NOT the histo number
nxs->GetEntryIdf1()->GetData()->SetT0(static_cast<Int_t>(dataSet->GetTimeZeroBin()/fAny2ManyInfo->rebin), i); nxs->GetEntryIdf1()->GetData()->SetT0(static_cast<Int_t>(dataSet->GetTimeZeroBin()/fAny2ManyInfo->rebin), i);

View File

@@ -436,9 +436,9 @@ class PRunDataHandler
virtual Bool_t FileExistsCheck(const Bool_t fileName, const Int_t idx); virtual Bool_t FileExistsCheck(const Bool_t fileName, const Int_t idx);
virtual Bool_t FileExistsCheck(const TString fileName); virtual Bool_t FileExistsCheck(const TString fileName);
virtual Bool_t ReadRootFile(); virtual Bool_t ReadRootFile();
virtual Bool_t ReadNexusFile();
template <typename T> Bool_t ReadNexusFileIdf1(T& nxs_file); template <typename T> Bool_t ReadNexusFileIdf1(T& nxs_file);
template <typename T> Bool_t ReadNexusFileIdf2(T& nxs_file); template <typename T> Bool_t ReadNexusFileIdf2(T& nxs_file);
virtual Bool_t ReadNexusFile();
virtual Bool_t ReadWkmFile(); virtual Bool_t ReadWkmFile();
virtual Bool_t ReadPsiBinFile(); virtual Bool_t ReadPsiBinFile();
virtual Bool_t ReadMudFile(); virtual Bool_t ReadMudFile();