diff --git a/src/classes/PRunDataHandler.cpp b/src/classes/PRunDataHandler.cpp index b7bb01ed..f2c2559d 100644 --- a/src/classes/PRunDataHandler.cpp +++ b/src/classes/PRunDataHandler.cpp @@ -4830,20 +4830,20 @@ Bool_t PRunDataHandler::WriteNexusFile(TString format, TString fln) return false; } + // 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); + 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); @@ -5037,8 +5037,150 @@ Bool_t PRunDataHandler::WriteNexusFile(TString format, TString fln) res = (float)(fData[0].GetTimeResolution()*fAny2ManyInfo->rebin*1.0e3)/2.0; nxs->AddDatasetAttribute("/run/histogram_data_1/counts", "offset", res); } else { // IDF V2 + nxs->AddGroupAttribute("/raw_data_1", "NX_class", std::string("NXentry")); + // set IDF version nxs->AddDataset("/raw_data_1/IDF_version", {(int)fAny2ManyInfo->idf}, {1}, H5::PredType::NATIVE_INT32); + + // set beamline + str = *fData[0].GetBeamline(); + nxs->AddDataset("/raw_data_1/beamline", {str}, {1}, H5::StrType(H5::PredType::C_S1, H5T_VARIABLE)); + + // set definition + nxs->AddDataset("/raw_data_1/definition", {std::string("muonTD")}, {1}, H5::StrType(H5::PredType::C_S1, H5T_VARIABLE)); + + // set run_number + nxs->AddDataset("/raw_data_1/run_number", {fData[0].GetRunNumber()}, {1}, H5::PredType::NATIVE_INT32); + + // set title + nxs->AddDataset("/raw_data_1/title", {fData[0].GetRunTitle()->Data()}, {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("/raw_data_1/start_time", {str}, {1}, H5::StrType(H5::PredType::C_S1, H5T_VARIABLE)); + nxs->AddDatasetAttribute("/raw_data_1/start_time", "units", "ISO8601"); + + // set end time + str = std::string(fData[0].GetStopDate()->Data()) + std::string("T") + std::string(fData[0].GetStopTime()->Data()); + nxs->AddDataset("/raw_data_1/end_time", {str}, {1}, H5::StrType(H5::PredType::C_S1, H5T_VARIABLE)); + nxs->AddDatasetAttribute("/raw_data_1/end_time", "units", "ISO8601"); + + // set experiment_identifier + str = "n/a"; + nxs->AddDataset("/raw_data_1/experiment_identifier", {str}, {1}, H5::StrType(H5::PredType::C_S1, H5T_VARIABLE)); + + // set instrument attribute + nxs->AddGroupAttribute("/raw_data_1/instrument", "NX_class", std::string("NXinstrument")); + + // set instrument name + str = *fData[0].GetInstrument(); + nxs->AddDataset("/raw_data_1/instrument/name", {str}, {1}, H5::StrType(H5::PredType::C_S1, H5T_VARIABLE)); + + // set instrument/source attribute + nxs->AddGroupAttribute("/raw_data_1/instrument/source", "NX_class", std::string("NXsource")); + + // set instrument/source/name + str = fData[0].GetLaboratory()->Data(); + nxs->AddDataset("/raw_data_1/instrument/source/name", {str}, {1}, H5::StrType(H5::PredType::C_S1, H5T_VARIABLE)); + + // set instrument/source/type + TString tstr = *fData[0].GetInstrument(); + std::string type{"n/a"}; + if (tstr.Contains("LEM", TString::kIgnoreCase)) { + type = "low energy muon source"; + } else if (tstr.Contains("GPS", TString::kIgnoreCase) || tstr.Contains("GPD", TString::kIgnoreCase) || + tstr.Contains("LTF", TString::kIgnoreCase) || tstr.Contains("FLAME", TString::kIgnoreCase) || + tstr.Contains("HAL-9500", TString::kIgnoreCase) || tstr.Contains("DOLLY", TString::kIgnoreCase) || + tstr.Contains("VMS", TString::kIgnoreCase)) { + type = "quasi-continous muon source"; + } else if (tstr.Contains("EMU", TString::kIgnoreCase) || tstr.Contains("MUSR", TString::kIgnoreCase) || + tstr.Contains("HIFI", TString::kIgnoreCase)) { + type = "pulsed muon source"; + } + nxs->AddDataset("/raw_data_1/instrument/source/type", {type}, {1}, H5::StrType(H5::PredType::C_S1, H5T_VARIABLE)); + + // set instrument/source/probe + str = "positive muons"; + nxs->AddDataset("/raw_data_1/instrument/source/probe", {str}, {1}, H5::StrType(H5::PredType::C_S1, H5T_VARIABLE)); + + // set instrument/detector info + nxs->AddGroupAttribute("/raw_data_1/instrument/detector_1", "NX_class", std::string("NXdetector")); + + // set instrument/detector/spectrum_index + int noHistos = fData[0].GetNoOfHistos(); + std::vector spectrum_index(noHistos); + for (unsigned int i=0; iAddDataset("/raw_data_1/instrument/detector_1/spectrum_index", spectrum_index, {spectrum_index.size()}, H5::PredType::NATIVE_INT32); + + // set instrument/detector/raw_time (not useful for quasi-continuous sources) + int ival=0; + nxs->AddDataset("/raw_data_1/instrument/detector_1/raw_time", {ival}, {1}, H5::PredType::NATIVE_INT32); + nxs->AddDatasetAttribute("/raw_data_1/instrument/detector_1/raw_time", "available", 0); + + // set instrument/detector/counts + // set counts + // feed histos + PRawRunDataSet *dataSet = nullptr; + 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("/raw_data_1/instrument/detector_1/counts", data, {(long unsigned int)noHisto, size}, H5::PredType::NATIVE_INT32); + nxs->AddDatasetAttribute("/raw_data_1/instrument/detector_1/counts", "axis", std::string("spectrum_index,time_bin")); + nxs->AddDatasetAttribute("/raw_data_1/instrument/detector_1/counts", "long_name", std::string("positon counts")); + nxs->AddDatasetAttribute("/raw_data_1/instrument/detector_1/counts", "signal", 1); + // t0_bin attributes + std::vector t0_bin; + for (unsigned int i=0; irebin)); +std::cerr << std::endl; +for (unsigned int i=0; iAddDatasetAttribute("/raw_data_1/instrument/detector_1/counts", "t0_bin", {t0_bin}); + nxs->AddDatasetAttribute("/raw_data_1/instrument/detector_1/counts", "units", std::string("counts")); + + // set raw_data_1/detector info + nxs->AddGroupAttribute("/raw_data_1/detector_1", "NX_class", std::string("NXdata")); } int result = nxs->WriteNexusFile(fln.Data(), fAny2ManyInfo->idf);