clean up HDF4 in PNeXus. First implementation for HDF4 IDF1/2 write. Compiles, but still some issues.
This commit is contained in:
@@ -4818,8 +4818,378 @@ Bool_t PRunDataHandler::WriteNexusFile(TString format, TString fln)
|
|||||||
|
|
||||||
if (format.Contains("HDF4", TString::kIgnoreCase)) { // HDF4
|
if (format.Contains("HDF4", TString::kIgnoreCase)) { // HDF4
|
||||||
#ifdef HAVE_HDF4
|
#ifdef HAVE_HDF4
|
||||||
std::cerr << "**ERROR** not yet implemented!" << std::endl;
|
try {
|
||||||
return false;
|
// create NeXus object
|
||||||
|
std::unique_ptr<nxH4::PNeXus> nxs = std::make_unique<nxH4::PNeXus>();
|
||||||
|
if (nxs == nullptr) {
|
||||||
|
std::cerr << std::endl << ">> PRunDataHandler::WriteNexusFile(): **ERROR** couldn't invoke the NeXus object." << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// set NeXus version
|
||||||
|
nxs->AddGroupAttribute("/", "NeXus_version", std::string("4.3.0"));
|
||||||
|
|
||||||
|
// set HDF4 version
|
||||||
|
nxs->AddGroupAttribute("/", "HDF_version", nxs->GetHdf4LibVersion());
|
||||||
|
|
||||||
|
// 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 IDF version
|
||||||
|
nxs->AddDataset<int>("/run/IDF_version", {(int)fAny2ManyInfo->idf}, {1}, nxH4::H4DataType::INT32);
|
||||||
|
|
||||||
|
// set program name
|
||||||
|
nxs->AddDataset<std::string>("/run/program_name", {"any2many"}, {1}, nxH4::H4DataType::CHAR8);
|
||||||
|
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}, nxH4::H4DataType::INT32);
|
||||||
|
|
||||||
|
// set title
|
||||||
|
nxs->AddDataset<std::string>("/run/title", {fData[0].GetRunTitle()->Data()}, {1}, nxH4::H4DataType::CHAR8);
|
||||||
|
|
||||||
|
// set notes
|
||||||
|
nxs->AddDataset<std::string>("/run/notes", {std::string("n/a")}, {1}, nxH4::H4DataType::CHAR8);
|
||||||
|
|
||||||
|
// set analysis
|
||||||
|
nxs->AddDataset<std::string>("/run/notes", {std::string("muonTD")}, {1}, nxH4::H4DataType::CHAR8);
|
||||||
|
|
||||||
|
// set lab
|
||||||
|
str = *fData[0].GetLaboratory();
|
||||||
|
nxs->AddDataset<std::string>("/run/lab", {str}, {1}, nxH4::H4DataType::CHAR8);
|
||||||
|
|
||||||
|
// set beamline
|
||||||
|
str = *fData[0].GetBeamline();
|
||||||
|
nxs->AddDataset<std::string>("/run/beamline", {str}, {1}, nxH4::H4DataType::CHAR8);
|
||||||
|
|
||||||
|
// 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}, nxH4::H4DataType::CHAR8);
|
||||||
|
|
||||||
|
// 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}, nxH4::H4DataType::CHAR8);
|
||||||
|
|
||||||
|
// set switching state
|
||||||
|
nxs->AddDataset<int>("/run/switching_states", {1}, {1}, nxH4::H4DataType::INT32);
|
||||||
|
|
||||||
|
// set user name
|
||||||
|
nxs->AddDataset<std::string>("/run/user/name", {std::string("n/a")}, {1}, nxH4::H4DataType::CHAR8);
|
||||||
|
|
||||||
|
// set user experiment_number
|
||||||
|
nxs->AddDataset<std::string>("/run/user/experiment_number", {std::string("n/a")}, {1}, nxH4::H4DataType::CHAR8);
|
||||||
|
|
||||||
|
// set sample name
|
||||||
|
nxs->AddDataset<std::string>("/run/sample/name", {fData[0].GetSample()->Data()}, {1}, nxH4::H4DataType::CHAR8);
|
||||||
|
|
||||||
|
// set sample temperature
|
||||||
|
nxs->AddDataset<float>("/run/sample/temperature", {(float)fData[0].GetTemperature(0)}, {1}, nxH4::H4DataType::FLOAT32);
|
||||||
|
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}, nxH4::H4DataType::FLOAT32);
|
||||||
|
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}, nxH4::H4DataType::CHAR8);
|
||||||
|
|
||||||
|
// set sample shape
|
||||||
|
nxs->AddDataset<std::string>("/run/sample/shape", {std::string("n/a")}, {1}, nxH4::H4DataType::CHAR8);
|
||||||
|
|
||||||
|
// set magnetic field vector
|
||||||
|
nxs->AddDataset<float>("/run/sample/magnetic_field_vector", {1.0f, 1.0f, 1.0f}, {3}, nxH4::H4DataType::FLOAT32);
|
||||||
|
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}, nxH4::H4DataType::CHAR8);
|
||||||
|
|
||||||
|
// set instrument number of detectors
|
||||||
|
nxs->AddDataset<int>("/run/instrument/detector/number", {(int)fData[0].GetNoOfHistos()}, {1}, nxH4::H4DataType::INT32);
|
||||||
|
|
||||||
|
// set instrument collimator
|
||||||
|
nxs->AddDataset<std::string>("/run/instrument/collimator/type", {std::string("n/a")}, {1}, nxH4::H4DataType::CHAR8);
|
||||||
|
|
||||||
|
// 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}, nxH4::H4DataType::FLOAT32);
|
||||||
|
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}, nxH4::H4DataType::FLOAT32);
|
||||||
|
nxs->AddDatasetAttribute<float>("/run/histogram_data_1/resolution", "units", std::string("picoseconds"));
|
||||||
|
|
||||||
|
// set time zero time to 0. see t0_bin attribute of counts!
|
||||||
|
nxs->AddDataset<int>("/run/histogram_data_1/time_zero", {0}, {1}, nxH4::H4DataType::INT32);
|
||||||
|
nxs->AddDatasetAttribute<int>("/run/histogram_data_1/time_zero", "units", std::string("microseconds"));
|
||||||
|
nxs->AddDatasetAttribute<int>("/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<float> time;
|
||||||
|
for (unsigned int i=0; i<length; i++)
|
||||||
|
time.push_back(((float)i+0.5)*res);
|
||||||
|
nxs->AddDataset<float>("/run/histogram_data_1/raw_time", time, {length}, nxH4::H4DataType::FLOAT32);
|
||||||
|
nxs->AddDatasetAttribute<float>("/run/histogram_data_1/raw_time", "axis", 1);
|
||||||
|
nxs->AddDatasetAttribute<float>("/run/histogram_data_1/raw_time", "primary", 0);
|
||||||
|
nxs->AddDatasetAttribute<float>("/run/histogram_data_1/raw_time", "units", std::string("microseconds"));
|
||||||
|
nxs->AddDatasetAttribute<float>("/run/histogram_data_1/raw_time", "available", 0);
|
||||||
|
|
||||||
|
// set corrected_time
|
||||||
|
nxs->AddDataset<float>("/run/histogram_data_1/corrected_time", time, {length}, nxH4::H4DataType::FLOAT32);
|
||||||
|
nxs->AddDatasetAttribute<float>("/run/histogram_data_1/corrected_time", "axis", 1);
|
||||||
|
nxs->AddDatasetAttribute<float>("/run/histogram_data_1/corrected_time", "units", std::string("microseconds"));
|
||||||
|
nxs->AddDatasetAttribute<float>("/run/histogram_data_1/corrected_time", "available", 0);
|
||||||
|
|
||||||
|
// set grouping
|
||||||
|
std::vector<int> grouping(fData[0].GetNoOfHistos(), 0);
|
||||||
|
nxs->AddDataset<int>("/run/histogram_data_1/grouping", grouping, {(uint32_t)grouping.size()}, nxH4::H4DataType::INT32);
|
||||||
|
nxs->AddDatasetAttribute<int>("/run/histogram_data_1/grouping", "avaliabe", 0);
|
||||||
|
|
||||||
|
// set alpha
|
||||||
|
int ival=1;
|
||||||
|
nxs->AddDataset<int>("/run/histogram_data_1/alpha", {ival}, {1}, nxH4::H4DataType::INT32);
|
||||||
|
nxs->AddDatasetAttribute<int>("/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<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=" << i << ")";
|
||||||
|
std::cerr << std::endl << ">> something is really wrong!" << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
size = dataSet->GetData()->size();
|
||||||
|
histoLength = size;
|
||||||
|
for (UInt_t j=0; j<size; j++) {
|
||||||
|
data.push_back((UInt_t)dataSet->GetData()->at(j));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else { // rebin > 1
|
||||||
|
UInt_t dataRebin = 0;
|
||||||
|
UInt_t dataCount = 0;
|
||||||
|
noHisto = fData[0].GetNoOfHistos();
|
||||||
|
for (UInt_t 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=" << 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<size; j++) {
|
||||||
|
if ((j > 0) && (j % fAny2ManyInfo->rebin == 0)) {
|
||||||
|
dataCount++;
|
||||||
|
data.push_back(dataRebin);
|
||||||
|
dataRebin = 0;
|
||||||
|
}
|
||||||
|
dataRebin += static_cast<UInt_t>(dataSet->GetData()->at(j));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
size = dataCount;
|
||||||
|
}
|
||||||
|
nxs->AddDataset<int>("/run/histogram_data_1/counts", data, {(uint32_t)noHisto, (uint32_t)size}, nxH4::H4DataType::INT32);
|
||||||
|
nxs->AddDatasetAttribute<int>("/run/histogram_data_1/counts", "units", std::string("counts"));
|
||||||
|
nxs->AddDatasetAttribute<int>("/run/histogram_data_1/counts", "signal", 1);
|
||||||
|
nxs->AddDatasetAttribute<int>("/run/histogram_data_1/counts", "number", noHisto);
|
||||||
|
nxs->AddDatasetAttribute<int>("/run/histogram_data_1/counts", "length", (int)size);
|
||||||
|
nxs->AddDatasetAttribute<int>("/run/histogram_data_1/counts", "t0_bin", 0);
|
||||||
|
nxs->AddDatasetAttribute<int>("/run/histogram_data_1/counts", "first_good_bin", 0);
|
||||||
|
nxs->AddDatasetAttribute<int>("/run/histogram_data_1/counts", "last_good_bin", 0);
|
||||||
|
res = (float)(fData[0].GetTimeResolution()*fAny2ManyInfo->rebin*1.0e3)/2.0;
|
||||||
|
nxs->AddDatasetAttribute<int>("/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<int>("/raw_data_1/IDF_version", {(int)fAny2ManyInfo->idf}, {1}, nxH4::H4DataType::INT32);
|
||||||
|
|
||||||
|
// set beamline
|
||||||
|
str = *fData[0].GetBeamline();
|
||||||
|
nxs->AddDataset<std::string>("/raw_data_1/beamline", {str}, {1}, nxH4::H4DataType::CHAR8);
|
||||||
|
|
||||||
|
// set definition
|
||||||
|
nxs->AddDataset<std::string>("/raw_data_1/definition", {std::string("muonTD")}, {1}, nxH4::H4DataType::CHAR8);
|
||||||
|
|
||||||
|
// set run_number
|
||||||
|
nxs->AddDataset<int>("/raw_data_1/run_number", {fData[0].GetRunNumber()}, {1}, nxH4::H4DataType::INT32);
|
||||||
|
|
||||||
|
// set title
|
||||||
|
nxs->AddDataset<std::string>("/raw_data_1/title", {fData[0].GetRunTitle()->Data()}, {1}, nxH4::H4DataType::CHAR8);
|
||||||
|
|
||||||
|
// set start time
|
||||||
|
str = std::string(fData[0].GetStartDate()->Data()) + std::string("T") + std::string(fData[0].GetStartTime()->Data());
|
||||||
|
nxs->AddDataset<std::string>("/raw_data_1/start_time", {str}, {1}, nxH4::H4DataType::CHAR8);
|
||||||
|
nxs->AddDatasetAttribute<std::string>("/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<std::string>("/raw_data_1/end_time", {str}, {1}, nxH4::H4DataType::CHAR8);
|
||||||
|
nxs->AddDatasetAttribute<std::string>("/raw_data_1/end_time", "units", "ISO8601");
|
||||||
|
|
||||||
|
// set experiment_identifier
|
||||||
|
str = "n/a";
|
||||||
|
nxs->AddDataset<std::string>("/raw_data_1/experiment_identifier", {str}, {1}, nxH4::H4DataType::CHAR8);
|
||||||
|
|
||||||
|
// set instrument attribute
|
||||||
|
nxs->AddGroupAttribute("/raw_data_1/instrument", "NX_class", std::string("NXinstrument"));
|
||||||
|
|
||||||
|
// set instrument name
|
||||||
|
str = *fData[0].GetInstrument();
|
||||||
|
nxs->AddDataset<std::string>("/raw_data_1/instrument/name", {str}, {1}, nxH4::H4DataType::CHAR8);
|
||||||
|
|
||||||
|
// 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<std::string>("/raw_data_1/instrument/source/name", {str}, {1}, nxH4::H4DataType::CHAR8);
|
||||||
|
|
||||||
|
// 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<std::string>("/raw_data_1/instrument/source/type", {type}, {1}, nxH4::H4DataType::CHAR8);
|
||||||
|
|
||||||
|
// set instrument/source/probe
|
||||||
|
str = "positive muons";
|
||||||
|
nxs->AddDataset<std::string>("/raw_data_1/instrument/source/probe", {str}, {1}, nxH4::H4DataType::CHAR8);
|
||||||
|
|
||||||
|
// 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<int> spectrum_index(noHistos);
|
||||||
|
for (unsigned int i=0; i<spectrum_index.size(); i++)
|
||||||
|
spectrum_index[i] = i+1;
|
||||||
|
nxs->AddDataset<int>("/raw_data_1/instrument/detector_1/spectrum_index", spectrum_index, {(uint32_t)spectrum_index.size()}, nxH4::H4DataType::INT32);
|
||||||
|
|
||||||
|
// set instrument/detector/raw_time (not useful for quasi-continuous sources)
|
||||||
|
int ival=0;
|
||||||
|
nxs->AddDataset<int>("/raw_data_1/instrument/detector_1/raw_time", {ival}, {1}, nxH4::H4DataType::INT32);
|
||||||
|
nxs->AddDatasetAttribute<int>("/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<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=" << i << ")";
|
||||||
|
std::cerr << std::endl << ">> something is really wrong!" << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
size = dataSet->GetData()->size();
|
||||||
|
histoLength = size;
|
||||||
|
for (UInt_t j=0; j<size; j++) {
|
||||||
|
data.push_back((UInt_t)dataSet->GetData()->at(j));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else { // rebin > 1
|
||||||
|
UInt_t dataRebin = 0;
|
||||||
|
UInt_t dataCount = 0;
|
||||||
|
noHisto = fData[0].GetNoOfHistos();
|
||||||
|
for (UInt_t 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=" << 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<size; j++) {
|
||||||
|
if ((j > 0) && (j % fAny2ManyInfo->rebin == 0)) {
|
||||||
|
dataCount++;
|
||||||
|
data.push_back(dataRebin);
|
||||||
|
dataRebin = 0;
|
||||||
|
}
|
||||||
|
dataRebin += static_cast<UInt_t>(dataSet->GetData()->at(j));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
size = dataCount;
|
||||||
|
}
|
||||||
|
nxs->AddDataset<int>("/raw_data_1/instrument/detector_1/counts", data, {(uint32_t)noHisto, (uint32_t)size}, nxH4::H4DataType::INT32);
|
||||||
|
nxs->AddDatasetAttribute<int>("/raw_data_1/instrument/detector_1/counts", "axes", std::string("spectrum_index,time_bin"));
|
||||||
|
nxs->AddDatasetAttribute<int>("/raw_data_1/instrument/detector_1/counts", "long_name", std::string("positon counts"));
|
||||||
|
nxs->AddDatasetAttribute<int>("/raw_data_1/instrument/detector_1/counts", "signal", 1);
|
||||||
|
// t0_bin attributes
|
||||||
|
std::vector<int> t0_bin;
|
||||||
|
for (unsigned int i=0; i<fData[0].GetNoOfHistos(); i++)
|
||||||
|
t0_bin.push_back((int)(fData[0].GetT0Bin(i+1)/fAny2ManyInfo->rebin));
|
||||||
|
nxs->AddDatasetAttribute<int>("/raw_data_1/instrument/detector_1/counts", "t0_bin", {t0_bin});
|
||||||
|
nxs->AddDatasetAttribute<int>("/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"));
|
||||||
|
|
||||||
|
// set detector/counts
|
||||||
|
nxs->AddDataset<int>("/raw_data_1/detector_1/counts", data, {(uint32_t)noHisto, (uint32_t)size}, nxH4::H4DataType::INT32);
|
||||||
|
nxs->AddDatasetAttribute<int>("/raw_data_1/detector_1/counts", "axes", std::string("spectrum_index,time_bin"));
|
||||||
|
nxs->AddDatasetAttribute<int>("/raw_data_1/detector_1/counts", "long_name", std::string("positon counts"));
|
||||||
|
nxs->AddDatasetAttribute<int>("/raw_data_1/detector_1/counts", "signal", 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int result = nxs->WriteNexusFile(fln.Data(), fAny2ManyInfo->idf);
|
||||||
|
if (result != 0) {
|
||||||
|
std::cerr << std::endl << "**ERROR** PRunDataHandler::WriteNexusFile, fln=" << fln << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} catch (const std::runtime_error& e) {
|
||||||
|
std::cerr << std::endl << "HDF4 error: " << e.what() << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
} else { // HDF5
|
} else { // HDF5
|
||||||
try {
|
try {
|
||||||
@@ -5196,190 +5566,6 @@ Bool_t PRunDataHandler::WriteNexusFile(TString format, TString fln)
|
|||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
/* //as35
|
|
||||||
} else if (fAny2ManyInfo->idf == 2) {
|
|
||||||
// fill necessary data structures
|
|
||||||
nxs->SetFileName(fln.Data());
|
|
||||||
|
|
||||||
// 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);
|
|
||||||
|
|
||||||
// NXroot info
|
|
||||||
nxs->SetCreator("PSI: any2many");
|
|
||||||
|
|
||||||
// NXentry info
|
|
||||||
nxs->GetEntryIdf2()->SetDefinition("muonTD");
|
|
||||||
nxs->GetEntryIdf2()->SetProgramName("any2many");
|
|
||||||
nxs->GetEntryIdf2()->SetProgramVersion("$Id$");
|
|
||||||
nxs->GetEntryIdf2()->SetRunNumber(fData[0].GetRunNumber());
|
|
||||||
nxs->GetEntryIdf2()->SetTitle(fData[0].GetRunTitle()->Data());
|
|
||||||
str = std::string(fData[0].GetStartDate()->Data()) + std::string("T") + std::string(fData[0].GetStartTime()->Data());
|
|
||||||
nxs->GetEntryIdf2()->SetStartTime(str);
|
|
||||||
str = std::string(fData[0].GetStopDate()->Data()) + std::string("T") + std::string(fData[0].GetStopTime()->Data());
|
|
||||||
nxs->GetEntryIdf2()->SetStopTime(str);
|
|
||||||
|
|
||||||
nxs->GetEntryIdf2()->SetExperimentIdentifier("n/a");
|
|
||||||
|
|
||||||
// NXuser info
|
|
||||||
nxs->GetEntryIdf2()->GetUser()->SetName("n/a");
|
|
||||||
|
|
||||||
// NXsample info
|
|
||||||
nxs->GetEntryIdf2()->GetSample()->SetName(fData[0].GetSample()->Data());
|
|
||||||
nxs->GetEntryIdf2()->GetSample()->SetDescription("n/a");
|
|
||||||
nxs->GetEntryIdf2()->GetSample()->SetPhysProp("temperature_1", fData[0].GetTemperature(0), "Kelvin");
|
|
||||||
nxs->GetEntryIdf2()->GetSample()->SetPhysProp("magnetic_field_1", fData[0].GetField(), "Gauss");
|
|
||||||
nxs->GetEntryIdf2()->GetSample()->SetEnvironmentTemp(fData[0].GetSetup()->Data());
|
|
||||||
nxs->GetEntryIdf2()->GetSample()->SetEnvironmentField("n/a");
|
|
||||||
|
|
||||||
// here would be the information for NXinstrument. Currently there are not much information to feed this
|
|
||||||
nxs->GetEntryIdf2()->GetInstrument()->SetName(fData[0].GetInstrument()->Data());
|
|
||||||
|
|
||||||
// NXinstrument/NXsource
|
|
||||||
nxs->GetEntryIdf2()->GetInstrument()->GetSource()->SetName(fData[0].GetLaboratory()->Data());
|
|
||||||
nxs->GetEntryIdf2()->GetInstrument()->GetSource()->SetType(fData[0].GetMuonSource()->Data());
|
|
||||||
nxs->GetEntryIdf2()->GetInstrument()->GetSource()->SetProbe(fData[0].GetMuonSpecies()->Data());
|
|
||||||
|
|
||||||
// NXinstrument/NXbeamline
|
|
||||||
nxs->GetEntryIdf2()->GetInstrument()->GetBeamline()->SetName(fData[0].GetBeamline()->Data());
|
|
||||||
|
|
||||||
// NXinstrument/NXdetector
|
|
||||||
nxs->GetEntryIdf2()->GetInstrument()->GetDetector()->SetDescription(fData[0].GetInstrument()->Data()); // assume that this should be the instrument name
|
|
||||||
nxs->GetEntryIdf2()->GetInstrument()->GetDetector()->SetNoOfPeriods(0); // currently red/green is not distinguished
|
|
||||||
nxs->GetEntryIdf2()->GetInstrument()->GetDetector()->SetNoOfSpectra(fData[0].GetNoOfHistos());
|
|
||||||
PRawRunDataSet *dataSet = fData[0].GetDataSet(0, 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)";
|
|
||||||
std::cerr << std::endl << ">> something is really wrong!" << std::endl;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
nxs->GetEntryIdf2()->GetInstrument()->GetDetector()->SetNoOfBins((unsigned int)(dataSet->GetData()->size() / fAny2ManyInfo->rebin));
|
|
||||||
nxs->GetEntryIdf2()->GetInstrument()->GetDetector()->SetTimeResolution(fData[0].GetTimeResolution()*fAny2ManyInfo->rebin, "ns");
|
|
||||||
int *histo = nullptr;
|
|
||||||
int idx = 0;
|
|
||||||
if (fAny2ManyInfo->rebin == 1) {
|
|
||||||
histo = new int[fData[0].GetNoOfHistos()*dataSet->GetData()->size()];
|
|
||||||
idx = 0;
|
|
||||||
for (int i=0; i<nxs->GetEntryIdf2()->GetInstrument()->GetDetector()->GetNoOfSpectra(); 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=" << i << ")";
|
|
||||||
std::cerr << std::endl << ">> something is really wrong!" << std::endl;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
for (unsigned int j=0; j<dataSet->GetData()->size(); j++) {
|
|
||||||
*(histo+idx++) = (int) dataSet->GetData()->at(j);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
nxs->GetEntryIdf2()->GetInstrument()->GetDetector()->SetHistos(histo);
|
|
||||||
// clean up
|
|
||||||
if (histo) {
|
|
||||||
delete [] histo;
|
|
||||||
histo = nullptr;
|
|
||||||
}
|
|
||||||
} else { // rebin > 1
|
|
||||||
histo = new int[fData[0].GetNoOfHistos()*(int)(dataSet->GetData()->size()/fAny2ManyInfo->rebin)];
|
|
||||||
int counts = 0;
|
|
||||||
idx = 0;
|
|
||||||
for (int i=0; i<nxs->GetEntryIdf2()->GetInstrument()->GetDetector()->GetNoOfSpectra(); 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=" << i << ")";
|
|
||||||
std::cerr << std::endl << ">> something is really wrong!" << std::endl;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
for (unsigned int j=0; j<dataSet->GetData()->size(); j++) {
|
|
||||||
if ((j>0) && (j % fAny2ManyInfo->rebin == 0)) {
|
|
||||||
*(histo+idx++) = counts;
|
|
||||||
counts = 0;
|
|
||||||
}
|
|
||||||
counts += (int) dataSet->GetData()->at(j);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
nxs->GetEntryIdf2()->GetInstrument()->GetDetector()->SetHistos(histo);
|
|
||||||
// clean up
|
|
||||||
if (histo) {
|
|
||||||
delete [] histo;
|
|
||||||
histo = nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// handle spectrum index
|
|
||||||
for (int i=0; i<nxs->GetEntryIdf2()->GetInstrument()->GetDetector()->GetNoOfSpectra(); i++)
|
|
||||||
nxs->GetEntryIdf2()->GetInstrument()->GetDetector()->SetSpectrumIndex(i+1);
|
|
||||||
|
|
||||||
// handle histogram resolution
|
|
||||||
nxs->GetEntryIdf2()->GetInstrument()->GetDetector()->SetTimeResolution(fData[0].GetTimeResolution()*fAny2ManyInfo->rebin, "ns");
|
|
||||||
|
|
||||||
// handle raw time
|
|
||||||
std::vector<double> raw_time;
|
|
||||||
UInt_t size = (unsigned int)(dataSet->GetData()->size() / fAny2ManyInfo->rebin);
|
|
||||||
for (unsigned int i=0; i<size; i++) {
|
|
||||||
raw_time.push_back((double)i * fData[0].GetTimeResolution() * fAny2ManyInfo->rebin * 1.0e-3); // since time resolution is given in ns, the factor 1.0e-3 is needed to convert to us
|
|
||||||
}
|
|
||||||
nxs->GetEntryIdf2()->GetInstrument()->GetDetector()->SetRawTime(raw_time);
|
|
||||||
nxs->GetEntryIdf2()->GetInstrument()->GetDetector()->SetRawTimeUnit("micro.second");
|
|
||||||
nxs->GetEntryIdf2()->GetInstrument()->GetDetector()->SetRawTimeName("time");
|
|
||||||
raw_time.clear();
|
|
||||||
|
|
||||||
// handle t0
|
|
||||||
nxs->GetEntryIdf2()->GetInstrument()->GetDetector()->SetT0Tag(2); // i.e. t0[#histo] format
|
|
||||||
int *t0 = new int[fData[0].GetNoOfHistos()];
|
|
||||||
int *fgb = new int[fData[0].GetNoOfHistos()];
|
|
||||||
int *lgb = new int[fData[0].GetNoOfHistos()];
|
|
||||||
if ((t0==0) || (fgb==0) || (lgb==0)) {
|
|
||||||
std::cerr << std::endl << ">> PRunDataHandler::WriteNeXusFile: **ERROR** Couldn't allocate memory for t0, fgb, lgb" << std::endl;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
for (unsigned int i=0; i<fData[0].GetNoOfHistos(); i++) {
|
|
||||||
PRawRunDataSet *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)";
|
|
||||||
std::cerr << std::endl << ">> something is really wrong!" << std::endl;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
t0[i] = (int)(dataSet->GetTimeZeroBin() / fAny2ManyInfo->rebin);
|
|
||||||
fgb[i] = (int)(dataSet->GetFirstGoodBin() / fAny2ManyInfo->rebin);
|
|
||||||
lgb[i] = (int)(dataSet->GetLastGoodBin() / fAny2ManyInfo->rebin);
|
|
||||||
}
|
|
||||||
nxs->GetEntryIdf2()->GetInstrument()->GetDetector()->SetT0(t0);
|
|
||||||
nxs->GetEntryIdf2()->GetInstrument()->GetDetector()->SetFirstGoodBin(fgb);
|
|
||||||
nxs->GetEntryIdf2()->GetInstrument()->GetDetector()->SetLastGoodBin(lgb);
|
|
||||||
|
|
||||||
// clean up
|
|
||||||
if (t0) delete [] t0;
|
|
||||||
if (fgb) delete [] fgb;
|
|
||||||
if (lgb) delete [] lgb;
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// filter out the proper file type, i.e. HDF4, HDF5, or XML
|
|
||||||
char fileType[32];
|
|
||||||
memset(fileType, '\0', 32);
|
|
||||||
if (!fAny2ManyInfo->outFormat.CompareTo("nexus1-hdf4", TString::kIgnoreCase) || !fAny2ManyInfo->outFormat.CompareTo("nexus2-hdf4", TString::kIgnoreCase))
|
|
||||||
strncpy(fileType, "hdf4", sizeof(fileType));
|
|
||||||
else if (!fAny2ManyInfo->outFormat.CompareTo("nexus1-hdf5", TString::kIgnoreCase) || !fAny2ManyInfo->outFormat.CompareTo("nexus2-hdf5", TString::kIgnoreCase))
|
|
||||||
strncpy(fileType, "hdf5", sizeof(fileType));
|
|
||||||
else if (!fAny2ManyInfo->outFormat.CompareTo("nexus1-xml", TString::kIgnoreCase) || !fAny2ManyInfo->outFormat.CompareTo("nexus2-xml", TString::kIgnoreCase))
|
|
||||||
strncpy(fileType, "xml", sizeof(fileType));
|
|
||||||
else {
|
|
||||||
std::cerr << std::endl << ">> PRunDataHandler::WriteNexusFile(): **ERROR** undefined output NeXus format " << fAny2ManyInfo->outFormat.Data() << " found.";
|
|
||||||
std::cerr << std::endl << ">> Allowed are: hdf4, hdf5, xml" << std::endl;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// write file
|
|
||||||
nxs->WriteFile(fln, fileType, fAny2ManyInfo->idf);
|
|
||||||
*/ //as35
|
|
||||||
#else
|
#else
|
||||||
std::cout << std::endl << ">> PRunDataHandler::WriteNexusFile(): Sorry, not enabled at configuration level, i.e. -Dnexus=1 when executing configure" << std::endl << std::endl;
|
std::cout << std::endl << ">> PRunDataHandler::WriteNexusFile(): Sorry, not enabled at configuration level, i.e. -Dnexus=1 when executing configure" << std::endl << std::endl;
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
56
src/external/nexus/PNeXus.cpp
vendored
56
src/external/nexus/PNeXus.cpp
vendored
@@ -1982,8 +1982,30 @@ int nxH4::PNeXus::WriteNexusFile(const std::string& filename, int idfVersion)
|
|||||||
WriteFileAttributes(sd_id);
|
WriteFileAttributes(sd_id);
|
||||||
|
|
||||||
// Write datasets based on IDF version
|
// Write datasets based on IDF version
|
||||||
if (idfVersion == 2) {
|
if ((idfVersion == 1) || (idfVersion == 2)) {
|
||||||
WriteIdfV2(sd_id);
|
// Write all datasets from data map
|
||||||
|
for (const auto& [path, data_any] : fDataMap) {
|
||||||
|
// Try to write as int dataset
|
||||||
|
try {
|
||||||
|
auto data = std::any_cast<PNXdata<int>>(data_any);
|
||||||
|
WriteIntDataset(sd_id, path, data);
|
||||||
|
continue;
|
||||||
|
} catch (...) {}
|
||||||
|
|
||||||
|
// Try to write as float dataset
|
||||||
|
try {
|
||||||
|
auto data = std::any_cast<PNXdata<float>>(data_any);
|
||||||
|
WriteFloatDataset(sd_id, path, data);
|
||||||
|
continue;
|
||||||
|
} catch (...) {}
|
||||||
|
|
||||||
|
// Try to write as string dataset
|
||||||
|
try {
|
||||||
|
auto data = std::any_cast<PNXdata<std::string>>(data_any);
|
||||||
|
WriteStringDataset(sd_id, path, data);
|
||||||
|
continue;
|
||||||
|
} catch (...) {}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
std::cerr << "**ERROR** Unsupported IDF version for writing: " << idfVersion << std::endl;
|
std::cerr << "**ERROR** Unsupported IDF version for writing: " << idfVersion << std::endl;
|
||||||
SDend(sd_id);
|
SDend(sd_id);
|
||||||
@@ -2039,36 +2061,6 @@ void nxH4::PNeXus::WriteFileAttributes(int32 sd_id)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//=============================================================================
|
|
||||||
// nxH4::PNeXus::WriteIdfV2
|
|
||||||
//=============================================================================
|
|
||||||
void nxH4::PNeXus::WriteIdfV2(int32 sd_id)
|
|
||||||
{
|
|
||||||
// Write all datasets from data map
|
|
||||||
for (const auto& [path, data_any] : fDataMap) {
|
|
||||||
// Try to write as int dataset
|
|
||||||
try {
|
|
||||||
auto data = std::any_cast<PNXdata<int>>(data_any);
|
|
||||||
WriteIntDataset(sd_id, path, data);
|
|
||||||
continue;
|
|
||||||
} catch (...) {}
|
|
||||||
|
|
||||||
// Try to write as float dataset
|
|
||||||
try {
|
|
||||||
auto data = std::any_cast<PNXdata<float>>(data_any);
|
|
||||||
WriteFloatDataset(sd_id, path, data);
|
|
||||||
continue;
|
|
||||||
} catch (...) {}
|
|
||||||
|
|
||||||
// Try to write as string dataset
|
|
||||||
try {
|
|
||||||
auto data = std::any_cast<PNXdata<std::string>>(data_any);
|
|
||||||
WriteStringDataset(sd_id, path, data);
|
|
||||||
continue;
|
|
||||||
} catch (...) {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
// nxH4::PNeXus::WriteIntDataset
|
// nxH4::PNeXus::WriteIntDataset
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
|
|||||||
7
src/external/nexus/PNeXus.h
vendored
7
src/external/nexus/PNeXus.h
vendored
@@ -989,13 +989,6 @@ private:
|
|||||||
*/
|
*/
|
||||||
void WriteFileAttributes(int32 sd_id);
|
void WriteFileAttributes(int32 sd_id);
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Write IDF version 2 structure
|
|
||||||
* @param sd_id HDF4 SD interface ID
|
|
||||||
* @throws std::runtime_error if writing fails
|
|
||||||
*/
|
|
||||||
void WriteIdfV2(int32 sd_id);
|
|
||||||
|
|
||||||
// ========================================================================
|
// ========================================================================
|
||||||
// Case-insensitive lookup helper methods
|
// Case-insensitive lookup helper methods
|
||||||
// ========================================================================
|
// ========================================================================
|
||||||
|
|||||||
Reference in New Issue
Block a user