From df379b834eade04b76d48f269b4e4b9c2e0d9a5e Mon Sep 17 00:00:00 2001 From: Andreas Suter Date: Sat, 7 Feb 2026 17:25:52 +0100 Subject: [PATCH] first full version for HDF5 IDF V1 write. --- src/classes/PRunDataHandler.cpp | 168 ++++++++++++++++++++++---------- 1 file changed, 116 insertions(+), 52 deletions(-) diff --git a/src/classes/PRunDataHandler.cpp b/src/classes/PRunDataHandler.cpp index c5cccdf6..b7bb01ed 100644 --- a/src/classes/PRunDataHandler.cpp +++ b/src/classes/PRunDataHandler.cpp @@ -4833,15 +4833,20 @@ Bool_t PRunDataHandler::WriteNexusFile(TString format, TString fln) if (fAny2ManyInfo->idf == 1) { // IDF V1 // set NeXus version nxs->AddGroupAttribute("/", "NeXus_version", std::string("4.3.0")); + // set HDF5 version nxs->AddGroupAttribute("/", "HDF_version", nxs->GetHdf5LibVersion()); + // set file name nxs->AddGroupAttribute("/", "file_name", std::string(fln.Data())); + // set creation time std::string dt = nxs::getIso8601TimestampLocal(); nxs->AddGroupAttribute("/", "file_time", dt); + // set IDF version nxs->AddDataset("/run/IDF_version", {(int)fAny2ManyInfo->idf}, {1}, H5::PredType::NATIVE_INT32); + // set program name nxs->AddDataset("/run/program_name", {"any2many"}, {1}, H5::StrType(H5::PredType::C_S1, H5T_VARIABLE)); str="n/a"; @@ -4849,56 +4854,77 @@ Bool_t PRunDataHandler::WriteNexusFile(TString format, TString fln) str = PACKAGE_VERSION; #endif nxs->AddDatasetAttribute("/run/program_name", "version", str); + // set run number nxs->AddDataset("/run/number", {fData[0].GetRunNumber()}, {1}, H5::PredType::NATIVE_INT32); + // set title nxs->AddDataset("/run/title", {fData[0].GetRunTitle()->Data()}, {1}, H5::StrType(H5::PredType::C_S1, H5T_VARIABLE)); + // set notes nxs->AddDataset("/run/notes", {std::string("n/a")}, {1}, H5::StrType(H5::PredType::C_S1, H5T_VARIABLE)); + // set analysis nxs->AddDataset("/run/notes", {std::string("muonTD")}, {1}, H5::StrType(H5::PredType::C_S1, H5T_VARIABLE)); + // set lab str = *fData[0].GetLaboratory(); nxs->AddDataset("/run/lab", {str}, {1}, H5::StrType(H5::PredType::C_S1, H5T_VARIABLE)); + // set beamline str = *fData[0].GetBeamline(); nxs->AddDataset("/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("/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("/run/stop_time", {str}, {1}, H5::StrType(H5::PredType::C_S1, H5T_VARIABLE)); + // set switching state nxs->AddDataset("/run/switching_states", {1}, {1}, H5::PredType::NATIVE_INT32); + // set user name nxs->AddDataset("/run/user/name", {std::string("n/a")}, {1}, H5::StrType(H5::PredType::C_S1, H5T_VARIABLE)); + // set user experiment_number nxs->AddDataset("/run/user/experiment_number", {std::string("n/a")}, {1}, H5::StrType(H5::PredType::C_S1, H5T_VARIABLE)); + // set sample name nxs->AddDataset("/run/sample/name", {fData[0].GetSample()->Data()}, {1}, H5::StrType(H5::PredType::C_S1, H5T_VARIABLE)); + // set sample temperature nxs->AddDataset("/run/sample/temperature", {(float)fData[0].GetTemperature(0)}, {1}, H5::PredType::NATIVE_FLOAT); nxs->AddDatasetAttribute("/run/sample/temperature", "units", std::string("Kelvin")); + // set magnetic field nxs->AddDataset("/run/sample/magnetic_field", {(float)fData[0].GetField()}, {1}, H5::PredType::NATIVE_FLOAT); nxs->AddDatasetAttribute("/run/sample/magnetic_field", "units", std::string("Gauss")); + // set sample environment nxs->AddDataset("/run/sample/environment", {fData[0].GetSetup()->Data()}, {1}, H5::StrType(H5::PredType::C_S1, H5T_VARIABLE)); + // set sample shape nxs->AddDataset("/run/sample/shape", {std::string("n/a")}, {1}, H5::StrType(H5::PredType::C_S1, H5T_VARIABLE)); + // set magnetic field vector nxs->AddDataset("/run/sample/magnetic_field_vector", {1.0, 1.0, 1.0}, {3}, H5::PredType::NATIVE_FLOAT); nxs->AddDatasetAttribute("/run/sample/magnetic_field_vector", "coordinate_system", std::string("cartesian")); nxs->AddDatasetAttribute("/run/sample/magnetic_field_vector", "units", std::string("Gauss")); nxs->AddDatasetAttribute("/run/sample/magnetic_field_vector", "available", 0); + // set instrument name str = *fData[0].GetInstrument(); nxs->AddDataset("/run/instrument/name", {str}, {1}, H5::StrType(H5::PredType::C_S1, H5T_VARIABLE)); + // set instrument number of detectors nxs->AddDataset("/run/instrument/detector/number", {(int)fData[0].GetNoOfHistos()}, {1}, H5::PredType::NATIVE_INT32); + // set instrument collimator nxs->AddDataset("/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; @@ -4916,10 +4942,100 @@ Bool_t PRunDataHandler::WriteNexusFile(TString format, TString fln) float total_counts_mev = (float) total_counts / 1.0e6; nxs->AddDataset("/run/instrument/beam/total_counts", {total_counts_mev}, {1}, H5::PredType::NATIVE_FLOAT); nxs->AddDatasetAttribute("/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("/run/histogram_data_1/resolution", {res}, {1}, H5::PredType::NATIVE_FLOAT); nxs->AddDatasetAttribute("/run/histogram_data_1/resolution", "units", std::string("picoseconds")); + + // set time zero time to 0. see t0_bin attribute of counts! + nxs->AddDataset("/run/histogram_data_1/time_zero", {0}, {1}, H5::PredType::NATIVE_INT32); + nxs->AddDatasetAttribute("/run/histogram_data_1/time_zero", "units", std::string("microseconds")); + nxs->AddDatasetAttribute("/run/histogram_data_1/time_zero", "available", 0); + + // set raw_time + res = (float)(fData[0].GetTimeResolution()*fAny2ManyInfo->rebin*1.0e-3); + dataSet = fData[0].GetDataSet(0, false); // i.e. the false means, that i is the index and NOT the histo number + unsigned int length = (int)(dataSet->GetData()->size() / fAny2ManyInfo->rebin); + std::vector time; + for (unsigned int i=0; iAddDataset("/run/histogram_data_1/raw_time", time, {length}, H5::PredType::NATIVE_FLOAT); + nxs->AddDatasetAttribute("/run/histogram_data_1/raw_time", "axis", 1); + nxs->AddDatasetAttribute("/run/histogram_data_1/raw_time", "primary", 0); + nxs->AddDatasetAttribute("/run/histogram_data_1/raw_time", "units", std::string("microseconds")); + nxs->AddDatasetAttribute("/run/histogram_data_1/raw_time", "available", 0); + + // set corrected_time + nxs->AddDataset("/run/histogram_data_1/corrected_time", time, {length}, H5::PredType::NATIVE_FLOAT); + nxs->AddDatasetAttribute("/run/histogram_data_1/corrected_time", "axis", 1); + nxs->AddDatasetAttribute("/run/histogram_data_1/corrected_time", "units", std::string("microseconds")); + nxs->AddDatasetAttribute("/run/histogram_data_1/corrected_time", "available", 0); + + // set grouping + std::vector grouping(fData[0].GetNoOfHistos(), 0); + nxs->AddDataset("/run/histogram_data_1/grouping", grouping, {grouping.size()}, H5::PredType::NATIVE_INT32); + nxs->AddDatasetAttribute("/run/histogram_data_1/grouping", "avaliabe", 0); + + // set alpha + int ival=1; + nxs->AddDataset("/run/histogram_data_1/alpha", {ival}, {1}, H5::PredType::NATIVE_INT32); + nxs->AddDatasetAttribute("/run/histogram_data_1/alpha", "avaliabe", 0); + + // set counts + // feed histos + PIntVector data; + UInt_t size = 0; + int noHisto, histoLength; + if (fAny2ManyInfo->rebin == 1) { + noHisto = fData[0].GetNoOfHistos(); + for (UInt_t i=0; i> PRunDataHandler::WriteNexusFile: **ERROR** Couldn't get data set (idx=" << i << ")"; + std::cerr << std::endl << ">> something is really wrong!" << std::endl; + return false; + } + size = dataSet->GetData()->size(); + histoLength = size; + for (UInt_t j=0; jGetData()->at(j)); + } + } + } else { // rebin > 1 + UInt_t dataRebin = 0; + UInt_t dataCount = 0; + noHisto = fData[0].GetNoOfHistos(); + for (UInt_t i=0; i> PRunDataHandler::WriteNexusFile: **ERROR** Couldn't get data set (idx=" << i << ")"; + std::cerr << std::endl << ">> something is really wrong!" << std::endl; + return false; + } + size = dataSet->GetData()->size(); + dataCount = 0; + for (UInt_t j=0; j 0) && (j % fAny2ManyInfo->rebin == 0)) { + dataCount++; + data.push_back(dataRebin); + dataRebin = 0; + } + dataRebin += static_cast(dataSet->GetData()->at(j)); + } + } + size = dataCount; + } + nxs->AddDataset("/run/histogram_data_1/counts", data, {(long unsigned int)noHisto, size}, H5::PredType::NATIVE_INT32); + nxs->AddDatasetAttribute("/run/histogram_data_1/counts", "units", std::string("counts")); + nxs->AddDatasetAttribute("/run/histogram_data_1/counts", "signal", 1); + nxs->AddDatasetAttribute("/run/histogram_data_1/counts", "number", noHisto); + nxs->AddDatasetAttribute("/run/histogram_data_1/counts", "length", size); + nxs->AddDatasetAttribute("/run/histogram_data_1/counts", "t0_bin", 0); + nxs->AddDatasetAttribute("/run/histogram_data_1/counts", "first_good_bin", 0); + nxs->AddDatasetAttribute("/run/histogram_data_1/counts", "last_good_bin", 0); + res = (float)(fData[0].GetTimeResolution()*fAny2ManyInfo->rebin*1.0e3)/2.0; + nxs->AddDatasetAttribute("/run/histogram_data_1/counts", "offset", res); } else { // IDF V2 // set IDF version nxs->AddDataset("/raw_data_1/IDF_version", {(int)fAny2ManyInfo->idf}, {1}, H5::PredType::NATIVE_INT32); @@ -4938,58 +5054,6 @@ Bool_t PRunDataHandler::WriteNexusFile(TString format, TString fln) return true; /* //as35 - if (fAny2ManyInfo->idf == 1) { - // fill necessary data structures - - for (unsigned int i=0; iGetEntryIdf1()->GetData()->SetT0(static_cast(dataSet->GetTimeZeroBin()/fAny2ManyInfo->rebin), i); - nxs->GetEntryIdf1()->GetData()->SetFirstGoodBin(static_cast(dataSet->GetFirstGoodBin()/fAny2ManyInfo->rebin), i); - nxs->GetEntryIdf1()->GetData()->SetLastGoodBin(static_cast(dataSet->GetLastGoodBin()/fAny2ManyInfo->rebin), i); - } - - // feed histos - PUIntVector data; - UInt_t size = 0; - if (fAny2ManyInfo->rebin == 1) { - for (UInt_t i=0; i> PRunDataHandler::WriteNexusFile: **ERROR** Couldn't get data set (idx=" << i << ")"; - std::cerr << std::endl << ">> something is really wrong!" << std::endl; - return false; - } - size = dataSet->GetData()->size(); - for (UInt_t j=0; jGetData()->at(j)); - } - nxs->GetEntryIdf1()->GetData()->SetHisto(data, i); - data.clear(); - } - } else { // rebin > 1 - UInt_t dataRebin = 0; - UInt_t dataCount = 0; - for (UInt_t i=0; i> PRunDataHandler::WriteNexusFile: **ERROR** Couldn't get data set (idx=" << i << ")"; - std::cerr << std::endl << ">> something is really wrong!" << std::endl; - return false; - } - size = dataSet->GetData()->size(); - dataCount = 0; - for (UInt_t j=0; j 0) && (j % fAny2ManyInfo->rebin == 0)) { - dataCount++; - data.push_back(dataRebin); - dataRebin = 0; - } - dataRebin += static_cast(dataSet->GetData()->at(j)); - } - nxs->GetEntryIdf1()->GetData()->SetHisto(data, i); - data.clear(); - } - } } else if (fAny2ManyInfo->idf == 2) { // fill necessary data structures nxs->SetFileName(fln.Data());