diff --git a/ChangeLog b/ChangeLog index 5490fea9..57a00291 100644 --- a/ChangeLog +++ b/ChangeLog @@ -6,6 +6,7 @@ changes since 0.9.0 =================================== +NEW added minimal NeXus IDF 2 support. NEW Added the online documentation to the repository. It can be found under "doc/html". NEW added chisq per run block information (all fit types). The same output rules as for the expected chisq are in place. NEW calculate expected chisq (Pearson's chisq) for single histogram fits. It always will send this information to the stdout diff --git a/doc/examples/data/emu00005989_v2.nxs b/doc/examples/data/emu00005989_v2.nxs new file mode 100644 index 00000000..91f812aa Binary files /dev/null and b/doc/examples/data/emu00005989_v2.nxs differ diff --git a/doc/examples/test-histo-NeXus2.msr b/doc/examples/test-histo-NeXus2.msr new file mode 100644 index 00000000..115f4f64 --- /dev/null +++ b/doc/examples/test-histo-NeXus2.msr @@ -0,0 +1,74 @@ +nc-ZnO T=80 F=69 +############################################################### +FITPARAMETER +# No Name Value Step Pos_Error Boundaries + 1 zero 0 0 none + 2 phase 2.84 -0.43 0.43 0 100 + 3 field 70.996 -0.035 0.035 0 none + 4 asym 0.1698 -0.0016 0.0017 0 0.3 + 5 rate 0.1523 -0.0023 0.0023 0 100 + 6 beta 1.261 -0.046 0.047 + 7 Norm_L 2409.7 -1.2 1.2 + 8 BG_L 0 0 none 0 none + 9 Norm_R 2120.7 -1.1 1.1 0 none + 10 BG_R 0 0 none 0 none + 11 relPhase 182.26 -0.44 0.44 0 none + +############################################################### +THEORY +asymmetry 4 +generExpo 5 6 (rate exponent) +TFieldCos fun1 fun2 (phase frequency) + +############################################################### +FUNCTIONS +fun1 = par2 + map1 +fun2 = gamma_mu * par3 + +############################################################### +RUN data/emu00005989_v2 XXXX ISIS NEXUS (name beamline institute data-file-format) +fittype 0 (single histogram fit) +norm 7 +backgr.fit 8 +lifetimecorrection +map 1 0 0 0 0 0 0 0 0 0 +forward 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 +data 40 1500 +fit 0.2 14 +packing 1 + +RUN data/emu00005989_v2 XXXX ISIS NEXUS (name beamline institute data-file-format) +fittype 0 (single histogram fit) +norm 9 +backgr.fit 10 +lifetimecorrection +map 11 0 0 0 0 0 0 0 0 0 +forward 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 +data 40 1500 +fit 0.2 14 +packing 1 + +############################################################### +COMMANDS +MINIMIZE +MINOS +SAVE + +############################################################### +FOURIER +units Gauss # units either 'Gauss', 'MHz', or 'Mc/s' +fourier_power 10 +apodization STRONG # NONE, WEAK, MEDIUM, STRONG +plot REAL # REAL, IMAG, REAL_AND_IMAG, POWER, PHASE +range 0 100 +phase par2 + +############################################################### +PLOT 0 (single histo plot) +runs 1 2 +range 0 14 -0.22 0.22 +view_packing 5 + +############################################################### +STATISTIC --- 2011-08-23 14:56:52 + chisq = 2643.1, NDF = 1696, chisq/NDF = 1.558403 diff --git a/src/any2many.cpp b/src/any2many.cpp index 852c2253..6b3cd275 100644 --- a/src/any2many.cpp +++ b/src/any2many.cpp @@ -64,9 +64,10 @@ void any2many_syntax() cout << endl << " etc., or a sequence of runs -, e.g. 111-222"; cout << endl << " -c : "; cout << endl << " : input data file format. Supported formats are:"; - cout << endl << " PSI-BIN, ROOT (LEM), MUD, NeXus, PSI-MDU, WKM"; + cout << endl << " PSI-BIN, ROOT (LEM), MUD, NeXus1, NeXus2, PSI-MDU, WKM"; cout << endl << " : ouput data file format. Supported formats are:"; - cout << endl << " PSI-BIN, ROOT (LEM), MUD, NeXus-HDF4, NeXus-HDF5, NeXus-XML, WKM, ASCII"; + cout << endl << " PSI-BIN, ROOT (LEM), MUD, NeXus1-HDF4, NeXus1-HDF5, NeXus1-XML,"; + cout << endl << " NeXus2-HDF4, NeXus2-HDF5, NeXus2-XML, WKM, ASCII"; cout << endl << " -p : where is the output path for the"; cout << endl << " converted files. If nothing is given, the current directory"; cout << endl << " will be used, unless the option '-s' is used."; @@ -149,9 +150,12 @@ int main(int argc, char *argv[]) outputFormat.push_back("psi-bin"); outputFormat.push_back("root"); outputFormat.push_back("mud"); - outputFormat.push_back("nexus-hdf4"); - outputFormat.push_back("nexus-hdf5"); - outputFormat.push_back("nexus-xml"); + outputFormat.push_back("nexus1-hdf4"); + outputFormat.push_back("nexus1-hdf5"); + outputFormat.push_back("nexus1-xml"); + outputFormat.push_back("nexus2-hdf4"); + outputFormat.push_back("nexus2-hdf5"); + outputFormat.push_back("nexus2-xml"); outputFormat.push_back("wkm"); outputFormat.push_back("ascii"); @@ -159,6 +163,7 @@ int main(int argc, char *argv[]) info.useStandardOutput = false; info.rebin = 1; info.compressionTag = 0; // no compression as default + info.idf = 0; // undefined // call any2many without arguments if (argc == 1) { @@ -404,6 +409,12 @@ int main(int argc, char *argv[]) show_syntax = true; } + // check if the output format is nexus + if (info.outFormat.Contains("nexus1", TString::kIgnoreCase)) + info.idf = 1; + if (info.outFormat.Contains("nexus2", TString::kIgnoreCase)) + info.idf = 2; + if (show_syntax) { info.runList.clear(); any2many_syntax(); diff --git a/src/classes/PRunDataHandler.cpp b/src/classes/PRunDataHandler.cpp index 79420d26..66fbb7a1 100644 --- a/src/classes/PRunDataHandler.cpp +++ b/src/classes/PRunDataHandler.cpp @@ -1346,7 +1346,9 @@ Bool_t PRunDataHandler::ReadNexusFile() PDoubleVector histoData; PRawRunData runData; TString str; + string sstr; Double_t dval; + bool ok; PNeXus *nxs_file = new PNeXus(fRunPathName.Data()); if (!nxs_file->IsValid()) { @@ -1355,81 +1357,265 @@ Bool_t PRunDataHandler::ReadNexusFile() return false; } - // get header information - - // get/set run title - str = TString(nxs_file->GetRunTitle()); - runData.SetRunTitle(str); - - // get/set run number - runData.SetRunNumber(nxs_file->GetRunNumber()); - - // get/set temperature - runData.SetTemperature(0, nxs_file->GetSampleTemperature(), 0.0); - - // get/set field - dval = nxs_file->GetMagneticField(); - str = TString(nxs_file->GetMagneticFieldUnits()); - // since field has to be given in Gauss, check the units - Double_t factor=1.0; - if (!str.CompareTo("gauss", TString::kIgnoreCase)) - factor=1.0; - else if (!str.CompareTo("tesla", TString::kIgnoreCase)) - factor=1.0e4; - else - factor=1.0; - runData.SetField(factor*dval); - - // 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 - runData.SetSetup(nxs_file->GetRunNotes()); - - // get/set sample - runData.SetSample(nxs_file->GetSampleName()); - - // get/set orientation - runData.SetOrientation("??"); - - // get/set time resolution (ns) - runData.SetTimeResolution(nxs_file->GetTimeResolution()); - - // get/set start/stop time - runData.SetStartTime(nxs_file->GetStartTime()); - runData.SetStartDate(nxs_file->GetStartDate()); - runData.SetStopTime(nxs_file->GetStopTime()); - runData.SetStopDate(nxs_file->GetStopDate()); - - // get t0, firstGoodBin, lastGoodBin, data - UInt_t t0=nxs_file->GetT0(); - PIntPair goodDataBin; - goodDataBin.first = nxs_file->GetFirstGoodBin(); - goodDataBin.second = nxs_file->GetLastGoodBin(); - PDoubleVector data; - for (Int_t i=0; iGetNoHistos(); i++) { - runData.AppendT0(t0); - runData.AppendGoodDataBin(goodDataBin); - data.clear(); - for (UInt_t j=0; jGetHisto(i)->size(); j++) { - data.push_back((Double_t)nxs_file->GetHisto(i)->at(j)); + if (nxs_file->GetIdfVersion() == 1) { + if (!nxs_file->IsValid()) { + cout << endl << "**ERROR** invalid NeXus IDF 2 version file found." << endl; + return false; } - runData.AppendDataBin(data); + + // get header information + + // get/set run title + str = TString(nxs_file->GetEntryIdf1()->GetTitle()); + runData.SetRunTitle(str); + + // get/set run number + runData.SetRunNumber(nxs_file->GetEntryIdf1()->GetRunNumber()); + + // get/set temperature + dval = nxs_file->GetEntryIdf1()->GetSample()->GetPhysPropValue("temperature", ok); + if (ok) + runData.SetTemperature(0, dval, 0.0); + + // get/set field + dval = nxs_file->GetEntryIdf1()->GetSample()->GetPhysPropValue("magnetic_field", ok); + nxs_file->GetEntryIdf1()->GetSample()->GetPhysPropUnit("magnetic_field", sstr, ok); + str = sstr; + // since field has to be given in Gauss, check the units + Double_t factor=1.0; + if (!str.CompareTo("gauss", TString::kIgnoreCase)) + factor=1.0; + else if (!str.CompareTo("tesla", TString::kIgnoreCase)) + factor=1.0e4; + else + factor=1.0; + runData.SetField(factor*dval); + + // 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 + runData.SetSetup(nxs_file->GetEntryIdf1()->GetNotes()); + + // get/set sample + runData.SetSample(nxs_file->GetEntryIdf1()->GetSample()->GetName()); + + // get/set orientation + runData.SetOrientation("??"); + + // get/set time resolution (ns) + runData.SetTimeResolution(nxs_file->GetEntryIdf1()->GetData()->GetTimeResolution("ns")); + + // get/set start/stop time + sstr = nxs_file->GetEntryIdf1()->GetStartTime(); + str = sstr; + TString date, time; + SplitTimeDate(str, time, date, ok); + if (ok) { + runData.SetStartTime(time); + runData.SetStartDate(date); + } + + sstr = nxs_file->GetEntryIdf1()->GetStopTime(); + str = sstr; + SplitTimeDate(str, time, date, ok); + if (ok) { + runData.SetStopTime(time); + runData.SetStopDate(date); + } + + // get/set t0, firstGoodBin, lastGoodBin + vector *t0 = nxs_file->GetEntryIdf1()->GetData()->GetT0s(); + vector *fgb = nxs_file->GetEntryIdf1()->GetData()->GetFirstGoodBins(); + vector *lgb = nxs_file->GetEntryIdf1()->GetData()->GetLastGoodBins(); + PIntPair goodDataBin; + for (UInt_t i=0; iGetEntryIdf1()->GetData()->GetNoOfHistos(); i++) { + if (isize()) { + runData.AppendT0(t0->at(i)); + } else { + runData.AppendT0(t0->at(0)); + } + if (isize()) { + goodDataBin.first = fgb->at(i); + goodDataBin.second = lgb->at(i); + } else { + goodDataBin.first = fgb->at(0); + goodDataBin.second = lgb->at(0); + } + runData.AppendGoodDataBin(goodDataBin); + } + + // get/set data + vector *pdata; + PDoubleVector data; + for (UInt_t i=0; iGetEntryIdf1()->GetData()->GetNoOfHistos(); i++) { + pdata = nxs_file->GetEntryIdf1()->GetData()->GetHisto(i); + for (UInt_t j=0; jsize(); j++) + data.push_back(pdata->at(j)); + runData.AppendDataBin(data); + data.clear(); + } + + // keep run name from the msr-file + runData.SetRunName(fRunName); + + // keep the information + fData.push_back(runData); + } else if (nxs_file->GetIdfVersion() == 2) { + if (!nxs_file->IsValid()) { + cout << endl << "**ERROR** invalid NeXus IDF 2 version file found." << endl; + return false; + } + // get header information + + // get/set run title + str = TString(nxs_file->GetEntryIdf2()->GetTitle()); + runData.SetRunTitle(str); + + // get/set run number + runData.SetRunNumber(nxs_file->GetEntryIdf2()->GetRunNumber()); + + // get/set temperature + dval = nxs_file->GetEntryIdf2()->GetSample()->GetPhysPropValue("temperature", ok); + if (ok) + runData.SetTemperature(0, dval, 0.0); + + // get/set field + dval = nxs_file->GetEntryIdf2()->GetSample()->GetPhysPropValue("magnetic_field", ok); + nxs_file->GetEntryIdf2()->GetSample()->GetPhysPropUnit("magnetic_field", sstr, ok); + str = sstr; + // since field has to be given in Gauss, check the units + Double_t factor=1.0; + if (!str.CompareTo("gauss", TString::kIgnoreCase)) + factor=1.0; + else if (!str.CompareTo("tesla", TString::kIgnoreCase)) + factor=1.0e4; + else + factor=1.0; + runData.SetField(factor*dval); + + // 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 take NXsample/temperature_1_env and NXsample/magnetic_field_1_env + sstr = nxs_file->GetEntryIdf2()->GetSample()->GetEnvironmentTemp() + string("/"); + sstr += nxs_file->GetEntryIdf2()->GetSample()->GetEnvironmentField(); + str = sstr; + runData.SetSetup(str); + + // get/set sample + runData.SetSample(nxs_file->GetEntryIdf2()->GetSample()->GetName()); + + // get/set orientation + runData.SetOrientation("??"); + + // get/set time resolution (ns) + runData.SetTimeResolution(nxs_file->GetEntryIdf2()->GetInstrument()->GetDetector()->GetTimeResolution("ns")); + + // get/set start/stop time + sstr = nxs_file->GetEntryIdf2()->GetStartTime(); + str = sstr; + TString date, time; + SplitTimeDate(str, time, date, ok); + if (ok) { + runData.SetStartTime(time); + runData.SetStartDate(date); + } + + sstr = nxs_file->GetEntryIdf2()->GetStopTime(); + str = sstr; + SplitTimeDate(str, time, date, ok); + if (ok) { + runData.SetStopTime(time); + runData.SetStopDate(date); + } + + // get/set t0, firstGoodBin, lastGoodBin + int *t0 = nxs_file->GetEntryIdf2()->GetInstrument()->GetDetector()->GetT0s(); + int *fgb = nxs_file->GetEntryIdf2()->GetInstrument()->GetDetector()->GetFirstGoodBins(); + int *lgb = nxs_file->GetEntryIdf2()->GetInstrument()->GetDetector()->GetLastGoodBins(); + PIntPair goodDataBin; + + if (nxs_file->GetEntryIdf2()->GetInstrument()->GetDetector()->GetT0Tag() == 2) { // t0, fgb, lgb: [][] + for (int i=0; iGetEntryIdf2()->GetInstrument()->GetDetector()->GetNoOfPeriods(); i++) { + for (int j=0; jGetEntryIdf2()->GetInstrument()->GetDetector()->GetNoOfSpectra(); j++) { + if (fgb && lgb) { + goodDataBin.first = *(fgb+i*nxs_file->GetEntryIdf2()->GetInstrument()->GetDetector()->GetNoOfSpectra()+j); + goodDataBin.second = *(lgb+i*nxs_file->GetEntryIdf2()->GetInstrument()->GetDetector()->GetNoOfSpectra()+j); + } + runData.AppendT0(*(t0+i*nxs_file->GetEntryIdf2()->GetInstrument()->GetDetector()->GetNoOfSpectra()+j)); + if (fgb && lgb) { + runData.AppendGoodDataBin(goodDataBin); + } + } + } + } else { // t0, fgb, lgb: single numbers + if (fgb && lgb) { + goodDataBin.first = *fgb; + goodDataBin.second = *lgb; + } + for (int i=0; iGetEntryIdf2()->GetInstrument()->GetDetector()->GetNoOfPeriods(); i++) { + for (int j=0; jGetEntryIdf2()->GetInstrument()->GetDetector()->GetNoOfSpectra(); j++) { + runData.AppendT0(*t0); + if (fgb && lgb) + runData.AppendGoodDataBin(goodDataBin); + } + } + } + + // get/set data + PDoubleVector data; + int *histos = nxs_file->GetEntryIdf2()->GetInstrument()->GetDetector()->GetHistos(); + if (nxs_file->GetEntryIdf2()->GetInstrument()->GetDetector()->GetNoOfPeriods() > 0) { // counts[][][] + for (int i=0; iGetEntryIdf2()->GetInstrument()->GetDetector()->GetNoOfPeriods(); i++) { + for (int j=0; jGetEntryIdf2()->GetInstrument()->GetDetector()->GetNoOfSpectra(); j++) { + for (int k=0; kGetEntryIdf2()->GetInstrument()->GetDetector()->GetNoOfBins(); k++) { + data.push_back(*(histos+i*nxs_file->GetEntryIdf2()->GetInstrument()->GetDetector()->GetNoOfSpectra()+j*nxs_file->GetEntryIdf2()->GetInstrument()->GetDetector()->GetNoOfBins()+k)); + } + runData.AppendDataBin(data); + data.clear(); + } + } + } else { + if (nxs_file->GetEntryIdf2()->GetInstrument()->GetDetector()->GetNoOfSpectra() > 0) { // counts[][] + for (int i=0; iGetEntryIdf2()->GetInstrument()->GetDetector()->GetNoOfSpectra(); i++) { + for (int j=0; jGetEntryIdf2()->GetInstrument()->GetDetector()->GetNoOfBins(); j++) { + data.push_back(*(histos+i*nxs_file->GetEntryIdf2()->GetInstrument()->GetDetector()->GetNoOfBins()+j)); + } + runData.AppendDataBin(data); + data.clear(); + } + } else { // counts[] + for (int i=0; iGetEntryIdf2()->GetInstrument()->GetDetector()->GetNoOfBins(); i++) { + data.push_back(*(histos+i)); + } + runData.AppendDataBin(data); + data.clear(); + } + } + + // keep run name from the msr-file + runData.SetRunName(fRunName); + + // keep the information + fData.push_back(runData); + } else { + cout << endl << ">> PRunDataHandler::ReadNexusFile(): IDF version " << nxs_file->GetIdfVersion() << ", not implemented." << endl; } - data.clear(); - - // keep run name from the msr-file - runData.SetRunName(fRunName); - - // keep the information - fData.push_back(runData); // clean up if (nxs_file) { @@ -3405,8 +3591,11 @@ Bool_t PRunDataHandler::WriteRootFile(TString fln) * \param fln file name. If empty, the routine will try to construct one */ Bool_t PRunDataHandler::WriteNexusFile(TString fln) -{ +{ + #ifdef PNEXUS_ENABLED + int *t0=0, *fgb=0, *lgb=0, *histo=0; + // generate output file name if (fln.Length() == 0) { Bool_t ok = false; @@ -3429,65 +3618,151 @@ Bool_t PRunDataHandler::WriteNexusFile(TString fln) return false; } - // fill necessary data structures - nxs->SetFileName(fln.Data()); - nxs->SetIDFVersion(1); - nxs->SetProgramName("any2many"); - nxs->SetProgramVersion("$Id$"); - nxs->SetRunNumber(fData[0].GetRunNumber()); - nxs->SetRunTitle(fData[0].GetRunTitle()->Data()); - nxs->SetRunNotes("n/a"); - nxs->SetAnalysisTag("n/a"); - nxs->SetLab("PSI"); - nxs->SetBeamline("n/a"); - nxs->SetStartDate(fData[0].GetStartDate()->Data()); - nxs->SetStartTime(fData[0].GetStartTime()->Data()); - nxs->SetStopDate(fData[0].GetStopDate()->Data()); - nxs->SetStopTime(fData[0].GetStopTime()->Data()); - nxs->SetSwitchingState(0); - nxs->SetUser("n/a"); - nxs->SetExperimentNumber("n/a"); - nxs->SetSampleName(fData[0].GetSample()->Data()); - nxs->SetSampleTemperature(fData[0].GetTemperature(0)); - nxs->SetSampleTemperatureUints("Kelvin"); - nxs->SetMagneticField(fData[0].GetField()); - nxs->SetMagneticFieldUnits("Gauss"); - nxs->SetSampleEnvironment("n/a"); - nxs->SetSampleShape("n/a"); - nxs->SetMagneticFieldVectorAvailable(0); - nxs->SetExperimentName("n/a"); - nxs->SetNoDetectors(fData[0].GetNoOfHistos()); - nxs->SetCollimatorType("n/a"); - nxs->SetTimeResolution(fData[0].GetTimeResolution()); - if (fData[0].GetT0(0) == -1) - nxs->SetT0(0); - else - nxs->SetT0(fData[0].GetT0(0)); // this needs to be changed in the long term, since for continous sources each detector has its one t0!! - if (fData[0].GetGoodDataBin(0).first == -1) { - nxs->SetFirstGoodBin(0); - nxs->SetLastGoodBin(0); - } else { - nxs->SetFirstGoodBin(fData[0].GetGoodDataBin(0).first); - nxs->SetLastGoodBin(fData[0].GetGoodDataBin(0).second); - } - // feed real histogram data - PUIntVector data; - for (UInt_t i=0; isize(); j++) { - data.push_back((UInt_t)fData[0].GetDataBin(i)->at(j)); + // set IDF version + nxs->SetIdfVersion(fAny2ManyInfo->idf); + + if (fAny2ManyInfo->idf == 1) { + // fill necessary data structures + nxs->SetFileName(fln.Data()); + + // set file creating time + time_t now; + struct tm *tm; + time(&now); + tm = localtime(&now); + string str(""); + char cstr[128]; + sprintf(cstr, "%04d-%02d-%02d %02d:%02d:%02d", 1900+tm->tm_year, tm->tm_mon, tm->tm_mday, tm->tm_hour, tm->tm_hour, tm->tm_sec); + str = 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("n/a"); + nxs->GetEntryIdf1()->SetLaboratory("PSI"); + nxs->GetEntryIdf1()->SetBeamline("n/a"); + str = string(fData[0].GetStartDate()->Data()) + string(" ") + string(fData[0].GetStartTime()->Data()); + nxs->GetEntryIdf1()->SetStartTime(str); + str = string(fData[0].GetStopDate()->Data()) + string(" ") + string(fData[0].GetStopTime()->Data()); + nxs->GetEntryIdf1()->SetStopTime(str); + nxs->GetEntryIdf1()->SetSwitchingState(0); + 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("n/a"); + nxs->GetEntryIdf1()->GetSample()->SetShape("n/a"); + nxs->GetEntryIdf1()->GetSample()->SetMagneticFieldVectorAvailable(0); + nxs->GetEntryIdf1()->GetInstrument()->SetName("n/a"); + nxs->GetEntryIdf1()->GetInstrument()->GetDetector()->SetNumber(fData[0].GetNoOfHistos()); + nxs->GetEntryIdf1()->GetInstrument()->GetCollimator()->SetType("n/a"); + nxs->GetEntryIdf1()->GetData()->SetTimeResolution(fData[0].GetTimeResolution(), "ns"); + if (fData[0].GetT0(0) == -1) + nxs->GetEntryIdf1()->GetData()->SetT0(0); + else + nxs->GetEntryIdf1()->GetData()->SetT0(fData[0].GetT0(0)); // this needs to be changed in the long term, since for continous sources each detector has its one t0!! + if (fData[0].GetGoodDataBin(0).first == -1) { + nxs->GetEntryIdf1()->GetData()->SetFirstGoodBin(0); + nxs->GetEntryIdf1()->GetData()->SetLastGoodBin(0); + } else { + nxs->GetEntryIdf1()->GetData()->SetFirstGoodBin(fData[0].GetGoodDataBin(0).first); + nxs->GetEntryIdf1()->GetData()->SetLastGoodBin(fData[0].GetGoodDataBin(0).second); } - nxs->SetHisto(i, data); - data.clear(); + // feed real histogram data + PUIntVector data; + for (UInt_t i=0; isize(); j++) { + data.push_back((UInt_t)fData[0].GetDataBin(i)->at(j)); + } + nxs->GetEntryIdf1()->GetData()->SetHisto(data, i); + data.clear(); + } + } 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); + string str(""); + char cstr[128]; + sprintf(cstr, "%04d-%02d-%02d %02d:%02d:%02d", 1900+tm->tm_year, tm->tm_mon, tm->tm_mday, tm->tm_hour, tm->tm_hour, tm->tm_sec); + str = string(cstr); + nxs->SetFileTime(str); + + nxs->SetCreator("PSI - any2many"); + + nxs->GetEntryIdf2()->SetDefinition("pulsedTD"); + nxs->GetEntryIdf2()->SetRunNumber(fData[0].GetRunNumber()); + nxs->GetEntryIdf2()->SetTitle(fData[0].GetRunTitle()->Data()); + str = string(fData[0].GetStartDate()->Data()) + string(" ") + string(fData[0].GetStartTime()->Data()); + nxs->GetEntryIdf2()->SetStartTime(str); + str = string(fData[0].GetStopDate()->Data()) + string(" ") + string(fData[0].GetStopTime()->Data()); + nxs->GetEntryIdf2()->SetStopTime(str); + + nxs->GetEntryIdf2()->SetExperimentIdentifier("n/a"); + + nxs->GetEntryIdf2()->GetUser()->SetName("n/a"); + + 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("n/a"); + nxs->GetEntryIdf2()->GetSample()->SetEnvironmentField("n/a"); + + // here would be the information for NXinstrument. Currently there are not enough information to feed this + + nxs->GetEntryIdf2()->GetInstrument()->GetDetector()->SetDescription("n/a"); + nxs->GetEntryIdf2()->GetInstrument()->GetDetector()->SetNoOfPeriods(1); // currently red/green is not distinguished + nxs->GetEntryIdf2()->GetInstrument()->GetDetector()->SetNoOfSpectra(fData[0].GetNoOfHistos()); + nxs->GetEntryIdf2()->GetInstrument()->GetDetector()->SetNoOfBins(fData[0].GetDataBin(0)->size()); + nxs->GetEntryIdf2()->GetInstrument()->GetDetector()->SetTimeResolution(fData[0].GetTimeResolution(), "ns"); + histo = new int[fData[0].GetNoOfHistos()*fData[0].GetDataBin(0)->size()]; + for (int i=0; iGetEntryIdf2()->GetInstrument()->GetDetector()->GetNoOfSpectra(); i++) { + for (unsigned int j=0; jsize(); j++) { + *(histo+i*fData[0].GetDataBin(0)->size()+j) = (int) fData[0].GetDataBin(i)->at(j); + } + } + nxs->GetEntryIdf2()->GetInstrument()->GetDetector()->SetHisto(histo); + for (int i=0; iGetEntryIdf2()->GetInstrument()->GetDetector()->GetNoOfSpectra(); i++) + nxs->GetEntryIdf2()->GetInstrument()->GetDetector()->SetSpectrumIndex(i+1); + + nxs->GetEntryIdf2()->GetInstrument()->GetDetector()->SetT0Tag(2); + int *t0 = new int[fData[0].GetT0Size()]; + for (unsigned int i=0; iGetEntryIdf2()->GetInstrument()->GetDetector()->SetT0(t0); + + // first_good_bin - still missing + // last_good_bin - still missing + } else { + // clean up + if (nxs != 0) { + delete nxs; + nxs = 0; + } + 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("nexus-hdf4", TString::kIgnoreCase)) + 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("nexus-hdf5", TString::kIgnoreCase)) + 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("nexus-xml", TString::kIgnoreCase)) + else if (!fAny2ManyInfo->outFormat.CompareTo("nexus1-xml", TString::kIgnoreCase) || !fAny2ManyInfo->outFormat.CompareTo("nexus2-xml", TString::kIgnoreCase)) strncpy(fileType, "xml", sizeof(fileType)); else { cerr << endl << ">> PRunDataHandler::WriteNexusFile(): **ERROR** undefined output NeXus format " << fAny2ManyInfo->outFormat.Data() << " found."; @@ -3500,9 +3775,25 @@ Bool_t PRunDataHandler::WriteNexusFile(TString fln) } // write file - nxs->WriteFile(fln, fileType); + nxs->WriteFile(fln, fileType, fAny2ManyInfo->idf); // clean up + if (t0) { + delete [] t0; + t0 = 0; + } + if (fgb) { + delete [] fgb; + fgb = 0; + } + if (lgb) { + delete [] lgb; + lgb = 0; + } + if (histo) { + delete [] histo; + histo = 0; + } if (nxs != 0) { delete nxs; nxs = 0; @@ -3510,6 +3801,7 @@ Bool_t PRunDataHandler::WriteNexusFile(TString fln) #else cout << endl << ">> PRunDataHandler::WriteNexusFile(): Sorry, not enabled at configuration level, i.e. --enable-NeXus when executing configure" << endl << endl; #endif + return true; } @@ -4567,3 +4859,32 @@ TString PRunDataHandler::GetMonth(Int_t month) return mm; } + +//-------------------------------------------------------------------------- +// SplitTimeData (private) +//-------------------------------------------------------------------------- +/** + *

splits an ISO 8601 timeDate into seperate time and data. The flag ok + * shows if it was successfull. + * + * \param timeData ISO 8601 timeData + * \param time part of timeData + * \param date part of timeData + * \param ok flag showing if the splitting was successfull + */ +void PRunDataHandler::SplitTimeDate(TString timeData, TString &time, TString &date, Bool_t &ok) +{ + struct tm tm; + memset(&tm, 0, sizeof(tm)); + strptime(timeData.Data(), "%Y-%m-%d %H:%M:S", &tm); + if (tm.tm_year == 0) + strptime(timeData.Data(), "%Y-%m-%dT%H:%M:S", &tm); + + if (tm.tm_year == 0) { + ok = false; + return; + } + + time = TString::Format("%02d:%02d:%02d", tm.tm_hour, tm.tm_min, tm.tm_sec); + date = TString::Format("%04d-%02d-%02d", tm.tm_year+1900, tm.tm_mon, tm.tm_mday); +} diff --git a/src/external/nexus/Makefile.am b/src/external/nexus/Makefile.am index 23be2465..8206d53d 100644 --- a/src/external/nexus/Makefile.am +++ b/src/external/nexus/Makefile.am @@ -5,7 +5,7 @@ h_sources = \ PNeXus.h cpp_sources = \ - PNeXus.cpp + PNeXus.cpp include_HEADERS = $(h_sources) diff --git a/src/external/nexus/PNeXus.cpp b/src/external/nexus/PNeXus.cpp index 469a9b2d..ca33e904 100644 --- a/src/external/nexus/PNeXus.cpp +++ b/src/external/nexus/PNeXus.cpp @@ -11,7 +11,7 @@ /*************************************************************************** * Copyright (C) 2007-2011 by Andreas Suter * - * andreas.suter@psi.ch * + * andreas.suter@psi.ch * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * @@ -29,8 +29,13 @@ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ -#include -#include +#include +#include +#include + +#include +#include +using namespace std; #include "PNeXus.h" @@ -53,66 +58,1603 @@ # define SIZE_UCHAR16 2 #endif /* SIZE_FLOAT32 */ -//----------------------------------------------------------------------------------------------------- -// PNeXus constructor -//----------------------------------------------------------------------------------------------------- +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +//------------------------------------------------------------------------------------------ +// PNeXusProp Constructor +//------------------------------------------------------------------------------------------ /** + *

+ */ +PNeXusProp::PNeXusProp() +{ + fName = "n/a"; + fUnit = "n/a"; + fValue = 1.0e99; +} + +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +//------------------------------------------------------------------------------------------ +// IsValid (public) +//------------------------------------------------------------------------------------------ +/** + *

Validates the NXbeam data. * + * \param strict flag if true a strict NeXus validation is performed. + */ +bool PNeXusBeam1::IsValid(bool strict) +{ + bool valid = true; + + if (fTotalCounts == 0) { + cerr << ">> **WARNING** NXbeam total_counts not given" << endl; + } else if (!fUnits.compare("n/a")) { + cerr << ">> **WARNING** NXbeam total_counts units not given" << endl; + } + + return valid; +} + +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +//------------------------------------------------------------------------------------------ +// IsValid (public) +//------------------------------------------------------------------------------------------ +/** + *

Validates the NXdetector data. + * + * \param strict flag if true a strict NeXus validation is performed. + */ +bool PNeXusDetector1::IsValid(bool strict) +{ + bool valid = true; + + if (fNumber == 0) { + cerr << ">> **WARNING** NXdetector number of detectors not given" << endl; + } + + return valid; +} + +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +//------------------------------------------------------------------------------------------ +// IsValid (public) +//------------------------------------------------------------------------------------------ +/** + *

Validates the NXinstrument data. + * + * \param strict flag if true a strict NeXus validation is performed. + */ +bool PNeXusInstrument1::IsValid(bool strict) +{ + bool valid = true; + + if (!fName.compare("n/a")) { + cerr << ">> **ERROR** NXinstrument name not given" << endl; + valid = false; + } else if (!fDetector.IsValid(strict)) { + valid = false; + } else if (!fCollimator.IsValid(strict)) { + valid = false; + } else if (!fBeam.IsValid(strict)) { + valid = false; + } + + return valid; +} + +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +//------------------------------------------------------------------------------------------ +// PNeXusSample1 Constructor +//------------------------------------------------------------------------------------------ +/** + *

+ */ +PNeXusSample1::PNeXusSample1() +{ + fName = "n/a"; + fShape = "n/a"; + fMagneticFieldState = "n/a"; + fEnvironment = "n/a"; + fMagneticFieldVectorAvailable = -1; + fMagneticFieldVectorUnits = "n/a"; + fMagneticFieldVectorCoordinateSystem = "n/a"; +} + +//------------------------------------------------------------------------------------------ +// PNeXusSample1 Destructor +//------------------------------------------------------------------------------------------ +/** + *

+ */ +PNeXusSample1::~PNeXusSample1() +{ + fPhysProp.clear(); + fMagneticFieldVector.clear(); +} + +//------------------------------------------------------------------------------------------ +// IsValid (public) +//------------------------------------------------------------------------------------------ +/** + *

Validates the NXsample data. + * + * \param strict flag if true a strict NeXus validation is performed. + */ +bool PNeXusSample1::IsValid(bool strict) +{ + bool valid = true; + + if (!fName.compare("n/a")) { + cerr << ">> **ERROR** NXsample name not given." << endl; + valid = false; + } else if (!fShape.compare("n/a")) { + cerr << ">> **WARNING** NXsample shape not given." << endl; + } + + int count=0; // at the end count holds the number of required physiscal properties. Currently these are: temperature, magnetic_field + for (unsigned int i=0; i> **ERROR** NXsample temperature unit not given." << endl; + valid = false; + } + if (fPhysProp[i].GetValue() == 1.0e99) { + cerr << ">> **ERROR** NXsample temperature value not given." << endl; + valid = false; + } + } + if (!fPhysProp[i].GetName().compare("magnetic_field")) { + count++; + if (!fPhysProp[i].GetUnit().compare("n/a")) { + cerr << ">> **ERROR** NXsample magnetic_field unit not given." << endl; + valid = false; + } + if (fPhysProp[i].GetValue() == 1.0e99) { + cerr << ">> **ERROR** NXsample magnetic_field value not given." << endl; + valid = false; + } + } + } + if (count < 2) { + cerr << ">> **ERROR** not all required physical properties (e.g. temperature, magnetic_field) are given." << endl; + valid = false; + } + + return valid; +} + +//------------------------------------------------------------------------------------------ +// GetPhysPropValue (public) +//------------------------------------------------------------------------------------------ +/** + *

+ * + * \param name + * \param ok + */ +double PNeXusSample1::GetPhysPropValue(string name, bool &ok) +{ + double dval=0.0; + ok = false; + + for (unsigned int i=0; i + * + * \param name + * \param ok + */ +void PNeXusSample1::GetPhysPropUnit(string name, string &unit, bool &ok) +{ + unit = "n/a"; + ok = false; + + for (unsigned int i=0; iSet the physical property with 'name' and 'value' at index 'idx'. If idx==-1 add it at the + * end, otherwise set it at index idx. + * + * \param name of the physical property + * \param value of the physical property + * \param idx index where to set the physical property + */ +void PNeXusSample1::SetPhysProp(string name, double value, string unit, int idx) +{ + PNeXusProp prop; + + prop.SetName(name); + prop.SetValue(value); + prop.SetUnit(unit); + + if (idx == -1) { + fPhysProp.push_back(prop); + } else if (idx >= (int)fPhysProp.size()) { + fPhysProp.resize(idx+1); + fPhysProp[idx] = prop; + } else { + fPhysProp[idx] = prop; + } +} + +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +//------------------------------------------------------------------------------------------ +// PNeXusUser1 Constructor +//------------------------------------------------------------------------------------------ +/** + *

+ */ +PNeXusUser1::PNeXusUser1() +{ + fName = "n/a"; + fExperimentNumber = "n/a"; +} + +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +//------------------------------------------------------------------------------------------ +// PNeXusEntry1 Constructor +//------------------------------------------------------------------------------------------ +/** + *

+ */ +PNeXusEntry1::PNeXusEntry1() +{ + fProgramName = "n/a"; + fProgramVersion = "n/a"; + fRunNumber = -1; + fTitle = "n/a"; + fNotes = "n/a"; + fAnalysis = "n/a"; + fLaboratory = "n/a"; + fBeamline = "n/a"; + fStartTime = "n/a"; + fStopTime = "n/a"; + fSwitchingState = -1; +} + +//------------------------------------------------------------------------------------------ +// IsValid (public) +//------------------------------------------------------------------------------------------ +/** + *

Validates the NXentry data. + * + * \param strict flag if true a strict NeXus validation is performed. + */ +bool PNeXusEntry1::IsValid(bool strict) +{ + if (!fProgramName.compare("n/a")) { + cerr << ">> **WARNING** NXentry: program_name not given." << endl; + } else if (!fProgramVersion.compare("n/a")) { + cerr << ">> **WARNING** NXentry: program_name/version not given." << endl; + } else if (fRunNumber == -1) { + cerr << ">> **ERROR** NXentry: number (i.e. run number) not given." << endl; + return false; + } else if (!fTitle.compare("n/a")) { + cerr << ">> **ERROR** NXentry: title not given." << endl; + return false; + } else if (!fNotes.compare("n/a")) { + cerr << ">> **WARNING** NXentry: notes not given." << endl; + } else if (!fAnalysis.compare("n/a")) { + cerr << ">> **ERROR** NXentry: analysis (i.e. type of muon experiment like 'TF', 'ALC', ...) not given." << endl; + return false; + } else if (!fLaboratory.compare("n/a")) { + cerr << ">> **ERROR** NXentry: lab (e.g. 'PSI') not given." << endl; + return false; + } else if (!fBeamline.compare("n/a")) { + cerr << ">> **ERROR** NXentry: beamline (e.g. 'piE3') not given." << endl; + return false; + } else if (!fStartTime.compare("n/a")) { + cerr << ">> **ERROR** NXentry: start_time not given." << endl; + return false; + } else if (!fStopTime.compare("n/a")) { + cerr << ">> **ERROR** NXentry: stop_time not given." << endl; + return false; + } else if (fSwitchingState == -1) { + cerr << ">> **ERROR** NXentry: switching_state (i.e. '1' normal data taking, '2' red/green mode) not given." << endl; + return false; + } else if (!fUser.IsValid(strict)) { + return false; + } else if (!fSample.IsValid(strict)) { + return false; + } else if (!fInstrument.IsValid(strict)) { + return false; + } else if (!fData.IsValid(strict)) { + return false; + } + + return true; +} + +//------------------------------------------------------------------------------------------ +// SetStartTime (public) +//------------------------------------------------------------------------------------------ +/** + *

Set the start time string and check that it is ISO 8601 conform. + * + * \param time start time string + */ +int PNeXusEntry1::SetStartTime(string time) +{ + struct tm tm; + memset(&tm, 0, sizeof(tm)); + strptime(time.c_str(), "%Y-%m-%d %H:%M:S", &tm); + if (tm.tm_year == 0) + strptime(time.c_str(), "%Y-%m-%dT%H:%M:S", &tm); + if (tm.tm_year == 0) + return NX_ERROR; + + fStartTime = time; + + return NX_OK; +} + +//------------------------------------------------------------------------------------------ +// SetStopTime (public) +//------------------------------------------------------------------------------------------ +/** + *

Set the stop time string and check that it is ISO 8601 conform. + * + * \param time stop time string + */ +int PNeXusEntry1::SetStopTime(string time) +{ + struct tm tm; + memset(&tm, 0, sizeof(tm)); + strptime(time.c_str(), "%Y-%m-%d %H:%M:S", &tm); + if (tm.tm_year == 0) + strptime(time.c_str(), "%Y-%m-%dT%H:%M:S", &tm); + if (tm.tm_year == 0) + return NX_ERROR; + + fStopTime = time; + + return NX_OK; +} + +//------------------------------------------------------------------------------------------ +// SetSwitchingState (public) +//------------------------------------------------------------------------------------------ +/** + *

Set the switching state tag. '1' normal data collection, '2' Red/Green mode + * + * \param state switching state tag + */ +int PNeXusEntry1::SetSwitchingState(int state) +{ + if ((state != 1) && (state != 2)) + return NX_ERROR; + + fSwitchingState = state; + + return NX_OK; +} + +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +//------------------------------------------------------------------------------------------ +// PNeXusAlpha1 Constructor +//------------------------------------------------------------------------------------------ +/** + *

+ */ +PNeXusAlpha1::PNeXusAlpha1() +{ + fGroupFirst=0; + fGroupSecond=0; + fAlphaVal=0.0; +} + +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +//------------------------------------------------------------------------------------------ +// PNeXusData1 Destructor +//------------------------------------------------------------------------------------------ +/** + *

+ */ +PNeXusData1::~PNeXusData1() +{ + fT0.clear(); + fFirstGoodBin.clear(); + fLastGoodBin.clear(); + fHistoName.clear(); + for (unsigned int i=0; iValidates the NXbeam data. + * + * \param strict flag if true a strict NeXus validation is performed. + */ +bool PNeXusData1::IsValid(bool strict) +{ + if (GetNoOfHistos() == 0) { + cerr << ">> **ERROR** NXdata no histograms given." << endl; + return false; + } else if (fTimeResolution == 0.0) { + cerr << ">> **ERROR** NXdata time resolution not given." << endl; + return false; + } else if (fT0.size() == 0) { + cerr << ">> **WARNING** NXdata t0 not given." << endl; + } else if (fFirstGoodBin.size() == 0) { + cerr << ">> **WARNING** NXdata first good bin not given." << endl; + } else if (fLastGoodBin.size() == 0) { + cerr << ">> **WARNING** NXdata last good bin not given." << endl; + } + + return true; +} + + +//------------------------------------------------------------------------------------------ +// GetTimeResolution (public) +//------------------------------------------------------------------------------------------ +/** + *

Get time resolution in the requested units. Allowed units are 'fs', 'ps', 'ns', 'us'. + * If unsupported time units are given, a time resolution == 0.0 is returned. Internally the + * time resolution is stored in 'ps'. + * + * \param units requested units for the time resolution. + */ +double PNeXusData1::GetTimeResolution(string units) +{ + double result=0.0; + + if (!units.compare("fs")) + result = fTimeResolution * 1.0e3; + else if (!units.compare("ps")) + result = fTimeResolution; + else if (!units.compare("ns")) + result = fTimeResolution * 1.0e-3; + else if (!units.compare("us")) + result = fTimeResolution * 1.0e-6; + else + result = 0.0; + + return result; +} + +//------------------------------------------------------------------------------------------ +// GetT0 (public) +//------------------------------------------------------------------------------------------ +/** + *

Returns the t0 at index 'idx' or -1 if the index is out of range. + * + * \param idx index of the requested t0 + */ +int PNeXusData1::GetT0(unsigned int idx) +{ + if (idx >= fT0.size()) + return -1; + + return fT0[idx]; +} + +//------------------------------------------------------------------------------------------ +// GetFirstGoodBin (public) +//------------------------------------------------------------------------------------------ +/** + *

Returns the first good bin at index 'idx' or -1 if the index is out of range. + * + * \param idx index of the requested first good bin + */ +int PNeXusData1::GetFirstGoodBin(unsigned int idx) +{ + if (idx >= fFirstGoodBin.size()) + return -1; + + return fFirstGoodBin[idx]; +} + +//------------------------------------------------------------------------------------------ +// GetLastGoodBin (public) +//------------------------------------------------------------------------------------------ +/** + *

Returns the last good bin at index 'idx' or -1 if the index is out of range. + * + * \param idx index of the requested last good bin + */ +int PNeXusData1::GetLastGoodBin(unsigned int idx) +{ + if (idx >= fLastGoodBin.size()) + return -1; + + return fLastGoodBin[idx]; +} + + +//------------------------------------------------------------------------------------------ +// GetHistoName (public) +//------------------------------------------------------------------------------------------ +/** + *

Extract the histogram name at position 'idx'. If 'idx' is out of range, the 'ok' flag + * is set to 'false' in which case the 'name' is undefined. + * + * \param idx index of the requested histogram name. + * \param name histogram name if idx is within range + * \param ok =true if idx was within range, otherwise false + */ +void PNeXusData1::GetHistoName(unsigned int idx, string &name, bool &ok) +{ + if (idx >= fHistoName.size()) { + ok = false; + } else { + ok = true; + name = fHistoName[idx]; + } +} + +//------------------------------------------------------------------------------------------ +// GetHisto (public) +//------------------------------------------------------------------------------------------ +/** + *

Returns the histogram with index 'histoNo' or 0 if 'histoNo' is out of range. + * + * \param histoNo index of the requested histogram + */ +vector *PNeXusData1::GetHisto(unsigned int histoNo) +{ + if (histoNo >= fHisto.size()) + return 0; + + return &fHisto[histoNo]; +} + + +//------------------------------------------------------------------------------------------ +// SetTimeResolution (public) +//------------------------------------------------------------------------------------------ +/** + *

Set the time resolution. 'units' tells in which units 'val' is provided. Acteptable units + * are 'fs', 'ps', 'ns', 'us'. + * + * \param val time resolution value + * \param units time resolution units + */ +void PNeXusData1::SetTimeResolution(double val, string units) +{ + if (!units.compare("fs")) + fTimeResolution = val * 1.0e-3; + else if (!units.compare("ps")) + fTimeResolution = val; + else if (!units.compare("ns")) + fTimeResolution = val * 1.0e3; + else if (!units.compare("us")) + fTimeResolution = val * 1.0e6; +} + +//------------------------------------------------------------------------------------------ +// SetT0 (public) +//------------------------------------------------------------------------------------------ +/** + *

Set the t0 value at index 'idx'. If 'idx'==-1, the t0 value will be appended + * + * \param t0 bin value + * \param idx index where to set t0 bin value + */ +void PNeXusData1::SetT0(unsigned int t0, int idx) +{ + if (idx == -1) { + fT0.push_back(t0); + } else if (idx >= (int)fT0.size()) { + fT0.resize(idx+1); + fT0[idx] = t0; + } else { + fT0[idx] = t0; + } +} + +//------------------------------------------------------------------------------------------ +// SetFirstGoodBin (public) +//------------------------------------------------------------------------------------------ +/** + *

Set the first good bin value at index 'idx'. If 'idx'==-1, the first good bin value will be appended + * + * \param fgb first good bin value + * \param idx index where to set first good bin value + */ +void PNeXusData1::SetFirstGoodBin(unsigned int fgb, int idx) +{ + if (idx == -1) { + fFirstGoodBin.push_back(fgb); + } else if (idx >= (int)fFirstGoodBin.size()) { + fFirstGoodBin.resize(idx+1); + fFirstGoodBin[idx] = fgb; + } else { + fFirstGoodBin[idx] = fgb; + } +} + +//------------------------------------------------------------------------------------------ +// SetLastGoodBin (public) +//------------------------------------------------------------------------------------------ +/** + *

Set the last good bin value at index 'idx'. If 'idx'==-1, the last good bin value will be appended + * + * \param lgb last good bin value + * \param idx index where to set last good bin value + */ +void PNeXusData1::SetLastGoodBin(unsigned int lgb, int idx) +{ + if (idx == -1) { + fLastGoodBin.push_back(lgb); + } else if (idx >= (int)fLastGoodBin.size()) { + fLastGoodBin.resize(idx+1); + fLastGoodBin[idx] = lgb; + } else { + fLastGoodBin[idx] = lgb; + } +} + +//------------------------------------------------------------------------------------------ +// FlushHistos (public) +//------------------------------------------------------------------------------------------ +/** + *

Flushes all previously allocated histograms. + * + */ +void PNeXusData1::FlushHistos() +{ + for (unsigned int i=0; iSet a histogram at index 'histoNo'. If 'histoNo'==-1, the histogram will be appended + * + * \param data histogram vector + * \param histoNo index where to set the histogram + */ +void PNeXusData1::SetHisto(vector &data, int histoNo) +{ + if (histoNo == -1) { + fHisto.push_back(data); + } else if (histoNo >= (int)fHisto.size()) { + fHisto.resize(histoNo+1); + fHisto[histoNo] = data; + } else { + fHisto[histoNo] = data; + } +} + +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +//------------------------------------------------------------------------------------------ +// IsValid (public) +//------------------------------------------------------------------------------------------ +/** + *

Validates the NXbeamline data. + * + * \param strict flag if true a strict NeXus validation is performed. + */ +bool PNeXusBeamline2::IsValid(bool strict) +{ + string msg(""); + + if (!fName.compare("n/a")) { + msg = "IDF2 NXbeamline 'name' not set."; + if (strict) { + cerr << ">> **ERROR** " << msg << endl; + return false; + } else { + cerr << ">> **WARNING** " << msg << endl; + } + } + + return true; +} + +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +//------------------------------------------------------------------------------------------ +// PNeXusDetector2 Constructor +//------------------------------------------------------------------------------------------ +/** + *

+ */ +PNeXusDetector2::PNeXusDetector2() +{ + fDescription = "n/a"; + fTimeResolution = 0; + fNoOfPeriods = -1; + fNoOfSpectra = -1; + fNoOfBins = -1; + + fT0Tag = -1; + fT0 = 0; + fFirstGoodBin = 0; + fLastGoodBin = 0; + fHisto = 0; +} + +//------------------------------------------------------------------------------------------ +// PNeXusDetector2 Destructor +//------------------------------------------------------------------------------------------ +/** + *

+ */ +PNeXusDetector2::~PNeXusDetector2() +{ + fSpectrumIndex.clear(); + + if (fT0) { + delete [] fT0; + fT0 = 0; + } + if (fFirstGoodBin) { + delete [] fFirstGoodBin; + fFirstGoodBin = 0; + } + if (fLastGoodBin) { + delete [] fLastGoodBin; + fLastGoodBin = 0; + } + if (fHisto) { + delete [] fHisto; + fHisto = 0; + } +} + +//------------------------------------------------------------------------------------------ +// IsValid (public) +//------------------------------------------------------------------------------------------ +/** + *

Validates the NXdetector data. + * + * \param strict flag if true a strict NeXus validation is performed. + */ +bool PNeXusDetector2::IsValid(bool strict) +{ + string msg(""); + + if (!fDescription.compare("n/a")) { + msg = "IDF2 NXdetector 'description' not set."; + if (strict) { + cerr << ">> **ERROR** " << msg << endl; + return false; + } else { + cerr << ">> **WARNING** " << msg << endl; + } + } + + if (fTimeResolution == 0.0) { + cerr << ">> **ERROR** IDF2 NXdetector 'histogram_resolution' is not set." << endl; + return false; + } + + if (fSpectrumIndex.size() == 0) { + cerr << ">> **ERROR** IDF2 NXdetector 'spectrum_index' is not set." << endl; + return false; + } + + if ((fT0Tag != 1) && (fT0Tag !=2)) { + cerr << ">> **ERROR** IDF2 NXdetector problem with t0/first_good_bin/last_good_bin/counts settings (tagging)." << endl; + return false; + } + + if ((fT0 == 0) || (fHisto == 0)) { + cerr << ">> **ERROR** IDF2 NXdetector problem with t0/counts settings (data)." << endl; + return false; + } + + if (fNoOfBins == -1) { + cerr << ">> **ERROR** IDF2 NXdetector fNoOfBins==-1." << endl; + return false; + } + + return true; +} + +//------------------------------------------------------------------------------------------ +// GetT0 (public) +//------------------------------------------------------------------------------------------ +/** + *

Get T0 bin if present, otherwise return -1. + * + * \param idxp period index + * \param idxs spectrum index + */ +int PNeXusDetector2::GetT0(int idxp, int idxs) +{ + int result = -1; + + if ((idxp < 0) || (idxs < 0)) { // assumption: there is only ONE t0 for all spectra + if (fT0 != 0) { + result = *fT0; + } + } else { // assumption: t0's are represented as t0[np][ns] + if ((idxp < fNoOfPeriods) || (idxs < fNoOfSpectra)) { + result = *(fT0+idxp*fNoOfSpectra+idxs); + } + } + + return result; +} + +//------------------------------------------------------------------------------------------ +// GetFirstGoodBin (public) +//------------------------------------------------------------------------------------------ +/** + *

Get first good bin if present, otherwise return -1. + * + * \param idxp period index + * \param idxs spectrum index + */ +int PNeXusDetector2::GetFirstGoodBin(int idxp, int idxs) +{ + int result = -1; + + if ((idxp < 0) || (idxs < 0)) { // assumption: there is only ONE t0 for all spectra + if (fFirstGoodBin != 0) { + result = *fFirstGoodBin; + } + } else { // assumption: fgb's are represented as fgb[np][ns] + if ((idxp < fNoOfPeriods) || (idxs < fNoOfSpectra)) { + result = *(fFirstGoodBin+idxp*fNoOfSpectra+idxs); + } + } + + return result; +} + +//------------------------------------------------------------------------------------------ +// GetLastGoodBin (public) +//------------------------------------------------------------------------------------------ +/** + *

Get last good bin if present, otherwise return -1. + * + * \param idxp period index + * \param idxs spectrum index + */ +int PNeXusDetector2::GetLastGoodBin(int idxp, int idxs) +{ + int result = -1; + + if ((idxp < 0) || (idxs < 0)) { // assumption: there is only ONE t0 for all spectra + if (fLastGoodBin != 0) { + result = *fLastGoodBin; + } + } else { // assumption: lgb's are represented as lgb[np][ns] + if ((idxp < fNoOfPeriods) || (idxs < fNoOfSpectra)) { + result = *(fLastGoodBin+idxp*fNoOfSpectra+idxs); + } + } + + return result; +} + +//------------------------------------------------------------------------------------------ +// GetHistoValue (public) +//------------------------------------------------------------------------------------------ +/** + *

Get histogram value. If any of the indices is out of range, -1 is returned. Since the + * histogram can have the structures: histo[][][], histo[][], or histo[] + * + * \param idx_p period index + * \param idx_s spectrum index + * \param idx_b histogram bin index + */ +int PNeXusDetector2::GetHistoValue(int idx_p, int idx_s, int idx_b) +{ + int value = -1; + + if ((idx_b < 0) || (idx_b >= fNoOfBins)) { // make sure that idx_b is within proper bounds + return -1; + } + + if (fNoOfSpectra > 0) { // make sure that idx_s is within proper bounds if there are different spectra + if ((idx_s < 0) || (idx_s >= fNoOfSpectra)) { + return -1; + } + } + + if (fNoOfPeriods > 0) { // make sure that idx_p is within proper bounds if there are different periods + if ((idx_p < 0) || (idx_p >= fNoOfPeriods)) { + return -1; + } + } + + if (fNoOfPeriods > 0) { + value = *(fHisto+idx_p*fNoOfSpectra*fNoOfBins+idx_s*fNoOfBins+idx_b); + } else { + if (fNoOfSpectra > 0) { + value = *(fHisto+idx_s*fNoOfBins+idx_b); + } else { + value = *(fHisto+idx_b); + } + } + + return value; +} + +//------------------------------------------------------------------------------------------ +// GetTimeResolution (public) +//------------------------------------------------------------------------------------------ +/** + *

Get time resolution in the requested units. Allowed units are 'fs', 'ps', 'ns', 'us'. + * If unsupported time units are given, a time resolution == 0.0 is returned. Internally the + * time resolution is stored in 'ps'. + * + * \param units requested units for the time resolution. + */ +double PNeXusDetector2::GetTimeResolution(string units) +{ + double result=0.0; + + if (!units.compare("fs") || !units.compare("femto.second") || !units.compare("femto second") || !units.compare("femtoseconds")) + result = fTimeResolution * 1.0e3; + else if (!units.compare("ps") || !units.compare("pico.second") || !units.compare("pico second") || !units.compare("picoseconds")) + result = fTimeResolution; + else if (!units.compare("ns") || !units.compare("nano.second") || !units.compare("nano second") || !units.compare("nanoseconds")) + result = fTimeResolution * 1.0e-3; + else if (!units.compare("us") || !units.compare("micro.second") || !units.compare("micro second") || !units.compare("microseconds")) + result = fTimeResolution * 1.0e-6; + else + result = 0.0; + + return result; +} + +//------------------------------------------------------------------------------------------ +// SetTimeResolution (public) +//------------------------------------------------------------------------------------------ +/** + *

Set the time resolution. 'units' tells in which units 'val' is provided. Acteptable units + * are 'fs', 'ps', 'ns', 'us'. + * + * \param val time resolution value + * \param units time resolution units + */ +void PNeXusDetector2::SetTimeResolution(double val, string units) +{ + if (!units.compare("fs") || !units.compare("femto.second") || !units.compare("femto second") || !units.compare("femtoseconds")) + fTimeResolution = val * 1.0e-3; + else if (!units.compare("ps") || !units.compare("pico.second") || !units.compare("pico second") || !units.compare("picoseconds")) + fTimeResolution = val; + else if (!units.compare("ns") || !units.compare("nano.second") || !units.compare("nano second") || !units.compare("nanoseconds")) + fTimeResolution = val * 1.0e3; + else if (!units.compare("us") || !units.compare("micro.second") || !units.compare("micro second") || !units.compare("microseconds")) + fTimeResolution = val * 1.0e6; +} + +//------------------------------------------------------------------------------------------ +// GetSpectrumIndex (public) +//------------------------------------------------------------------------------------------ +/** + *

returns the global spectrum index of index idx. + * + * \param idx spectrum index idx + */ +int PNeXusDetector2::GetSpectrumIndex(unsigned int idx) +{ + if (idx >= fSpectrumIndex.size()) + return -1; + + return fSpectrumIndex[idx]; +} + +//------------------------------------------------------------------------------------------ +// SetSpectrumIndex (public) +//------------------------------------------------------------------------------------------ +/** + *

set the global spectrum index of index idx. + * + * \param spectIdx spectrum index value + * \param idx spectrum index idx + */ +void PNeXusDetector2::SetSpectrumIndex(int spectIdx, int idx) +{ + if (idx < 0) { + fSpectrumIndex.push_back(spectIdx); + } else if (idx >= (int)fSpectrumIndex.size()) { + fSpectrumIndex.resize(idx+1); + fSpectrumIndex[idx] = spectIdx; + } else { + fSpectrumIndex[idx] = spectIdx; + } +} + +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +//------------------------------------------------------------------------------------------ +// IsValid (public) +//------------------------------------------------------------------------------------------ +/** + *

Validates the NXinstrument data. + * + * \param strict flag if true a strict NeXus validation is performed. + */ +bool PNeXusInstrument2::IsValid(bool strict) +{ + string msg(""); + + if (!fName.compare("n/a")) { + msg = "IDF2 NXinstrument 'name' not set."; + if (strict) { + cerr << ">> **ERROR** " << msg << endl; + return false; + } else { + cerr << ">> **WARNING** " << msg << endl; + } + } + + if (!fSource.IsValid(strict)) + return false; + + if (!fBeamline.IsValid(strict)) + return false; + + if (!fDetector.IsValid(strict)) + return false; + + return true; +} + +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +//------------------------------------------------------------------------------------------ +// PNeXusSource2 Constructor +//------------------------------------------------------------------------------------------ +/** + *

+ */ +PNeXusSource2::PNeXusSource2() +{ + fName = "n/a"; + fType = "n/a"; + fProbe = "n/a"; +} + +//------------------------------------------------------------------------------------------ +// IsValid (public) +//------------------------------------------------------------------------------------------ +/** + *

Validates the NXsource data. + * + * \param strict flag if true a strict NeXus validation is performed. + */ +bool PNeXusSource2::IsValid(bool strict) +{ + string msg(""); + + if (!fName.compare("n/a")) { + msg = "IDF2 NXsample 'name' not set."; + if (strict) { + cerr << ">> **ERROR** " << msg << endl; + return false; + } else { + cerr << ">> **WARNING** " << msg << endl; + } + } + + if (!fType.compare("n/a")) { + msg = "IDF2 NXsample 'type' not set."; + if (strict) { + cerr << ">> **ERROR** " << msg << endl; + return false; + } else { + cerr << ">> **WARNING** " << msg << endl; + } + } + + if (!fProbe.compare("n/a")) { + msg = "IDF2 NXsample 'probe' not set."; + if (strict) { + cerr << ">> **ERROR** " << msg << endl; + return false; + } else { + cerr << ">> **WARNING** " << msg << endl; + } + } + + return true; +} + +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +//------------------------------------------------------------------------------------------ +// PNeXusSample2 Constructor +//------------------------------------------------------------------------------------------ +/** + *

+ */ +PNeXusSample2::PNeXusSample2() +{ + fName = "n/a"; + fDescription = "n/a"; + fMagneticFieldState = "n/a"; + fEnvironmentTemp = "n/a"; + fEnvironmentField = "n/a"; +} + +//------------------------------------------------------------------------------------------ +// PNeXusSample2 Destructor +//------------------------------------------------------------------------------------------ +/** + *

+ */ +PNeXusSample2::~PNeXusSample2() +{ + fPhysProp.clear(); +} + +//------------------------------------------------------------------------------------------ +// IsValid (public) +//------------------------------------------------------------------------------------------ +/** + *

Validates the NXsample data. + * + * \param strict flag if true a strict NeXus validation is performed. + */ +bool PNeXusSample2::IsValid(bool strict) +{ + string msg(""); + + if (!fName.compare("n/a")) { + msg = "IDF2 NXsample 'name' not set."; + if (strict) { + cerr << ">> **ERROR** " << msg << endl; + return false; + } else { + cerr << ">> **WARNING** " << msg << endl; + } + } + + if (!fDescription.compare("n/a")) { + cerr << endl << ">> **WARNING** IDF2 NXsample 'description' not set." << endl; + } + + if (!fMagneticFieldState.compare("n/a")) { + cerr << endl << ">> **WARNING** IDF2 NXsample 'magnetic_field_state' not set." << endl; + } + + if (!fEnvironmentTemp.compare("n/a")) { + cerr << endl << ">> **WARNING** IDF2 NXsample 'temperature_1_env' not set." << endl; + } + + if (!fEnvironmentField.compare("n/a")) { + cerr << endl << ">> **WARNING** IDF2 NXsample 'magnetic_field_1_env' not set." << endl; + } + + bool ok; + double dummy; + + dummy = GetPhysPropValue("temperature_1", ok); + if (!ok) { + cerr << endl << ">> **WARNING** IDF2 NXsample 'temperature_1' not set." << endl; + } + + dummy = GetPhysPropValue("magnetic_field_1", ok); + if (!ok) { + cerr << endl << ">> **WARNING** IDF2 NXsample 'magnetic_field_1' not set." << endl; + } + + return true; +} + +//------------------------------------------------------------------------------------------ +// GetPhysPropValue (public) +//------------------------------------------------------------------------------------------ +/** + *

+ * + * \param name + * \param ok + */ +double PNeXusSample2::GetPhysPropValue(string name, bool &ok) +{ + double dval=0.0; + ok = false; + + for (unsigned int i=0; i + * + * \param name + * \param ok + */ +void PNeXusSample2::GetPhysPropUnit(string name, string &unit, bool &ok) +{ + unit = "n/a"; + ok = false; + + for (unsigned int i=0; iSet the physical property with 'name' and 'value' at index 'idx'. If idx==-1 add it at the + * end, otherwise set it at index idx. + * + * \param name of the physical property + * \param value of the physical property + * \param idx index where to set the physical property + */ +void PNeXusSample2::SetPhysProp(string name, double value, string unit, int idx) +{ + PNeXusProp prop; + + prop.SetName(name); + prop.SetValue(value); + prop.SetUnit(unit); + + if (idx == -1) { + fPhysProp.push_back(prop); + } else if (idx >= (int)fPhysProp.size()) { + fPhysProp.resize(idx+1); + fPhysProp[idx] = prop; + } else { + fPhysProp[idx] = prop; + } +} + +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +//------------------------------------------------------------------------------------------ +// PNeXusEntry2 Constructor +//------------------------------------------------------------------------------------------ +/** + *

+ */ +PNeXusEntry2::PNeXusEntry2() +{ + fDefinition = "n/a"; + fProgramName = "n/a"; + fProgramVersion = "n/a"; + fRunNumber = -1; + fTitle = "n/a"; + fStartTime = "n/a"; + fStopTime = "n/a"; + fExperimentIdentifier = "n/a"; +} + +//------------------------------------------------------------------------------------------ +// IsValid (public) +//------------------------------------------------------------------------------------------ +/** + *

Validates the NXentry data. + * + * \param strict flag if true a strict NeXus validation is performed. + */ +bool PNeXusEntry2::IsValid(bool strict) +{ + string msg(""); + + if (!fDefinition.compare("n/a")) { + msg = "IDF2 NXentry definition not set."; + if (strict) { + cerr << endl << ">> **ERROR** " << msg << endl; + return false; + } else { + cerr << endl << ">> **WARNING** " << msg << endl; + } + } + + if (fRunNumber == -1) { + msg = "run number not set."; + if (strict) { + cerr << endl << ">> **ERROR** " << msg << endl; + return false; + } else { + cerr << endl << ">> **WARNING** " << msg << endl; + } + } + + if (!fTitle.compare("n/a")) { + msg = "run title not set."; + if (strict) { + cerr << endl << ">> **ERROR** " << msg << endl; + return false; + } else { + cerr << endl << ">> **WARNING** " << msg << endl; + } + } + + if (!fStartTime.compare("n/a")) { + msg = "start time not set."; + if (strict) { + cerr << endl << ">> **ERROR** " << msg << endl; + return false; + } else { + cerr << endl << ">> **WARNING** " << msg << endl; + } + } + + if (!fStopTime.compare("n/a")) { + msg = "end time not set."; + if (strict) { + cerr << endl << ">> **ERROR** " << msg << endl; + return false; + } else { + cerr << endl << ">> **WARNING** " << msg << endl; + } + } + + if (!fExperimentIdentifier.compare("n/a")) { + msg = "experiment identifier not set."; + if (strict) { + cerr << endl << ">> **ERROR** " << msg << endl; + return false; + } else { + cerr << endl << ">> **WARNING** " << msg << endl; + } + } + + if (!fUser.IsValid(strict)) + return false; + + if (!fSample.IsValid(strict)) + return false; + + if (!fInstrument.IsValid(strict)) + return false; + + return true; +} + +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +//------------------------------------------------------------------------------------------ +// SetStartTime (public) +//------------------------------------------------------------------------------------------ +/** + *

Set the start time string and check that it is ISO 8601 conform. + * + * \param time start time string + */ +int PNeXusEntry2::SetStartTime(string time) +{ + struct tm tm; + memset(&tm, 0, sizeof(tm)); + strptime(time.c_str(), "%Y-%m-%d %H:%M:S", &tm); + if (tm.tm_year == 0) + strptime(time.c_str(), "%Y-%m-%dT%H:%M:S", &tm); + if (tm.tm_year == 0) + return NX_ERROR; + + fStartTime = time; + + return NX_OK; +} + +//------------------------------------------------------------------------------------------ +// SetStopTime (public) +//------------------------------------------------------------------------------------------ +/** + *

Set the stop time string and check that it is ISO 8601 conform. + * + * \param time stop time string + */ +int PNeXusEntry2::SetStopTime(string time) +{ + struct tm tm; + memset(&tm, 0, sizeof(tm)); + strptime(time.c_str(), "%Y-%m-%d %H:%M:S", &tm); + if (tm.tm_year == 0) + strptime(time.c_str(), "%Y-%m-%dT%H:%M:S", &tm); + if (tm.tm_year == 0) + return NX_ERROR; + + fStopTime = time; + + return NX_OK; +} + +//------------------------------------------------------------------------------------------ +// PNeXus Constructor +//------------------------------------------------------------------------------------------ +/** + *

*/ PNeXus::PNeXus() { Init(); } -//----------------------------------------------------------------------------------------------------- -// PNeXus constructor -//----------------------------------------------------------------------------------------------------- +//------------------------------------------------------------------------------------------ +// PNeXus Constructor +//------------------------------------------------------------------------------------------ /** - * + *

* * \param fileName */ PNeXus::PNeXus(const char* fileName) { Init(); + fFileName = fileName; + if (ReadFile(fileName) != NX_OK) { cerr << endl << fErrorMsg << " (error code=" << fErrorCode << ")" << endl << endl; } else { - fIsValid = true; + fValid = true; } } -//----------------------------------------------------------------------------------------------------- -// PNeXus destructor -//----------------------------------------------------------------------------------------------------- +//------------------------------------------------------------------------------------------ +// PNeXus Destructor +//------------------------------------------------------------------------------------------ /** - * + *

*/ PNeXus::~PNeXus() { - CleanUp(); + if (fNxEntry1) { + delete fNxEntry1; + fNxEntry1 = 0; + } + + for (unsigned int i=0; i + *

Define which IDF version shall be written/created. + * + * \param idf version number + */ +void PNeXus::SetIdfVersion(unsigned int idf) +{ + if ((idf != 1) && (idf != 2)) { + cerr << endl << ">> **ERROR** Only IDF versions 1 and 2 are supported." << endl; + return; + } + + fIdfVersion = idf; + + if (idf == 1) { // IDF 1 + if (fNxEntry2) { + delete fNxEntry2; + fNxEntry2 = 0; + } + + fNxEntry1 = new PNeXusEntry1(); + if (fNxEntry1 == 0) { + cerr << endl << ">> **ERROR** couldn't invoke IDF 1 object PNeXusEntry1." << endl; + return; + } + } else { // IDF 2 + if (fNxEntry1) { + delete fNxEntry1; + fNxEntry1 = 0; + } + + fNxEntry2 = new PNeXusEntry2(); + if (fNxEntry2 == 0) { + cerr << endl << ">> **ERROR** couldn't invoke IDF 2 object PNeXusEntry1." << endl; + return; + } + } +} + +//------------------------------------------------------------------------------------------ +// Init (public) +//------------------------------------------------------------------------------------------ +/** + *

Validates the NeXus data. A flag 'strict' controls the degree of validation. If 'strict' == true + * a full NeXus validation is done, otherwise a much sloppier validation is performed. This sloppier + * validation is needed when converting data. + * + * \param strict flag if true a strict NeXus validation is performed. + */ +bool PNeXus::IsValid(bool strict) +{ + bool valid = true; + + if (fIdfVersion == 1) // IDF Version 1 + valid = IsValidIdf1(strict); + else if (fIdfVersion == 2) // IDF Version 2 + valid = IsValidIdf2(strict); + else { + cerr << endl << ">> **ERROR** found IDF Version " << fIdfVersion << ", which is not implemented yet." << endl << endl; + valid = false; + } + + return valid; +} + +//------------------------------------------------------------------------------------------ +// GetGroupedHisto (public) +//------------------------------------------------------------------------------------------ +/** + *

Returns the grouped histogram if idx is within range, otherwise 0. + * + * \param idx index of the grouped histogram to be returned. + */ +vector* PNeXus::GetGroupedHisto(unsigned int idx) +{ + if (idx >= fGroupedHisto.size()) + return 0; + + return &fGroupedHisto[idx]; +} + +//------------------------------------------------------------------------------------------ +// ReadFile (public) +//------------------------------------------------------------------------------------------ +/** + *

Read the NeXus file 'fileName'. * * return: * - NX_OK on successfull reading * - NX_ERROR on error. The error code/message will give the details. * - * \param fileName + * \param fileName file name of the nexus file to be read */ int PNeXus::ReadFile(const char *fileName) { - int status, ival; - float fval; - string str(""); + fFileName = fileName; // open file + NXstatus status; status = NXopen(fileName, NXACC_READ, &fFileHandle); if (status != NX_OK) { fErrorCode = PNEXUS_FILE_OPEN_ERROR; @@ -120,443 +1662,90 @@ int PNeXus::ReadFile(const char *fileName) return NX_ERROR; } - // open group - status = NXopengroup(fFileHandle, "run", "NXentry"); + // get idf in order to decide which read routine needs to be used. + bool found = false; + NXname nxname, nxclass; + int dataType; + // 1) get the first NXentry + if (!SearchInGroup("NXentry", "class", nxname, nxclass, dataType)) { + fErrorCode = PNEXUS_NXENTRY_NOT_FOUND; + fErrorMsg = "PNeXus::ReadFile() **ERROR** Couldn't find any NXentry!"; + return NX_ERROR; + } + // 2) open the NXentry group to obtain the IDF + status = NXopengroup(fFileHandle, nxname, "NXentry"); if (status != NX_OK) { fErrorCode = PNEXUS_GROUP_OPEN_ERROR; - fErrorMsg = "PNeXus::ReadFile() **ERROR** Couldn't open NeXus group run!"; + fErrorMsg = "PNeXus::ReadFile() **ERROR** Couldn't open the NeXus group '" + string(nxname) + "'!"; return NX_ERROR; } - + // 3) get the IDF // IDF - if (NXopendata(fFileHandle, "idf_version") != NX_OK) { - if (NXopendata(fFileHandle, "IDF_version") != NX_OK) { - fErrorCode = PNEXUS_OPEN_DATA_ERROR; - fErrorMsg = "PNeXus::ReadFile() **ERROR** couldn't open 'IDF_version' nor 'idf_version' data!!"; - return NX_ERROR; - } - } - if (!ErrorHandler(NXgetdata(fFileHandle, &fIDFVersion), PNEXUS_GET_DATA_ERROR, "couldn't read 'IDF_version' data!")) return NX_ERROR; + found = false; + do { + status = NXgetnextentry(fFileHandle, nxname, nxclass, &dataType); + if ((strstr(nxname, "IDF_version") != NULL) || (strstr(nxname, "idf_version") != NULL)) + found = true; + } while (!found || (status == NX_EOD)); + + if (!ErrorHandler(NXopendata(fFileHandle, nxname), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'IDF_version' nor 'idf_version' data!!")) return NX_ERROR; + if (!ErrorHandler(NXgetdata(fFileHandle, &fIdfVersion), PNEXUS_GET_DATA_ERROR, "couldn't read 'idf_version' data!")) return NX_ERROR; if (!ErrorHandler(NXclosedata(fFileHandle), PNEXUS_CLOSE_DATA_ERROR, "couldn't close 'IDF_version' data")) return NX_ERROR; - - // program_name - if (!ErrorHandler(NXopendata(fFileHandle, "program_name"), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'program_name' data!")) return NX_ERROR; - if (!ErrorHandler(GetStringData(fProgramName), PNEXUS_GET_DATA_ERROR, "couldn't read 'program_name' data!")) return NX_ERROR; - if (!ErrorHandler(GetStringAttr("version", fProgramVersion), PNEXUS_GET_ATTR_ERROR, "couldn't read program_name attribute!")) return NX_ERROR; - if (!ErrorHandler(NXclosedata(fFileHandle), PNEXUS_CLOSE_DATA_ERROR, "couldn't close 'program_name' data")) return NX_ERROR; - - // run number - if (!ErrorHandler(NXopendata(fFileHandle, "number"), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'number' data!")) return NX_ERROR; - if (!ErrorHandler(NXgetdata(fFileHandle, &fRunNumber), PNEXUS_GET_DATA_ERROR, "couldn't read 'number' data!")) return NX_ERROR; - if (!ErrorHandler(NXclosedata(fFileHandle), PNEXUS_CLOSE_DATA_ERROR, "couldn't close 'number' data")) return NX_ERROR; - - // title - if (!ErrorHandler(NXopendata(fFileHandle, "title"), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'title' data!")) return NX_ERROR; - if (!ErrorHandler(GetStringData(fRunTitle), PNEXUS_GET_DATA_ERROR, "couldn't read 'title' data!")) return NX_ERROR; - if (!ErrorHandler(NXclosedata(fFileHandle), PNEXUS_CLOSE_DATA_ERROR, "couldn't close 'title' data")) return NX_ERROR; - - // notes - if (!ErrorHandler(NXopendata(fFileHandle, "notes"), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'notes' data!")) return NX_ERROR; - if (!ErrorHandler(GetStringData(fNotes), PNEXUS_GET_DATA_ERROR, "couldn't read 'notes' data!")) return NX_ERROR; - if (!ErrorHandler(NXclosedata(fFileHandle), PNEXUS_CLOSE_DATA_ERROR, "couldn't close 'notes' data")) return NX_ERROR; - - // analysis tag - if (!ErrorHandler(NXopendata(fFileHandle, "analysis"), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'analysis' data!")) return NX_ERROR; - if (!ErrorHandler(GetStringData(fAnalysisTag), PNEXUS_GET_DATA_ERROR, "couldn't read 'analysis' data!")) return NX_ERROR; - if (!ErrorHandler(NXclosedata(fFileHandle), PNEXUS_CLOSE_DATA_ERROR, "couldn't close 'analysis' data")) return NX_ERROR; - - // lab - if (!ErrorHandler(NXopendata(fFileHandle, "lab"), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'lab' data!")) return NX_ERROR; - if (!ErrorHandler(GetStringData(fLab), PNEXUS_GET_DATA_ERROR, "couldn't read 'lab' data!")) return NX_ERROR; - if (!ErrorHandler(NXclosedata(fFileHandle), PNEXUS_CLOSE_DATA_ERROR, "couldn't close 'lab' data")) return NX_ERROR; - - // beamline - if (!ErrorHandler(NXopendata(fFileHandle, "beamline"), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'beamline' data!")) return NX_ERROR; - if (!ErrorHandler(GetStringData(fBeamLine), PNEXUS_GET_DATA_ERROR, "couldn't read 'beamline' data!")) return NX_ERROR; - if (!ErrorHandler(NXclosedata(fFileHandle), PNEXUS_CLOSE_DATA_ERROR, "couldn't close 'beamline' data")) return NX_ERROR; - - // start time - if (!ErrorHandler(NXopendata(fFileHandle, "start_time"), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'start_time' data!")) return NX_ERROR; - if (!ErrorHandler(GetStringData(str), PNEXUS_GET_DATA_ERROR, "couldn't read 'start_time' data!")) return NX_ERROR; - if (!ErrorHandler(NXclosedata(fFileHandle), PNEXUS_CLOSE_DATA_ERROR, "couldn't close 'start_time' data")) return NX_ERROR; - size_t pos, pos1, pos2; - pos1 = str.find("T"); - pos2 = str.find(" "); - if ((pos1 == string::npos) && (pos2 == string::npos)) { - fErrorCode = PNEXUS_GET_DATA_ERROR; - fErrorMsg = "PNeXus::ReadFile() **ERROR** Wrong start date-time found (" + str + ")!"; - return NX_ERROR; - } - if (pos1 != string::npos) - pos = pos1; - else - pos = pos2; - fStartDate = str.substr(0, pos); - fStartTime = str.substr(pos+1, str.length()); - - // stop time - if (!ErrorHandler(NXopendata(fFileHandle, "stop_time"), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'start_time' data!")) return NX_ERROR; - if (!ErrorHandler(GetStringData(str), PNEXUS_GET_DATA_ERROR, "couldn't read 'start_time' data!")) return NX_ERROR; - if (!ErrorHandler(NXclosedata(fFileHandle), PNEXUS_CLOSE_DATA_ERROR, "couldn't close 'start_time' data")) return NX_ERROR; - pos1 = str.find("T"); - pos2 = str.find(" "); - if ((pos1 == string::npos) && (pos2 == string::npos)) { - fErrorCode = PNEXUS_GET_DATA_ERROR; - fErrorMsg = "PNeXus::ReadFile() **ERROR** Wrong stop date-time found (" + str + ")!"; - return NX_ERROR; - } - if (pos1 != string::npos) - pos = pos1; - else - pos = pos2; - fStopDate = str.substr(0, pos); - fStopTime = str.substr(pos+1, str.length()); - - // switching state (red/green mode) - if (!ErrorHandler(NXopendata(fFileHandle, "switching_states"), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'switching_states' data!")) return NX_ERROR; - if (!ErrorHandler(NXgetdata(fFileHandle, &fSwitchingState), PNEXUS_GET_DATA_ERROR, "couldn't read 'switching_states' data!")) return NX_ERROR; - if (!ErrorHandler(NXclosedata(fFileHandle), PNEXUS_CLOSE_DATA_ERROR, "couldn't close 'switching_states' data")) return NX_ERROR; - - // open subgroup NXuser - if (!ErrorHandler(NXopengroup(fFileHandle, "user", "NXuser"), PNEXUS_GROUP_OPEN_ERROR, "couldn't open NeXus subgroup user!")) return NX_ERROR; - - // change to subgroup - if (!ErrorHandler(NXinitgroupdir(fFileHandle), PNEXUS_INIT_GROUPDIR_ERROR, "couldn't init group directory")) return NX_ERROR; - int numItems = 0; - NXname groupName, className; - if (!ErrorHandler(NXgetgroupinfo(fFileHandle, &numItems, groupName, className), PNEXUS_GET_GROUP_INFO_ERROR, "couldn't get user group info")) return NX_ERROR; - - // get all the user info - // initialize the user data set - fUser.fUserName = ""; - fUser.fExperimentNumber = ""; - // go through the user list and filter out the required items - NXname nx_label; - int nx_dataType; - for (int i=0; i("available"), &fSample.fMagneticFieldVectorAvailable, &attLen, &attType), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'magnetic_field_vector available' data in sample group!")) return NX_ERROR; - if (fSample.fMagneticFieldVectorAvailable) { - if (!ErrorHandler(GetDoubleVectorData(fSample.fMagneticFieldVector), PNEXUS_GET_DATA_ERROR, "couldn't get 'magnetic_field_vector' data!")) return NX_ERROR; - } - if (!ErrorHandler(NXclosedata(fFileHandle), PNEXUS_CLOSE_DATA_ERROR, "couldn't close 'magnetic_field_vector' data in sample group")) return NX_ERROR; - - // read sample environment, e.g. CCR, LowTemp-2, etc. - if (!ErrorHandler(NXopendata(fFileHandle, "environment"), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'environment' data in sample group!")) return NX_ERROR; - if (!ErrorHandler(GetStringData(str), PNEXUS_GET_DATA_ERROR, "couldn't read 'environment' data in sample group!")) return NX_ERROR; - if (!ErrorHandler(NXclosedata(fFileHandle), PNEXUS_CLOSE_DATA_ERROR, "couldn't close 'environment' data in sample group")) return NX_ERROR; - fSample.fEnvironment = str; - - // close subgroup NXsample - NXclosegroup(fFileHandle); - - // get required instrument information - // open subgroup NXinstrument with subgroups detector, collimator, beam - if (!ErrorHandler(NXopengroup(fFileHandle, "instrument", "NXinstrument"), PNEXUS_GROUP_OPEN_ERROR, "couldn't open NeXus subgroup instrument!")) return NX_ERROR; - - // get instrument name - if (!ErrorHandler(NXopendata(fFileHandle, "name"), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'name' data in instrument group!")) return NX_ERROR; - if (!ErrorHandler(GetStringData(str), PNEXUS_GET_DATA_ERROR, "couldn't read 'name' data in instrument group!")) return NX_ERROR; - if (!ErrorHandler(NXclosedata(fFileHandle), PNEXUS_CLOSE_DATA_ERROR, "couldn't close 'name' data in instrument group")) return NX_ERROR; - fInstrument.name = str; - - // open subgroup NXdetector - if (!ErrorHandler(NXopengroup(fFileHandle, "detector", "NXdetector"), PNEXUS_GROUP_OPEN_ERROR, "couldn't open NeXus subgroup detector!")) return NX_ERROR; - - // get number of detectors - if (!ErrorHandler(NXopendata(fFileHandle, "number"), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'number' data in detector group!")) return NX_ERROR; - if (!ErrorHandler(NXgetdata(fFileHandle, &ival), PNEXUS_GET_DATA_ERROR, "couldn't read 'number' data in detector group!")) return NX_ERROR; - if (!ErrorHandler(NXclosedata(fFileHandle), PNEXUS_CLOSE_DATA_ERROR, "couldn't close 'number' data in detector group")) return NX_ERROR; - fInstrument.detector.number = ival; - - // close subgroup NXdetector - NXclosegroup(fFileHandle); - - // open subgroup NXcollimator - if (!ErrorHandler(NXopengroup(fFileHandle, "collimator", "NXcollimator"), PNEXUS_GROUP_OPEN_ERROR, "couldn't open NeXus subgroup collimator!")) return NX_ERROR; - - // get collimator type - if (!ErrorHandler(NXopendata(fFileHandle, "type"), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'type' data in collimator group!")) return NX_ERROR; - if (!ErrorHandler(GetStringData(str), PNEXUS_GET_DATA_ERROR, "couldn't read 'type' data in collimator group!")) return NX_ERROR; - if (!ErrorHandler(NXclosedata(fFileHandle), PNEXUS_CLOSE_DATA_ERROR, "couldn't close 'type' data in collimator group")) return NX_ERROR; - fInstrument.collimator.type = str; - - // close subgroup NXcollimator - NXclosegroup(fFileHandle); - - // open subgroup NXbeam - if (!ErrorHandler(NXopengroup(fFileHandle, "beam", "NXbeam"), PNEXUS_GROUP_OPEN_ERROR, "couldn't open NeXus subgroup beam!")) return NX_ERROR; - - // get the total counts - if (!ErrorHandler(NXopendata(fFileHandle, "total_counts"), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'total_counts' data in beam group!")) return NX_ERROR; - if (!ErrorHandler(NXgetdata(fFileHandle, &fval), PNEXUS_GET_DATA_ERROR, "couldn't read 'total_counts' data in beam group!")) return NX_ERROR; - fInstrument.beam.total_counts = (double)fval; - if (!ErrorHandler(GetStringAttr("units", str), PNEXUS_GET_ATTR_ERROR, "couldn't read total_counts units!")) return NX_ERROR; - fInstrument.beam.total_counts_units = str; - if (!ErrorHandler(NXclosedata(fFileHandle), PNEXUS_CLOSE_DATA_ERROR, "couldn't close 'total_counts' data in beam group")) return NX_ERROR; - - // close subgroup NXbeam - NXclosegroup(fFileHandle); - - // close subgroup NXinstrument - NXclosegroup(fFileHandle); - - // open subgroup NXdata (this is for Version 1, only and is subject to change in the near future!) - if (!ErrorHandler(NXopengroup(fFileHandle, "histogram_data_1", "NXdata"), PNEXUS_GROUP_OPEN_ERROR, "couldn't open NeXus subgroup histogram_data_1!")) return NX_ERROR; - - // get time resolution - if (!ErrorHandler(NXopendata(fFileHandle, "resolution"), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'resolution' data in histogram_data_1 group!")) return NX_ERROR; - if (!ErrorHandler(NXgetdata(fFileHandle, &ival), PNEXUS_GET_DATA_ERROR, "couldn't read 'resolution' data in histogram_data_1 group!")) return NX_ERROR; - if (!ErrorHandler(GetStringAttr("units", str), PNEXUS_GET_ATTR_ERROR, "couldn't read 'resolution'' units!")) return NX_ERROR; - if (!ErrorHandler(NXclosedata(fFileHandle), PNEXUS_CLOSE_DATA_ERROR, "couldn't close 'resolution' data in histogram_data_1 group")) return NX_ERROR; - if (!strcmp(str.data(), "picoseconds")) { - fData.fTimeResolution = (double)ival/1000.0; // time resolution in (ns) - } - - // get data, t0, first good bin, last good bin, data - if (!ErrorHandler(NXopendata(fFileHandle, "counts"), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'counts' data in histogram_data_1 group!")) return NX_ERROR; - int histoLength=0; - - // get number of histos - attLen = SIZE_INT32; - attType = NX_INT32; - if (!ErrorHandler(NXgetattr(fFileHandle, const_cast("number"), &fData.fNumberOfHistos, &attLen, &attType), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'number' data in histogram_data_1 group!")) return NX_ERROR; - - // get histo length - attLen = SIZE_INT32; - attType = NX_INT32; - if (!ErrorHandler(NXgetattr(fFileHandle, const_cast("length"), &histoLength, &attLen, &attType), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'number' data in histogram_data_1 group!")) return NX_ERROR; - - // get t0 - attLen = SIZE_INT32; - attType = NX_INT32; - if (!ErrorHandler(NXgetattr(fFileHandle, const_cast("t0_bin"), &ival, &attLen, &attType), PNEXUS_OPEN_DATA_ERROR, "couldn't open 't0_bin' data in histogram_data_1 group!")) return NX_ERROR; - fData.fT0.push_back(ival); - - // get first good bin - attLen = SIZE_INT32; - attType = NX_INT32; - if (!ErrorHandler(NXgetattr(fFileHandle, const_cast("first_good_bin"), &ival, &attLen, &attType), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'first_good_bin' data in histogram_data_1 group!")) return NX_ERROR; - fData.fFirstGoodBin.push_back(ival); - - // get last good bin - attLen = SIZE_INT32; - attType = NX_INT32; - if (!ErrorHandler(NXgetattr(fFileHandle, const_cast("last_good_bin"), &ival, &attLen, &attType), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'last_good_bin' data in histogram_data_1 group!")) return NX_ERROR; - fData.fLastGoodBin.push_back(ival); - - // get data - - // get information of the current nexus entity - int rank, type, dims[32], size, noOfElements; - if (!ErrorHandler(NXgetinfo(fFileHandle, &rank, dims, &type), PNEXUS_GET_META_INFO_ERROR, "couldn't get data info!")) return NX_ERROR; - - // calculate the needed size - size = dims[0]; - for (int i=1; i data; - for (int i=0; i0)) { - fData.fHisto.push_back(data); - data.clear(); - data.push_back(*(i_data_ptr+i)); - } else { - data.push_back(*(i_data_ptr+i)); - } - } - fData.fHisto.push_back(data); - data.clear(); - - // clean up - if (data_ptr) { - delete [] data_ptr; - } - - if (!ErrorHandler(NXclosedata(fFileHandle), PNEXUS_CLOSE_DATA_ERROR, "couldn't close 'counts' data in histogram_data_1 group")) return NX_ERROR; - - // get grouping - if (!ErrorHandler(NXopendata(fFileHandle, "grouping"), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'grouping' data in histogram_data_1 group!")) return NX_ERROR; - attLen = SIZE_INT32; - attType = NX_INT32; - if (!ErrorHandler(NXgetattr(fFileHandle, const_cast("available"), &ival, &attLen, &attType), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'grouping available' data in histogram_data_1 group!")) return NX_ERROR; - if (ival) { - vector grouping; - if (!ErrorHandler(GetIntVectorData(grouping), PNEXUS_GET_DATA_ERROR, "couldn't read 'grouping' data in histogram_data_1 group!")) return NX_ERROR; - for (unsigned int i=0; i("available"), &ival, &attLen, &attType), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'alpha available' data in histogram_data_1 group!")) return NX_ERROR; - if (ival) { - if (!ErrorHandler(NXgetinfo(fFileHandle, &rank, dims, &type), PNEXUS_GET_META_INFO_ERROR, "couldn't get alpha info!")) return NX_ERROR; - // calculate the needed size - size = dims[0]; - for (int i=1; i> **ERROR** idf_version=" << fIdfVersion << " not yet implemented."; + fErrorMsg = ss.str(); + status = NX_ERROR; + break; + } - fIsValid = true; - - return true; + return status; } -//----------------------------------------------------------------------------------------------------- +//------------------------------------------------------------------------------------------ // WriteFile (public) -//----------------------------------------------------------------------------------------------------- +//------------------------------------------------------------------------------------------ /** - *

+ *

Write the NeXus file 'fileName', with the 'fileType' (HDF4 | HDF5 | XML) and the instrument + * definition (1 | 2). * * return: - * - NX_OK on successfull writing + * - NX_OK on successfull reading * - NX_ERROR on error. The error code/message will give the details. * - * \param fileName - * \param fileType, allowed types are: hdf4, hdf5, xml + * \param fileName file name of the nexus file to be written + * \param fileType = HDF4 | HDF5 | XML + * \param idf = 1 or 2 */ -int PNeXus::WriteFile(const char *fileName, const char *fileType) +int PNeXus::WriteFile(const char *fileName, const char *fileType, const unsigned int idf) { - char str[256]; - int size, idata; - float fdata; + if (!IsValid()) { + return NX_ERROR; + } + + int status = NX_OK; NXaccess access=NXACC_CREATE4; if (!strcmp(fileType, "hdf4")) @@ -568,810 +1757,312 @@ int PNeXus::WriteFile(const char *fileName, const char *fileType) else access=NXACC_CREATE4; - sprintf(str, "couldn't open file '%s' for writing", fileName); - if (!ErrorHandler(NXopen(fileName, access, &fFileHandle), PNEXUS_FILE_OPEN_ERROR, str)) return NX_ERROR; - - // write NXfile attributes (NeXus_version, user) - strncpy(str, fUser.fUserName.data(), sizeof(str)); - if (!ErrorHandler(NXputattr(fFileHandle, "user", str, strlen(str), NX_CHAR), PNEXUS_SET_ATTR_ERROR, "couldn't set NXfile attributes")) return NX_ERROR; - - // make group 'run' - if (!ErrorHandler(NXmakegroup(fFileHandle, "run", "NXentry"), PNEXUS_CREATE_GROUP_ERROR, "couldn't create group 'run'.")) return NX_ERROR; - // open group 'run' - if (!ErrorHandler(NXopengroup(fFileHandle, "run", "NXentry"), PNEXUS_GROUP_OPEN_ERROR, "couldn't open group 'run' for writting.")) return NX_ERROR; - - // write IDF_version - size = 1; - if (!ErrorHandler(NXmakedata(fFileHandle, "IDF_version", NX_INT32, 1, &size), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'IDF_version'.")) return NX_ERROR; - if (!ErrorHandler(NXopendata(fFileHandle, "IDF_version"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'IDF_version' for writting.")) return NX_ERROR; - idata = fIDFVersion; - if (!ErrorHandler(NXputdata(fFileHandle, &idata), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'IDF_version'.")) return NX_ERROR; - NXclosedata(fFileHandle); - - // write program_name, and attribute version - size = fProgramName.length(); - if (!ErrorHandler(NXmakedata(fFileHandle, "program_name", NX_CHAR, 1, &size), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'program_name'.")) return NX_ERROR; - if (!ErrorHandler(NXopendata(fFileHandle, "program_name"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'program_name' for writting.")) return NX_ERROR; - strncpy(str, fProgramName.data(), sizeof(str)); - if (!ErrorHandler(NXputdata(fFileHandle, str), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'program_name'.")) return NX_ERROR; - strncpy(str, fProgramVersion.data(), sizeof(str)); - if (!ErrorHandler(NXputattr(fFileHandle, "version", str, strlen(str), NX_CHAR), PNEXUS_PUT_ATTR_ERROR, "couldn't put attribute 'version' for 'program_name'")) return NX_ERROR; - NXclosedata(fFileHandle); - - // write run 'number' - size = 1; - if (!ErrorHandler(NXmakedata(fFileHandle, "number", NX_INT32, 1, &size), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'number'.")) return NX_ERROR; - if (!ErrorHandler(NXopendata(fFileHandle, "number"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'number' for writting.")) return NX_ERROR; - idata = fRunNumber; - if (!ErrorHandler(NXputdata(fFileHandle, &idata), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'number'.")) return NX_ERROR; - NXclosedata(fFileHandle); - - // write run 'title' - size = fRunTitle.length(); - if (!ErrorHandler(NXmakedata(fFileHandle, "title", NX_CHAR, 1, &size), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'title'.")) return NX_ERROR; - if (!ErrorHandler(NXopendata(fFileHandle, "title"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'title' for writting.")) return NX_ERROR; - strncpy(str, fRunTitle.data(), sizeof(str)); - if (!ErrorHandler(NXputdata(fFileHandle, str), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'title'.")) return NX_ERROR; - NXclosedata(fFileHandle); - - // write run 'notes' - size = fNotes.length(); - if (!ErrorHandler(NXmakedata(fFileHandle, "notes", NX_CHAR, 1, &size), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'notes'.")) return NX_ERROR; - if (!ErrorHandler(NXopendata(fFileHandle, "notes"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'notes' for writting.")) return NX_ERROR; - strncpy(str, fNotes.data(), sizeof(str)); - if (!ErrorHandler(NXputdata(fFileHandle, str), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'notes'.")) return NX_ERROR; - NXclosedata(fFileHandle); - - // write run 'analysis' - size = fAnalysisTag.length(); - if (!ErrorHandler(NXmakedata(fFileHandle, "analysis", NX_CHAR, 1, &size), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'analysis'.")) return NX_ERROR; - if (!ErrorHandler(NXopendata(fFileHandle, "analysis"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'analysis' for writting.")) return NX_ERROR; - strncpy(str, fAnalysisTag.data(), sizeof(str)); - if (!ErrorHandler(NXputdata(fFileHandle, str), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'analysis'.")) return NX_ERROR; - NXclosedata(fFileHandle); - - // write run 'lab' - size = fLab.length(); - if (!ErrorHandler(NXmakedata(fFileHandle, "lab", NX_CHAR, 1, &size), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'lab'.")) return NX_ERROR; - if (!ErrorHandler(NXopendata(fFileHandle, "lab"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'lab' for writting.")) return NX_ERROR; - strncpy(str, fLab.data(), sizeof(str)); - if (!ErrorHandler(NXputdata(fFileHandle, str), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'lab'.")) return NX_ERROR; - NXclosedata(fFileHandle); - - // write run 'beamline' - size = fBeamLine.length(); - if (!ErrorHandler(NXmakedata(fFileHandle, "beamline", NX_CHAR, 1, &size), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'beamline'.")) return NX_ERROR; - if (!ErrorHandler(NXopendata(fFileHandle, "beamline"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'beamline' for writting.")) return NX_ERROR; - strncpy(str, fBeamLine.data(), sizeof(str)); - if (!ErrorHandler(NXputdata(fFileHandle, str), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'beamline'.")) return NX_ERROR; - NXclosedata(fFileHandle); - - // write run 'start_time' - snprintf(str, sizeof(str), "%s %s", fStartDate.data(), fStartTime.data()); - size = strlen(str); - if (!ErrorHandler(NXmakedata(fFileHandle, "start_time", NX_CHAR, 1, &size), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'start_time'.")) return NX_ERROR; - if (!ErrorHandler(NXopendata(fFileHandle, "start_time"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'start_time' for writting.")) return NX_ERROR; - if (!ErrorHandler(NXputdata(fFileHandle, str), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'start_time'.")) return NX_ERROR; - NXclosedata(fFileHandle); - - // write run 'end_time' - snprintf(str, sizeof(str), "%s %s", fStopDate.data(), fStopTime.data()); - size = strlen(str); - if (!ErrorHandler(NXmakedata(fFileHandle, "end_time", NX_CHAR, 1, &size), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'end_time'.")) return NX_ERROR; - if (!ErrorHandler(NXopendata(fFileHandle, "end_time"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'end_time' for writting.")) return NX_ERROR; - if (!ErrorHandler(NXputdata(fFileHandle, str), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'end_time'.")) return NX_ERROR; - NXclosedata(fFileHandle); - - // write run 'switching_states' - size = 1; - if (!ErrorHandler(NXmakedata(fFileHandle, "switching_states", NX_INT32, 1, &size), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'switching_states'.")) return NX_ERROR; - if (!ErrorHandler(NXopendata(fFileHandle, "switching_states"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'switching_states' for writting.")) return NX_ERROR; - idata = fSwitchingState; - if (!ErrorHandler(NXputdata(fFileHandle, &idata), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'switching_states'.")) return NX_ERROR; - NXclosedata(fFileHandle); - - - // make group 'user' - if (!ErrorHandler(NXmakegroup(fFileHandle, "user", "NXuser"), PNEXUS_CREATE_GROUP_ERROR, "couldn't create group 'user'.")) return NX_ERROR; - // open group 'user' - if (!ErrorHandler(NXopengroup(fFileHandle, "user", "NXuser"), PNEXUS_GROUP_OPEN_ERROR, "couldn't open group 'user' for writting.")) return NX_ERROR; - - // write user 'name' - size = fUser.fUserName.length(); - if (!ErrorHandler(NXmakedata(fFileHandle, "name", NX_CHAR, 1, &size), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'name'.")) return NX_ERROR; - if (!ErrorHandler(NXopendata(fFileHandle, "name"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'name' for writting.")) return NX_ERROR; - strncpy(str, fUser.fUserName.data(), sizeof(str)); - if (!ErrorHandler(NXputdata(fFileHandle, str), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'name'.")) return NX_ERROR; - NXclosedata(fFileHandle); - - // write user 'experiment_number' - size = fUser.fExperimentNumber.length(); - if (!ErrorHandler(NXmakedata(fFileHandle, "experiment_number", NX_CHAR, 1, &size), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'experiment_number'.")) return NX_ERROR; - if (!ErrorHandler(NXopendata(fFileHandle, "experiment_number"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'experiment_number' for writting.")) return NX_ERROR; - strncpy(str, fUser.fExperimentNumber.data(), sizeof(str)); - if (!ErrorHandler(NXputdata(fFileHandle, str), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'experiment_number'.")) return NX_ERROR; - NXclosedata(fFileHandle); - - // close group 'user' - NXclosegroup(fFileHandle); - - // make group 'sample' - if (!ErrorHandler(NXmakegroup(fFileHandle, "sample", "NXuser"), PNEXUS_CREATE_GROUP_ERROR, "couldn't create group 'sample'.")) return NX_ERROR; - // open group 'sample' - if (!ErrorHandler(NXopengroup(fFileHandle, "sample", "NXuser"), PNEXUS_GROUP_OPEN_ERROR, "couldn't open group 'sample' for writting.")) return NX_ERROR; - - // write sample 'name' - size = fSample.fName.length(); - if (!ErrorHandler(NXmakedata(fFileHandle, "name", NX_CHAR, 1, &size), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'name'.")) return NX_ERROR; - if (!ErrorHandler(NXopendata(fFileHandle, "name"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'name' for writting.")) return NX_ERROR; - strncpy(str, fSample.fName.data(), sizeof(str)); - if (!ErrorHandler(NXputdata(fFileHandle, str), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'name'.")) return NX_ERROR; - NXclosedata(fFileHandle); - - // write sample 'temperature' - size = 1; - if (!ErrorHandler(NXmakedata(fFileHandle, "temperature", NX_FLOAT32, 1, &size), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'temperature'.")) return NX_ERROR; - if (!ErrorHandler(NXopendata(fFileHandle, "temperature"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'temperature' for writting.")) return NX_ERROR; - fdata = fSample.fTemperature; - if (!ErrorHandler(NXputdata(fFileHandle, &fdata), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'temperature'.")) return NX_ERROR; - strncpy(str, fSample.fTemperatureUnit.data(), sizeof(str)); - if (!ErrorHandler(NXputattr(fFileHandle, "units", str, strlen(str), NX_CHAR), PNEXUS_PUT_ATTR_ERROR, "couldn't put attribute 'units' for 'temperature'")) return NX_ERROR; - NXclosedata(fFileHandle); - - // write sample 'magnetic_field' - size = 1; - if (!ErrorHandler(NXmakedata(fFileHandle, "magnetic_field", NX_FLOAT32, 1, &size), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'magnetic_field'.")) return NX_ERROR; - if (!ErrorHandler(NXopendata(fFileHandle, "magnetic_field"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'magnetic_field' for writting.")) return NX_ERROR; - fdata = fSample.fMagneticField; - if (!ErrorHandler(NXputdata(fFileHandle, &fdata), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'magnetic_field'.")) return NX_ERROR; - strncpy(str, fSample.fMagneticFieldUnit.data(), sizeof(str)); - if (!ErrorHandler(NXputattr(fFileHandle, "units", str, strlen(str), NX_CHAR), PNEXUS_PUT_ATTR_ERROR, "couldn't put attribute 'units' for 'magnetic_field'")) return NX_ERROR; - NXclosedata(fFileHandle); - - // write sample 'shape' - size = fSample.fShape.length(); - if (!ErrorHandler(NXmakedata(fFileHandle, "shape", NX_CHAR, 1, &size), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'shape'.")) return NX_ERROR; - if (!ErrorHandler(NXopendata(fFileHandle, "shape"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'shape' for writting.")) return NX_ERROR; - strncpy(str, fSample.fShape.data(), sizeof(str)); - if (!ErrorHandler(NXputdata(fFileHandle, str), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'shape'.")) return NX_ERROR; - NXclosedata(fFileHandle); - - // write sample 'magnetic_field_state' - size = fSample.fMagneticFieldState.length(); - if (!ErrorHandler(NXmakedata(fFileHandle, "magnetic_field_state", NX_CHAR, 1, &size), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'magnetic_field_state'.")) return NX_ERROR; - if (!ErrorHandler(NXopendata(fFileHandle, "magnetic_field_state"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'magnetic_field_state' for writting.")) return NX_ERROR; - strncpy(str, fSample.fMagneticFieldState.data(), sizeof(str)); - if (!ErrorHandler(NXputdata(fFileHandle, str), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'magnetic_field_state'.")) return NX_ERROR; - NXclosedata(fFileHandle); - - // write sample 'magnetic_field_vector' - // !! TO BE DONE !! - - // write sample 'environment' - size = fSample.fEnvironment.length(); - if (!ErrorHandler(NXmakedata(fFileHandle, "environment", NX_CHAR, 1, &size), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'environment'.")) return NX_ERROR; - if (!ErrorHandler(NXopendata(fFileHandle, "environment"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'environment' for writting.")) return NX_ERROR; - strncpy(str, fSample.fEnvironment.data(), sizeof(str)); - if (!ErrorHandler(NXputdata(fFileHandle, str), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'environment'.")) return NX_ERROR; - NXclosedata(fFileHandle); - - // close group 'sample' - NXclosegroup(fFileHandle); - - // make group 'instrument' - if (!ErrorHandler(NXmakegroup(fFileHandle, "instrument", "NXinstrument"), PNEXUS_CREATE_GROUP_ERROR, "couldn't create group 'instrument'.")) return NX_ERROR; - // open group 'instrument' - if (!ErrorHandler(NXopengroup(fFileHandle, "instrument", "NXinstrument"), PNEXUS_GROUP_OPEN_ERROR, "couldn't open group 'instrument' for writting.")) return NX_ERROR; - - // write instrument 'name' - size = fInstrument.name.length(); - if (!ErrorHandler(NXmakedata(fFileHandle, "name", NX_CHAR, 1, &size), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'name'.")) return NX_ERROR; - if (!ErrorHandler(NXopendata(fFileHandle, "name"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'name' for writting.")) return NX_ERROR; - strncpy(str, fInstrument.name.data(), sizeof(str)); - if (!ErrorHandler(NXputdata(fFileHandle, str), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'name'.")) return NX_ERROR; - NXclosedata(fFileHandle); - - // make group 'detector' - if (!ErrorHandler(NXmakegroup(fFileHandle, "detector", "NXdetector"), PNEXUS_CREATE_GROUP_ERROR, "couldn't create group 'detector'.")) return NX_ERROR; - // open group 'detector' - if (!ErrorHandler(NXopengroup(fFileHandle, "detector", "NXdetector"), PNEXUS_GROUP_OPEN_ERROR, "couldn't open group 'detector' for writting.")) return NX_ERROR; - - // write detector 'number' - size = 1; - if (!ErrorHandler(NXmakedata(fFileHandle, "number", NX_INT32, 1, &size), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'number'.")) return NX_ERROR; - if (!ErrorHandler(NXopendata(fFileHandle, "number"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'number' for writting.")) return NX_ERROR; - idata = fInstrument.detector.number; - if (!ErrorHandler(NXputdata(fFileHandle, &idata), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'number'.")) return NX_ERROR; - NXclosedata(fFileHandle); - - // close group 'detector' - NXclosegroup(fFileHandle); - - // make group 'collimator' - if (!ErrorHandler(NXmakegroup(fFileHandle, "collimator", "NXcollimator"), PNEXUS_CREATE_GROUP_ERROR, "couldn't create group 'collimator'.")) return NX_ERROR; - // open group 'collimator' - if (!ErrorHandler(NXopengroup(fFileHandle, "collimator", "NXcollimator"), PNEXUS_GROUP_OPEN_ERROR, "couldn't open group 'collimator' for writting.")) return NX_ERROR; - - // write collimator 'type' - size = fInstrument.collimator.type.length(); - if (!ErrorHandler(NXmakedata(fFileHandle, "type", NX_CHAR, 1, &size), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'type'.")) return NX_ERROR; - if (!ErrorHandler(NXopendata(fFileHandle, "type"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'type' for writting.")) return NX_ERROR; - strncpy(str, fInstrument.collimator.type.data(), sizeof(str)); - if (!ErrorHandler(NXputdata(fFileHandle, str), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'type'.")) return NX_ERROR; - NXclosedata(fFileHandle); - - // close group 'collimator' - NXclosegroup(fFileHandle); - - // make group 'beam' - if (!ErrorHandler(NXmakegroup(fFileHandle, "beam", "NXbeam"), PNEXUS_CREATE_GROUP_ERROR, "couldn't create group 'beam'.")) return NX_ERROR; - // open group 'beam' - if (!ErrorHandler(NXopengroup(fFileHandle, "beam", "NXbeam"), PNEXUS_GROUP_OPEN_ERROR, "couldn't open group 'beam' for writting.")) return NX_ERROR; - - size = 1; - if (!ErrorHandler(NXmakedata(fFileHandle, "total_counts", NX_FLOAT32, 1, &size), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'total_counts'.")) return NX_ERROR; - if (!ErrorHandler(NXopendata(fFileHandle, "total_counts"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'total_counts' for writting.")) return NX_ERROR; - fdata = fInstrument.beam.total_counts; - if (!ErrorHandler(NXputdata(fFileHandle, &fdata), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'total_counts'.")) return NX_ERROR; - strncpy(str, fInstrument.beam.total_counts_units.data(), sizeof(str)); - if (!ErrorHandler(NXputattr(fFileHandle, "units", str, strlen(str), NX_CHAR), PNEXUS_PUT_ATTR_ERROR, "couldn't put attribute 'units' for 'total_counts'")) return NX_ERROR; - NXclosedata(fFileHandle); - - // close group 'beam' - NXclosegroup(fFileHandle); - - // close group 'instrument' - NXclosegroup(fFileHandle); - - // make group 'histogram_data_1' - if (!ErrorHandler(NXmakegroup(fFileHandle, "histogram_data_1", "NXdata"), PNEXUS_CREATE_GROUP_ERROR, "couldn't create group 'histogram_data_1'.")) return NX_ERROR; - // open group 'histogram_data_1' - if (!ErrorHandler(NXopengroup(fFileHandle, "histogram_data_1", "NXdata"), PNEXUS_GROUP_OPEN_ERROR, "couldn't open group 'histogram_data_1' for writting.")) return NX_ERROR; - - // write data 'counts' - int *histo_data=0; - int histo_size[2]; - if (fData.fHisto.size() == 0) { - histo_data = new int[1]; - histo_data[0] = -1; - histo_size[0] = 1; - histo_size[1] = 1; - } else { - histo_data = new int[fData.fHisto.size()*fData.fHisto[0].size()]; - for (unsigned int i=0; i ps - if (!ErrorHandler(NXputdata(fFileHandle, &fdata), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'histogram_resolution'.")) return NX_ERROR; - strncpy(str, "picoseconds", sizeof(str)); - if (!ErrorHandler(NXputattr(fFileHandle, "units", str, strlen(str), NX_CHAR), PNEXUS_PUT_ATTR_ERROR, "couldn't put attribute 'units' for 'histogram_resolution'")) return NX_ERROR; - NXclosedata(fFileHandle); - - // write data 'time_zero' always set to 0 since the T0_bin attribute of counts is relevant only - if (!ErrorHandler(NXmakedata(fFileHandle, "time_zero", NX_FLOAT32, 1, &size), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'time_zero'.")) return NX_ERROR; - if (!ErrorHandler(NXopendata(fFileHandle, "time_zero"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'time_zero' for writting.")) return NX_ERROR; - fdata = 0.0; - if (!ErrorHandler(NXputdata(fFileHandle, &fdata), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'time_zero'.")) return NX_ERROR; - strncpy(str, "microseconds", sizeof(str)); - if (!ErrorHandler(NXputattr(fFileHandle, "units", str, strlen(str), NX_CHAR), PNEXUS_PUT_ATTR_ERROR, "couldn't put attribute 'units' for 'time_zero'")) return NX_ERROR; - idata = 0; - if (!ErrorHandler(NXputattr(fFileHandle, "available", &idata, 1, NX_INT32), PNEXUS_PUT_ATTR_ERROR, "couldn't put attribute 'available' for 'time_zero'")) return NX_ERROR; - NXclosedata(fFileHandle); - - // write data 'raw_time' - if (fData.fHisto.size() == 0) { - fErrorCode = PNEXUS_HISTO_ERROR; - fErrorMsg = "no data for writing present."; - return NX_ERROR; - } - float *raw_time = new float[fData.fHisto[0].size()-1]; - for (unsigned int i=0; i groupNo; // keep the number of different groupings - if (fData.fHisto.size() == fData.fGrouping.size()) { // grouping vector seems to be properly defined - bool found; - groupNo.push_back(fData.fGrouping[0]); - for (unsigned int i=0; iDump read data to the standard output. + *

Write the content of the NeXus file to stdout. Used for debugging purposes. + * */ void PNeXus::Dump() { - cout << endl << "-----------------------------"; - cout << endl << " NeXus Dump"; - cout << endl << "-----------------------------"; - cout << endl; - cout << endl << "file name : " << fFileName; - cout << endl << "IDF version : " << fIDFVersion; - cout << endl << "program name : " << fProgramName << ", version : " << fProgramVersion; - cout << endl << "run number : " << fRunNumber; - cout << endl << "run title : " << fRunTitle; - cout << endl << "run notes : " << fNotes; - cout << endl << "analysis : " << fAnalysisTag; - cout << endl << "lab : " << fLab; - cout << endl << "beamline : " << fBeamLine; - cout << endl << "start date/time : " << fStartDate << "/" << fStartTime; - cout << endl << "stop date/time : " << fStopDate << "/" << fStopTime; - cout << endl << "switching state : " << fSwitchingState << " (red/green mode)"; - cout << endl << "-----------------------------"; - cout << endl << "user info"; - cout << endl << "user : " << fUser.fUserName; - cout << endl << "exp. number : " << fUser.fExperimentNumber; - cout << endl << "-----------------------------"; - cout << endl << "sample info"; - cout << endl << "sample name : " << fSample.fName; - cout << endl << "temperature : " << fSample.fTemperature << " (" << fSample.fTemperatureUnit << ")"; - cout << endl << "magnetic state : " << fSample.fMagneticFieldState; - cout << endl << "magnetic field : " << fSample.fMagneticField << " (" << fSample.fMagneticFieldUnit << ")"; - cout << endl << "mag. vector : "; - if (fSample.fMagneticFieldVectorAvailable) { - for (unsigned int i=0; iGetProgramName() << ", version: " << fNxEntry1->GetProgramVersion(); + cout << endl << " run number : " << fNxEntry1->GetRunNumber(); + cout << endl << " title : " << fNxEntry1->GetTitle(); + cout << endl << " notes : " << fNxEntry1->GetNotes(); + cout << endl << " analysis : " << fNxEntry1->GetAnalysis(); + cout << endl << " laboratory : " << fNxEntry1->GetLaboratory(); + cout << endl << " beamline : " << fNxEntry1->GetBeamline(); + cout << endl << " start time : " << fNxEntry1->GetStartTime(); + cout << endl << " stop time : " << fNxEntry1->GetStopTime(); + cout << endl << " switching state: " << fNxEntry1->GetSwitchingState() << ", '1' normal data collection, '2' Red/Green mode"; + cout << endl << "NXuser:"; + cout << endl << " name : " << fNxEntry1->GetUser()->GetName(); + cout << endl << " exp.number : " << fNxEntry1->GetUser()->GetExperimentNumber(); + cout << endl << "NXsample:"; + cout << endl << " name : " << fNxEntry1->GetSample()->GetName(); + dval = fNxEntry1->GetSample()->GetPhysPropValue("temperature", ok); + if (ok) + cout << endl << " temperature : " << dval; + fNxEntry1->GetSample()->GetPhysPropUnit("temperature", str, ok); + if (ok) + cout << " (" << str << ")"; + dval = fNxEntry1->GetSample()->GetPhysPropValue("magnetic_field", ok); + if (ok) + cout << endl << " magnetic_field : " << dval; + fNxEntry1->GetSample()->GetPhysPropUnit("magnetic_field", str, ok); + if (ok) + cout << " (" << str << ")"; + cout << endl << " shape : " << fNxEntry1->GetSample()->GetShape(); + cout << endl << " mag.field state: " << fNxEntry1->GetSample()->GetMagneticFieldState(); + cout << endl << " environment : " << fNxEntry1->GetSample()->GetEnvironment(); + if (fNxEntry1->GetSample()->IsMagneticFieldVectorAvailable()) { + cout << endl << " magnetic field vector: "; + for (unsigned int i=0; iGetSample()->GetMagneticFieldVector().size(); i++) { + cout << fNxEntry1->GetSample()->GetMagneticFieldVector().at(i) << ", "; + } + cout << "(" << fNxEntry1->GetSample()->GetMagneticFieldVectorUnits() << "), "; + cout << fNxEntry1->GetSample()->GetMagneticFieldVectorCoordinateSystem(); } - cout << "(" << fSample.fMagneticFieldVectorUnits << "), coord.system: " << fSample.fMagneticFieldVectorCoordinateSystem; - } else { - cout << "not available."; - } - cout << endl << "shape : " << fSample.fShape; - cout << endl << "environment : " << fSample.fEnvironment; - cout << endl << "-----------------------------"; - cout << endl << "instrument info"; - cout << endl << "instrument name : " << fInstrument.name; - cout << endl << " detector info"; - cout << endl << " detector number : " << fInstrument.detector.number; - cout << endl << " -----------------------------"; - cout << endl << " collimator info"; - cout << endl << " collimator type : " << fInstrument.collimator.type; - cout << endl << " -----------------------------"; - cout << endl << " beam info"; - cout << endl << " beam total number of counts : " << fInstrument.beam.total_counts << " " << fInstrument.beam.total_counts_units; - cout << endl << "-----------------------------"; - cout << endl << "run data"; - cout << endl << "time resolution : " << fData.fTimeResolution << " (ns)"; - cout << endl << "number of histos: " << fData.fNumberOfHistos; - if (fData.fAlpha.size() != 0) { - cout << endl << "alpha : "; - for (unsigned int i=0; iGetInstrument()->GetName(); + cout << endl << " NXdetector:"; + cout << endl << " number of detectors: " << fNxEntry1->GetInstrument()->GetDetector()->GetNumber(); + cout << endl << " NXcollimator:"; + cout << endl << " type : " << fNxEntry1->GetInstrument()->GetCollimator()->GetType(); + cout << endl << " Nxbeam:"; + cout << endl << " total_counts : " << fNxEntry1->GetInstrument()->GetBeam()->GetTotalCounts() << " (" << fNxEntry1->GetInstrument()->GetBeam()->GetUnits() << ")"; + cout << endl << "NXdata:"; + cout << endl << " number of histos : " << fNxEntry1->GetData()->GetNoOfHistos(); + cout << endl << " time resolution : " << fNxEntry1->GetData()->GetTimeResolution("ns") << " (ns)"; + if (fNxEntry1->GetData()->GetGrouping()->size() != 0) { + cout << endl << " grouping : "; + for (unsigned int i=0; iGetData()->GetGrouping()->size(); i++) { + cout << "(" << i << "/" << fNxEntry1->GetData()->GetGrouping()->at(i) << "), "; + } + } else { + cout << endl << " grouping : not available"; } - } else { - cout << endl << "alpha : not available"; - } - if (fData.fGrouping.size() != 0) { - cout << endl << "grouping : "; - for (unsigned int i=0; iGetData()->GetT0s()->size() == 0) { + cout << endl << " t0's : not available"; + } else { + cout << endl << " t0's : "; + for (unsigned int i=0; iGetData()->GetT0s()->size(); i++) { + cout << fNxEntry1->GetData()->GetT0(i) << ", "; + } } - } else { - cout << endl << "grouping : not available"; - } - cout << endl << "t0 : " << fData.fT0[0]; - cout << endl << "first good bin : " << fData.fFirstGoodBin[0]; - cout << endl << "last good bin : " << fData.fLastGoodBin[0]; - cout << endl << "histograms : +++++++++++"; - for (unsigned int i=0; iGetData()->GetFirstGoodBins()->size() == 0) { + cout << endl << " first good bins : not available"; + } else { + cout << endl << " first good bins : "; + for (unsigned int i=0; iGetData()->GetFirstGoodBins()->size(); i++) { + cout << fNxEntry1->GetData()->GetFirstGoodBin(i) << ", "; + } } - cout << "..."; - } - cout << endl << "-----------------------------"; - cout << endl << "grouped histograms : ++++++++"; - for (unsigned int i=0; iGetData()->GetLastGoodBins()->size() == 0) { + cout << endl << " last good bins : not available"; + } else { + cout << endl << " last good bins : "; + for (unsigned int i=0; iGetData()->GetLastGoodBins()->size(); i++) { + cout << fNxEntry1->GetData()->GetLastGoodBin(i) << ", "; + } } - cout << "..."; + if (fNxEntry1->GetData()->GetNoOfHistos() == 0) { + cout << endl << " historgrams : not available"; + } else { + cout << endl << " historgrams : +++++++++++++"; + for (unsigned int i=0; iGetData()->GetNoOfHistos(); i++) { + cout << endl << " histo " << i+1 << ": "; + for (unsigned int j=0; j<15; j++) { + cout << fNxEntry1->GetData()->GetHisto(i)->at(j) << ", "; + } + cout << "..."; + } + } + if (fNxEntry1->GetData()->GetAlpha()->size() == 0) { + cout << endl << " alpha : not available"; + } else { + cout << endl << " alpha : "; + for (unsigned int i=0; iGetData()->GetAlpha()->size(); i++) + cout << "(" << fNxEntry1->GetData()->GetAlpha()->at(i).GetGroupFirst() << "/" << fNxEntry1->GetData()->GetAlpha()->at(i).GetGroupSecond() << "/" << fNxEntry1->GetData()->GetAlpha()->at(i).GetAlpha() << "), "; + } + if (fGroupedHisto.size() == 0) { + cout << endl << " grouped historgrams : not available"; + } else { + cout << endl << " grouped historgrams : +++++++++++++"; + for (unsigned int i=0; iGetDefinition(); + cout << endl << " program name : " << fNxEntry2->GetProgramName() << ", version: " << fNxEntry2->GetProgramVersion(); + cout << endl << " run_number : " << fNxEntry2->GetRunNumber(); + cout << endl << " run_title : " << fNxEntry2->GetTitle(); + cout << endl << " start_time : " << fNxEntry2->GetStartTime(); + cout << endl << " end_time : " << fNxEntry2->GetStopTime(); + cout << endl << " exp.identifier : " << fNxEntry2->GetExperimentIdentifier(); + cout << endl << " NXuser:"; + cout << endl << " name : " << fNxEntry2->GetUser()->GetName(); + cout << endl << " NXsample:"; + cout << endl << " name : " << fNxEntry2->GetSample()->GetName(); + cout << endl << " description : " << fNxEntry2->GetSample()->GetDescription(); + cout << endl << " mag.field state : " << fNxEntry2->GetSample()->GetMagneticFieldState(); + dval = fNxEntry2->GetSample()->GetPhysPropValue("temperature", ok); + if (ok) + cout << endl << " temperature : " << dval; + fNxEntry2->GetSample()->GetPhysPropUnit("temperature", str, ok); + if (ok) + cout << " (" << str << ")"; + cout << endl << " temp.environment : " << fNxEntry2->GetSample()->GetEnvironmentTemp(); + dval = fNxEntry2->GetSample()->GetPhysPropValue("magnetic_field", ok); + if (ok) + cout << endl << " magnetic_field : " << dval; + fNxEntry2->GetSample()->GetPhysPropUnit("magnetic_field", str, ok); + if (ok) + cout << " (" << str << ")"; + cout << endl << " mag. field env. : " << fNxEntry2->GetSample()->GetEnvironmentField(); + cout << endl << " NXinstrument:"; + cout << endl << " name : " << fNxEntry2->GetInstrument()->GetName(); + cout << endl << " NXsource:"; + cout << endl << " name : " << fNxEntry2->GetInstrument()->GetSource()->GetName(); + cout << endl << " type : " << fNxEntry2->GetInstrument()->GetSource()->GetType(); + cout << endl << " probe : " << fNxEntry2->GetInstrument()->GetSource()->GetProbe(); + cout << endl << " NXbeamline:"; + cout << endl << " name : " << fNxEntry2->GetInstrument()->GetBeamline()->GetName(); + cout << endl << " NXdetector:"; + cout << endl << " description : " << fNxEntry2->GetInstrument()->GetDetector()->GetDescription(); + cout << endl << " time resolution : " << fNxEntry2->GetInstrument()->GetDetector()->GetTimeResolution("ns") << " (ns)"; + if (fNxEntry2->GetInstrument()->GetDetector()->IsT0Present()) { + if (fNxEntry2->GetInstrument()->GetDetector()->GetT0Tag() == 1) { // only one t0 for all histograms + cout << endl << " t0 : " << fNxEntry2->GetInstrument()->GetDetector()->GetT0(); + } else { // t0 vector of the form t0[np][ns] + cout << endl << " t0 (idx_p/idx_s/t0): "; + for (int i=0; iGetInstrument()->GetDetector()->GetNoOfPeriods(); i++) { + for (int j=0; jGetInstrument()->GetDetector()->GetNoOfSpectra(); j++) { + cout << "(" << i << "/" << j << "/" << fNxEntry2->GetInstrument()->GetDetector()->GetT0(i,j); + } + } + } + } else { + cout << endl << " t0 : n/a"; + } + if (fNxEntry2->GetInstrument()->GetDetector()->IsFirstGoodBinPresent()) { + if (fNxEntry2->GetInstrument()->GetDetector()->GetT0Tag() == 1) { // only one t0/fgb/lgb for all histograms + cout << endl << " first good bin : " << fNxEntry2->GetInstrument()->GetDetector()->GetFirstGoodBin(); + } else { // fgb vector of the form fgb[np][ns] + cout << endl << " fgb (idx_p/idx_s/fgb): "; + for (int i=0; iGetInstrument()->GetDetector()->GetNoOfPeriods(); i++) { + for (int j=0; jGetInstrument()->GetDetector()->GetNoOfSpectra(); j++) { + cout << "(" << i << "/" << j << "/" << fNxEntry2->GetInstrument()->GetDetector()->GetFirstGoodBin(i,j); + } + } + } + } else { + cout << endl << " first good bin : n/a"; + } + if (fNxEntry2->GetInstrument()->GetDetector()->IsFirstGoodBinPresent()) { + if (fNxEntry2->GetInstrument()->GetDetector()->GetT0Tag() == 1) { // only one t0/fgb/lgb for all histograms + cout << endl << " last good bin : " << fNxEntry2->GetInstrument()->GetDetector()->GetLastGoodBin(); + } else { // lgb vector of the form lgb[np][ns] + cout << endl << " lgb (idx_p/idx_s/lgb): "; + for (int i=0; iGetInstrument()->GetDetector()->GetNoOfPeriods(); i++) { + for (int j=0; jGetInstrument()->GetDetector()->GetNoOfSpectra(); j++) { + cout << "(" << i << "/" << j << "/" << fNxEntry2->GetInstrument()->GetDetector()->GetLastGoodBin(i,j); + } + } + } + } else { + cout << endl << " last good bin : n/a"; + } + cout << endl << " spectrum_index : "; + for (unsigned int i=0; iGetInstrument()->GetDetector()->GetSpectrumIndexSize(); i++) + cout << fNxEntry2->GetInstrument()->GetDetector()->GetSpectrumIndex(i) << ", "; + + // dump data + int maxDump = 15; + cout << endl << " counts : "; + if (fNxEntry2->GetInstrument()->GetDetector()->GetNoOfPeriods() > 0) { // counts[np][ns][ntc] + for (int i=0; iGetInstrument()->GetDetector()->GetNoOfPeriods(); i++) { + cout << endl << " period : " << i+1; + for (int j=0; jGetInstrument()->GetDetector()->GetNoOfSpectra(); j++) { + cout << endl << " spectrum : " << j+1 << ", (#bins=" << fNxEntry2->GetInstrument()->GetDetector()->GetNoOfBins() << ")"; + if (maxDump > fNxEntry2->GetInstrument()->GetDetector()->GetNoOfBins()) + maxDump = fNxEntry2->GetInstrument()->GetDetector()->GetNoOfBins(); + cout << endl << " "; + for (int k=0; kGetInstrument()->GetDetector()->GetHistoValue(i,j,k) << ", "; + } + cout << "..."; + } + } + } else { + if (fNxEntry2->GetInstrument()->GetDetector()->GetNoOfSpectra() > 0) { // counts[ns][ntc] + for (int j=0; jGetInstrument()->GetDetector()->GetNoOfSpectra(); j++) { + cout << endl << " spectrum : " << j+1 << ", (#bins=" << fNxEntry2->GetInstrument()->GetDetector()->GetNoOfBins() << ")"; + if (maxDump > fNxEntry2->GetInstrument()->GetDetector()->GetNoOfBins()) + maxDump = fNxEntry2->GetInstrument()->GetDetector()->GetNoOfBins(); + cout << endl << " "; + for (int k=0; kGetInstrument()->GetDetector()->GetHistoValue(0,j,k) << ", "; + } + cout << "..."; + } + } else { // counts[ntc] + cout << endl << " (#bins=" << fNxEntry2->GetInstrument()->GetDetector()->GetNoOfBins() << ")"; + if (maxDump > fNxEntry2->GetInstrument()->GetDetector()->GetNoOfBins()) + maxDump = fNxEntry2->GetInstrument()->GetDetector()->GetNoOfBins(); + cout << endl << " "; + for (int k=0; kGetInstrument()->GetDetector()->GetHistoValue(0,0,k) << ", "; + } + cout << "..."; + } + } + cout << endl << "that's all!"; + cout << endl << endl; } - cout << endl << "-----------------------------"; - cout << endl << "done."; - cout << endl << endl; - } -//----------------------------------------------------------------------------------------------------- -// SetStartDate (public) -//----------------------------------------------------------------------------------------------------- -/** - *

The date should look like yyyy-mm-dd. - * - * return: - * - true on date string has proper format - * - false on error. The error code/message will give the details. - * - * \param date - */ -bool PNeXus::SetStartDate(const char *date) -{ - string strDate = date; - return SetStartDate(strDate); -} - -//----------------------------------------------------------------------------------------------------- -// SetStartDate (public) -//----------------------------------------------------------------------------------------------------- -/** - *

The date should look like yyyy-mm-dd. - * - * return: - * - true on date string has proper format - * - false on error. The error code/message will give the details. - * - * \param date - */ -bool PNeXus::SetStartDate(string date) -{ - bool ok=false; - string str = TransformDate(date, ok); - - if (!ok) - return false; - - fStartDate = str; - - return true; -} - -//----------------------------------------------------------------------------------------------------- -// SetStartTime (public) -//----------------------------------------------------------------------------------------------------- -/** - *

The time should look like hh:mm:ss. - * - * return: - * - true on time string has proper format - * - false on error. The error code/message will give the details. - * - * \param time - */ -bool PNeXus::SetStartTime(const char *time) -{ - string strTime = time; - return SetStartTime(strTime); -} - -//----------------------------------------------------------------------------------------------------- -// SetStartTime (public) -//----------------------------------------------------------------------------------------------------- -/** - *

The time should look like hh:mm:ss. - * - * return: - * - true on time string has proper format - * - false on error. The error code/message will give the details. - * - * \param time - */ -bool PNeXus::SetStartTime(string time) -{ - if (time.length() != 8) { - fErrorCode = PNEXUS_WRONG_TIME_FORMAT; - fErrorMsg = "PNeXus::SetStartTime **ERROR** given time="+time+", is not of the required form hh:mm:ss!"; - return false; - } - - if ((time[2] != ':') || (time[5] != ':')) { - fErrorCode = PNEXUS_WRONG_TIME_FORMAT; - fErrorMsg = "PNeXus::SetStartTime **ERROR** given time="+time+", is not of the required form hh:mm:ss!"; - return false; - } - - fStartTime = time; - - return true; -} - -//----------------------------------------------------------------------------------------------------- -// SetStopDate (public) -//----------------------------------------------------------------------------------------------------- -/** - *

- * - * return: - * - true on date string has proper format - * - false on error. The error code/message will give the details. - * - * \param date - */ -bool PNeXus::SetStopDate(const char *date) -{ - string strDate = date; - return SetStopDate(strDate); -} - -//----------------------------------------------------------------------------------------------------- -// SetStopDate (public) -//----------------------------------------------------------------------------------------------------- -/** - *

- * - * return: - * - true on date string has proper format - * - false on error. The error code/message will give the details. - * - * \param date - */ -bool PNeXus::SetStopDate(string date) -{ - bool ok=false; - string str = TransformDate(date, ok); - - if (!ok) - return false; - - fStopDate = str; - - return true; -} - -//----------------------------------------------------------------------------------------------------- -// SetStopTime (public) -//----------------------------------------------------------------------------------------------------- -/** - *

- * - * return: - * - true on time string has proper format - * - false on error. The error code/message will give the details. - * - * \param time - */ -bool PNeXus::SetStopTime(const char *time) -{ - string strTime = time; - return SetStopTime(strTime); -} - -//----------------------------------------------------------------------------------------------------- -// SetStopTime (public) -//----------------------------------------------------------------------------------------------------- -/** - *

- * - * return: - * - true on time string has proper format - * - false on error. The error code/message will give the details. - * - * \param time - */ -bool PNeXus::SetStopTime(string time) -{ - if (time.length() != 8) { - fErrorCode = PNEXUS_WRONG_TIME_FORMAT; - fErrorMsg = "PNeXus::SetStopTime **ERROR** given time="+time+", is not of the required form hh:mm:ss!"; - return false; - } - - if ((time[2] != ':') || (time[5] != ':')) { - fErrorCode = PNEXUS_WRONG_TIME_FORMAT; - fErrorMsg = "PNeXus::SetStopTime **ERROR** given time="+time+", is not of the required form hh:mm:ss!"; - return false; - } - - fStopTime = time; - - return true; -} - -//----------------------------------------------------------------------------------------------------- -// CleanUp (private) -//----------------------------------------------------------------------------------------------------- -/** - * - */ -void PNeXus::CleanUp() -{ - fData.fTimeResolution = 0.0; - fData.fNumberOfHistos = 0; - fData.fAlpha.clear(); - fData.fGrouping.clear(); - fData.fFirstGoodBin.clear(); - fData.fLastGoodBin.clear(); - fData.fT0.clear(); - fData.fHistoName.clear(); - for (unsigned int i=0; i */ void PNeXus::Init() { - fIsValid = false; + fValid = false; + fErrorCode = PNEXUS_NO_ERROR; + fErrorMsg = "n/a"; + fNeXusVersion = NEXUS_VERSION; + fFileFormatVersion = "n/a"; + fIdfVersion = 0; + fFileName = "n/a"; + fFileTime = "n/a"; + fCreator = "n/a"; - fFileName = "n/a"; - fFileHandle = 0; - - fErrorMsg = "No Data available!"; - fErrorCode = -1; - - fIDFVersion = -1; - fProgramName = "n/a"; - fProgramVersion = "n/a"; - - fRunNumber = -1; - fRunTitle = "n/a"; - fNotes = "n/a"; - fAnalysisTag = "n/a"; - fLab = "n/a"; - fBeamLine = "n/a"; - fStartDate = "n/a"; - fStartTime = "n/a"; - fStopDate = "n/a"; - fStopTime = "n/a"; - - fSwitchingState = -1; - - fSample.fEnvironment = "n/a"; - fSample.fMagneticField = 9.9e17; - fSample.fMagneticFieldUnit = "n/a"; - fSample.fMagneticFieldState = "n/a"; - fSample.fName = "n/a"; - fSample.fShape = "n/a"; - fSample.fTemperature = 9.9e17; - fSample.fTemperatureUnit = "n/a"; - - fInstrument.name = "n/a"; - fInstrument.detector.number = 0; - fInstrument.collimator.type = "n/a"; - fInstrument.beam.total_counts = 0; - fInstrument.beam.total_counts_units = "n/a"; - - fData.fNumberOfHistos = 0; - fData.fTimeResolution = 0.0; - fData.fAlpha.clear(); - fData.fFirstGoodBin.clear(); - fData.fLastGoodBin.clear(); - fData.fHistoName.clear(); - fData.fGrouping.clear(); - fData.fT0.clear(); + fNxEntry1 = 0; + fNxEntry2 = 0; } //----------------------------------------------------------------------------------------------------- @@ -1393,8 +2084,8 @@ bool PNeXus::ErrorHandler(NXstatus status, int errCode, const string &errMsg) if (status != NX_OK) { fErrorCode = errCode; fErrorMsg = errMsg; + cerr << endl << ">> **ERROR** " << fErrorMsg << endl; if (fFileHandle != 0) { - CleanUp(); NXclose(&fFileHandle); } return false; @@ -1434,8 +2125,9 @@ NXstatus PNeXus::GetStringData(string &str) status = NXgetdata(fFileHandle, data_value); if (status != NX_OK) { + cerr << endl << ">> **ERROR** in routine NXgetdata: couldn't get data for '" << str << "'!" << endl; fErrorCode = PNEXUS_GET_DATA_ERROR; - fErrorMsg = "PNeXus::GetStringData() **ERROR** couldn't get data!"; + fErrorMsg = "couldn't get data!"; return NX_ERROR; } @@ -1471,9 +2163,9 @@ NXstatus PNeXus::GetStringAttr(string attr, string &str) atttype = NX_CHAR; status = NXgetattr(fFileHandle, (char *)attr.c_str(), data_value, &attlen, &atttype); if (status != NX_OK) { - cerr << endl << "**ERROR** in routine NXMgetstringattr: couldn't get attribute!" << endl << endl; + cerr << endl << ">> **ERROR** in routine NXgetattr: couldn't get attribute '" << attr << "'! status=" << status << endl << endl; fErrorCode = PNEXUS_GET_ATTR_ERROR; - fErrorMsg = "PNeXus::GetStringAttr() **ERROR** couldn't get string attribute data!"; + fErrorMsg = "couldn't get string attribute data!"; return NX_ERROR; } @@ -1644,296 +2336,2386 @@ NXstatus PNeXus::GetIntVectorData(vector &data) return NX_OK; } -//----------------------------------------------------------------------------------------------------- -// SetT0 (public) -//----------------------------------------------------------------------------------------------------- +//------------------------------------------------------------------------------------------ +// ReadFileIdf1 (private) +//------------------------------------------------------------------------------------------ /** - *

Sets t0. The current muSR NeXus implementation has only a single t0 for all detectors since it was - * tailored for pulsed muon sources (ISIS). This eventually needs to be changed. + *

Read the NeXus file of type IDF Version 1. * - * \param t0 to be set - * \param idx index of t0 + * return: + * - NX_OK on successfull reading + * - NX_ERROR on error. The error code/message will give the details. */ -void PNeXus::SetT0(unsigned int t0, unsigned idx) +int PNeXus::ReadFileIdf1() { - if (idx >= fData.fT0.size()) - fData.fT0.resize(idx+1); + // create first the necessary NXentry object for IDF Version 1 + fNxEntry1 = new PNeXusEntry1(); + if (fNxEntry1 == 0) { + fErrorCode = PNEXUS_OBJECT_INVOK_ERROR; + fErrorMsg = ">> **ERROR** couldn't invoke PNeXusEntry1 object."; + return NX_ERROR; + } - fData.fT0[idx] = t0; + string str; + char cstr[128]; + int ival; + float fval; + + // open file + NXstatus status; + status = NXopen(fFileName.c_str(), NXACC_READ, &fFileHandle); + if (status != NX_OK) { + fErrorCode = PNEXUS_FILE_OPEN_ERROR; + fErrorMsg = "PNeXus::ReadFile() **ERROR** Couldn't open file '"+fFileName+"' !"; + return NX_ERROR; + } + + // look for the first occurring NXentry + bool found = false; + NXname nxname, nxclass; + int dataType; + do { + status = NXgetnextentry(fFileHandle, nxname, nxclass, &dataType); + if (strstr(nxclass, "NXentry") != NULL) + found = true; + } while (!found || (status == NX_EOD)); + // make sure any NXentry has been found + if (!found) { + fErrorCode = PNEXUS_NXENTRY_NOT_FOUND; + fErrorMsg = ">> **ERROR** Couldn't find any NXentry!"; + return NX_ERROR; + } + // open the NXentry group to obtain the necessary stuff + status = NXopengroup(fFileHandle, nxname, "NXentry"); + if (status != NX_OK) { + fErrorCode = PNEXUS_GROUP_OPEN_ERROR; + fErrorMsg = "PNeXus::ReadFile() **ERROR** Couldn't open the NeXus group '" + string(nxname) + "'!"; + return NX_ERROR; + } + + // program_name + if (!ErrorHandler(NXopendata(fFileHandle, "program_name"), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'program_name' data in NXentry!")) return NX_ERROR; + if (!ErrorHandler(GetStringData(str), PNEXUS_GET_DATA_ERROR, "couldn't read 'program_name' data in NXentry!")) return NX_ERROR; + fNxEntry1->SetProgramName(str); + if (!ErrorHandler(GetStringAttr("version", str), PNEXUS_GET_ATTR_ERROR, "couldn't read 'program_name' attribute in NXentry!")) return NX_ERROR; + fNxEntry1->SetProgramVersion(str); + if (!ErrorHandler(NXclosedata(fFileHandle), PNEXUS_CLOSE_DATA_ERROR, "couldn't close 'program_name' data in NXentry!")) return NX_ERROR; + + // run number + if (!ErrorHandler(NXopendata(fFileHandle, "number"), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'number' data in NXentry!")) return NX_ERROR; + if (!ErrorHandler(NXgetdata(fFileHandle, &ival), PNEXUS_GET_DATA_ERROR, "couldn't read 'number' data in NXentry!")) return NX_ERROR; + fNxEntry1->SetRunNumber(ival); + if (!ErrorHandler(NXclosedata(fFileHandle), PNEXUS_CLOSE_DATA_ERROR, "couldn't close 'number' data in NXentry!")) return NX_ERROR; + + // title + if (!ErrorHandler(NXopendata(fFileHandle, "title"), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'title' data in NXentry!")) return NX_ERROR; + if (!ErrorHandler(GetStringData(str), PNEXUS_GET_DATA_ERROR, "couldn't read 'title' data in NXentry!")) return NX_ERROR; + fNxEntry1->SetTitle(str); + if (!ErrorHandler(NXclosedata(fFileHandle), PNEXUS_CLOSE_DATA_ERROR, "couldn't close 'title' data in NXentry!")) return NX_ERROR; + + // notes + if (!ErrorHandler(NXopendata(fFileHandle, "notes"), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'notes' data in NXentry!")) return NX_ERROR; + if (!ErrorHandler(GetStringData(str), PNEXUS_GET_DATA_ERROR, "couldn't read 'notes' data in NXentry!")) return NX_ERROR; + fNxEntry1->SetNotes(str); + if (!ErrorHandler(NXclosedata(fFileHandle), PNEXUS_CLOSE_DATA_ERROR, "couldn't close 'notes' data in NXentry!")) return NX_ERROR; + + // analysis tag + if (!ErrorHandler(NXopendata(fFileHandle, "analysis"), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'analysis' data in NXentry!")) return NX_ERROR; + if (!ErrorHandler(GetStringData(str), PNEXUS_GET_DATA_ERROR, "couldn't read 'analysis' data in NXentry!")) return NX_ERROR; + fNxEntry1->SetAnalysis(str); + if (!ErrorHandler(NXclosedata(fFileHandle), PNEXUS_CLOSE_DATA_ERROR, "couldn't close 'analysis' data in NXentry!")) return NX_ERROR; + + // lab + if (!ErrorHandler(NXopendata(fFileHandle, "lab"), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'lab' data in NXentry!")) return NX_ERROR; + if (!ErrorHandler(GetStringData(str), PNEXUS_GET_DATA_ERROR, "couldn't read 'lab' data in NXentry!")) return NX_ERROR; + fNxEntry1->SetLaboratory(str); + if (!ErrorHandler(NXclosedata(fFileHandle), PNEXUS_CLOSE_DATA_ERROR, "couldn't close 'lab' data in NXentry!")) return NX_ERROR; + + // beamline + if (!ErrorHandler(NXopendata(fFileHandle, "beamline"), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'beamline' data in NXentry!")) return NX_ERROR; + if (!ErrorHandler(GetStringData(str), PNEXUS_GET_DATA_ERROR, "couldn't read 'beamline' data in NXentry!")) return NX_ERROR; + fNxEntry1->SetBeamline(str); + if (!ErrorHandler(NXclosedata(fFileHandle), PNEXUS_CLOSE_DATA_ERROR, "couldn't close 'beamline' data in NXentry!")) return NX_ERROR; + + // start time + if (!ErrorHandler(NXopendata(fFileHandle, "start_time"), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'start_time' data in NXentry!")) return NX_ERROR; + if (!ErrorHandler(GetStringData(str), PNEXUS_GET_DATA_ERROR, "couldn't read 'start_time' data in NXentry!")) return NX_ERROR; + if (!ErrorHandler(NXclosedata(fFileHandle), PNEXUS_CLOSE_DATA_ERROR, "couldn't close 'start_time' data in NXentry!")) return NX_ERROR; + if (fNxEntry1->SetStartTime(str) != NX_OK) { + fErrorCode = PNEXUS_TIME_FORMAT_ERROR; + fErrorMsg = "start time format is not ISO 8601 conform."; + } + + // stop time + if (!ErrorHandler(NXopendata(fFileHandle, "stop_time"), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'start_time' data in NXentry!")) return NX_ERROR; + if (!ErrorHandler(GetStringData(str), PNEXUS_GET_DATA_ERROR, "couldn't read 'start_time' data in NXentry!")) return NX_ERROR; + if (!ErrorHandler(NXclosedata(fFileHandle), PNEXUS_CLOSE_DATA_ERROR, "couldn't close 'start_time' data in NXentry!")) return NX_ERROR; + if (fNxEntry1->SetStopTime(str) != NX_OK) { + fErrorCode = PNEXUS_TIME_FORMAT_ERROR; + fErrorMsg = "stop time format is not ISO 8601 conform.."; + } + + // switching state (red/green mode) + if (!ErrorHandler(NXopendata(fFileHandle, "switching_states"), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'switching_states' data in NXentry!")) return NX_ERROR; + if (!ErrorHandler(NXgetdata(fFileHandle, &ival), PNEXUS_GET_DATA_ERROR, "couldn't read 'switching_states' data in NXentry!")) return NX_ERROR; + if (!ErrorHandler(NXclosedata(fFileHandle), PNEXUS_CLOSE_DATA_ERROR, "couldn't close 'switching_states' data in NXentry!")) return NX_ERROR; + if (fNxEntry1->SetSwitchingState(ival)) { + fErrorCode = PNEXUS_DATA_ERROR; + fErrorMsg = "unkown switching state found."; + } + + // open group NXuser + if (!ErrorHandler(NXopengroup(fFileHandle, "user", "NXuser"), PNEXUS_GROUP_OPEN_ERROR, "couldn't open NeXus subgroup 'user'!")) return NX_ERROR; + + // change to subgroup + if (!ErrorHandler(NXinitgroupdir(fFileHandle), PNEXUS_INIT_GROUPDIR_ERROR, "couldn't init group directory")) return NX_ERROR; + int numItems = 0; + NXname groupName, className; + if (!ErrorHandler(NXgetgroupinfo(fFileHandle, &numItems, groupName, className), PNEXUS_GET_GROUP_INFO_ERROR, "couldn't get user group info")) return NX_ERROR; + + // get all the user info + // go through the user list and filter out the required items + NXname nx_label; + int nx_dataType; + for (int i=0; iGetUser()->SetName(str); + } + if (!strcmp(nx_label, "experiment_number")) { + if (!ErrorHandler(GetStringData(str), PNEXUS_GET_DATA_ERROR, "couldn't get user name")) return NX_ERROR; + fNxEntry1->GetUser()->SetExperimentNumber(str); + } + if (!ErrorHandler(NXclosedata(fFileHandle), PNEXUS_CLOSE_DATA_ERROR, "couldn't close data")) return NX_ERROR; + } + + // close group NXuser + NXclosegroup(fFileHandle); + + // open group NXsample + if (!ErrorHandler(NXopengroup(fFileHandle, "sample", "NXSample"), PNEXUS_GROUP_OPEN_ERROR, "couldn't open NeXus subgroup sample!")) return NX_ERROR; + + // read sample name + if (!ErrorHandler(NXopendata(fFileHandle, "name"), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'name' data in sample group!")) return NX_ERROR; + if (!ErrorHandler(GetStringData(str), PNEXUS_GET_DATA_ERROR, "couldn't read 'name' data in sample group!")) return NX_ERROR; + if (!ErrorHandler(NXclosedata(fFileHandle), PNEXUS_CLOSE_DATA_ERROR, "couldn't close 'name' data in sample group")) return NX_ERROR; + fNxEntry1->GetSample()->SetName(str); + + // read sample temperature + if (!ErrorHandler(NXopendata(fFileHandle, "temperature"), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'temperature' data in sample group!")) return NX_ERROR; + if (!ErrorHandler(NXgetdata(fFileHandle, &fval), PNEXUS_GET_DATA_ERROR, "couldn't read 'temperature' data in sample group!")) return NX_ERROR; + if (!ErrorHandler(GetStringAttr("units", str), PNEXUS_GET_ATTR_ERROR, "couldn't read temperature units!")) return NX_ERROR; + if (!ErrorHandler(NXclosedata(fFileHandle), PNEXUS_CLOSE_DATA_ERROR, "couldn't close 'temperature' data in sample group")) return NX_ERROR; + fNxEntry1->GetSample()->SetPhysProp("temperature", (double)fval, str); + + // read sample magnetic field + if (!ErrorHandler(NXopendata(fFileHandle, "magnetic_field"), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'magnetic_field' data in sample group!")) return NX_ERROR; + if (!ErrorHandler(NXgetdata(fFileHandle, &fval), PNEXUS_GET_DATA_ERROR, "couldn't read 'magnetic_field' data in sample group!")) return NX_ERROR; + if (!ErrorHandler(GetStringAttr("units", str), PNEXUS_GET_ATTR_ERROR, "couldn't read magnetic_field units!")) return NX_ERROR; + if (!ErrorHandler(NXclosedata(fFileHandle), PNEXUS_CLOSE_DATA_ERROR, "couldn't close 'magnetic_field' data in sample group")) return NX_ERROR; + fNxEntry1->GetSample()->SetPhysProp("magnetic_field", (double)fval, str); + + // read sample shape, e.g. powder, single crystal, etc. + if (!ErrorHandler(NXopendata(fFileHandle, "shape"), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'shape' data in sample group!")) return NX_ERROR; + if (!ErrorHandler(GetStringData(str), PNEXUS_GET_DATA_ERROR, "couldn't read 'shape' data in sample group!")) return NX_ERROR; + if (!ErrorHandler(NXclosedata(fFileHandle), PNEXUS_CLOSE_DATA_ERROR, "couldn't close 'shape' data in sample group")) return NX_ERROR; + fNxEntry1->GetSample()->SetShape(str); + + // read magnetic field state, e.g. TF, LF, ZF + if (!ErrorHandler(NXopendata(fFileHandle, "magnetic_field_state"), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'magnetic_field_state' data in sample group!")) return NX_ERROR; + if (!ErrorHandler(GetStringData(str), PNEXUS_GET_DATA_ERROR, "couldn't read 'magnetic_field_state' data in sample group!")) return NX_ERROR; + if (!ErrorHandler(NXclosedata(fFileHandle), PNEXUS_CLOSE_DATA_ERROR, "couldn't close 'magnetic_field_state' data in sample group")) return NX_ERROR; + fNxEntry1->GetSample()->SetMagneticFieldState(str); + + // read 'magnetic_field_vector' and 'coordinate_system' attribute + if (!ErrorHandler(NXopendata(fFileHandle, "magnetic_field_vector"), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'magnetic_field_vector' data in sample group!")) return NX_ERROR; + int attLen = 1, attType = NX_INT32; + memset(cstr, '\0', sizeof(cstr)); + strncpy(cstr, "available", sizeof(cstr)); + if (!ErrorHandler(NXgetattr(fFileHandle, cstr, &ival, &attLen, &attType), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'magnetic_field_vector available' data in sample group!")) return NX_ERROR; + fNxEntry1->GetSample()->SetMagneticFieldVectorAvailable(ival); + if (fNxEntry1->GetSample()->IsMagneticFieldVectorAvailable()) { + vector magVec; + if (!ErrorHandler(GetDoubleVectorData(magVec), PNEXUS_GET_DATA_ERROR, "couldn't get 'magnetic_field_vector' data!")) return NX_ERROR; + fNxEntry1->GetSample()->SetMagneticFieldVector(magVec); + magVec.clear(); + if (!ErrorHandler(GetStringAttr("coordinate_system", str), PNEXUS_GET_ATTR_ERROR, "couldn't read magnetic field coordinate_system!")) return NX_ERROR; + fNxEntry1->GetSample()->SetMagneticFieldVectorCoordinateSystem(str); + + // workaround since not all ISIS IDF 1 files have the 'units' entry!! + int i, status, attlen, atttype; + char cstr[VGNAMELENMAX]; + NXname data_value; + + attlen = VGNAMELENMAX - 1; + atttype = NX_CHAR; + status = NXgetattr(fFileHandle, "units", data_value, &attlen, &atttype); + if (status == NX_OK) { + for (i = 0; i < attlen; i++) + cstr[i] = *(data_value + i); + cstr[i] = '\0'; + + str = cstr; + } else { + str = string("Gauss"); + } + fNxEntry1->GetSample()->SetMagneticFieldUnits(str); + } + if (!ErrorHandler(NXclosedata(fFileHandle), PNEXUS_CLOSE_DATA_ERROR, "couldn't close 'magnetic_field_vector' data in sample group")) return NX_ERROR; + + // read sample environment, e.g. CCR, LowTemp-2, etc. + if (!ErrorHandler(NXopendata(fFileHandle, "environment"), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'environment' data in sample group!")) return NX_ERROR; + if (!ErrorHandler(GetStringData(str), PNEXUS_GET_DATA_ERROR, "couldn't read 'environment' data in sample group!")) return NX_ERROR; + if (!ErrorHandler(NXclosedata(fFileHandle), PNEXUS_CLOSE_DATA_ERROR, "couldn't close 'environment' data in sample group")) return NX_ERROR; + fNxEntry1->GetSample()->SetEnvironment(str); + + // close group NXsample + NXclosegroup(fFileHandle); + + // get required instrument information + // open subgroup NXinstrument with subgroups detector, collimator, beam + if (!ErrorHandler(NXopengroup(fFileHandle, "instrument", "NXinstrument"), PNEXUS_GROUP_OPEN_ERROR, "couldn't open NeXus subgroup instrument!")) return NX_ERROR; + + // get instrument name + if (!ErrorHandler(NXopendata(fFileHandle, "name"), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'name' data in instrument group!")) return NX_ERROR; + if (!ErrorHandler(GetStringData(str), PNEXUS_GET_DATA_ERROR, "couldn't read 'name' data in instrument group!")) return NX_ERROR; + if (!ErrorHandler(NXclosedata(fFileHandle), PNEXUS_CLOSE_DATA_ERROR, "couldn't close 'name' data in instrument group")) return NX_ERROR; + fNxEntry1->GetInstrument()->SetName(str); + + // open subgroup NXdetector + if (!ErrorHandler(NXopengroup(fFileHandle, "detector", "NXdetector"), PNEXUS_GROUP_OPEN_ERROR, "couldn't open NeXus subgroup detector!")) return NX_ERROR; + + // get number of detectors + if (!ErrorHandler(NXopendata(fFileHandle, "number"), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'number' data in detector group!")) return NX_ERROR; + if (!ErrorHandler(NXgetdata(fFileHandle, &ival), PNEXUS_GET_DATA_ERROR, "couldn't read 'number' data in detector group!")) return NX_ERROR; + if (!ErrorHandler(NXclosedata(fFileHandle), PNEXUS_CLOSE_DATA_ERROR, "couldn't close 'number' data in detector group")) return NX_ERROR; + fNxEntry1->GetInstrument()->GetDetector()->SetNumber(ival); + + // close subgroup NXdetector + NXclosegroup(fFileHandle); + + // open subgroup NXcollimator + if (!ErrorHandler(NXopengroup(fFileHandle, "collimator", "NXcollimator"), PNEXUS_GROUP_OPEN_ERROR, "couldn't open NeXus subgroup collimator!")) return NX_ERROR; + + // get collimator type + if (!ErrorHandler(NXopendata(fFileHandle, "type"), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'type' data in collimator group!")) return NX_ERROR; + if (!ErrorHandler(GetStringData(str), PNEXUS_GET_DATA_ERROR, "couldn't read 'type' data in collimator group!")) return NX_ERROR; + if (!ErrorHandler(NXclosedata(fFileHandle), PNEXUS_CLOSE_DATA_ERROR, "couldn't close 'type' data in collimator group")) return NX_ERROR; + fNxEntry1->GetInstrument()->GetCollimator()->SetType(str); + + // close subgroup NXcollimator + NXclosegroup(fFileHandle); + + // open subgroup NXbeam + if (!ErrorHandler(NXopengroup(fFileHandle, "beam", "NXbeam"), PNEXUS_GROUP_OPEN_ERROR, "couldn't open NeXus subgroup beam!")) return NX_ERROR; + + // get the total counts + if (!ErrorHandler(NXopendata(fFileHandle, "total_counts"), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'total_counts' data in beam group!")) return NX_ERROR; + if (!ErrorHandler(NXgetdata(fFileHandle, &fval), PNEXUS_GET_DATA_ERROR, "couldn't read 'total_counts' data in beam group!")) return NX_ERROR; + fNxEntry1->GetInstrument()->GetBeam()->SetTotalCounts((double)fval); + if (!ErrorHandler(GetStringAttr("units", str), PNEXUS_GET_ATTR_ERROR, "couldn't read total_counts units!")) return NX_ERROR; + fNxEntry1->GetInstrument()->GetBeam()->SetUnits(str); + if (!ErrorHandler(NXclosedata(fFileHandle), PNEXUS_CLOSE_DATA_ERROR, "couldn't close 'total_counts' data in beam group")) return NX_ERROR; + + // close subgroup NXbeam + NXclosegroup(fFileHandle); + + // close subgroup NXinstrument + NXclosegroup(fFileHandle); + + // open subgroup NXdata (this is for Version 1, only and is subject to change in the near future!) + if (!ErrorHandler(NXopengroup(fFileHandle, "histogram_data_1", "NXdata"), PNEXUS_GROUP_OPEN_ERROR, "couldn't open NeXus subgroup histogram_data_1!")) return NX_ERROR; + + // get time resolution + if (!ErrorHandler(NXopendata(fFileHandle, "resolution"), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'resolution' data in histogram_data_1 group!")) return NX_ERROR; + if (!ErrorHandler(NXgetdata(fFileHandle, &ival), PNEXUS_GET_DATA_ERROR, "couldn't read 'resolution' data in histogram_data_1 group!")) return NX_ERROR; + if (!ErrorHandler(GetStringAttr("units", str), PNEXUS_GET_ATTR_ERROR, "couldn't read 'resolution'' units!")) return NX_ERROR; + if (!ErrorHandler(NXclosedata(fFileHandle), PNEXUS_CLOSE_DATA_ERROR, "couldn't close 'resolution' data in histogram_data_1 group")) return NX_ERROR; + if (!strcmp(str.data(), "picoseconds")) { + fNxEntry1->GetData()->SetTimeResolution((double)ival, "ps"); + } + + // get data, t0, first good bin, last good bin, data + if (!ErrorHandler(NXopendata(fFileHandle, "counts"), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'counts' data in histogram_data_1 group!")) return NX_ERROR; + int histoLength=0; + int noOfHistos=0; + + // get number of histos + attLen = 1; + attType = NX_INT32; + memset(cstr, '\0', sizeof(cstr)); + strncpy(cstr, "number", sizeof(cstr)); + if (!ErrorHandler(NXgetattr(fFileHandle, cstr, &noOfHistos, &attLen, &attType), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'number' data in histogram_data_1 group!")) return NX_ERROR; + + // get histo length + attLen = 1; + attType = NX_INT32; + memset(cstr, '\0', sizeof(cstr)); + strncpy(cstr, "length", sizeof(cstr)); + if (!ErrorHandler(NXgetattr(fFileHandle, cstr, &histoLength, &attLen, &attType), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'number' data in histogram_data_1 group!")) return NX_ERROR; + + // get t0 + attLen = 1; + attType = NX_INT32; + memset(cstr, '\0', sizeof(cstr)); + strncpy(cstr, "t0_bin", sizeof(cstr)); + if (!ErrorHandler(NXgetattr(fFileHandle, cstr, &ival, &attLen, &attType), PNEXUS_OPEN_DATA_ERROR, "couldn't open 't0_bin' data in histogram_data_1 group!")) return NX_ERROR; + fNxEntry1->GetData()->SetT0(ival); + + // get first good bin + attLen = 1; + attType = NX_INT32; + memset(cstr, '\0', sizeof(cstr)); + strncpy(cstr, "first_good_bin", sizeof(cstr)); + if (!ErrorHandler(NXgetattr(fFileHandle, cstr, &ival, &attLen, &attType), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'first_good_bin' data in histogram_data_1 group!")) return NX_ERROR; + fNxEntry1->GetData()->SetFirstGoodBin(ival); + + // get last good bin + attLen = 1; + attType = NX_INT32; + memset(cstr, '\0', sizeof(cstr)); + strncpy(cstr, "last_good_bin", sizeof(cstr)); + if (!ErrorHandler(NXgetattr(fFileHandle, cstr, &ival, &attLen, &attType), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'last_good_bin' data in histogram_data_1 group!")) return NX_ERROR; + fNxEntry1->GetData()->SetLastGoodBin(ival); + + // get data + + // get information of the current nexus entity + int rank, type, dims[32], size, noOfElements; + if (!ErrorHandler(NXgetinfo(fFileHandle, &rank, dims, &type), PNEXUS_GET_META_INFO_ERROR, "couldn't get data info!")) return NX_ERROR; + + // calculate the needed size + size = dims[0]; + for (int i=1; iGetData()->FlushHistos(); + vector data; + for (int i=0; i0)) { + fNxEntry1->GetData()->SetHisto(data); + data.clear(); + data.push_back(*(i_data_ptr+i)); + } else { + data.push_back(*(i_data_ptr+i)); + } + } + fNxEntry1->GetData()->SetHisto(data); + data.clear(); + + // clean up + if (data_ptr) { + delete [] data_ptr; + } + + if (!ErrorHandler(NXclosedata(fFileHandle), PNEXUS_CLOSE_DATA_ERROR, "couldn't close 'counts' data in histogram_data_1 group")) return NX_ERROR; + + // get grouping + if (!ErrorHandler(NXopendata(fFileHandle, "grouping"), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'grouping' data in histogram_data_1 group!")) return NX_ERROR; + attLen = 1; + attType = NX_INT32; + memset(cstr, '\0', sizeof(cstr)); + strncpy(cstr, "available", sizeof(cstr)); + if (!ErrorHandler(NXgetattr(fFileHandle, cstr, &ival, &attLen, &attType), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'grouping available' data in histogram_data_1 group!")) return NX_ERROR; + if (ival) { + vector grouping; + if (!ErrorHandler(GetIntVectorData(grouping), PNEXUS_GET_DATA_ERROR, "couldn't read 'grouping' data in histogram_data_1 group!")) return NX_ERROR; + fNxEntry1->GetData()->SetGrouping(grouping); + grouping.clear(); + } + if (!ErrorHandler(NXclosedata(fFileHandle), PNEXUS_CLOSE_DATA_ERROR, "couldn't close 'grouping' data in histogram_data_1 group")) return NX_ERROR; + // check grouping vector for consistency + if (fNxEntry1->GetData()->GetGrouping()->size() != fNxEntry1->GetData()->GetNoOfHistos()) { + fNxEntry1->GetData()->FlushGrouping(); + cerr << endl << ">> **WARNING** grouping vector size != no of histograms which doesn't make sence, hence grouping will be ignored." << endl; + } + // check that the grouping values do make sense, i.e. allowed range is grouping value > 0 and grouping value <= # of histos + bool ok=true; + for (unsigned int i=0; iGetData()->GetGrouping()->size(); i++) { + if ((fNxEntry1->GetData()->GetGrouping()->at(i) == 0) || (fNxEntry1->GetData()->GetGrouping()->at(i) > (int)fNxEntry1->GetData()->GetNoOfHistos())) { + cerr << endl << ">> **WARNING** found grouping entry '" << fNxEntry1->GetData()->GetGrouping()->at(i) << "' which doesn't make sense, hence grouping will be ignored." << endl; + ok = false; + break; + } + } + if (!ok) + fNxEntry1->GetData()->FlushGrouping(); + + // get alpha + if (!ErrorHandler(NXopendata(fFileHandle, "alpha"), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'alpha' data in histogram_data_1 group!")) return NX_ERROR; + attLen = 1; + attType = NX_INT32; + memset(cstr, '\0', sizeof(cstr)); + strncpy(cstr, "available", sizeof(cstr)); + if (!ErrorHandler(NXgetattr(fFileHandle, cstr, &ival, &attLen, &attType), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'alpha available' data in histogram_data_1 group!")) return NX_ERROR; + if (ival) { + if (!ErrorHandler(NXgetinfo(fFileHandle, &rank, dims, &type), PNEXUS_GET_META_INFO_ERROR, "couldn't get alpha info!")) return NX_ERROR; + // calculate the needed size + size = dims[0]; + for (int i=1; i> **ERROR** " << fErrorMsg << endl; + return NX_ERROR; + } + + // allocate locale memory to get the data + char *data_ptr = new char[size]; + if (data_ptr == 0) { + return NX_ERROR; + } + + // get the data + float *f_data_ptr = (float*) data_ptr; + status = NXgetdata(fFileHandle, f_data_ptr); + if (status != NX_OK) { + return NX_ERROR; + } + + // copy the data into the vector + fNxEntry1->GetData()->FlushAlpha(); + PNeXusAlpha1 alpha; + vector alphaVec; + for (int i=0; iGetData()->SetAlpha(alphaVec); + + // clean up + alphaVec.clear(); + if (data_ptr) { + delete [] data_ptr; + } + } + if (!ErrorHandler(NXclosedata(fFileHandle), PNEXUS_CLOSE_DATA_ERROR, "couldn't close 'alpha' data in histogram_data_1 group")) return NX_ERROR; + + // close subgroup NXdata + NXclosegroup(fFileHandle); + + // close group NXentry + NXclosegroup(fFileHandle); + + // close file + NXclose(&fFileHandle); + + GroupHistoData(); + + fValid = true; + + return NX_OK; } -//----------------------------------------------------------------------------------------------------- -// SetFirstGoodBin (public) -//----------------------------------------------------------------------------------------------------- +//------------------------------------------------------------------------------------------ +// ReadFileIdf2 (private) +//------------------------------------------------------------------------------------------ /** - *

Sets first good bin. The current muSR NeXus implementation has only a single first good bin for all detectors since it was - * tailored for pulsed muon sources (ISIS). This eventually needs to be changed. + *

Read the NeXus file of type IDF Version 2. * - * \param fgb first good bin to be set - * \param idx index of t0 + * return: + * - NX_OK on successfull reading + * - NX_ERROR on error. The error code/message will give the details. */ -void PNeXus::SetFirstGoodBin(unsigned int fgb, unsigned int idx) +int PNeXus::ReadFileIdf2() { - if (idx >= fData.fFirstGoodBin.size()) - fData.fFirstGoodBin.resize(idx+1); + // create first the necessary NXentry object for IDF Version 1 + fNxEntry2 = new PNeXusEntry2(); + if (fNxEntry2 == 0) { + fErrorCode = PNEXUS_OBJECT_INVOK_ERROR; + fErrorMsg = ">> **ERROR** couldn't invoke PNeXusEntry2 object."; + return NX_ERROR; + } - fData.fFirstGoodBin[idx] = fgb; + string str; + int ival, attlen, atttype; + float fval; + NXname data_value; + int rank, type, dims[32], size, noOfElements; + + // open file + NXstatus status; + status = NXopen(fFileName.c_str(), NXACC_READ, &fFileHandle); + if (status != NX_OK) { + fErrorCode = PNEXUS_FILE_OPEN_ERROR; + fErrorMsg = "PNeXus::ReadFile() **ERROR** Couldn't open file '"+fFileName+"' !"; + return NX_ERROR; + } + + // collect the NXroot attribute information + if (!ErrorHandler(GetStringAttr("file_name", str), PNEXUS_GET_ATTR_ERROR, "couldn't read NXroot 'file_name' attribute!")) return NX_ERROR; + fFileName = str; + if (!ErrorHandler(GetStringAttr("file_time", str), PNEXUS_GET_ATTR_ERROR, "couldn't read NXroot 'file_time' attribute!")) return NX_ERROR; + fFileTime = str; + if (!ErrorHandler(GetStringAttr("creator", str), PNEXUS_GET_ATTR_ERROR, "couldn't read NXroot 'creator' attribute!")) return NX_ERROR; + fCreator = str; + + attlen = VGNAMELENMAX - 1; + atttype = NX_CHAR; + str = string("HDF_version"); + status = NXgetattr(fFileHandle, (char *)str.c_str(), data_value, &attlen, &atttype); + if (status == NX_OK) { + fFileFormatVersion = string(data_value); + } + + if (!fFileFormatVersion.compare("n/a")) { + attlen = VGNAMELENMAX - 1; + atttype = NX_CHAR; + str = string("HDF5_version"); + status = NXgetattr(fFileHandle, (char *)str.c_str(), data_value, &attlen, &atttype); + if (status == NX_OK) { + fFileFormatVersion = string(data_value); + } + } + + if (!fFileFormatVersion.compare("n/a")) { + attlen = VGNAMELENMAX - 1; + atttype = NX_CHAR; + str = string("XML_version"); + status = NXgetattr(fFileHandle, (char *)str.c_str(), data_value, &attlen, &atttype); + if (status == NX_OK) { + fFileFormatVersion = string(data_value); + } + } + + // look for the first occurring NXentry + NXname nxname, nxclass; + int dataType; + // make sure any NXentry has been found + if (!SearchInGroup("NXentry", "class", nxname, nxclass, dataType)) { + fErrorCode = PNEXUS_NXENTRY_NOT_FOUND; + fErrorMsg = ">> **ERROR** Couldn't find any NXentry!"; + return NX_ERROR; + } + // open the NXentry group to obtain the necessary stuff + status = NXopengroup(fFileHandle, nxname, "NXentry"); + if (status != NX_OK) { + fErrorCode = PNEXUS_GROUP_OPEN_ERROR; + fErrorMsg = "PNeXus::ReadFileIdf2() **ERROR** Couldn't open the NeXus group '" + string(nxname) + "'!"; + return NX_ERROR; + } + + // definition + if (!ErrorHandler(NXopendata(fFileHandle, "definition"), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'definition' data in NXentry!")) return NX_ERROR; + if (!ErrorHandler(GetStringData(str), PNEXUS_GET_DATA_ERROR, "couldn't read 'definition' data in NXentry!")) return NX_ERROR; + if (!ErrorHandler(NXclosedata(fFileHandle), PNEXUS_CLOSE_DATA_ERROR, "couldn't close 'definition' data in NXentry!")) return NX_ERROR; + fNxEntry2->SetDefinition(str); + + // program_name and version + if (NXopendata(fFileHandle, "program_name") == NX_OK) { + if (!ErrorHandler(GetStringData(str), PNEXUS_GET_DATA_ERROR, "couldn't read 'program_name' data in NXentry!")) return NX_ERROR; + fNxEntry2->SetProgramName(str); + if (!ErrorHandler(GetStringAttr("version", str), PNEXUS_GET_ATTR_ERROR, "couldn't read 'program_name' attribute in NXentry!")) return NX_ERROR; + fNxEntry2->SetProgramVersion(str); + if (!ErrorHandler(NXclosedata(fFileHandle), PNEXUS_CLOSE_DATA_ERROR, "couldn't close 'program_name' data in NXentry!")) return NX_ERROR; + } + + // run number + if (!ErrorHandler(NXopendata(fFileHandle, "run_number"), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'run_number' data in NXentry!")) return NX_ERROR; + if (!ErrorHandler(NXgetdata(fFileHandle, &ival), PNEXUS_GET_DATA_ERROR, "couldn't read 'run_number' data in NXentry!")) return NX_ERROR; + if (!ErrorHandler(NXclosedata(fFileHandle), PNEXUS_CLOSE_DATA_ERROR, "couldn't close 'run_number' data in NXentry!")) return NX_ERROR; + fNxEntry2->SetRunNumber(ival); + + // title + if (!ErrorHandler(NXopendata(fFileHandle, "title"), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'title' data in NXentry!")) return NX_ERROR; + if (!ErrorHandler(GetStringData(str), PNEXUS_GET_DATA_ERROR, "couldn't read 'title' data in NXentry!")) return NX_ERROR; + if (!ErrorHandler(NXclosedata(fFileHandle), PNEXUS_CLOSE_DATA_ERROR, "couldn't close 'title' data in NXentry!")) return NX_ERROR; + fNxEntry2->SetTitle(str); + + // start time + if (!ErrorHandler(NXopendata(fFileHandle, "start_time"), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'start_time' data in NXentry!")) return NX_ERROR; + if (!ErrorHandler(GetStringData(str), PNEXUS_GET_DATA_ERROR, "couldn't read 'start_time' data in NXentry!")) return NX_ERROR; + if (!ErrorHandler(NXclosedata(fFileHandle), PNEXUS_CLOSE_DATA_ERROR, "couldn't close 'start_time' data in NXentry!")) return NX_ERROR; + if (fNxEntry2->SetStartTime(str) != NX_OK) { + fErrorCode = PNEXUS_TIME_FORMAT_ERROR; + fErrorMsg = "start time format is not ISO 8601 conform."; + } + + // end time + if (!ErrorHandler(NXopendata(fFileHandle, "end_time"), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'end_time' data in NXentry!")) return NX_ERROR; + if (!ErrorHandler(GetStringData(str), PNEXUS_GET_DATA_ERROR, "couldn't read 'end_time' data in NXentry!")) return NX_ERROR; + if (!ErrorHandler(NXclosedata(fFileHandle), PNEXUS_CLOSE_DATA_ERROR, "couldn't close 'end_time' data in NXentry!")) return NX_ERROR; + if (fNxEntry2->SetStopTime(str) != NX_OK) { + fErrorCode = PNEXUS_TIME_FORMAT_ERROR; + fErrorMsg = "stop time format is not ISO 8601 conform.."; + } + + // experiment identifier + if (!ErrorHandler(NXopendata(fFileHandle, "experiment_identifier"), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'experiment_identifier' data in NXentry!")) return NX_ERROR; + if (!ErrorHandler(GetStringData(str), PNEXUS_GET_DATA_ERROR, "couldn't read 'experiment_identifier' data in NXentry!")) return NX_ERROR; + if (!ErrorHandler(NXclosedata(fFileHandle), PNEXUS_CLOSE_DATA_ERROR, "couldn't close 'experiment_identifier' data in NXentry!")) return NX_ERROR; + fNxEntry2->SetExperimentIdentifier(str); + + // find entry for NXuser + if (!SearchInGroup("NXuser", "class", nxname, nxclass, dataType)) { + fErrorCode = PNEXUS_NXUSER_NOT_FOUND; + fErrorMsg = ">> **ERROR** Couldn't find any NXuser int NXentry!"; + return NX_ERROR; + } + // open the NXuser + status = NXopengroup(fFileHandle, nxname, "NXuser"); + if (status != NX_OK) { + fErrorCode = PNEXUS_GROUP_OPEN_ERROR; + fErrorMsg = "PNeXus::ReadFileIdf2() **ERROR** Couldn't open NXuser '" + string(nxname) + "' in NXentry!"; + return NX_ERROR; + } + + // user name + if (!ErrorHandler(NXopendata(fFileHandle, "name"), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'name' data in NXuser!")) return NX_ERROR; + if (!ErrorHandler(GetStringData(str), PNEXUS_GET_DATA_ERROR, "couldn't read 'name' data in NXuser!")) return NX_ERROR; + if (!ErrorHandler(NXclosedata(fFileHandle), PNEXUS_CLOSE_DATA_ERROR, "couldn't close 'name' data in NXuser!")) return NX_ERROR; + fNxEntry2->GetUser()->SetName(str); + + // close group NXuser + NXclosegroup(fFileHandle); + + // open group NXsample + if (!ErrorHandler(NXopengroup(fFileHandle, "sample", "NXsample"), PNEXUS_GROUP_OPEN_ERROR, "couldn't open NeXus subgroup sample!")) return NX_ERROR; + + // sample name + if (!ErrorHandler(NXopendata(fFileHandle, "name"), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'name' data in NXsample!")) return NX_ERROR; + if (!ErrorHandler(GetStringData(str), PNEXUS_GET_DATA_ERROR, "couldn't read 'name' data in NXsample!")) return NX_ERROR; + if (!ErrorHandler(NXclosedata(fFileHandle), PNEXUS_CLOSE_DATA_ERROR, "couldn't close 'name' data in NXsample!")) return NX_ERROR; + fNxEntry2->GetSample()->SetName(str); + + // sample description + if (NXopendata(fFileHandle, "description") == NX_OK) { + if (!ErrorHandler(GetStringData(str), PNEXUS_GET_DATA_ERROR, "couldn't read 'description' data in NXsample!")) return NX_ERROR; + if (!ErrorHandler(NXclosedata(fFileHandle), PNEXUS_CLOSE_DATA_ERROR, "couldn't close 'description' data in NXsample!")) return NX_ERROR; + fNxEntry2->GetSample()->SetDescription(str); + } + + // temperature + if (NXopendata(fFileHandle, "temperature_1") == NX_OK) { + if (!ErrorHandler(NXgetdata(fFileHandle, &fval), PNEXUS_GET_DATA_ERROR, "couldn't read 'temperature_1' data in NXsample!")) return NX_ERROR; + if (!ErrorHandler(GetStringAttr("units", str), PNEXUS_GET_ATTR_ERROR, "couldn't read temperature units in NXsample!")) return NX_ERROR; + if (!ErrorHandler(NXclosedata(fFileHandle), PNEXUS_CLOSE_DATA_ERROR, "couldn't close 'temperature_1' data in NXsample!")) return NX_ERROR; + fNxEntry2->GetSample()->SetPhysProp("temperature_1", fval, str); + } + + // temperature environment + if (NXopengroup(fFileHandle, "temperature_1_env", "NXenvironment") == NX_OK) { + // user name + if (!ErrorHandler(NXopendata(fFileHandle, "name"), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'name' data in NXenvironment!")) return NX_ERROR; + if (!ErrorHandler(GetStringData(str), PNEXUS_GET_DATA_ERROR, "couldn't read 'name' data in NXenvironment!")) return NX_ERROR; + if (!ErrorHandler(NXclosedata(fFileHandle), PNEXUS_CLOSE_DATA_ERROR, "couldn't close 'name' data in NXenvironment!")) return NX_ERROR; + fNxEntry2->GetSample()->SetEnvironmentTemp(str); + // close group NXenvironment + NXclosegroup(fFileHandle); + } + + // magnetic_field + if (NXopendata(fFileHandle, "magnetic_field_1") == NX_OK) { + if (!ErrorHandler(NXgetdata(fFileHandle, &fval), PNEXUS_GET_DATA_ERROR, "couldn't read 'magnetic_field_1' data in NXsample!")) return NX_ERROR; + if (!ErrorHandler(GetStringAttr("units", str), PNEXUS_GET_ATTR_ERROR, "couldn't read magnetic field units in NXsample!")) return NX_ERROR; + if (!ErrorHandler(NXclosedata(fFileHandle), PNEXUS_CLOSE_DATA_ERROR, "couldn't close 'magnetic_field_1' data in NXsample!")) return NX_ERROR; + fNxEntry2->GetSample()->SetPhysProp("magnetic_field_1", fval, str); + } + + // magnetic field state + if (NXopendata(fFileHandle, "magnetic_field_state") == NX_OK) { + if (!ErrorHandler(GetStringData(str), PNEXUS_GET_DATA_ERROR, "couldn't read 'magnetic_field_state' data in NXsample!")) return NX_ERROR; + if (!ErrorHandler(NXclosedata(fFileHandle), PNEXUS_CLOSE_DATA_ERROR, "couldn't close 'magnetic_field_state' data in NXsample!")) return NX_ERROR; + fNxEntry2->GetSample()->SetMagneticFieldState(str); + } + + // magnetic field environment + if (NXopengroup(fFileHandle, "magnetic_field_1_env", "NXenvironment") == NX_OK) { + // user name + if (!ErrorHandler(NXopendata(fFileHandle, "name"), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'name' data in NXenvironment!")) return NX_ERROR; + if (!ErrorHandler(GetStringData(str), PNEXUS_GET_DATA_ERROR, "couldn't read 'name' data in NXenvironment!")) return NX_ERROR; + if (!ErrorHandler(NXclosedata(fFileHandle), PNEXUS_CLOSE_DATA_ERROR, "couldn't close 'name' data in NXenvironment!")) return NX_ERROR; + fNxEntry2->GetSample()->SetEnvironmentField(str); + // close group NXenvironment + NXclosegroup(fFileHandle); + } + + // close group NXsample + NXclosegroup(fFileHandle); + + // open group NXinstrument + if (!ErrorHandler(NXopengroup(fFileHandle, "instrument", "NXinstrument"), PNEXUS_GROUP_OPEN_ERROR, "couldn't open NeXus subgroup instrument in NXentry!")) return NX_ERROR; + + // name + if (!ErrorHandler(NXopendata(fFileHandle, "name"), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'name' data in NXinstrument!")) return NX_ERROR; + if (!ErrorHandler(GetStringData(str), PNEXUS_GET_DATA_ERROR, "couldn't read 'name' data in NXinstrument!")) return NX_ERROR; + if (!ErrorHandler(NXclosedata(fFileHandle), PNEXUS_CLOSE_DATA_ERROR, "couldn't close 'name' data in NXinstrument!")) return NX_ERROR; + fNxEntry2->GetInstrument()->SetName(str); + + // open group NXsource + if (!ErrorHandler(NXopengroup(fFileHandle, "source", "NXsource"), PNEXUS_GROUP_OPEN_ERROR, "couldn't open NeXus subgroup instrument in NXinstrument!")) return NX_ERROR; + + // name + if (!ErrorHandler(NXopendata(fFileHandle, "name"), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'name' data in NXsource!")) return NX_ERROR; + if (!ErrorHandler(GetStringData(str), PNEXUS_GET_DATA_ERROR, "couldn't read 'name' data in NXsource!")) return NX_ERROR; + if (!ErrorHandler(NXclosedata(fFileHandle), PNEXUS_CLOSE_DATA_ERROR, "couldn't close 'name' data in NXsource!")) return NX_ERROR; + fNxEntry2->GetInstrument()->GetSource()->SetName(str); + + // type + if (!ErrorHandler(NXopendata(fFileHandle, "type"), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'type' data in NXsource!")) return NX_ERROR; + if (!ErrorHandler(GetStringData(str), PNEXUS_GET_DATA_ERROR, "couldn't read 'type' data in NXsource!")) return NX_ERROR; + if (!ErrorHandler(NXclosedata(fFileHandle), PNEXUS_CLOSE_DATA_ERROR, "couldn't close 'type' data in NXsource!")) return NX_ERROR; + fNxEntry2->GetInstrument()->GetSource()->SetType(str); + + // probe + if (!ErrorHandler(NXopendata(fFileHandle, "probe"), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'probe' data in NXsource!")) return NX_ERROR; + if (!ErrorHandler(GetStringData(str), PNEXUS_GET_DATA_ERROR, "couldn't read 'probe' data in NXsource!")) return NX_ERROR; + if (!ErrorHandler(NXclosedata(fFileHandle), PNEXUS_CLOSE_DATA_ERROR, "couldn't close 'probe' data in NXsource!")) return NX_ERROR; + fNxEntry2->GetInstrument()->GetSource()->SetProbe(str); + + // close group NXsource + NXclosegroup(fFileHandle); + + // open group NXbeamline + if (!ErrorHandler(NXopengroup(fFileHandle, "beamline", "NXbeamline"), PNEXUS_GROUP_OPEN_ERROR, "couldn't open NeXus subgroup beamline in NXinstrument!")) return NX_ERROR; + + // beamline name + if (!ErrorHandler(NXopendata(fFileHandle, "beamline"), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'beamline' data in NXbeamline!")) return NX_ERROR; + if (!ErrorHandler(GetStringData(str), PNEXUS_GET_DATA_ERROR, "couldn't read 'beamline' data in NXbeamline!")) return NX_ERROR; + if (!ErrorHandler(NXclosedata(fFileHandle), PNEXUS_CLOSE_DATA_ERROR, "couldn't close 'beamline' data in NXbeamline!")) return NX_ERROR; + fNxEntry2->GetInstrument()->GetBeamline()->SetName(str); + + // close group NXbeamline + NXclosegroup(fFileHandle); + + // open group NXdetector + if (!ErrorHandler(NXopengroup(fFileHandle, "detector_1", "NXdetector"), PNEXUS_GROUP_OPEN_ERROR, "couldn't open NeXus subgroup detector_1 in NXinstrument!")) return NX_ERROR; + + // description + if (!ErrorHandler(NXopendata(fFileHandle, "description"), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'description' data in NXdetector!")) return NX_ERROR; + if (!ErrorHandler(GetStringData(str), PNEXUS_GET_DATA_ERROR, "couldn't read 'description' data in NXdetector!")) return NX_ERROR; + if (!ErrorHandler(NXclosedata(fFileHandle), PNEXUS_CLOSE_DATA_ERROR, "couldn't close 'description' data in NXdetector!")) return NX_ERROR; + fNxEntry2->GetInstrument()->GetDetector()->SetDescription(str); + + // get the time resolution. This is a little bit complicated since it is either present as 'histogram_resolution' or needs to be extracted from the 'raw_time' vector + // 1st check if 'histogram_resolution' is found + if (SearchInGroup("histogram_resolution", "name", nxname, nxclass, dataType)) { + if (!ErrorHandler(NXopendata(fFileHandle, "histogram_resolution"), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'histogram_resolution' data in NXdetector!")) return NX_ERROR; + if (!ErrorHandler(NXgetdata(fFileHandle, &ival), PNEXUS_GET_DATA_ERROR, "couldn't read 'histogram_resolution' data in NXdetector!")) return NX_ERROR; + if (!ErrorHandler(GetStringAttr("units", str), PNEXUS_GET_ATTR_ERROR, "couldn't read magnetic field units in NXsample!")) return NX_ERROR; + if (!ErrorHandler(NXclosedata(fFileHandle), PNEXUS_CLOSE_DATA_ERROR, "couldn't close 'histogram_resolution' data in NXdetector!")) return NX_ERROR; + fNxEntry2->GetInstrument()->GetDetector()->SetTimeResolution((double)ival, str); + } else { // 2nd 'histogram_resolution' is not present, hence extract the time resolution from the 'raw_time' vector + if (!ErrorHandler(NXopendata(fFileHandle, "raw_time"), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'raw_time' data in NXdetector!")) return NX_ERROR; + vector rawTime; + if (!ErrorHandler(GetDoubleVectorData(rawTime), PNEXUS_GET_DATA_ERROR, "couldn't get 'raw_time' data in NXdetector!")) return NX_ERROR; + if (!ErrorHandler(GetStringAttr("units", str), PNEXUS_GET_ATTR_ERROR, "couldn't read 'raw_time' units in NXdetector!")) return NX_ERROR; + if (!ErrorHandler(NXclosedata(fFileHandle), PNEXUS_CLOSE_DATA_ERROR, "couldn't close 'raw_time' data in NXdetector!")) return NX_ERROR; + fNxEntry2->GetInstrument()->GetDetector()->SetTimeResolution(rawTime[1]-rawTime[0], str); + rawTime.clear(); + } + + // get counts + if (!ErrorHandler(NXopendata(fFileHandle, "counts"), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'counts' data in NXdetector!")) return NX_ERROR; + // check the dimensions of 'counts' + if (!ErrorHandler(NXgetinfo(fFileHandle, &rank, dims, &type), PNEXUS_GET_META_INFO_ERROR, "couldn't get 'counts' info in NXdetector!")) return NX_ERROR; + + // calculate the needed size + size = dims[0]; + for (int i=1; iGetInstrument()->GetDetector()->SetHisto(i_data_ptr); + + if (rank == 3) { // i.e. np, ns, ntc + fNxEntry2->GetInstrument()->GetDetector()->SetNoOfPeriods(dims[0]); + fNxEntry2->GetInstrument()->GetDetector()->SetNoOfSpectra(dims[1]); + fNxEntry2->GetInstrument()->GetDetector()->SetNoOfBins(dims[2]); + } else if (rank == 2) { // i.e. ns, ntc + fNxEntry2->GetInstrument()->GetDetector()->SetNoOfPeriods(-1); + fNxEntry2->GetInstrument()->GetDetector()->SetNoOfSpectra(dims[0]); + fNxEntry2->GetInstrument()->GetDetector()->SetNoOfBins(dims[1]); + } else if (rank == 1) { // i.e. ntc only + fNxEntry2->GetInstrument()->GetDetector()->SetNoOfPeriods(-1); + fNxEntry2->GetInstrument()->GetDetector()->SetNoOfSpectra(1); + fNxEntry2->GetInstrument()->GetDetector()->SetNoOfBins(dims[0]); + } else { + fNxEntry2->GetInstrument()->GetDetector()->SetNoOfPeriods(-1); + fNxEntry2->GetInstrument()->GetDetector()->SetNoOfSpectra(-1); + fNxEntry2->GetInstrument()->GetDetector()->SetNoOfBins(-1); + cerr << endl << ">> **ERROR** found rank=" << rank << " for NXinstrument:NXdetector:counts! Allowed ranks are 1, 2, or 3." << endl; + return NX_ERROR; + } + + if (!ErrorHandler(NXclosedata(fFileHandle), PNEXUS_CLOSE_DATA_ERROR, "couldn't close 'counts' data in NXdetector!")) return NX_ERROR; + + // handle spectrum_index + if (!ErrorHandler(NXopendata(fFileHandle, "spectrum_index"), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'spectrum_index' data in NXdetector!")) return NX_ERROR; + // check the dimensions of 'spectrum_index' + if (!ErrorHandler(NXgetinfo(fFileHandle, &rank, dims, &type), PNEXUS_GET_META_INFO_ERROR, "couldn't get 'spectrum_index' info in NXdetector!")) return NX_ERROR; + if (rank > 1) { + cerr << endl << ">> **ERROR** found rank=" << rank << " of spectrum_index in NXdetector. Rank needs to be == 1!" << endl; + return NX_ERROR; + } + if (dims[0] != fNxEntry2->GetInstrument()->GetDetector()->GetNoOfSpectra()) { + cerr << endl << ">> **ERROR** found spectrum_index dimension=" << dims[0] << " inconsistent with counts (" << fNxEntry2->GetInstrument()->GetDetector()->GetNoOfSpectra() << "!" << endl; + return NX_ERROR; + } + // allocate locale memory to get the data + data_ptr = new char[dims[0]*GetDataSize(type)]; + if (data_ptr == 0) { + return NX_ERROR; + } + // get the data + i_data_ptr = (int*) data_ptr; + status = NXgetdata(fFileHandle, i_data_ptr); + if (status != NX_OK) { + return NX_ERROR; + } + for (int i=0; iGetInstrument()->GetDetector()->SetSpectrumIndex(*(i_data_ptr+i), i); + + // clean up + if (data_ptr) { + delete [] data_ptr; + data_ptr = 0; + } + + if (!ErrorHandler(NXclosedata(fFileHandle), PNEXUS_CLOSE_DATA_ERROR, "couldn't close 'spectrum_index' data in NXdetector!")) return NX_ERROR; + + // handle t0's + if (SearchInGroup("time_zero_bin", "name", nxname, nxclass, dataType)) { // check for 'time_zero_bin' + if (!ErrorHandler(NXopendata(fFileHandle, "time_zero_bin"), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'time_zero_bin' data in NXdetector!")) return NX_ERROR; + + // check the dimensions of the 'time_zero_bin' vector + if (!ErrorHandler(NXgetinfo(fFileHandle, &rank, dims, &type), PNEXUS_GET_META_INFO_ERROR, "couldn't get 'time_zero_bin' info in NXdetector!")) return NX_ERROR; + + if (rank <= 2) { + fNxEntry2->GetInstrument()->GetDetector()->SetT0Tag(rank); + } else { + cerr << endl << ">> **ERROR** found 'time_zero_bin' info in NXdetector with rank=" << rank << ". Do not know how to handle." << endl; + return NX_ERROR; + } + + // calculate the needed size + size = dims[0]; + for (int i=1; iGetInstrument()->GetDetector()->SetT0(i_data_ptr); + + if (!ErrorHandler(NXclosedata(fFileHandle), PNEXUS_CLOSE_DATA_ERROR, "couldn't close 'time_zero_bin' data in NXdetector!")) return NX_ERROR; + } else if (SearchInGroup("time_zero", "name", nxname, nxclass, dataType)) { // check for 'time_zero' + if (!ErrorHandler(NXopendata(fFileHandle, "time_zero"), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'time_zero' data in NXdetector!")) return NX_ERROR; + // check the dimensions of the 'time_zero' vector + if (!ErrorHandler(NXgetinfo(fFileHandle, &rank, dims, &type), PNEXUS_GET_META_INFO_ERROR, "couldn't get 'time_zero' info in NXdetector!")) return NX_ERROR; + + if (rank <= 2) { + fNxEntry2->GetInstrument()->GetDetector()->SetT0Tag(rank); + } else { + cerr << endl << ">> **ERROR** found 'time_zero' info in NXdetector with rank=" << rank << ". Do not know how to handle." << endl; + return NX_ERROR; + } + + // calculate the needed size + size = dims[0]; + for (int i=1; iGetInstrument()->GetDetector()->GetTimeResolution(str) == 0.0) { + cerr << endl << ">> **ERROR** trying to set T0's based on 'time_zero'. Need a valid time resolution to do so, but this is not given." << endl; + return NX_ERROR; + } + // set the t0's based on the t0 time stamp and the time resolution + int *pt0 = 0; + if (rank == 1) { + pt0 = new int; + *pt0 = (int)(*f_data_ptr / (float)fNxEntry2->GetInstrument()->GetDetector()->GetTimeResolution(str)); + } else { // rank == 2 + pt0 = new int[noOfElements]; + for (int i=0; iGetInstrument()->GetDetector()->GetTimeResolution(str)); + } + } + fNxEntry2->GetInstrument()->GetDetector()->SetT0(pt0); + + // clean up + if (data_ptr) { + delete [] data_ptr; + } + + cerr << endl << ">> **WARNING** found only 'time_zero' will convert it to 'time_zero_bin' values" << endl; + if (!ErrorHandler(NXclosedata(fFileHandle), PNEXUS_CLOSE_DATA_ERROR, "couldn't close 'time_zero' data in NXdetector!")) return NX_ERROR; + } else { + cerr << endl << ">> **WARNING** found neither 'time_zero_bin' nor 'time_zero' values ..." << endl; + } + + // handle first good bin + if (SearchInGroup("first_good_bin", "name", nxname, nxclass, dataType)) { + if (!ErrorHandler(NXopendata(fFileHandle, "first_good_bin"), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'first_good_bin' data in NXdetector!")) return NX_ERROR; + + // check the dimensions of the 'first_good_bin' vector + if (!ErrorHandler(NXgetinfo(fFileHandle, &rank, dims, &type), PNEXUS_GET_META_INFO_ERROR, "couldn't get 'first_good_bin' info in NXdetector!")) return NX_ERROR; + + if (rank <= 2) { + if (rank != fNxEntry2->GetInstrument()->GetDetector()->GetT0Tag()) { + cerr << endl << ">> **ERROR** rank of 'first_good_bin' (" << rank << ") is different than t0 rank=" << rank << ". Do not know how to handle." << endl; + return NX_ERROR; + } + } else { + cerr << endl << ">> **ERROR** found 'first_good_bin' info in NXdetector with rank=" << rank << ". Do not know how to handle." << endl; + return NX_ERROR; + } + + // calculate the needed size + size = dims[0]; + for (int i=1; iGetInstrument()->GetDetector()->SetFirstGoodBin(i_data_ptr); + + if (!ErrorHandler(NXclosedata(fFileHandle), PNEXUS_CLOSE_DATA_ERROR, "couldn't close 'first_good_bin' data in NXdetector!")) return NX_ERROR; + } else if (SearchInGroup("first_good_time", "name", nxname, nxclass, dataType)) { + if (!ErrorHandler(NXopendata(fFileHandle, "first_good_time"), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'first_good_time' data in NXdetector!")) return NX_ERROR; + + // check the dimensions of the 'first_good_time' vector + if (!ErrorHandler(NXgetinfo(fFileHandle, &rank, dims, &type), PNEXUS_GET_META_INFO_ERROR, "couldn't get 'first_good_time' info in NXdetector!")) return NX_ERROR; + + if (rank <= 2) { + if (rank != fNxEntry2->GetInstrument()->GetDetector()->GetT0Tag()) { + cerr << endl << ">> **ERROR** rank of 'first_good_time' (" << rank << ") is different than t0 rank=" << rank << ". Do not know how to handle." << endl; + return NX_ERROR; + } + } else { + cerr << endl << ">> **ERROR** found 'first_good_time' info in NXdetector with rank=" << rank << ". Do not know how to handle." << endl; + return NX_ERROR; + } + + // calculate the needed size + size = dims[0]; + for (int i=1; iGetInstrument()->GetDetector()->GetTimeResolution(str)); + } else { // rank == 2 + p_fgb = new int[noOfElements]; + for (int i=0; iGetInstrument()->GetDetector()->GetTimeResolution(str)); + } + } + + fNxEntry2->GetInstrument()->GetDetector()->SetFirstGoodBin(p_fgb); + + if (data_ptr) { + delete [] data_ptr; + data_ptr = 0; + } + + if (!ErrorHandler(NXclosedata(fFileHandle), PNEXUS_CLOSE_DATA_ERROR, "couldn't close 'first_good_time' data in NXdetector!")) return NX_ERROR; + } else { + cerr << endl << ">> **WARNING** found neither 'first_good_bin' nor 'first_good_time' values ..." << endl; + } + + // handle last good bin + if (SearchInGroup("last_good_bin", "name", nxname, nxclass, dataType)) { + if (!ErrorHandler(NXopendata(fFileHandle, "last_good_bin"), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'last_good_bin' data in NXdetector!")) return NX_ERROR; + + // check the dimensions of the 'last_good_bin' vector + if (!ErrorHandler(NXgetinfo(fFileHandle, &rank, dims, &type), PNEXUS_GET_META_INFO_ERROR, "couldn't get 'last_good_bin' info in NXdetector!")) return NX_ERROR; + + if (rank <= 2) { + if (rank != fNxEntry2->GetInstrument()->GetDetector()->GetT0Tag()) { + cerr << endl << ">> **ERROR** rank of 'last_good_bin' (" << rank << ") is different than t0 rank=" << rank << ". Do not know how to handle." << endl; + return NX_ERROR; + } + } else { + cerr << endl << ">> **ERROR** found 'last_good_bin' info in NXdetector with rank=" << rank << ". Do not know how to handle." << endl; + return NX_ERROR; + } + + // calculate the needed size + size = dims[0]; + for (int i=1; iGetInstrument()->GetDetector()->SetLastGoodBin(i_data_ptr); + + if (!ErrorHandler(NXclosedata(fFileHandle), PNEXUS_CLOSE_DATA_ERROR, "couldn't close 'last_good_bin' data in NXdetector!")) return NX_ERROR; + } else if (SearchInGroup("last_good_time", "name", nxname, nxclass, dataType)) { + if (!ErrorHandler(NXopendata(fFileHandle, "last_good_time"), PNEXUS_OPEN_DATA_ERROR, "couldn't open 'last_good_time' data in NXdetector!")) return NX_ERROR; + + // check the dimensions of the 'last_good_time' vector + if (!ErrorHandler(NXgetinfo(fFileHandle, &rank, dims, &type), PNEXUS_GET_META_INFO_ERROR, "couldn't get 'last_good_time' info in NXdetector!")) return NX_ERROR; + + if (rank <= 2) { + if (rank != fNxEntry2->GetInstrument()->GetDetector()->GetT0Tag()) { + cerr << endl << ">> **ERROR** rank of 'last_good_time' (" << rank << ") is different than t0 rank=" << rank << ". Do not know how to handle." << endl; + return NX_ERROR; + } + } else { + cerr << endl << ">> **ERROR** found 'last_good_time' info in NXdetector with rank=" << rank << ". Do not know how to handle." << endl; + return NX_ERROR; + } + + // calculate the needed size + size = dims[0]; + for (int i=1; iGetInstrument()->GetDetector()->GetTimeResolution(str)); + } else { // rank == 2 + p_lgb = new int[noOfElements]; + for (int i=0; iGetInstrument()->GetDetector()->GetTimeResolution(str)); + } + } + + fNxEntry2->GetInstrument()->GetDetector()->SetFirstGoodBin(p_lgb); + + if (data_ptr) { + delete [] data_ptr; + data_ptr = 0; + } + + if (!ErrorHandler(NXclosedata(fFileHandle), PNEXUS_CLOSE_DATA_ERROR, "couldn't close 'last_good_time' data in NXdetector!")) return NX_ERROR; + } else { + cerr << endl << ">> **WARNING** found neither 'last_good_bin' nor 'last_good_time' values ..." << endl; + } + + // close group NXdetector + NXclosegroup(fFileHandle); + + // close group NXinstrument + NXclosegroup(fFileHandle); + + // GET DATA : STILL MISSING : The real data are found under NXentry:NXinstrument:NXdetector + // CHECK if it is necessary to read ANY of these data + + // close group NXentry + NXclosegroup(fFileHandle); + + // close file + NXclose(&fFileHandle); + + fValid = true; + + return NX_OK; } -//----------------------------------------------------------------------------------------------------- -// SetLastGoodBin (public) -//----------------------------------------------------------------------------------------------------- -/** - *

Sets last good bin. The current muSR NeXus implementation has only a single last good bin for all detectors since it was - * tailored for pulsed muon sources (ISIS). This eventually needs to be changed. - * - * \param lgb to be set - * \param idx index of t0 - */ -void PNeXus::SetLastGoodBin(unsigned int lgb, unsigned int idx) -{ - if (idx >= fData.fLastGoodBin.size()) - fData.fLastGoodBin.resize(idx+1); - - fData.fLastGoodBin[idx] = lgb; -} - -//----------------------------------------------------------------------------------------------------- -// SetHisto (public) -//----------------------------------------------------------------------------------------------------- -/** - *

- * - * \param histoNo histogram number (start counting from 0) - * \param data histogram data vector to be set - */ -void PNeXus::SetHisto(unsigned int histoNo, vector &data) -{ - if (histoNo >= fData.fHisto.size()) - fData.fHisto.resize(histoNo+1); - - fData.fHisto[histoNo] = data; -} - -//----------------------------------------------------------------------------------------------------- +//------------------------------------------------------------------------------------------ // GroupHistoData (private) -//----------------------------------------------------------------------------------------------------- +//------------------------------------------------------------------------------------------ /** *

Feed the grouped histo data, based on the grouping vector and the raw histo data. */ NXstatus PNeXus::GroupHistoData() { - // check if NO grouping is whished, in which case fData.fHisto == fGroupedData - if (fData.fGrouping.size() == 0) { - for (unsigned int i=0; i groupingValue; - bool newGroup = true; - for (unsigned int i=0; iGetData()->GetGrouping()->size() == 0) { + return NX_OK; } - if (newGroup) - groupingValue.push_back(fData.fGrouping[i]); - } - // check that none of the grouping values is outside of the valid range - for (unsigned int i=0; i fData.fHisto.size()) { + // check that the grouping size is equal to the number of histograms + if (fNxEntry1->GetData()->GetGrouping()->size() != fNxEntry1->GetData()->GetNoOfHistos()) { fErrorCode = PNEXUS_HISTO_ERROR; - fErrorMsg = "PNeXus::GroupHistoData() **ERROR** grouping values out of range"; + fErrorMsg = "grouping vector size is unequal to the number of histos present!"; return NX_ERROR; } - } - // set fGroupedData to the proper size - fGroupedData.clear(); - fGroupedData.resize(groupingValue.size()); - for (unsigned int i=0; i groupingValue; + bool newGroup = true; + for (unsigned int i=0; iGetData()->GetGrouping()->size(); i++) { + newGroup = true; + for (unsigned int j=0; jGetData()->GetGrouping()->at(i)) { + newGroup = false; + break; + } + } + if (newGroup) + groupingValue.push_back(fNxEntry1->GetData()->GetGrouping()->at(i)); } - } - // cleanup - groupingValue.clear(); + // check that none of the grouping values is outside of the valid range + for (unsigned int i=0; i= fNxEntry1->GetData()->GetNoOfHistos()) { + fErrorCode = PNEXUS_HISTO_ERROR; + fErrorMsg = "grouping values out of range"; + return NX_ERROR; + } + } + + // set fGroupedHisto to the proper size + fGroupedHisto.clear(); + fGroupedHisto.resize(groupingValue.size()); + for (unsigned int i=0; iGetData()->GetHisto(0)->size()); + } + + for (unsigned int i=0; iGetData()->GetNoOfHistos(); i++) { + for (unsigned int j=0; jGetData()->GetHisto(i)->size(); j++) { + fGroupedHisto[fNxEntry1->GetData()->GetGrouping()->at(i)-1][j] += fNxEntry1->GetData()->GetHisto(i)->at(j); + } + } + + // cleanup + groupingValue.clear(); + } else if (fIdfVersion == 2) { + // will probably do nothing here + } else { + fErrorCode = PNEXUS_HISTO_ERROR; + fErrorMsg = "unsupported IDF"; + return NX_ERROR; + } return NX_OK; } -//----------------------------------------------------------------------------------------------------- -// TransformDate (private) -//----------------------------------------------------------------------------------------------------- +//------------------------------------------------------------------------------------------ +// WriteFileIdf1 (private) +//------------------------------------------------------------------------------------------ /** - *

Transformed a given date to the form yyyy-mm-dd if possible. Allowed input dates are yyyy-mm-dd, - * yy-mm-dd, yyyy-MMM-dd, or yy-MMM-dd, where mm is the month as number and MMM the month as string, e.g. APR + *

Write the NeXus file of type IDF Version 1. * - *

return: transformed date + * return: + * - NX_OK on successfull writting + * - NX_ERROR on error. The error code/message will give the details. * - * \param date - * \param ok + * \param fileName file name + * \param access flag needed to know in which format (HDF4, HDF5, or XML) the file shall be written. */ -string PNeXus::TransformDate(string date, bool &ok) +int PNeXus::WriteFileIdf1(const char* fileName, const NXaccess access) { - string result = date; string str; - char cstr[128]; - int status, yy, mm, dd; + char cstr[1204]; + bool ok = false; + int size, idata; + float fdata; - ok = true; + memset(cstr, '\0', sizeof(cstr)); + snprintf(cstr, sizeof(cstr), "couldn't open file '%s' for writing", fileName); + if (!ErrorHandler(NXopen(fileName, access, &fFileHandle), PNEXUS_FILE_OPEN_ERROR, cstr)) return NX_ERROR; - switch(date.length()) { - case 8: // yy-mm-dd - if ((date[2] != '-') || (date[5] != '-')) { - ok = false; - } else { - status = sscanf(date.c_str(), "%d-%d-%d", &yy, &mm, &dd); - if (status != 3) { - ok = false; - } else { - if (yy >= 70) // i.e. 1970 - result = "19"+date; - else // i.e. 20YY - result = "20"+date; - } - } - break; - case 9: // yy-MMM-dd - if ((date[2] != '-') || (date[6] != '-')) { - ok = false; - } else { - str = date.substr(0,2); // yy - status = sscanf(str.c_str(), "%d", &yy); - if (status != 1) - ok = false; - str = date.substr(3,3); // MMM - mm = GetMonth(str); - if (mm == 0) - ok = false; - str = date.substr(7,2); // dd - status = sscanf(str.c_str(), "%d", &dd); - if (status != 1) - ok = false; - if (ok) { - if (yy >= 70) // i.e. 1970 - yy += 1900; - else - yy += 2000; - snprintf(cstr, sizeof(cstr), "%04d-%02d-%02d", yy, mm, dd); - result = cstr; - } - } - break; - case 10: // yyyy-mm-dd - if ((date[4] != '-') || (date[7] != '-')) { - ok = false; - } else { - status = sscanf(date.c_str(), "%04d-%02d-%02d", &yy, &mm, &dd); - if (status != 3) { - ok = false; - } else { - ok = true; - } - } - break; - case 11: // yyyy-MMM-dd - if ((date[4] != '-') || (date[8] != '-')) { - ok = false; - } else { - str = date.substr(0,4); // yyyy - status = sscanf(str.c_str(), "%d", &yy); - if (status != 1) - ok = false; - str = date.substr(5,3); // MMM - mm = GetMonth(str); - if (mm == 0) - ok = false; - str = date.substr(9,2); // dd - status = sscanf(str.c_str(), "%d", &dd); - if (status != 1) - ok = false; - if (ok) { - snprintf(cstr, sizeof(cstr), "%04d-%02d-%02d", yy, mm, dd); - result = cstr; - } - } - break; - default: - ok = false; - break; + // write NXfile attribute NeXus_version + memset(cstr, '\0', sizeof(cstr)); + strncpy(cstr, NEXUS_VERSION, sizeof(cstr)); + if (!ErrorHandler(NXputattr(fFileHandle, "NeXus_version", cstr, strlen(cstr), NX_CHAR), PNEXUS_SET_ATTR_ERROR, "couldn't set NXfile attribute 'NeXus_version'")) return NX_ERROR; + + memset(cstr, '\0', sizeof(cstr)); + strncpy(cstr, fNxEntry1->GetUser()->GetName().c_str(), sizeof(cstr)); + if (!ErrorHandler(NXputattr(fFileHandle, "user", cstr, strlen(cstr), NX_CHAR), PNEXUS_SET_ATTR_ERROR, "couldn't set NXfile attributes")) return NX_ERROR; + + // make group 'run' + if (!ErrorHandler(NXmakegroup(fFileHandle, "run", "NXentry"), PNEXUS_CREATE_GROUP_ERROR, "couldn't create group 'run'.")) return NX_ERROR; + // open group 'run' + if (!ErrorHandler(NXopengroup(fFileHandle, "run", "NXentry"), PNEXUS_GROUP_OPEN_ERROR, "couldn't open group 'run' for writting.")) return NX_ERROR; + + // write IDF_version + size = 1; + if (!ErrorHandler(NXmakedata(fFileHandle, "IDF_version", NX_INT32, 1, &size), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'IDF_version'.")) return NX_ERROR; + if (!ErrorHandler(NXopendata(fFileHandle, "IDF_version"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'IDF_version' for writting.")) return NX_ERROR; + idata = fIdfVersion; + if (!ErrorHandler(NXputdata(fFileHandle, &idata), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'IDF_version'.")) return NX_ERROR; + NXclosedata(fFileHandle); + + // write program_name, and attribute version + size = fNxEntry1->GetProgramName().length(); + if (!ErrorHandler(NXmakedata(fFileHandle, "program_name", NX_CHAR, 1, &size), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'program_name'.")) return NX_ERROR; + if (!ErrorHandler(NXopendata(fFileHandle, "program_name"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'program_name' for writting.")) return NX_ERROR; + memset(cstr, '\0', sizeof(cstr)); + strncpy(cstr, fNxEntry1->GetProgramName().c_str(), sizeof(cstr)); + if (!ErrorHandler(NXputdata(fFileHandle, cstr), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'program_name'.")) return NX_ERROR; + memset(cstr, '\0', sizeof(cstr)); + strncpy(cstr, fNxEntry1->GetProgramVersion().c_str(), sizeof(cstr)); + if (!ErrorHandler(NXputattr(fFileHandle, "version", cstr, strlen(cstr), NX_CHAR), PNEXUS_PUT_ATTR_ERROR, "couldn't put attribute 'version' for 'program_name'")) return NX_ERROR; + NXclosedata(fFileHandle); + + // write run 'number' + size = 1; + if (!ErrorHandler(NXmakedata(fFileHandle, "number", NX_INT32, 1, &size), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'number'.")) return NX_ERROR; + if (!ErrorHandler(NXopendata(fFileHandle, "number"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'number' for writting.")) return NX_ERROR; + idata = fNxEntry1->GetRunNumber(); + if (!ErrorHandler(NXputdata(fFileHandle, &idata), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'number'.")) return NX_ERROR; + NXclosedata(fFileHandle); + + // write run 'title' + size = fNxEntry1->GetTitle().length(); + if (!ErrorHandler(NXmakedata(fFileHandle, "title", NX_CHAR, 1, &size), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'title'.")) return NX_ERROR; + if (!ErrorHandler(NXopendata(fFileHandle, "title"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'title' for writting.")) return NX_ERROR; + memset(cstr, '\0', sizeof(cstr)); + strncpy(cstr, fNxEntry1->GetTitle().c_str(), sizeof(cstr)); + if (!ErrorHandler(NXputdata(fFileHandle, cstr), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'title'.")) return NX_ERROR; + NXclosedata(fFileHandle); + + // write run 'notes' + size = fNxEntry1->GetNotes().length(); + if (!ErrorHandler(NXmakedata(fFileHandle, "notes", NX_CHAR, 1, &size), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'notes'.")) return NX_ERROR; + if (!ErrorHandler(NXopendata(fFileHandle, "notes"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'notes' for writting.")) return NX_ERROR; + memset(cstr, '\0', sizeof(cstr)); + strncpy(cstr, fNxEntry1->GetNotes().c_str(), sizeof(cstr)); + if (!ErrorHandler(NXputdata(fFileHandle, cstr), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'notes'.")) return NX_ERROR; + NXclosedata(fFileHandle); + + // write run 'analysis' + size = fNxEntry1->GetAnalysis().length(); + if (!ErrorHandler(NXmakedata(fFileHandle, "analysis", NX_CHAR, 1, &size), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'analysis'.")) return NX_ERROR; + if (!ErrorHandler(NXopendata(fFileHandle, "analysis"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'analysis' for writting.")) return NX_ERROR; + memset(cstr, '\0', sizeof(cstr)); + strncpy(cstr, fNxEntry1->GetAnalysis().c_str(), sizeof(cstr)); + if (!ErrorHandler(NXputdata(fFileHandle, cstr), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'analysis'.")) return NX_ERROR; + NXclosedata(fFileHandle); + + // write run 'lab' + size = fNxEntry1->GetLaboratory().length(); + if (!ErrorHandler(NXmakedata(fFileHandle, "lab", NX_CHAR, 1, &size), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'lab'.")) return NX_ERROR; + if (!ErrorHandler(NXopendata(fFileHandle, "lab"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'lab' for writting.")) return NX_ERROR; + memset(cstr, '\0', sizeof(cstr)); + strncpy(cstr, fNxEntry1->GetLaboratory().c_str(), sizeof(cstr)); + if (!ErrorHandler(NXputdata(fFileHandle, cstr), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'lab'.")) return NX_ERROR; + NXclosedata(fFileHandle); + + // write run 'beamline' + size = fNxEntry1->GetBeamline().length(); + if (!ErrorHandler(NXmakedata(fFileHandle, "beamline", NX_CHAR, 1, &size), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'beamline'.")) return NX_ERROR; + if (!ErrorHandler(NXopendata(fFileHandle, "beamline"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'beamline' for writting.")) return NX_ERROR; + memset(cstr, '\0', sizeof(cstr)); + strncpy(cstr, fNxEntry1->GetBeamline().c_str(), sizeof(cstr)); + if (!ErrorHandler(NXputdata(fFileHandle, cstr), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'beamline'.")) return NX_ERROR; + NXclosedata(fFileHandle); + + // write run 'start_time' + memset(cstr, '\0', sizeof(cstr)); + strncpy(cstr, fNxEntry1->GetStartTime().c_str(), sizeof(cstr)); + size = strlen(cstr); + if (!ErrorHandler(NXmakedata(fFileHandle, "start_time", NX_CHAR, 1, &size), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'start_time'.")) return NX_ERROR; + if (!ErrorHandler(NXopendata(fFileHandle, "start_time"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'start_time' for writting.")) return NX_ERROR; + if (!ErrorHandler(NXputdata(fFileHandle, cstr), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'start_time'.")) return NX_ERROR; + NXclosedata(fFileHandle); + + // write run 'stop_time' + memset(cstr, '\0', sizeof(cstr)); + strncpy(cstr, fNxEntry1->GetStopTime().c_str(), sizeof(cstr)); + size = strlen(cstr); + if (!ErrorHandler(NXmakedata(fFileHandle, "stop_time", NX_CHAR, 1, &size), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'stop_time'.")) return NX_ERROR; + if (!ErrorHandler(NXopendata(fFileHandle, "stop_time"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'stop_time' for writting.")) return NX_ERROR; + if (!ErrorHandler(NXputdata(fFileHandle, cstr), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'stop_time'.")) return NX_ERROR; + NXclosedata(fFileHandle); + + // write run 'switching_states' + size = 1; + if (!ErrorHandler(NXmakedata(fFileHandle, "switching_states", NX_INT32, 1, &size), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'switching_states'.")) return NX_ERROR; + if (!ErrorHandler(NXopendata(fFileHandle, "switching_states"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'switching_states' for writting.")) return NX_ERROR; + idata = fNxEntry1->GetSwitchingState(); + if (!ErrorHandler(NXputdata(fFileHandle, &idata), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'switching_states'.")) return NX_ERROR; + NXclosedata(fFileHandle); + + // make group 'user' + if (!ErrorHandler(NXmakegroup(fFileHandle, "user", "NXuser"), PNEXUS_CREATE_GROUP_ERROR, "couldn't create group 'user'.")) return NX_ERROR; + // open group 'user' + if (!ErrorHandler(NXopengroup(fFileHandle, "user", "NXuser"), PNEXUS_GROUP_OPEN_ERROR, "couldn't open group 'user' for writting.")) return NX_ERROR; + + // write user 'name' + size = fNxEntry1->GetUser()->GetName().length(); + if (!ErrorHandler(NXmakedata(fFileHandle, "name", NX_CHAR, 1, &size), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'name'.")) return NX_ERROR; + if (!ErrorHandler(NXopendata(fFileHandle, "name"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'name' for writting.")) return NX_ERROR; + memset(cstr, '\0', sizeof(cstr)); + strncpy(cstr, fNxEntry1->GetUser()->GetName().c_str(), sizeof(cstr)); + if (!ErrorHandler(NXputdata(fFileHandle, cstr), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'name'.")) return NX_ERROR; + NXclosedata(fFileHandle); + + // write user 'experiment_number' + size = fNxEntry1->GetUser()->GetExperimentNumber().length(); + if (!ErrorHandler(NXmakedata(fFileHandle, "experiment_number", NX_CHAR, 1, &size), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'experiment_number'.")) return NX_ERROR; + if (!ErrorHandler(NXopendata(fFileHandle, "experiment_number"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'experiment_number' for writting.")) return NX_ERROR; + memset(cstr, '\0', sizeof(cstr)); + strncpy(cstr, fNxEntry1->GetUser()->GetExperimentNumber().c_str(), sizeof(cstr)); + if (!ErrorHandler(NXputdata(fFileHandle, cstr), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'experiment_number'.")) return NX_ERROR; + NXclosedata(fFileHandle); + + // close group 'user' + NXclosegroup(fFileHandle); + + // make group 'sample' + if (!ErrorHandler(NXmakegroup(fFileHandle, "sample", "NXuser"), PNEXUS_CREATE_GROUP_ERROR, "couldn't create group 'sample'.")) return NX_ERROR; + // open group 'sample' + if (!ErrorHandler(NXopengroup(fFileHandle, "sample", "NXuser"), PNEXUS_GROUP_OPEN_ERROR, "couldn't open group 'sample' for writting.")) return NX_ERROR; + + // write sample 'name' + size = fNxEntry1->GetSample()->GetName().length(); + if (!ErrorHandler(NXmakedata(fFileHandle, "name", NX_CHAR, 1, &size), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'name'.")) return NX_ERROR; + if (!ErrorHandler(NXopendata(fFileHandle, "name"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'name' for writting.")) return NX_ERROR; + memset(cstr, '\0', sizeof(cstr)); + strncpy(cstr, fNxEntry1->GetSample()->GetName().c_str(), sizeof(cstr)); + if (!ErrorHandler(NXputdata(fFileHandle, cstr), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'name'.")) return NX_ERROR; + NXclosedata(fFileHandle); + + // write sample 'temperature' + size = 1; + if (!ErrorHandler(NXmakedata(fFileHandle, "temperature", NX_FLOAT32, 1, &size), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'temperature'.")) return NX_ERROR; + if (!ErrorHandler(NXopendata(fFileHandle, "temperature"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'temperature' for writting.")) return NX_ERROR; + fdata = (float)fNxEntry1->GetSample()->GetPhysPropValue(string("temperature"), ok); + if (!ErrorHandler(NXputdata(fFileHandle, &fdata), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'temperature'.")) return NX_ERROR; + memset(cstr, '\0', sizeof(cstr)); + str = string("n/a"); + fNxEntry1->GetSample()->GetPhysPropUnit(string("temperature"), str, ok); + strncpy(cstr, str.c_str(), sizeof(cstr)); + if (!ErrorHandler(NXputattr(fFileHandle, "units", cstr, strlen(cstr), NX_CHAR), PNEXUS_PUT_ATTR_ERROR, "couldn't put attribute 'units' for 'temperature'")) return NX_ERROR; + NXclosedata(fFileHandle); + + // write sample 'magnetic_field' + size = 1; + if (!ErrorHandler(NXmakedata(fFileHandle, "magnetic_field", NX_FLOAT32, 1, &size), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'magnetic_field'.")) return NX_ERROR; + if (!ErrorHandler(NXopendata(fFileHandle, "magnetic_field"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'magnetic_field' for writting.")) return NX_ERROR; + fdata = (float)fNxEntry1->GetSample()->GetPhysPropValue(string("magnetic_field"), ok); + if (!ErrorHandler(NXputdata(fFileHandle, &fdata), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'magnetic_field'.")) return NX_ERROR; + memset(cstr, '\0', sizeof(cstr)); + str = string("n/a"); + fNxEntry1->GetSample()->GetPhysPropUnit(string("magnetic_field"), str, ok); + memset(cstr, '\0', sizeof(cstr)); + strncpy(cstr, str.c_str(), sizeof(cstr)); + if (!ErrorHandler(NXputattr(fFileHandle, "units", cstr, strlen(cstr), NX_CHAR), PNEXUS_PUT_ATTR_ERROR, "couldn't put attribute 'units' for 'magnetic_field'")) return NX_ERROR; + NXclosedata(fFileHandle); + + // write sample 'shape' + size = fNxEntry1->GetSample()->GetShape().length(); + if (!ErrorHandler(NXmakedata(fFileHandle, "shape", NX_CHAR, 1, &size), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'shape'.")) return NX_ERROR; + if (!ErrorHandler(NXopendata(fFileHandle, "shape"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'shape' for writting.")) return NX_ERROR; + strncpy(cstr, fNxEntry1->GetSample()->GetShape().c_str(), sizeof(cstr)); + if (!ErrorHandler(NXputdata(fFileHandle, cstr), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'shape'.")) return NX_ERROR; + NXclosedata(fFileHandle); + + // write sample 'magnetic_field_state' + size = fNxEntry1->GetSample()->GetMagneticFieldState().length(); + if (!ErrorHandler(NXmakedata(fFileHandle, "magnetic_field_state", NX_CHAR, 1, &size), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'magnetic_field_state'.")) return NX_ERROR; + if (!ErrorHandler(NXopendata(fFileHandle, "magnetic_field_state"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'magnetic_field_state' for writting.")) return NX_ERROR; + memset(cstr, '\0', sizeof(cstr)); + strncpy(cstr, fNxEntry1->GetSample()->GetMagneticFieldState().c_str(), sizeof(cstr)); + if (!ErrorHandler(NXputdata(fFileHandle, cstr), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'magnetic_field_state'.")) return NX_ERROR; + NXclosedata(fFileHandle); + + // write sample 'magnetic_field_vector' + float *magFieldVec; + if (fNxEntry1->GetSample()->IsMagneticFieldVectorAvailable()) { + idata = 1; + size = fNxEntry1->GetSample()->GetMagneticFieldVector().size(); + magFieldVec = new float[size]; + for (int i=0; iGetSample()->GetMagneticFieldVector().at(i); + } else { + idata = 0; + size = 3; + magFieldVec = new float[size]; + for (int i=0; iGetSample()->GetMagneticFieldVectorCoordinateSystem().c_str(), sizeof(cstr)); + if (!ErrorHandler(NXputattr(fFileHandle, "coordinate_system", cstr, strlen(cstr), NX_CHAR), PNEXUS_PUT_ATTR_ERROR, "couldn't put attribute 'coordinate_system' for 'magnetic_field_vector'")) return NX_ERROR; + memset(cstr, '\0', sizeof(cstr)); + strncpy(cstr, fNxEntry1->GetSample()->GetMagneticFieldVectorUnits().c_str(), sizeof(cstr)); + if (!ErrorHandler(NXputattr(fFileHandle, "units", cstr, strlen(cstr), NX_CHAR), PNEXUS_PUT_ATTR_ERROR, "couldn't put attribute 'units' for 'magnetic_field_vector'")) return NX_ERROR; + if (!ErrorHandler(NXputattr(fFileHandle, "available", &idata, 1, NX_INT32), PNEXUS_PUT_ATTR_ERROR, "couldn't put attribute 'available' for 'magnetic_field_vector'")) return NX_ERROR; + NXclosedata(fFileHandle); + if (magFieldVec) { + delete [] magFieldVec; + magFieldVec = 0; } - if (!ok) { - fErrorCode = PNEXUS_WRONG_DATE_FORMAT; - fErrorMsg = "PNeXus::TransformDate **ERROR** given date="+date+", is not of any of the the required forms!"; + // write sample 'environment' + size = fNxEntry1->GetSample()->GetEnvironment().length(); + if (!ErrorHandler(NXmakedata(fFileHandle, "environment", NX_CHAR, 1, &size), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'environment'.")) return NX_ERROR; + if (!ErrorHandler(NXopendata(fFileHandle, "environment"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'environment' for writting.")) return NX_ERROR; + memset(cstr, '\0', sizeof(cstr)); + strncpy(cstr, fNxEntry1->GetSample()->GetEnvironment().c_str(), sizeof(cstr)); + if (!ErrorHandler(NXputdata(fFileHandle, cstr), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'environment'.")) return NX_ERROR; + NXclosedata(fFileHandle); + + // close group 'sample' + NXclosegroup(fFileHandle); + + // make group 'instrument' + if (!ErrorHandler(NXmakegroup(fFileHandle, "instrument", "NXinstrument"), PNEXUS_CREATE_GROUP_ERROR, "couldn't create group 'instrument'.")) return NX_ERROR; + // open group 'instrument' + if (!ErrorHandler(NXopengroup(fFileHandle, "instrument", "NXinstrument"), PNEXUS_GROUP_OPEN_ERROR, "couldn't open group 'instrument' for writting.")) return NX_ERROR; + + // write instrument 'name' + size = fNxEntry1->GetInstrument()->GetName().length(); + if (!ErrorHandler(NXmakedata(fFileHandle, "name", NX_CHAR, 1, &size), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'name'.")) return NX_ERROR; + if (!ErrorHandler(NXopendata(fFileHandle, "name"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'name' for writting.")) return NX_ERROR; + memset(cstr, '\0', sizeof(cstr)); + strncpy(cstr, fNxEntry1->GetInstrument()->GetName().c_str(), sizeof(cstr)); + if (!ErrorHandler(NXputdata(fFileHandle, cstr), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'name'.")) return NX_ERROR; + NXclosedata(fFileHandle); + + // make group 'detector' + if (!ErrorHandler(NXmakegroup(fFileHandle, "detector", "NXdetector"), PNEXUS_CREATE_GROUP_ERROR, "couldn't create group 'detector'.")) return NX_ERROR; + // open group 'detector' + if (!ErrorHandler(NXopengroup(fFileHandle, "detector", "NXdetector"), PNEXUS_GROUP_OPEN_ERROR, "couldn't open group 'detector' for writting.")) return NX_ERROR; + + // write detector 'number' + size = 1; + if (!ErrorHandler(NXmakedata(fFileHandle, "number", NX_INT32, 1, &size), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'number'.")) return NX_ERROR; + if (!ErrorHandler(NXopendata(fFileHandle, "number"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'number' for writting.")) return NX_ERROR; + idata = fNxEntry1->GetInstrument()->GetDetector()->GetNumber(); + if (!ErrorHandler(NXputdata(fFileHandle, &idata), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'number'.")) return NX_ERROR; + NXclosedata(fFileHandle); + + // close group 'detector' + NXclosegroup(fFileHandle); + + // make group 'collimator' + if (!ErrorHandler(NXmakegroup(fFileHandle, "collimator", "NXcollimator"), PNEXUS_CREATE_GROUP_ERROR, "couldn't create group 'collimator'.")) return NX_ERROR; + // open group 'collimator' + if (!ErrorHandler(NXopengroup(fFileHandle, "collimator", "NXcollimator"), PNEXUS_GROUP_OPEN_ERROR, "couldn't open group 'collimator' for writting.")) return NX_ERROR; + + // write collimator 'type' + size = fNxEntry1->GetInstrument()->GetCollimator()->GetType().length(); + if (!ErrorHandler(NXmakedata(fFileHandle, "type", NX_CHAR, 1, &size), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'type'.")) return NX_ERROR; + if (!ErrorHandler(NXopendata(fFileHandle, "type"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'type' for writting.")) return NX_ERROR; + memset(cstr, '\0', sizeof(cstr)); + strncpy(cstr, fNxEntry1->GetInstrument()->GetCollimator()->GetType().c_str(), sizeof(cstr)); + if (!ErrorHandler(NXputdata(fFileHandle, cstr), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'type'.")) return NX_ERROR; + NXclosedata(fFileHandle); + + // close group 'collimator' + NXclosegroup(fFileHandle); + + // make group 'beam' + if (!ErrorHandler(NXmakegroup(fFileHandle, "beam", "NXbeam"), PNEXUS_CREATE_GROUP_ERROR, "couldn't create group 'beam'.")) return NX_ERROR; + // open group 'beam' + if (!ErrorHandler(NXopengroup(fFileHandle, "beam", "NXbeam"), PNEXUS_GROUP_OPEN_ERROR, "couldn't open group 'beam' for writting.")) return NX_ERROR; + + size = 1; + if (!ErrorHandler(NXmakedata(fFileHandle, "total_counts", NX_FLOAT32, 1, &size), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'total_counts'.")) return NX_ERROR; + if (!ErrorHandler(NXopendata(fFileHandle, "total_counts"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'total_counts' for writting.")) return NX_ERROR; + fdata = (float)fNxEntry1->GetInstrument()->GetBeam()->GetTotalCounts(); + if (!ErrorHandler(NXputdata(fFileHandle, &fdata), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'total_counts'.")) return NX_ERROR; + memset(cstr, '\0', sizeof(cstr)); + strncpy(cstr, fNxEntry1->GetInstrument()->GetBeam()->GetUnits().c_str(), sizeof(cstr)); + if (!ErrorHandler(NXputattr(fFileHandle, "units", cstr, strlen(cstr), NX_CHAR), PNEXUS_PUT_ATTR_ERROR, "couldn't put attribute 'units' for 'total_counts'")) return NX_ERROR; + NXclosedata(fFileHandle); + + // close group 'beam' + NXclosegroup(fFileHandle); + + // close group 'instrument' + NXclosegroup(fFileHandle); + + // make group 'histogram_data_1' + if (!ErrorHandler(NXmakegroup(fFileHandle, "histogram_data_1", "NXdata"), PNEXUS_CREATE_GROUP_ERROR, "couldn't create group 'histogram_data_1'.")) return NX_ERROR; + // open group 'histogram_data_1' + if (!ErrorHandler(NXopengroup(fFileHandle, "histogram_data_1", "NXdata"), PNEXUS_GROUP_OPEN_ERROR, "couldn't open group 'histogram_data_1' for writting.")) return NX_ERROR; + + // write data 'counts' + int *histo_data=0; + int histo_size[2]; + if (fNxEntry1->GetData()->GetNoOfHistos() == 0) { + histo_data = new int[1]; + histo_data[0] = -1; + histo_size[0] = 1; + histo_size[1] = 1; + } else { + int noOfHistos = fNxEntry1->GetData()->GetNoOfHistos(); + int histoLength = fNxEntry1->GetData()->GetHisto(0)->size(); + histo_data = new int[noOfHistos*histoLength]; + for (int i=0; iGetData()->GetHisto(i)->at(j); + histo_size[0] = noOfHistos; + histo_size[1] = histoLength; } - return result; + if (!ErrorHandler(NXmakedata(fFileHandle, "counts", NX_INT32, 2, histo_size), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'counts'.")) return NX_ERROR; + if (!ErrorHandler(NXopendata(fFileHandle, "counts"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'counts' for writting.")) return NX_ERROR; + if (!ErrorHandler(NXputdata(fFileHandle, (void*)histo_data), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'counts'.")) return NX_ERROR; + memset(cstr, '\0', sizeof(cstr)); + strncpy(cstr, "counts", sizeof(cstr)); + if (!ErrorHandler(NXputattr(fFileHandle, "units", cstr, strlen(cstr), NX_CHAR), PNEXUS_PUT_ATTR_ERROR, "couldn't put attribute 'units' for 'counts'")) return NX_ERROR; + idata = 1; + if (!ErrorHandler(NXputattr(fFileHandle, "signal", &idata, 1, NX_INT32), PNEXUS_PUT_ATTR_ERROR, "couldn't put attribute 'signal' for 'counts'")) return NX_ERROR; + idata = fNxEntry1->GetData()->GetNoOfHistos(); + if (!ErrorHandler(NXputattr(fFileHandle, "number", &idata, 1, NX_INT32), PNEXUS_PUT_ATTR_ERROR, "couldn't put attribute 'number' for 'counts'")) return NX_ERROR; + idata = fNxEntry1->GetData()->GetT0(0); + if (!ErrorHandler(NXputattr(fFileHandle, "T0_bin", &idata, 1, NX_INT32), PNEXUS_PUT_ATTR_ERROR, "couldn't put attribute 'T0_bin' for 'counts'")) return NX_ERROR; + idata = fNxEntry1->GetData()->GetFirstGoodBin(0); + if (!ErrorHandler(NXputattr(fFileHandle, "first_good_bin", &idata, 1, NX_INT32), PNEXUS_PUT_ATTR_ERROR, "couldn't put attribute 'first_good_bin' for 'counts'")) return NX_ERROR; + idata = fNxEntry1->GetData()->GetLastGoodBin(0); + if (!ErrorHandler(NXputattr(fFileHandle, "last_good_bin", &idata, 1, NX_INT32), PNEXUS_PUT_ATTR_ERROR, "couldn't put attribute 'last_good_bin' for 'counts'")) return NX_ERROR; + fdata = (float)fNxEntry1->GetData()->GetTimeResolution("ps")/2.0; + if (!ErrorHandler(NXputattr(fFileHandle, "offset", &fdata, 1, NX_FLOAT32), PNEXUS_PUT_ATTR_ERROR, "couldn't put attribute 'offset' for 'counts'")) return NX_ERROR; + + if (histo_data) { + delete [] histo_data; + } + + // write data 'histogram_resolution' + if (!ErrorHandler(NXmakedata(fFileHandle, "histogram_resolution", NX_FLOAT32, 1, &size), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'histogram_resolution'.")) return NX_ERROR; + if (!ErrorHandler(NXopendata(fFileHandle, "histogram_resolution"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'histogram_resolution' for writting.")) return NX_ERROR; + fdata = fNxEntry1->GetData()->GetTimeResolution("ps"); + if (!ErrorHandler(NXputdata(fFileHandle, &fdata), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'histogram_resolution'.")) return NX_ERROR; + memset(cstr, '\0', sizeof(cstr)); + strncpy(cstr, "picoseconds", sizeof(cstr)); + if (!ErrorHandler(NXputattr(fFileHandle, "units", cstr, strlen(cstr), NX_CHAR), PNEXUS_PUT_ATTR_ERROR, "couldn't put attribute 'units' for 'histogram_resolution'")) return NX_ERROR; + NXclosedata(fFileHandle); + + // write data 'time_zero' always set to 0 since the T0_bin attribute of counts is relevant only + if (!ErrorHandler(NXmakedata(fFileHandle, "time_zero", NX_FLOAT32, 1, &size), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'time_zero'.")) return NX_ERROR; + if (!ErrorHandler(NXopendata(fFileHandle, "time_zero"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'time_zero' for writting.")) return NX_ERROR; + fdata = 0.0; + if (!ErrorHandler(NXputdata(fFileHandle, &fdata), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'time_zero'.")) return NX_ERROR; + memset(cstr, '\0', sizeof(cstr)); + strncpy(cstr, "microseconds", sizeof(cstr)); + if (!ErrorHandler(NXputattr(fFileHandle, "units", cstr, strlen(cstr), NX_CHAR), PNEXUS_PUT_ATTR_ERROR, "couldn't put attribute 'units' for 'time_zero'")) return NX_ERROR; + idata = 0; + if (!ErrorHandler(NXputattr(fFileHandle, "available", &idata, 1, NX_INT32), PNEXUS_PUT_ATTR_ERROR, "couldn't put attribute 'available' for 'time_zero'")) return NX_ERROR; + NXclosedata(fFileHandle); + + // write data 'raw_time' + int noOfHistos = fNxEntry1->GetData()->GetNoOfHistos(); + int histoLength = fNxEntry1->GetData()->GetHisto(0)->size(); + if (noOfHistos == 0) { + fErrorCode = PNEXUS_HISTO_ERROR; + fErrorMsg = "no data for writing present."; + return NX_ERROR; + } + float *raw_time = new float[histoLength]; + for (int i=0; iGetData()->GetTimeResolution("us") * (float)i; // raw time in (us) + } + size = histoLength; + if (!ErrorHandler(NXmakedata(fFileHandle, "raw_time", NX_FLOAT32, 1, &size), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'raw_time'.")) return NX_ERROR; + if (!ErrorHandler(NXopendata(fFileHandle, "raw_time"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'raw_time' for writting.")) return NX_ERROR; + if (!ErrorHandler(NXputdata(fFileHandle, raw_time), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'raw_time'.")) return NX_ERROR; + idata = 1; + if (!ErrorHandler(NXputattr(fFileHandle, "axis", &idata, 1, NX_INT32), PNEXUS_PUT_ATTR_ERROR, "couldn't put attribute 'axis' for 'raw_time'")) return NX_ERROR; + idata = 1; + if (!ErrorHandler(NXputattr(fFileHandle, "primary", &idata, 1, NX_INT32), PNEXUS_PUT_ATTR_ERROR, "couldn't put attribute 'primary' for 'raw_time'")) return NX_ERROR; + memset(cstr, '\0', sizeof(cstr)); + strncpy(cstr, "microseconds", sizeof(cstr)); + if (!ErrorHandler(NXputattr(fFileHandle, "units", cstr, strlen(cstr), NX_CHAR), PNEXUS_PUT_ATTR_ERROR, "couldn't put attribute 'units' for 'raw_time'")) return NX_ERROR; + NXclosedata(fFileHandle); + if (raw_time) { + delete [] raw_time; + raw_time = 0; + } + + // write data 'corrected_time' + float *corrected_time = new float[histoLength]; + for (int i=0; iGetData()->GetTimeResolution("us") * (float)((int)i-(int)fNxEntry1->GetData()->GetT0(0)+1); // raw time in (us) + } + size = histoLength; + if (!ErrorHandler(NXmakedata(fFileHandle, "corrected_time", NX_FLOAT32, 1, &size), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'corrected_time'.")) return NX_ERROR; + if (!ErrorHandler(NXopendata(fFileHandle, "corrected_time"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'corrected_time' for writting.")) return NX_ERROR; + if (!ErrorHandler(NXputdata(fFileHandle, corrected_time), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'corrected_time'.")) return NX_ERROR; + idata = 1; + if (!ErrorHandler(NXputattr(fFileHandle, "axis", &idata, 1, NX_INT32), PNEXUS_PUT_ATTR_ERROR, "couldn't put attribute 'axis' for 'corrected_time'")) return NX_ERROR; + memset(cstr, '\0', sizeof(cstr)); + strncpy(cstr, "microseconds", sizeof(cstr)); + if (!ErrorHandler(NXputattr(fFileHandle, "units", cstr, strlen(cstr), NX_CHAR), PNEXUS_PUT_ATTR_ERROR, "couldn't put attribute 'units' for 'corrected_time'")) return NX_ERROR; + NXclosedata(fFileHandle); + if (corrected_time) { + delete [] corrected_time; + corrected_time = 0; + } + + // write data 'grouping' + int *grouping = new int[noOfHistos]; + vector groupNo; // keep the number of different groupings + if (noOfHistos == (int)fNxEntry1->GetData()->GetGrouping()->size()) { // grouping vector seems to be properly defined + bool found; + groupNo.push_back(fNxEntry1->GetData()->GetGrouping()->at(0)); + for (int i=0; iGetData()->GetGrouping()->at(i); + found = false; + for (unsigned int j=0; jGetData()->GetGrouping()->at(i) == groupNo[j]) { + found = true; + break; + } + } + if (!found) { + groupNo.push_back(fNxEntry1->GetData()->GetGrouping()->at(i)); + } + } + } else { // grouping vector not available + for (int i=0; iGetData()->GetAlpha()->size() == 0) { + alpha = new float[3]; + alpha[0] = -1.0; + alpha[1] = -1.0; + alpha[2] = -1.0; + array_size[0] = 1; + array_size[1] = 3; + } else { + alpha = new float[fNxEntry1->GetData()->GetAlpha()->size()*3]; + for (unsigned int i=0; iGetData()->GetAlpha()->size(); i++) { + alpha[i] = (float)fNxEntry1->GetData()->GetAlpha()->at(i).GetGroupFirst(); + alpha[i+1] = (float)fNxEntry1->GetData()->GetAlpha()->at(i).GetGroupSecond(); + alpha[i+2] = (float)(float)fNxEntry1->GetData()->GetAlpha()->at(i).GetAlpha(); + } + array_size[0] = fNxEntry1->GetData()->GetAlpha()->size(); + array_size[1] = 3; + } + if (!ErrorHandler(NXmakedata(fFileHandle, "alpha", NX_FLOAT32, 2, array_size), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'alpha'.")) return NX_ERROR; + if (!ErrorHandler(NXopendata(fFileHandle, "alpha"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'alpha' for writting.")) return NX_ERROR; + if (!ErrorHandler(NXputdata(fFileHandle, (void*)alpha), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'alpha'.")) return NX_ERROR; + idata = fNxEntry1->GetData()->GetAlpha()->size(); + if (!ErrorHandler(NXputattr(fFileHandle, "available", &idata, 1, NX_INT32), PNEXUS_PUT_ATTR_ERROR, "couldn't put attribute 'available' for 'alpha'")) return NX_ERROR; + if (alpha) { + delete [] alpha; + } + + // close group 'histogram_data_1' + NXclosegroup(fFileHandle); + + // close group 'run' + NXclosegroup(fFileHandle); + + NXclose(&fFileHandle); + + return NX_OK; } -//----------------------------------------------------------------------------------------------------- -// GetMonth (private) -//----------------------------------------------------------------------------------------------------- +//------------------------------------------------------------------------------------------ +// WriteFileIdf2 (private) +//------------------------------------------------------------------------------------------ /** - *

For a month string MMM (e.g. APR) return the month number + *

Write the NeXus file of type IDF Version 2. * - *

return: month number + * return: + * - NX_OK on successfull writting + * - NX_ERROR on error. The error code/message will give the details. * - * \param month string of the form MMM, e.g. APR + * \param fileName file name + * \param access flag needed to know in which format (HDF4, HDF5, or XML) the file shall be written. */ -int PNeXus::GetMonth(const string month) +int PNeXus::WriteFileIdf2(const char* fileName, const NXaccess access) { - int result = 0; + string str; + char cstr[1204]; + bool ok = false; + int size, idata; + float fdata; + double dval; + NXlink clink; - if (!month.compare("jan") || !month.compare("Jan") || !month.compare("JAN")) - result = 1; - else if (!month.compare("feb") || !month.compare("Feb") || !month.compare("FEB")) - result = 2; - else if (!month.compare("mar") || !month.compare("Mar") || !month.compare("MAR")) - result = 3; - else if (!month.compare("apr") || !month.compare("Apr") || !month.compare("APR")) - result = 4; - else if (!month.compare("may") || !month.compare("May") || !month.compare("MAY")) - result = 5; - else if (!month.compare("jun") || !month.compare("Jun") || !month.compare("JUN")) - result = 6; - else if (!month.compare("jul") || !month.compare("Jul") || !month.compare("JUL")) - result = 7; - else if (!month.compare("aug") || !month.compare("Aug") || !month.compare("AUG")) - result = 8; - else if (!month.compare("sep") || !month.compare("Sep") || !month.compare("SEP")) - result = 9; - else if (!month.compare("oct") || !month.compare("Oct") || !month.compare("OCT")) - result = 10; - else if (!month.compare("nov") || !month.compare("Nov") || !month.compare("NOV")) - result = 11; - else if (!month.compare("dec") || !month.compare("Dec") || !month.compare("DEC")) - result = 12; - else - result = 0; + memset(cstr, '\0', sizeof(cstr)); + snprintf(cstr, sizeof(cstr), "couldn't open file '%s' for writing", fileName); + if (!ErrorHandler(NXopen(fileName, access, &fFileHandle), PNEXUS_FILE_OPEN_ERROR, cstr)) return NX_ERROR; - return result; + // write NXroot attribute 'file_name' + memset(cstr, '\0', sizeof(cstr)); + strncpy(cstr, fileName, sizeof(cstr)); + if (!ErrorHandler(NXputattr(fFileHandle, "file_name", cstr, strlen(cstr), NX_CHAR), PNEXUS_SET_ATTR_ERROR, "couldn't set NXroot attribute 'file_name'")) return NX_ERROR; + + // write NXroot attribute 'creator' + memset(cstr, '\0', sizeof(cstr)); + strncpy(cstr, fCreator.c_str(), sizeof(cstr)); + if (!ErrorHandler(NXputattr(fFileHandle, "creator", cstr, strlen(cstr), NX_CHAR), PNEXUS_SET_ATTR_ERROR, "couldn't set NXroot attribute 'creator'")) return NX_ERROR; + + // make group 'raw_data_1' + if (!ErrorHandler(NXmakegroup(fFileHandle, "raw_data_1", "NXentry"), PNEXUS_CREATE_GROUP_ERROR, "couldn't create group 'raw_data_1' in NXroot.")) return NX_ERROR; + // open group 'raw_data_1' + if (!ErrorHandler(NXopengroup(fFileHandle, "raw_data_1", "NXentry"), PNEXUS_GROUP_OPEN_ERROR, "couldn't open group 'raw_data_1' in NXroot for writting.")) return NX_ERROR; + + // write idf_version + size = 1; + if (!ErrorHandler(NXmakedata(fFileHandle, "idf_version", NX_INT32, 1, &size), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'idf_version' in NXentry.")) return NX_ERROR; + if (!ErrorHandler(NXopendata(fFileHandle, "idf_version"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'idf_version' in NXentry for writting.")) return NX_ERROR; + idata = fIdfVersion; + if (!ErrorHandler(NXputdata(fFileHandle, &idata), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'idf_version' in NXentry.")) return NX_ERROR; + NXclosedata(fFileHandle); + + // write run 'definition' + size = fNxEntry2->GetDefinition().length(); + if (!ErrorHandler(NXmakedata(fFileHandle, "definition", NX_CHAR, 1, &size), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'definition' in NXentry.")) return NX_ERROR; + if (!ErrorHandler(NXopendata(fFileHandle, "definition"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'definition' in NXentry for writting.")) return NX_ERROR; + memset(cstr, '\0', sizeof(cstr)); + strncpy(cstr, fNxEntry2->GetDefinition().c_str(), sizeof(cstr)); + if (!ErrorHandler(NXputdata(fFileHandle, cstr), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'definition' in NXentry.")) return NX_ERROR; + NXclosedata(fFileHandle); + + // write run 'run_number' + size = 1; + if (!ErrorHandler(NXmakedata(fFileHandle, "run_number", NX_INT32, 1, &size), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'run_number' in NXentry.")) return NX_ERROR; + if (!ErrorHandler(NXopendata(fFileHandle, "run_number"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'run_number' in NXentry for writting.")) return NX_ERROR; + idata = fNxEntry2->GetRunNumber(); + if (!ErrorHandler(NXputdata(fFileHandle, &idata), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'run_number' in NXentry.")) return NX_ERROR; + NXclosedata(fFileHandle); + + // write run 'title' + size = fNxEntry2->GetTitle().length(); + if (!ErrorHandler(NXmakedata(fFileHandle, "title", NX_CHAR, 1, &size), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'title' in NXentry.")) return NX_ERROR; + if (!ErrorHandler(NXopendata(fFileHandle, "title"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'title' in NXentry for writting.")) return NX_ERROR; + memset(cstr, '\0', sizeof(cstr)); + strncpy(cstr, fNxEntry2->GetTitle().c_str(), sizeof(cstr)); + if (!ErrorHandler(NXputdata(fFileHandle, cstr), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'title' in NXentry.")) return NX_ERROR; + NXclosedata(fFileHandle); + + // write run 'start_time' + size = fNxEntry2->GetStartTime().length(); + if (!ErrorHandler(NXmakedata(fFileHandle, "start_time", NX_CHAR, 1, &size), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'start_time' in NXentry.")) return NX_ERROR; + if (!ErrorHandler(NXopendata(fFileHandle, "start_time"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'start_time' in NXentry for writting.")) return NX_ERROR; + memset(cstr, '\0', sizeof(cstr)); + strncpy(cstr, fNxEntry2->GetStartTime().c_str(), sizeof(cstr)); + if (!ErrorHandler(NXputdata(fFileHandle, cstr), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'start_time' in NXentry.")) return NX_ERROR; + NXclosedata(fFileHandle); + + // write run 'end_time' + size = fNxEntry2->GetStopTime().length(); + if (!ErrorHandler(NXmakedata(fFileHandle, "end_time", NX_CHAR, 1, &size), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'end_time' in NXentry.")) return NX_ERROR; + if (!ErrorHandler(NXopendata(fFileHandle, "end_time"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'end_time' in NXentry for writting.")) return NX_ERROR; + memset(cstr, '\0', sizeof(cstr)); + strncpy(cstr, fNxEntry2->GetStopTime().c_str(), sizeof(cstr)); + if (!ErrorHandler(NXputdata(fFileHandle, cstr), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'end_time' in NXentry.")) return NX_ERROR; + NXclosedata(fFileHandle); + + // write run 'experiment_identifier' + size = fNxEntry2->GetExperimentIdentifier().length(); + if (!ErrorHandler(NXmakedata(fFileHandle, "experiment_identifier", NX_CHAR, 1, &size), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'experiment_identifier' in NXentry.")) return NX_ERROR; + if (!ErrorHandler(NXopendata(fFileHandle, "experiment_identifier"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'experiment_identifier' in NXentry for writting.")) return NX_ERROR; + memset(cstr, '\0', sizeof(cstr)); + strncpy(cstr, fNxEntry2->GetExperimentIdentifier().c_str(), sizeof(cstr)); + if (!ErrorHandler(NXputdata(fFileHandle, cstr), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'experiment_identifier' in NXentry.")) return NX_ERROR; + NXclosedata(fFileHandle); + + // make group 'user_1' + if (!ErrorHandler(NXmakegroup(fFileHandle, "user_1", "NXuser"), PNEXUS_CREATE_GROUP_ERROR, "couldn't create group 'user_1' in NXentry.")) return NX_ERROR; + // open group 'user' + if (!ErrorHandler(NXopengroup(fFileHandle, "user_1", "NXuser"), PNEXUS_GROUP_OPEN_ERROR, "couldn't open group 'user_1' in NXentry for writting.")) return NX_ERROR; + + // write user 'name' + size = fNxEntry2->GetUser()->GetName().length(); + if (!ErrorHandler(NXmakedata(fFileHandle, "name", NX_CHAR, 1, &size), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'name' in NXuser.")) return NX_ERROR; + if (!ErrorHandler(NXopendata(fFileHandle, "name"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'name' in NXuser for writting.")) return NX_ERROR; + memset(cstr, '\0', sizeof(cstr)); + strncpy(cstr, fNxEntry2->GetUser()->GetName().c_str(), sizeof(cstr)); + if (!ErrorHandler(NXputdata(fFileHandle, cstr), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'name' in NXuser.")) return NX_ERROR; + NXclosedata(fFileHandle); + + // close group 'user_1' + NXclosegroup(fFileHandle); + + // make group 'sample' + if (!ErrorHandler(NXmakegroup(fFileHandle, "sample", "NXsample"), PNEXUS_CREATE_GROUP_ERROR, "couldn't create group 'sample' in NXentry.")) return NX_ERROR; + // open group 'sample' + if (!ErrorHandler(NXopengroup(fFileHandle, "sample", "NXsample"), PNEXUS_GROUP_OPEN_ERROR, "couldn't open group 'sample' in NXentry for writting.")) return NX_ERROR; + + // write sample 'name' + size = fNxEntry2->GetSample()->GetName().length(); + if (!ErrorHandler(NXmakedata(fFileHandle, "name", NX_CHAR, 1, &size), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'name' in NXsample.")) return NX_ERROR; + if (!ErrorHandler(NXopendata(fFileHandle, "name"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'name' in NXsample for writting.")) return NX_ERROR; + memset(cstr, '\0', sizeof(cstr)); + strncpy(cstr, fNxEntry2->GetSample()->GetName().c_str(), sizeof(cstr)); + if (!ErrorHandler(NXputdata(fFileHandle, cstr), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'name' in NXsample.")) return NX_ERROR; + NXclosedata(fFileHandle); + + // check if description is present + if (fNxEntry2->GetSample()->GetDescription().compare("n/a")) { + // write sample 'description' + size = fNxEntry2->GetSample()->GetDescription().length(); + if (!ErrorHandler(NXmakedata(fFileHandle, "description", NX_CHAR, 1, &size), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'description' in NXsample.")) return NX_ERROR; + if (!ErrorHandler(NXopendata(fFileHandle, "description"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'description' in NXsample for writting.")) return NX_ERROR; + memset(cstr, '\0', sizeof(cstr)); + strncpy(cstr, fNxEntry2->GetSample()->GetDescription().c_str(), sizeof(cstr)); + if (!ErrorHandler(NXputdata(fFileHandle, cstr), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'description' in NXsample.")) return NX_ERROR; + NXclosedata(fFileHandle); + } + + // check if temperature is present and if yes, write it into the file + ok=false; + dval = fNxEntry2->GetSample()->GetPhysPropValue("temperature", ok); + if (ok) { + fdata = (float)dval; + fNxEntry2->GetSample()->GetPhysPropUnit("temperature", str, ok); + } + if (ok) { + size = 1; + if (!ErrorHandler(NXmakedata(fFileHandle, "temperature_1", NX_FLOAT32, 1, &size), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'temperature_1' in NXsample.")) return NX_ERROR; + if (!ErrorHandler(NXopendata(fFileHandle, "temperature_1"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'temperature_1' in NXsample for writting.")) return NX_ERROR; + if (!ErrorHandler(NXputdata(fFileHandle, (void*)&fdata), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'temperature_1' in NXsample.")) return NX_ERROR; + memset(cstr, '\0', sizeof(cstr)); + strncpy(cstr, str.c_str(), sizeof(cstr)); + if (!ErrorHandler(NXputattr(fFileHandle, "units", cstr, strlen(cstr), NX_CHAR), PNEXUS_PUT_ATTR_ERROR, "couldn't put attribute 'units' for 'temperature_1' in NXsample.")) return NX_ERROR; + NXclosedata(fFileHandle); + } + + // check if temperature environment info is present + if (fNxEntry2->GetSample()->GetEnvironmentTemp().compare("n/a")) { + // write sample 'temperature_1_env' + size = fNxEntry2->GetSample()->GetEnvironmentTemp().length(); + if (!ErrorHandler(NXmakedata(fFileHandle, "temperature_1_env", NX_CHAR, 1, &size), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'temperature_1_env' in NXsample.")) return NX_ERROR; + if (!ErrorHandler(NXopendata(fFileHandle, "temperature_1_env"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'temperature_1_env' in NXsample for writting.")) return NX_ERROR; + memset(cstr, '\0', sizeof(cstr)); + strncpy(cstr, fNxEntry2->GetSample()->GetEnvironmentTemp().c_str(), sizeof(cstr)); + if (!ErrorHandler(NXputdata(fFileHandle, cstr), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'temperature_1_env' in NXsample.")) return NX_ERROR; + NXclosedata(fFileHandle); + } + + // check if magnetic field is present and if yes, write it into the file + ok=false; + dval = fNxEntry2->GetSample()->GetPhysPropValue("magnetic_field", ok); + if (ok) { + fdata = (float)dval; + fNxEntry2->GetSample()->GetPhysPropUnit("magnetic_field", str, ok); + } + if (ok) { + size = 1; + if (!ErrorHandler(NXmakedata(fFileHandle, "magnetic_field_1", NX_FLOAT32, 1, &size), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'magnetic_field_1' in NXsample.")) return NX_ERROR; + if (!ErrorHandler(NXopendata(fFileHandle, "magnetic_field_1"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'magnetic_field_1' in NXsample for writting.")) return NX_ERROR; + if (!ErrorHandler(NXputdata(fFileHandle, (void*)&fdata), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'magnetic_field_1' in NXsample.")) return NX_ERROR; + memset(cstr, '\0', sizeof(cstr)); + strncpy(cstr, str.c_str(), sizeof(cstr)); + if (!ErrorHandler(NXputattr(fFileHandle, "units", cstr, strlen(cstr), NX_CHAR), PNEXUS_PUT_ATTR_ERROR, "couldn't put attribute 'units' for 'magnetic_field_1' in NXsample.")) return NX_ERROR; + NXclosedata(fFileHandle); + } + + // check if magnetic field environment info is present + if (fNxEntry2->GetSample()->GetEnvironmentField().compare("n/a")) { + // write sample 'magnetic_field_1_env' + size = fNxEntry2->GetSample()->GetEnvironmentField().length(); + if (!ErrorHandler(NXmakedata(fFileHandle, "magnetic_field_1_env", NX_CHAR, 1, &size), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'magnetic_field_1_env' in NXsample.")) return NX_ERROR; + if (!ErrorHandler(NXopendata(fFileHandle, "magnetic_field_1_env"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'magnetic_field_1_env' in NXsample for writting.")) return NX_ERROR; + memset(cstr, '\0', sizeof(cstr)); + strncpy(cstr, fNxEntry2->GetSample()->GetEnvironmentField().c_str(), sizeof(cstr)); + if (!ErrorHandler(NXputdata(fFileHandle, cstr), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'magnetic_field_1_env' in NXsample.")) return NX_ERROR; + NXclosedata(fFileHandle); + } + + // check if magnetic field state info is present + if (fNxEntry2->GetSample()->GetMagneticFieldState().compare("n/a")) { + // write sample 'magnetic_field_state' + size = fNxEntry2->GetSample()->GetMagneticFieldState().length(); + if (!ErrorHandler(NXmakedata(fFileHandle, "magnetic_field_state", NX_CHAR, 1, &size), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'magnetic_field_state' in NXsample.")) return NX_ERROR; + if (!ErrorHandler(NXopendata(fFileHandle, "magnetic_field_state"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'magnetic_field_state' in NXsample for writting.")) return NX_ERROR; + memset(cstr, '\0', sizeof(cstr)); + strncpy(cstr, fNxEntry2->GetSample()->GetMagneticFieldState().c_str(), sizeof(cstr)); + if (!ErrorHandler(NXputdata(fFileHandle, cstr), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'magnetic_field_state' in NXsample.")) return NX_ERROR; + NXclosedata(fFileHandle); + } + + // close group 'sample' + NXclosegroup(fFileHandle); + + + // make group 'instrument' + if (!ErrorHandler(NXmakegroup(fFileHandle, "instrument", "NXinstrument"), PNEXUS_CREATE_GROUP_ERROR, "couldn't create group 'instrument' in NXentry.")) return NX_ERROR; + // open group 'instrument' + if (!ErrorHandler(NXopengroup(fFileHandle, "instrument", "NXinstrument"), PNEXUS_GROUP_OPEN_ERROR, "couldn't open group 'instrument' in NXentry for writting.")) return NX_ERROR; + + // write instrument 'name' + size = fNxEntry2->GetInstrument()->GetName().length(); + if (!ErrorHandler(NXmakedata(fFileHandle, "name", NX_CHAR, 1, &size), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'name' in NXinstrument.")) return NX_ERROR; + if (!ErrorHandler(NXopendata(fFileHandle, "name"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'name' in NXinstrument for writting.")) return NX_ERROR; + memset(cstr, '\0', sizeof(cstr)); + strncpy(cstr, fNxEntry2->GetInstrument()->GetName().c_str(), sizeof(cstr)); + if (!ErrorHandler(NXputdata(fFileHandle, cstr), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'name' in NXinstrument.")) return NX_ERROR; + NXclosedata(fFileHandle); + + // make group 'source' + if (!ErrorHandler(NXmakegroup(fFileHandle, "source", "NXsource"), PNEXUS_CREATE_GROUP_ERROR, "couldn't create group 'source' in NXinstrument.")) return NX_ERROR; + // open group 'source' + if (!ErrorHandler(NXopengroup(fFileHandle, "source", "NXsource"), PNEXUS_GROUP_OPEN_ERROR, "couldn't open group 'source' in NXentry for NXinstrument.")) return NX_ERROR; + + // write instrument 'name' + size = fNxEntry2->GetInstrument()->GetSource()->GetName().length(); + if (!ErrorHandler(NXmakedata(fFileHandle, "name", NX_CHAR, 1, &size), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'name' in NXsource.")) return NX_ERROR; + if (!ErrorHandler(NXopendata(fFileHandle, "name"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'name' in NXsource for writting.")) return NX_ERROR; + memset(cstr, '\0', sizeof(cstr)); + strncpy(cstr, fNxEntry2->GetInstrument()->GetSource()->GetName().c_str(), sizeof(cstr)); + if (!ErrorHandler(NXputdata(fFileHandle, cstr), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'name' in NXsource.")) return NX_ERROR; + NXclosedata(fFileHandle); + + // write instrument 'type' + size = fNxEntry2->GetInstrument()->GetSource()->GetType().length(); + if (!ErrorHandler(NXmakedata(fFileHandle, "type", NX_CHAR, 1, &size), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'type' in NXsource.")) return NX_ERROR; + if (!ErrorHandler(NXopendata(fFileHandle, "type"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'type' in NXsource for writting.")) return NX_ERROR; + memset(cstr, '\0', sizeof(cstr)); + strncpy(cstr, fNxEntry2->GetInstrument()->GetSource()->GetType().c_str(), sizeof(cstr)); + if (!ErrorHandler(NXputdata(fFileHandle, cstr), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'type' in NXsource.")) return NX_ERROR; + NXclosedata(fFileHandle); + + // write instrument 'probe' + size = fNxEntry2->GetInstrument()->GetSource()->GetProbe().length(); + if (!ErrorHandler(NXmakedata(fFileHandle, "probe", NX_CHAR, 1, &size), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'probe' in NXsource.")) return NX_ERROR; + if (!ErrorHandler(NXopendata(fFileHandle, "probe"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'probe' in NXsource for writting.")) return NX_ERROR; + memset(cstr, '\0', sizeof(cstr)); + strncpy(cstr, fNxEntry2->GetInstrument()->GetSource()->GetProbe().c_str(), sizeof(cstr)); + if (!ErrorHandler(NXputdata(fFileHandle, cstr), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'probe' in NXsource.")) return NX_ERROR; + NXclosedata(fFileHandle); + + // close group 'source' + NXclosegroup(fFileHandle); + + // make group 'beamline' + if (!ErrorHandler(NXmakegroup(fFileHandle, "beamline", "NXbeamline"), PNEXUS_CREATE_GROUP_ERROR, "couldn't create group 'beamline' in NXinstrument.")) return NX_ERROR; + // open group 'beamline' + if (!ErrorHandler(NXopengroup(fFileHandle, "beamline", "NXbeamline"), PNEXUS_GROUP_OPEN_ERROR, "couldn't open group 'beamline' in NXentry for NXinstrument.")) return NX_ERROR; + + // write instrument 'name' + size = fNxEntry2->GetInstrument()->GetBeamline()->GetName().length(); + if (!ErrorHandler(NXmakedata(fFileHandle, "name", NX_CHAR, 1, &size), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'name' in NXbeamline.")) return NX_ERROR; + if (!ErrorHandler(NXopendata(fFileHandle, "name"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'name' in NXbeamline for writting.")) return NX_ERROR; + memset(cstr, '\0', sizeof(cstr)); + strncpy(cstr, fNxEntry2->GetInstrument()->GetBeamline()->GetName().c_str(), sizeof(cstr)); + if (!ErrorHandler(NXputdata(fFileHandle, cstr), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'name' in NXbeamline.")) return NX_ERROR; + NXclosedata(fFileHandle); + + // close group 'beamline' + NXclosegroup(fFileHandle); + + // make group 'detector_1' + if (!ErrorHandler(NXmakegroup(fFileHandle, "detector_1", "NXdetector"), PNEXUS_CREATE_GROUP_ERROR, "couldn't create group 'detector_1' in NXinstrument.")) return NX_ERROR; + // open group 'detector_1' + if (!ErrorHandler(NXopengroup(fFileHandle, "detector_1", "NXdetector"), PNEXUS_GROUP_OPEN_ERROR, "couldn't open group 'detector_1' in NXinstrument.")) return NX_ERROR; + + // write detector_1 'description' + size = fNxEntry2->GetInstrument()->GetDetector()->GetDescription().length(); + if (!ErrorHandler(NXmakedata(fFileHandle, "description", NX_CHAR, 1, &size), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'description' in NXdetector.")) return NX_ERROR; + if (!ErrorHandler(NXopendata(fFileHandle, "description"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'description' in NXdetector for writting.")) return NX_ERROR; + memset(cstr, '\0', sizeof(cstr)); + strncpy(cstr, fNxEntry2->GetInstrument()->GetDetector()->GetDescription().c_str(), sizeof(cstr)); + if (!ErrorHandler(NXputdata(fFileHandle, cstr), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'description' in NXdetector.")) return NX_ERROR; + NXclosedata(fFileHandle); + + // write detector_1 'counts' + int dims[3]; + if (fNxEntry2->GetInstrument()->GetDetector()->GetNoOfPeriods() > 0) { // counts[][][] + dims[0] = fNxEntry2->GetInstrument()->GetDetector()->GetNoOfPeriods(); + dims[1] = fNxEntry2->GetInstrument()->GetDetector()->GetNoOfSpectra(); + dims[2] = fNxEntry2->GetInstrument()->GetDetector()->GetNoOfBins(); + if (!ErrorHandler(NXmakedata(fFileHandle, "counts", NX_INT32, 3, dims), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'counts' in NXdetector.")) return NX_ERROR; + } else { + if (fNxEntry2->GetInstrument()->GetDetector()->GetNoOfSpectra() > 0) { // counts[][] + dims[0] = fNxEntry2->GetInstrument()->GetDetector()->GetNoOfSpectra(); + dims[1] = fNxEntry2->GetInstrument()->GetDetector()->GetNoOfBins(); + if (!ErrorHandler(NXmakedata(fFileHandle, "counts", NX_INT32, 2, dims), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'counts' in NXdetector.")) return NX_ERROR; + } else { // counts[] + dims[0] = fNxEntry2->GetInstrument()->GetDetector()->GetNoOfBins(); + if (!ErrorHandler(NXmakedata(fFileHandle, "counts", NX_INT32, 1, dims), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'counts' in NXdetector.")) return NX_ERROR; + } + } + if (!ErrorHandler(NXopendata(fFileHandle, "counts"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'counts' in NXdetector for writting.")) return NX_ERROR; + if (!ErrorHandler(NXputdata(fFileHandle, (void*)fNxEntry2->GetInstrument()->GetDetector()->GetHistos()), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'counts' in NXdetector.")) return NX_ERROR; + + // write 'counts' attributes + idata = 1; + if (!ErrorHandler(NXputattr(fFileHandle, "signal", &idata, 1, NX_INT32), PNEXUS_PUT_ATTR_ERROR, "couldn't put attribute 'signal' for 'counts' in NXdetector.")) return NX_ERROR; + + memset(cstr, '\0', sizeof(cstr)); + if (fNxEntry2->GetInstrument()->GetDetector()->GetNoOfPeriods() > 0) { // counts[][][] + strncpy(cstr, "[period_index, spectrum_index, raw_time_bin]", sizeof(cstr)); + } else { + if (fNxEntry2->GetInstrument()->GetDetector()->GetNoOfSpectra() > 0) { // counts[][] + strncpy(cstr, "[spectrum_index, raw_time_bin]", sizeof(cstr)); + } else { // counts[] + strncpy(cstr, "[raw_time_bin]", sizeof(cstr)); + } + } + if (!ErrorHandler(NXputattr(fFileHandle, "axes", cstr, strlen(cstr), NX_CHAR), PNEXUS_PUT_ATTR_ERROR, "couldn't put attribute 'axes' for 'counts' in NXdetector.")) return NX_ERROR; + + memset(cstr, '\0', sizeof(cstr)); + if (!fNxEntry2->GetInstrument()->GetSource()->GetProbe().compare("positive muons")) { + strncpy(cstr, "positron counts", sizeof(cstr)); + } else if (!fNxEntry2->GetInstrument()->GetSource()->GetProbe().compare("negative muons")) { + strncpy(cstr, "electron counts", sizeof(cstr)); + } else { + strncpy(cstr, "n/a", sizeof(cstr)); + } + if (!ErrorHandler(NXputattr(fFileHandle, "long_name", cstr, strlen(cstr), NX_CHAR), PNEXUS_PUT_ATTR_ERROR, "couldn't put attribute 'long_name' for 'counts' in NXdetector.")) return NX_ERROR; + // create link of 'counts' for NXdata + if (!ErrorHandler(NXgetdataID(fFileHandle, &clink), PNEXUS_LINKING_ERROR, "couldn't obtain link of 'counts' in NXdetector.")) return NX_ERROR; + NXclosedata(fFileHandle); + + // write detector_1 'spectrum_index' + size = fNxEntry2->GetInstrument()->GetDetector()->GetSpectrumIndexSize(); + int *p_idata = new int[size]; + for (int i=0; iGetInstrument()->GetDetector()->GetSpectrumIndex(i); + if (!ErrorHandler(NXmakedata(fFileHandle, "spectrum_index", NX_INT32, 1, &size), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'spectrum_index' in NXdetector.")) return NX_ERROR; + if (!ErrorHandler(NXopendata(fFileHandle, "spectrum_index"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'spectrum_index' in NXdetector for writting.")) return NX_ERROR; + if (!ErrorHandler(NXputdata(fFileHandle, (void*)p_idata), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'spectrum_index' in NXdetector.")) return NX_ERROR; + NXclosedata(fFileHandle); + if (p_idata) { + delete [] p_idata; + p_idata = 0; + } + + // write detector_1 'time_zero_bin' if present + if (fNxEntry2->GetInstrument()->GetDetector()->IsT0Present()) { + if (fNxEntry2->GetInstrument()->GetDetector()->GetT0Tag() == 1) { + size = 1; + idata = fNxEntry2->GetInstrument()->GetDetector()->GetT0(); + if (!ErrorHandler(NXmakedata(fFileHandle, "time_zero_bin", NX_INT32, 1, &size), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'time_zero_bin' in NXdetector.")) return NX_ERROR; + if (!ErrorHandler(NXopendata(fFileHandle, "time_zero_bin"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'time_zero_bin' in NXdetector for writting.")) return NX_ERROR; + if (!ErrorHandler(NXputdata(fFileHandle, (void*)&idata), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'time_zero_bin' in NXdetector.")) return NX_ERROR; + NXclosedata(fFileHandle); + } else if (fNxEntry2->GetInstrument()->GetDetector()->GetT0Tag() == 2) { + int dims[2]; + dims[0] = fNxEntry2->GetInstrument()->GetDetector()->GetNoOfPeriods(); + dims[1] = fNxEntry2->GetInstrument()->GetDetector()->GetNoOfSpectra(); + if (!ErrorHandler(NXmakedata(fFileHandle, "time_zero_bin", NX_INT32, 2, dims), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'time_zero_bin' in NXdetector.")) return NX_ERROR; + if (!ErrorHandler(NXopendata(fFileHandle, "time_zero_bin"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'time_zero_bin' in NXdetector for writting.")) return NX_ERROR; + if (!ErrorHandler(NXputdata(fFileHandle, (void*)fNxEntry2->GetInstrument()->GetDetector()->GetT0s()), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'time_zero_bin' in NXdetector.")) return NX_ERROR; + NXclosedata(fFileHandle); + } else { + cerr << endl << ">> **WARNING** time_zero_bin with rank " << fNxEntry2->GetInstrument()->GetDetector()->GetT0Tag() << " requested. Do not know how to handle." << endl; + } + } + + // write detector_1 'first_good_bin' if present + if (fNxEntry2->GetInstrument()->GetDetector()->IsFirstGoodBinPresent()) { + if (fNxEntry2->GetInstrument()->GetDetector()->GetT0Tag() == 1) { + size = 1; + idata = fNxEntry2->GetInstrument()->GetDetector()->GetFirstGoodBin(); + if (!ErrorHandler(NXmakedata(fFileHandle, "first_good_bin", NX_INT32, 1, &size), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'first_good_bin' in NXdetector.")) return NX_ERROR; + if (!ErrorHandler(NXopendata(fFileHandle, "first_good_bin"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'first_good_bin' in NXdetector for writting.")) return NX_ERROR; + if (!ErrorHandler(NXputdata(fFileHandle, (void*)&idata), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'first_good_bin' in NXdetector.")) return NX_ERROR; + NXclosedata(fFileHandle); + } else if (fNxEntry2->GetInstrument()->GetDetector()->GetT0Tag() == 2) { + int dims[2]; + dims[0] = fNxEntry2->GetInstrument()->GetDetector()->GetNoOfPeriods(); + dims[1] = fNxEntry2->GetInstrument()->GetDetector()->GetNoOfSpectra(); + if (!ErrorHandler(NXmakedata(fFileHandle, "first_good_bin", NX_INT32, 2, dims), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'first_good_bin' in NXdetector.")) return NX_ERROR; + if (!ErrorHandler(NXopendata(fFileHandle, "first_good_bin"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'first_good_bin' in NXdetector for writting.")) return NX_ERROR; + if (!ErrorHandler(NXputdata(fFileHandle, (void*)fNxEntry2->GetInstrument()->GetDetector()->GetFirstGoodBins()), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'first_good_bin' in NXdetector.")) return NX_ERROR; + NXclosedata(fFileHandle); + } else { + cerr << endl << ">> **WARNING** first_good_bin with rank " << fNxEntry2->GetInstrument()->GetDetector()->GetT0Tag() << " requested. Do not know how to handle." << endl; + } + } + + // write detector_1 'last_good_bin' if present + if (fNxEntry2->GetInstrument()->GetDetector()->IsLastGoodBinPresent()) { + if (fNxEntry2->GetInstrument()->GetDetector()->GetT0Tag() == 1) { + size = 1; + idata = fNxEntry2->GetInstrument()->GetDetector()->GetLastGoodBin(); + if (!ErrorHandler(NXmakedata(fFileHandle, "last_good_bin", NX_INT32, 1, &size), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'last_good_bin' in NXdetector.")) return NX_ERROR; + if (!ErrorHandler(NXopendata(fFileHandle, "last_good_bin"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'last_good_bin' in NXdetector for writting.")) return NX_ERROR; + if (!ErrorHandler(NXputdata(fFileHandle, (void*)&idata), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'last_good_bin' in NXdetector.")) return NX_ERROR; + NXclosedata(fFileHandle); + } else if (fNxEntry2->GetInstrument()->GetDetector()->GetT0Tag() == 2) { + int dims[2]; + dims[0] = fNxEntry2->GetInstrument()->GetDetector()->GetNoOfPeriods(); + dims[1] = fNxEntry2->GetInstrument()->GetDetector()->GetNoOfSpectra(); + if (!ErrorHandler(NXmakedata(fFileHandle, "last_good_bin", NX_INT32, 2, dims), PNEXUS_MAKE_DATA_ERROR, "couldn't create data entry 'last_good_bin' in NXdetector.")) return NX_ERROR; + if (!ErrorHandler(NXopendata(fFileHandle, "last_good_bin"), PNEXUS_OPEN_DATA_ERROR, "couldn't open data 'last_good_bin' in NXdetector for writting.")) return NX_ERROR; + if (!ErrorHandler(NXputdata(fFileHandle, (void*)fNxEntry2->GetInstrument()->GetDetector()->GetLastGoodBins()), PNEXUS_PUT_DATA_ERROR, "couldn't put data 'last_good_bin' in NXdetector.")) return NX_ERROR; + NXclosedata(fFileHandle); + } else { + cerr << endl << ">> **WARNING** last_good_bin with rank " << fNxEntry2->GetInstrument()->GetDetector()->GetT0Tag() << " requested. Do not know how to handle." << endl; + } + } + + // close group 'detector_1' + NXclosegroup(fFileHandle); + + // close group 'instrument' + NXclosegroup(fFileHandle); + + // make group 'detector_1' NXdata + if (!ErrorHandler(NXmakegroup(fFileHandle, "detector_1", "NXdata"), PNEXUS_CREATE_GROUP_ERROR, "couldn't create group 'detector_1' in NXroot.")) return NX_ERROR; + // open group 'detector_1' NXdata + if (!ErrorHandler(NXopengroup(fFileHandle, "detector_1", "NXdata"), PNEXUS_GROUP_OPEN_ERROR, "couldn't open group 'detector_1' in NXroot.")) return NX_ERROR; + + if (!ErrorHandler(NXmakelink(fFileHandle, &clink), PNEXUS_LINKING_ERROR, "couldn't create link to 'counts' in NXdetector.")) return NX_ERROR; + + // close group 'detector_1' NXdata + NXclosegroup(fFileHandle); + + // close group 'raw_data_1' + NXclosegroup(fFileHandle); + + NXclose(&fFileHandle); + + return NX_OK; } -//----------------------------------------------------------------------------------------------------- -// end -//----------------------------------------------------------------------------------------------------- +//------------------------------------------------------------------------------------------ +// IsValidIdf1 (private) +//------------------------------------------------------------------------------------------ +/** + *

Checks if the given data are representing a valid IDF Version 1. + * + * return: + * - true if a valid IDF Version 1 representation is present + * - false otherwise + * + * \param strict flag if true a strict NeXus validation is performed. + */ +bool PNeXus::IsValidIdf1(bool strict) +{ + bool valid = true; + + if (fIdfVersion != 1) { + cerr << endl << ">> **ERROR** wrong IDF version found, namely IDF " << fIdfVersion << ", instead of IDF 1" << endl; + return false; + } + + if (!fNxEntry1->IsValid(strict)) + valid = false; + + return valid; +} + +//------------------------------------------------------------------------------------------ +// IsValidIdf2 (private) +//------------------------------------------------------------------------------------------ +/** + *

Checks if the given data are representing a valid IDF Version 2. + * + * return: + * - true if a valid IDF Version 2 representation is present + * - false otherwise + * + * \param strict flag if true a strict NeXus validation is performed. + */ +bool PNeXus::IsValidIdf2(bool strict) +{ + if (fIdfVersion != 2) { + cerr << endl << ">> **ERROR** wrong IDF version found, namely IDF " << fIdfVersion << ", instead of IDF 2" << endl; + return false; + } + + if (!fCreator.compare("n/a")) { + if (strict) { + cerr << endl << ">> **ERROR** creator not set." << endl; + return false; + } else { + cerr << endl << ">> **WARNING** creator not set." << endl; + } + } + + if (!fFileName.compare("n/a")) { + if (strict) { + cerr << endl << ">> **ERROR** file name not given." << endl; + return false; + } else { + cerr << endl << ">> **WARNING** file name not given." << endl; + } + } + + if (!fFileTime.compare("n/a")) { + if (strict) { + cerr << endl << ">> **ERROR** no file creation time is given." << endl; + return false; + } else { + cerr << endl << ">> **WARNING** no file creation time is given." << endl; + } + } + + if (!fNxEntry2->IsValid(strict)) { + return false; + } + + return true; +} + +//------------------------------------------------------------------------------------------ +// SearchInGroup (private) +//------------------------------------------------------------------------------------------ +/** + *

Searches an entry (labelled by str) in the currently open group. If the tag=='name' + * a label is looked for, if the tag=='class' a class is looked for. + * + * return: + * - true if entry 'str' is found in the currently open group. nxname, nxclass keeps than the entry information. + * - false otherwise + * + * \param str label/class of the entry to be looked for + * \param tag either 'name' or 'class' + * \param nxname 'name' of the entry if entry is found + * \param nxclass 'class name' of the entry if entry is found + * \param dataType of the entry if entry is found + */ +bool PNeXus::SearchInGroup(string str, string tag, NXname &nxname, NXname &nxclass, int &dataType) +{ + bool found = false; + int status; + + do { + status = NXgetnextentry(fFileHandle, nxname, nxclass, &dataType); + if (!tag.compare("name")) { + if (!str.compare(nxname)) { + found = true; + break; + } + } else if (!tag.compare("class")) { + if (!str.compare(nxclass)) { + found = true; + break; + } + } else { + cerr << endl << ">> **ERROR** found tag='" << tag << "' which is not handled!" << endl; + break; + } + } while (!found && (status == NX_OK)); + + return found; +} diff --git a/src/external/nexus/PNeXus.h b/src/external/nexus/PNeXus.h index cf403db7..ebd1abff 100644 --- a/src/external/nexus/PNeXus.h +++ b/src/external/nexus/PNeXus.h @@ -32,7 +32,6 @@ #ifndef _PNEXUS_H_ #define _PNEXUS_H_ -#include #include #include using namespace std; @@ -43,271 +42,581 @@ using namespace std; #define VGNAMELENMAX 64 #endif /* VGNAMELENMAX */ -#define PNEXUS_FILE_OPEN_ERROR 0 -#define PNEXUS_GROUP_OPEN_ERROR 1 -#define PNEXUS_OPEN_DATA_ERROR 2 -#define PNEXUS_GET_DATA_ERROR 3 -#define PNEXUS_GET_ATTR_ERROR 4 -#define PNEXUS_CLOSE_DATA_ERROR 5 -#define PNEXUS_GET_META_INFO_ERROR 6 -#define PNEXUS_WRONG_META_INFO 7 -#define PNEXUS_WRONG_DATE_FORMAT 8 -#define PNEXUS_WRONG_TIME_FORMAT 9 -#define PNEXUS_INIT_GROUPDIR_ERROR 10 -#define PNEXUS_GET_GROUP_INFO_ERROR 11 -#define PNEXUS_GET_NEXT_ENTRY_ERROR 12 -#define PNEXUS_HISTO_ERROR 13 -#define PNEXUS_SET_ATTR_ERROR 14 -#define PNEXUS_CREATE_GROUP_ERROR 15 -#define PNEXUS_MAKE_DATA_ERROR 16 -#define PNEXUS_PUT_DATA_ERROR 17 -#define PNEXUS_PUT_ATTR_ERROR 18 +#define PNEXUS_NO_ERROR 0 +#define PNEXUS_NXENTRY_NOT_FOUND 1 +#define PNEXUS_FILE_OPEN_ERROR 2 +#define PNEXUS_GROUP_OPEN_ERROR 3 +#define PNEXUS_OPEN_DATA_ERROR 4 +#define PNEXUS_GET_DATA_ERROR 5 +#define PNEXUS_GET_ATTR_ERROR 6 +#define PNEXUS_CLOSE_DATA_ERROR 7 +#define PNEXUS_GET_META_INFO_ERROR 8 +#define PNEXUS_WRONG_META_INFO 9 +#define PNEXUS_WRONG_DATE_FORMAT 10 +#define PNEXUS_WRONG_TIME_FORMAT 11 +#define PNEXUS_INIT_GROUPDIR_ERROR 12 +#define PNEXUS_GET_GROUP_INFO_ERROR 13 +#define PNEXUS_GET_NEXT_ENTRY_ERROR 14 +#define PNEXUS_HISTO_ERROR 15 +#define PNEXUS_SET_ATTR_ERROR 16 +#define PNEXUS_CREATE_GROUP_ERROR 17 +#define PNEXUS_MAKE_DATA_ERROR 18 +#define PNEXUS_PUT_DATA_ERROR 19 +#define PNEXUS_PUT_ATTR_ERROR 20 +#define PNEXUS_IDF_NOT_IMPLEMENTED 21 +#define PNEXUS_VAILD_READ_IDF1_FILE 22 +#define PNEXUS_VAILD_READ_IDF2_FILE 23 +#define PNEXUS_OBJECT_INVOK_ERROR 24 +#define PNEXUS_TIME_FORMAT_ERROR 25 +#define PNEXUS_DATA_ERROR 26 +#define PNEXUS_NXUSER_NOT_FOUND 27 +#define PNEXUS_LINKING_ERROR 28 -//----------------------------------------------------------------------------- -/** - * - */ -typedef struct { - string fUserName; - string fExperimentNumber; -} PNeXusUser; +class PNeXusProp { + public: + PNeXusProp(); + virtual ~PNeXusProp() {} -//----------------------------------------------------------------------------- -/** - * - */ -typedef struct { - string fName; - double fTemperature; - string fTemperatureUnit; - double fMagneticField; - string fMagneticFieldUnit; - string fShape; - string fMagneticFieldState; ///< ZF, TF, LF - int fMagneticFieldVectorAvailable; - vector fMagneticFieldVector; - string fMagneticFieldVectorUnits; - string fMagneticFieldVectorCoordinateSystem; - string fEnvironment; -} PNeXusSample; + virtual string GetName() { return fName; } + virtual double GetValue() { return fValue; } + virtual string GetUnit() { return fUnit; } -//----------------------------------------------------------------------------- -/** - *

currently only put in the requiered ones. - */ -typedef struct { - int number; -} PNeXusDetector; + virtual void SetName(string name) { fName = name; } + virtual void SetValue(double val) { fValue = val; } + virtual void SetUnit(string unit) { fUnit = unit; } -//----------------------------------------------------------------------------- -/** - *

currently only put in the requiered ones. - */ -typedef struct { - string type; -} PNeXusCollimator; + private: + string fName; + double fValue; + string fUnit; +}; -//----------------------------------------------------------------------------- -/** - *

currently only put in the requiered ones. - */ -typedef struct { - double total_counts; - string total_counts_units; -} PNeXusBeam; +class PNeXusBeam1 { + public: + PNeXusBeam1() { fTotalCounts = 0; fUnits = "n/a"; } + virtual ~PNeXusBeam1() {} -//----------------------------------------------------------------------------- -/** - * - */ -typedef struct { - string name; - PNeXusDetector detector; - PNeXusCollimator collimator; - PNeXusBeam beam; -} PNeXusInstrument; + virtual bool IsValid(bool strict); -//----------------------------------------------------------------------------- -/** - * - */ -typedef struct { - unsigned int fGroupFirst; - unsigned int fGroupSecond; - double fAlphaVal; -} PNeXusAlpha; + virtual double GetTotalCounts() { return fTotalCounts; } + virtual string GetUnits() { return fUnits; } -//----------------------------------------------------------------------------- -/** - * - */ -typedef struct { - double fTimeResolution; ///< time resolution in (ns) - unsigned int fNumberOfHistos; - vector fT0; - vector fFirstGoodBin; - vector fLastGoodBin; - vector fHistoName; - vector< vector > fHisto; - vector fGrouping; - vector fAlpha; -} PNeXusData; + virtual void SetTotalCounts(double counts) { fTotalCounts = counts; } + virtual void SetUnits(string units) { fUnits = units; } + + private: + double fTotalCounts; ///< total number of counts + string fUnits; ///< 'units' in which total counts is given, e.g. 'Mev' +}; + +class PNeXusCollimator1 { + public: + PNeXusCollimator1() { fType = "n/a"; } + virtual ~PNeXusCollimator1() {} + + virtual bool IsValid(bool strict) { return true; } // currently only a dummy + + virtual string GetType() { return fType; } + virtual void SetType(string type) { fType = type; } + + private: + string fType; +}; + +class PNeXusDetector1 { + public: + PNeXusDetector1() { fNumber = 0; } + virtual ~PNeXusDetector1() {} + + virtual bool IsValid(bool strict); + + virtual int GetNumber() { return fNumber; } + virtual void SetNumber(int number) { fNumber = number; } + + private: + int fNumber; +}; + +class PNeXusInstrument1 { + public: + PNeXusInstrument1() { fName = "n/a"; } + virtual ~PNeXusInstrument1() {} + + virtual bool IsValid(bool strict); + + virtual string GetName() { return fName; } + virtual PNeXusDetector1* GetDetector() { return &fDetector; } + virtual PNeXusCollimator1* GetCollimator() { return &fCollimator; } + virtual PNeXusBeam1* GetBeam() { return &fBeam; } + + virtual void SetName(string name) { fName = name; } + virtual void SetDetector(PNeXusDetector1 &detector) { fDetector = detector; } + virtual void SetCollimator(PNeXusCollimator1 &collimator) { fCollimator = collimator; } + virtual void SetBeam(PNeXusBeam1 &beam) { fBeam = beam; } + + private: + string fName; ///< instrument name + PNeXusDetector1 fDetector; + PNeXusCollimator1 fCollimator; + PNeXusBeam1 fBeam; +}; + +class PNeXusSample1 { + public: + PNeXusSample1(); + virtual ~PNeXusSample1(); + + virtual bool IsValid(bool strict); + + virtual string GetName() { return fName; } + virtual string GetShape() { return fShape; } + virtual string GetMagneticFieldState() { return fMagneticFieldState; } + virtual string GetEnvironment() { return fEnvironment; } + virtual double GetPhysPropValue(string name, bool &ok); + virtual void GetPhysPropUnit(string name, string &unit, bool &ok); + virtual int IsMagneticFieldVectorAvailable() { return fMagneticFieldVectorAvailable; } + virtual vector GetMagneticFieldVector() { return fMagneticFieldVector; } + virtual string GetMagneticFieldVectorUnits() { return fMagneticFieldVectorUnits; } + virtual string GetMagneticFieldVectorCoordinateSystem() { return fMagneticFieldVectorCoordinateSystem; } + + virtual void SetName(string name) { fName = name; } + virtual void SetShape(string shape) { fShape = shape; } + virtual void SetMagneticFieldState(string magFieldState) { fMagneticFieldState = magFieldState; } + virtual void SetEnvironment(string env) { fEnvironment = env; } + virtual void SetPhysProp(string name, double value, string unit, int idx=-1); + virtual void SetMagneticFieldVectorAvailable(int avail) { fMagneticFieldVectorAvailable = avail; } + virtual void SetMagneticFieldVector(vector &magVec) { fMagneticFieldVector = magVec; } + virtual void SetMagneticFieldVectorCoordinateSystem(string coord) { fMagneticFieldVectorCoordinateSystem = coord; } + virtual void SetMagneticFieldUnits(string units) { fMagneticFieldVectorUnits = units; } + + private: + string fName; ///< sample name + string fShape; ///< sample orientation + string fMagneticFieldState; ///< magnetic field state, e.g. TF, ZF, ... + string fEnvironment; ///< sample environment, e.g. CCR, Konti-1, ... + vector fPhysProp; ///< collects the temperature, magnetic field + + int fMagneticFieldVectorAvailable; ///< flag '0' magnetic field vector not available, '1' magnetic field vector available + vector fMagneticFieldVector; ///< magnetic field vector + string fMagneticFieldVectorUnits; ///< units in which the magnetic field vector is given + string fMagneticFieldVectorCoordinateSystem; ///< coordinate system, e.g. 'cartesian' +}; + +class PNeXusUser1 { + public: + PNeXusUser1(); + virtual ~PNeXusUser1() {} + + virtual bool IsValid(bool strict) { return true; } // currently only a dummy + + virtual string GetName() { return fName; } + virtual string GetExperimentNumber() { return fExperimentNumber; } + + virtual void SetName(string name) { fName = name; } + virtual void SetExperimentNumber(string expNum) { fExperimentNumber = expNum; } + + private: + string fName; ///< user name + string fExperimentNumber; ///< experiment number, RB number at ISIS +}; + +class PNeXusAlpha1 { + public: + PNeXusAlpha1(); + virtual ~PNeXusAlpha1() {} + + virtual unsigned int GetGroupFirst() { return fGroupFirst; } + virtual unsigned int GetGroupSecond() { return fGroupSecond; } + virtual double GetAlpha() { return fAlphaVal; } + + virtual void SetGroupFirst(unsigned int val) { fGroupFirst = val; } + virtual void SetGroupSecond(unsigned int val) { fGroupSecond = val; } + virtual void SetAlpha(double val) { fAlphaVal = val; } + + private: + unsigned int fGroupFirst; + unsigned int fGroupSecond; + double fAlphaVal; +}; + +class PNeXusData1 { + public: + PNeXusData1() { fTimeResolution = 0.0; } + virtual ~PNeXusData1(); + + virtual bool IsValid(bool strict); + + virtual double GetTimeResolution(string units); + virtual vector *GetT0s() { return &fT0; } + virtual int GetT0(unsigned int idx); + virtual vector *GetFirstGoodBins() { return &fFirstGoodBin; } + virtual int GetFirstGoodBin(unsigned int idx); + virtual vector *GetLastGoodBins() { return &fLastGoodBin; } + virtual int GetLastGoodBin(unsigned int idx); + virtual vector *GetHistoNames() { return &fHistoName; } + virtual void GetHistoName(unsigned int idx, string &name, bool &ok); + virtual unsigned int GetNoOfHistos() { return fHisto.size(); } + virtual vector *GetHisto(unsigned int histoNo); + virtual vector *GetGrouping() { return &fGrouping; } + virtual vector *GetAlpha() { return &fAlpha; } + + virtual void SetTimeResolution(double val, string units); + virtual void SetT0(unsigned int t0, int idx=-1); + virtual void SetFirstGoodBin(unsigned int fgb, int idx=-1); + virtual void SetLastGoodBin(unsigned int lgb, int idx=-1); + virtual void FlushHistos(); + virtual void SetHisto(vector &data, int histoNo=-1); + virtual void FlushGrouping() { fGrouping.clear(); } + virtual void SetGrouping(vector &grouping) { fGrouping = grouping; } + virtual void FlushAlpha() { fAlpha.clear(); } + virtual void SetAlpha(vector &alpha) { fAlpha = alpha; } + + private: + double fTimeResolution; ///< time resolution in (ps) + vector fT0; + vector fFirstGoodBin; + vector fLastGoodBin; + vector fHistoName; + vector< vector > fHisto; + vector fGrouping; + vector fAlpha; +}; + +class PNeXusEntry1 { + public: + PNeXusEntry1(); + virtual ~PNeXusEntry1() {} + + virtual bool IsValid(bool strict); + + virtual string GetProgramName() { return fProgramName; } + virtual string GetProgramVersion() { return fProgramVersion; } + virtual int GetRunNumber() { return fRunNumber; } + virtual string GetTitle() { return fTitle; } + virtual string GetNotes() { return fNotes; } + virtual string GetAnalysis() { return fAnalysis; } + virtual string GetLaboratory() { return fLaboratory; } + virtual string GetBeamline() { return fBeamline; } + virtual string GetStartTime() { return fStartTime; } + virtual string GetStopTime() { return fStopTime; } + virtual int GetSwitchingState() { return fSwitchingState; } + virtual PNeXusUser1* GetUser() { return &fUser; } + virtual PNeXusSample1* GetSample() { return &fSample; } + virtual PNeXusInstrument1* GetInstrument() { return &fInstrument; } + virtual PNeXusData1* GetData() { return &fData; } + + virtual void SetProgramName(string name) { fProgramName = name; } + virtual void SetProgramVersion(string version) { fProgramVersion = version; } + virtual void SetRunNumber(int number) { fRunNumber = number; } + virtual void SetTitle(string title) { fTitle = title; } + virtual void SetNotes(string notes) { fNotes = notes; } + virtual void SetAnalysis(string analysis) { fAnalysis = analysis; } + virtual void SetLaboratory(string lab) { fLaboratory = lab; } + virtual void SetBeamline(string beamline) { fBeamline = beamline; } + virtual int SetStartTime(string time); + virtual int SetStopTime(string time); + virtual int SetSwitchingState(int state); + virtual void SetUser(PNeXusUser1 &user) { fUser = user; } + virtual void SetSample(PNeXusSample1 &sample) { fSample = sample; } + virtual void SetInstrument(PNeXusInstrument1 &instrument) { fInstrument = instrument; } + virtual void SetData(PNeXusData1 &data) { fData = data; } + + private: + string fProgramName; ///< name of the creating program + string fProgramVersion; ///< version of the creating program + int fRunNumber; ///< run number + string fTitle; ///< string containing the run title + string fNotes; ///< comments + string fAnalysis; ///< type of muon experiment "muonTD", "ALC", ... + string fLaboratory; ///< name of the laboratory where the data are taken, e.g. PSI, triumf, ISIS, J-Parc + string fBeamline; ///< name of the beamline used for the experiment, e.g. muE4 + string fStartTime; ///< start date/time of the run + string fStopTime; ///< stop date/time of the run + int fSwitchingState; ///< '1' normal data collection, '2' Red/Green mode + PNeXusUser1 fUser; ///< NXuser info IDF Version 1 + PNeXusSample1 fSample; ///< NXsample info IDF Version 1 + PNeXusInstrument1 fInstrument; ///< NXinstrument info IDF Version 1 + PNeXusData1 fData; ///< NXdata info IDF Version 1 +}; + +class PNeXusSource2 { + public: + PNeXusSource2(); + virtual ~PNeXusSource2() {} + + virtual bool IsValid(bool strict); + + virtual string GetName() { return fName; } + virtual string GetType() { return fType; } + virtual string GetProbe() { return fProbe; } + + virtual void SetName(string name) { fName = name; } + virtual void SetType(string type) { fType = type; } + virtual void SetProbe(string probe) { fProbe = probe; } + + private: + string fName; ///< facility name + string fType; ///< continous muon source, pulsed muon source, low energy muon source, ... + string fProbe; ///< positive muon, negative muon +}; + +class PNeXusBeamline2 { + public: + PNeXusBeamline2() { fName = "n/a"; } + virtual ~PNeXusBeamline2() {} + + virtual bool IsValid(bool strict); + + virtual string GetName() { return fName; } + + virtual void SetName(string name) { fName = name; } + + private: + string fName; +}; + +class PNeXusDetector2 { + public: + PNeXusDetector2(); + virtual ~PNeXusDetector2(); + + virtual bool IsValid(bool strict); + + virtual string GetDescription() { return fDescription; } + virtual double GetTimeResolution(string units); + virtual bool IsT0Present() { return (fT0 == 0) ? false : true; } + virtual int GetT0Tag() { return fT0Tag; } + virtual int GetT0(int idxp=-1, int idxs=-1); + virtual int* GetT0s() { return fT0; } + virtual bool IsFirstGoodBinPresent() { return (fFirstGoodBin == 0) ? false : true; } + virtual int GetFirstGoodBin(int idxp=-1, int idxs=-1); + virtual int* GetFirstGoodBins() { return fFirstGoodBin; } + virtual bool IsLastGoodBinPresent() { return (fFirstGoodBin == 0) ? false : true; } + virtual int GetLastGoodBin(int idxp=-1, int idxs=-1); + virtual int* GetLastGoodBins() { return fLastGoodBin; } + virtual int GetNoOfPeriods() { return fNoOfPeriods; } + virtual int GetNoOfSpectra() { return fNoOfSpectra; } + virtual int GetNoOfBins() { return fNoOfBins; } + virtual int GetHistoValue(int idx_p, int idx_s, int idx_b); + virtual int* GetHistos() { return fHisto; } + virtual unsigned int GetSpectrumIndexSize() { return fSpectrumIndex.size(); } + virtual vector *GetSpectrumIndex() { return &fSpectrumIndex; } + virtual int GetSpectrumIndex(unsigned int idx); + + virtual void SetDescription(string description) { fDescription = description; } + virtual void SetTimeResolution(double val, string units); + virtual void SetT0Tag(int tag) { fT0Tag = tag; } + virtual void SetT0(int *t0) { fT0 = t0; } + virtual void SetFirstGoodBin(int *fgb) { fFirstGoodBin = fgb; } + virtual void SetLastGoodBin(int *lgb) { fLastGoodBin = lgb; } + virtual void SetNoOfPeriods(int val) { fNoOfPeriods = val; } + virtual void SetNoOfSpectra(int val) { fNoOfSpectra = val; } + virtual void SetNoOfBins(int val) { fNoOfBins = val; } + virtual void SetHisto(int *histo) { fHisto = histo; } + virtual void SetSpectrumIndex(vector spectIdx) { fSpectrumIndex = spectIdx; } + virtual void SetSpectrumIndex(int spectIdx, int idx=-1); + + private: + string fDescription; ///< description of the detector + double fTimeResolution; ///< keeps the time resolution in (ps) + vector fSpectrumIndex; ///< list of global spectra + + int fNoOfPeriods; ///< number of periods or -1 if not defined + int fNoOfSpectra; ///< number of spectra or -1 if not defined + int fNoOfBins; ///< number of bins of a spectrum or -1 if not defined + + int fT0Tag; ///< tag for t0, fgb, lgb structure. -1==not present, 1==NX_INT, 2=NX_INT[np][ns] + int *fT0; + int *fFirstGoodBin; + int *fLastGoodBin; + int *fHisto; +}; + +class PNeXusInstrument2 { + public: + PNeXusInstrument2() { fName = "n/a"; } + virtual ~PNeXusInstrument2() {} + + virtual bool IsValid(bool strict); + + virtual string GetName() { return fName; } + virtual PNeXusSource2* GetSource() { return &fSource; } + virtual PNeXusBeamline2* GetBeamline() { return &fBeamline; } + virtual PNeXusDetector2* GetDetector() { return &fDetector; } + + virtual void SetName(string name) { fName = name; } + virtual void SetSource(PNeXusSource2 &source) { fSource = source; } + virtual void SetBeamline(PNeXusBeamline2 &beamline) { fBeamline = beamline; } + virtual void SetDetector(PNeXusDetector2 &detector) { fDetector = detector; } + + private: + string fName; ///< name of the instrument + PNeXusSource2 fSource; ///< details of the muon source used + PNeXusBeamline2 fBeamline; ///< beamline description + PNeXusDetector2 fDetector; ///< details of the detectors which also includes the data!! +}; + +class PNeXusSample2 { + public: + PNeXusSample2(); + virtual ~PNeXusSample2(); + + virtual bool IsValid(bool strict); + + virtual string GetName() { return fName; } + virtual string GetDescription() { return fDescription; } + virtual string GetMagneticFieldState() { return fMagneticFieldState; } + virtual string GetEnvironmentTemp() { return fEnvironmentTemp; } + virtual string GetEnvironmentField() { return fEnvironmentField; } + virtual double GetPhysPropValue(string name, bool &ok); + virtual void GetPhysPropUnit(string name, string &unit, bool &ok); + + virtual void SetName(string name) { fName = name; } + virtual void SetDescription(string description) { fDescription = description; } + virtual void SetMagneticFieldState(string magFieldState) { fMagneticFieldState = magFieldState; } + virtual void SetEnvironmentTemp(string env) { fEnvironmentTemp = env; } + virtual void SetEnvironmentField(string env) { fEnvironmentField = env; } + virtual void SetPhysProp(string name, double value, string unit, int idx=-1); + + private: + string fName; ///< sample name + string fDescription; ///< sample description + string fMagneticFieldState; ///< magnetic field state, e.g. TF, ZF, ... + string fEnvironmentTemp; ///< sample environment related to temperature, e.g. CCR, Konti-1, ... + string fEnvironmentField; ///< sample environment related to field, e.g. WEW-Bruker + vector fPhysProp; ///< collects the temperature, magnetic field +}; + +class PNeXusUser2 { + public: + PNeXusUser2() { fName = "n/a"; } + virtual ~PNeXusUser2() {} + + virtual bool IsValid(bool strict) { return true; } // currently only a dummy + + virtual string GetName() { return fName; } + + virtual void SetName(string name) { fName = name; } + + private: + string fName; ///< user name +}; + +class PNeXusEntry2 { + public: + PNeXusEntry2(); + virtual ~PNeXusEntry2() {} + + virtual bool IsValid(bool strict); + + virtual string GetDefinition() { return fDefinition; } + virtual string GetProgramName() { return fProgramName; } + virtual string GetProgramVersion() { return fProgramVersion; } + virtual int GetRunNumber() { return fRunNumber; } + virtual string GetTitle() { return fTitle; } + virtual string GetStartTime() { return fStartTime; } + virtual string GetStopTime() { return fStopTime; } + virtual string GetExperimentIdentifier() { return fExperimentIdentifier; } + virtual PNeXusUser2* GetUser() { return &fUser; } + virtual PNeXusSample2* GetSample() { return &fSample; } + virtual PNeXusInstrument2* GetInstrument() { return &fInstrument; } + + virtual void SetDefinition(string def) { fDefinition = def; } + virtual void SetProgramName(string name) { fProgramName = name; } + virtual void SetProgramVersion(string version) { fProgramVersion = version; } + virtual void SetRunNumber(int number) { fRunNumber = number; } + virtual void SetTitle(string title) { fTitle = title; } + virtual int SetStartTime(string time); + virtual int SetStopTime(string time); + virtual void SetExperimentIdentifier(string expId) { fExperimentIdentifier = expId; } + virtual void SetUser(PNeXusUser2 &user) { fUser = user; } + virtual void SetSample(PNeXusSample2 &sample) { fSample = sample; } + virtual void SetInstrument(PNeXusInstrument2 &instrument) { fInstrument = instrument; } + + private: + string fDefinition; ///< the template (DTD name) on which the entry was based, e.g. 'pulsedTD' + string fProgramName; ///< name of the creating program + string fProgramVersion; ///< version of the creating program + int fRunNumber; ///< run number + string fTitle; ///< string containing the run title + string fStartTime; ///< start date/time of the run + string fStopTime; ///< stop date/time of the run + string fExperimentIdentifier; ///< experiment number, (for ISIS, the RB number) + PNeXusUser2 fUser; ///< NXuser info IDF Version 2 + PNeXusSample2 fSample; ///< NXsample info IDF Version 2 + PNeXusInstrument2 fInstrument; ///< NXinstrument inf IDF Version 2 +}; -//----------------------------------------------------------------------------- -/** - * - */ class PNeXus { public: PNeXus(); PNeXus(const char* fileName); virtual ~PNeXus(); - virtual bool IsValid() { return fIsValid; } + virtual int GetIdfVersion() { return fIdfVersion; } + virtual string GetFileName() { return fFileName; } + virtual string GetFileTime() { return fFileTime; } + + virtual void SetIdfVersion(unsigned int idf); + virtual void SetFileName(string name) { fFileName = name; } + virtual void SetFileTime(string time) { fFileTime = time; } + + virtual PNeXusEntry1* GetEntryIdf1() { return fNxEntry1; } + virtual PNeXusEntry2* GetEntryIdf2() { return fNxEntry2; } + + virtual bool IsValid(bool strict=false); + virtual int GetErrorCode() { return fErrorCode; } + virtual string GetErrorMsg() { return fErrorMsg; } + + virtual vector* GetGroupedHisto(unsigned int idx); virtual int ReadFile(const char *fileName); - virtual int WriteFile(const char *fileName, const char *fileType="hdf4"); + virtual int WriteFile(const char *fileName, const char *fileType="hdf4", const unsigned int idf=2); + + virtual void SetCreator(string str) { fCreator = str; } virtual void Dump(); - virtual int GetErrorCode() { return fErrorCode; } - virtual string GetErrorMsg() { return fErrorMsg; } - virtual string GetFileName() { return fFileName; } - virtual int GetIDFVersion() { return fIDFVersion; } - virtual string GetProgramName() { return fProgramName; } - virtual string GetProgramVersion() { return fProgramVersion; } - - virtual int GetRunNumber() { return fRunNumber; } - virtual string GetRunTitle() { return fRunTitle; } - virtual string GetRunNotes() { return fNotes; } - virtual string GetAnalysisTag() { return fAnalysisTag; } - virtual string GetLab() { return fLab; } - virtual string GetBeamline() { return fBeamLine; } - virtual string GetStartDate() { return fStartDate; } - virtual string GetStartTime() { return fStartTime; } - virtual string GetStopDate() { return fStopDate; } - virtual string GetStopTime() { return fStopTime; } - virtual int GetSwitchingState() { return fSwitchingState; } - virtual string GetUser() { return fUser.fUserName; } - virtual string GetExperimentNumber() { return fUser.fExperimentNumber; } - virtual string GetSampleName() { return fSample.fName; } - virtual double GetSampleTemperature() { return fSample.fTemperature; } - virtual string GetSampleTemperartureUnits() { return fSample.fTemperatureUnit; } - virtual double GetMagneticField() { return fSample.fMagneticField; } - virtual string GetMagneticFieldUnits() { return fSample.fMagneticFieldUnit; } - virtual string GetMagneticFieldState() { return fSample.fMagneticFieldState; } - virtual int IsMagneticFieldVectorAvailable() { return fSample.fMagneticFieldVectorAvailable; } - virtual vector& GetMagneticFieldVector() { return fSample.fMagneticFieldVector; } - virtual string GetMagneticFieldVectorCoordSystem() { return fSample.fMagneticFieldVectorCoordinateSystem; } - virtual string GetMagneticFieldVectorUnits() { return fSample.fMagneticFieldVectorUnits; } - virtual string GetSampleEnvironment() { return fSample.fEnvironment; } - virtual string GetSampleShape() { return fSample.fShape; } - virtual string GetExperimentName() { return fInstrument.name; } - virtual int GetNoDetectors() { return fInstrument.detector.number; } - virtual string GetCollimatorType() { return fInstrument.collimator.type; } - virtual double GetTotalNoEvents() { return fInstrument.beam.total_counts; } - virtual string GetTotalNoEventsUnits() { return fInstrument.beam.total_counts_units; } - virtual double GetTimeResolution() { return fData.fTimeResolution; } - virtual int GetNoHistos() { return fData.fNumberOfHistos; } - virtual int IsAlphaAvailable() { return fData.fAlpha.size(); } - virtual vector *GetAlpha() { if (fData.fAlpha.size()) return &fData.fAlpha; else return 0; } - virtual unsigned int GetT0() { if (fData.fT0.size()) return fData.fT0[0]; else return 0; } - virtual unsigned int GetFirstGoodBin() { if (fData.fFirstGoodBin.size()) return fData.fFirstGoodBin[0]; else return 0; } - virtual unsigned int GetLastGoodBin() { if (fData.fLastGoodBin.size()) return fData.fLastGoodBin[0]; else return 0; } - virtual vector *GetHisto(unsigned int histoNo) { if (fData.fHisto.size() > histoNo) return &fData.fHisto[histoNo]; else return 0;} - virtual vector *GetGroupedHisto(unsigned int histoNo) { if (fGroupedData.size() > histoNo) return &fGroupedData[histoNo]; else return 0; } - - virtual void SetFileName(const char* fileName) { fFileName = fileName; } - virtual void SetFileName(string fileName) { fFileName = fileName; } - virtual void SetIDFVersion(int idfVersion) { fIDFVersion = idfVersion; } - virtual void SetProgramName(const char* progName) { fProgramName = progName; } - virtual void SetProgramName(string progName) { fProgramName = progName; } - virtual void SetProgramVersion(const char* progVersion) { fProgramVersion = progVersion; } - virtual void SetProgramVersion(string progVersion) { fProgramVersion = progVersion; } - virtual void SetRunNumber(int runNumber) { fRunNumber = runNumber; } - virtual void SetRunTitle(const char* runTitle) { fRunTitle = runTitle; } - virtual void SetRunTitle(string runTitle) { fRunTitle = runTitle; } - virtual void SetRunNotes(const char* notes) { fNotes = notes; } - virtual void SetRunNotes(string notes) { fNotes = notes; } - virtual void SetAnalysisTag(const char* analysisTag) { fAnalysisTag = analysisTag; } - virtual void SetAnalysisTag(string analysisTag) { fAnalysisTag = analysisTag; } - virtual void SetLab(const char *lab) { fLab = lab; } - virtual void SetLab(string lab) { fLab = lab; } - virtual void SetBeamline(const char *beamline) { fBeamLine = beamline; } - virtual void SetBeamline(string beamline) { fBeamLine = beamline; } - virtual bool SetStartDate(const char *date); - virtual bool SetStartDate(string date); - virtual bool SetStartTime(const char *time); - virtual bool SetStartTime(string time); - virtual bool SetStopDate(const char *date); - virtual bool SetStopDate(string date); - virtual bool SetStopTime(const char *time); - virtual bool SetStopTime(string time); - virtual void SetSwitchingState(int state) { fSwitchingState=state; } - virtual void SetUser(string user) { fUser.fUserName = user; } - virtual void SetExperimentNumber(string number) { fUser.fExperimentNumber = number; } - virtual void SetSampleName(string name) { fSample.fName = name; } - virtual void SetSampleTemperature(double temp) { fSample.fTemperature = temp; } - virtual void SetSampleTemperatureUints(string units) { fSample.fTemperatureUnit = units; } - virtual void SetMagneticField(double field) { fSample.fMagneticField = field; } - virtual void SetMagneticFieldUnits(string units) { fSample.fMagneticFieldUnit = units; } - virtual void SetMagneticFieldState(string state) { fSample.fMagneticFieldState = state; } - virtual void SetSampleEnvironment(string env) { fSample.fEnvironment = env; } - virtual void SetSampleShape(string shape) { fSample.fShape = shape; } - virtual void SetMagneticFieldVectorAvailable(int available) { fSample.fMagneticFieldVectorAvailable = available; } - virtual void SetMagneticFieldVector(vector& vec) {fSample.fMagneticFieldVectorAvailable = 1; fSample.fMagneticFieldVector = vec;} - virtual void SetMagneticFieldVectorCoordSystem(string coord) { fSample.fMagneticFieldVectorCoordinateSystem = coord; } - virtual void SetMagneticFieldVectorUnits(string units) { fSample.fMagneticFieldVectorUnits = units; } - virtual void SetExperimentName(string name) { fInstrument.name = name; } - virtual void SetNoDetectors(unsigned int no) { fInstrument.detector.number = no; } - virtual void SetCollimatorType(string type) { fInstrument.collimator.type = type; } - virtual void SetTimeResolution(double timeResolution) { fData.fTimeResolution = timeResolution; } // given in ns - virtual void SetT0(unsigned int t0, unsigned int idx=0); - virtual void SetFirstGoodBin(unsigned int fgb, unsigned int idx=0); - virtual void SetLastGoodBin(unsigned int lgb, unsigned int idx=0); - virtual void SetHisto(unsigned int histoNo, vector &data); - private: - bool fIsValid; - string fFileName; ///< read/write file name - NXhandle fFileHandle; ///< nexus file handle + bool fValid; + int fErrorCode; + string fErrorMsg; - string fErrorMsg; ///< stores the current error message - int fErrorCode; ///< indicates the current error code + string fNeXusVersion; ///< version of the NeXus API used in writing the file + string fFileFormatVersion; ///< version of the HDF, HDF5, or XML library used to create the file (IDF 2 only) - int fIDFVersion; - string fProgramName; - string fProgramVersion; + unsigned int fIdfVersion; ///< version of the instrument definition + string fFileName; ///< file name of the original NeXus file to assist identification if the external name has been changed + string fFileTime; ///< date and time of file creating (IDF 2 only) + NXhandle fFileHandle; - int fRunNumber; - string fRunTitle; - string fNotes; - string fAnalysisTag; ///< type of muon experiment - string fLab; - string fBeamLine; - string fStartDate; - string fStartTime; - string fStopDate; - string fStopTime; - int fSwitchingState; ///< red/green mode + string fCreator; ///< facility of program where the file originated - PNeXusUser fUser; - PNeXusSample fSample; - PNeXusInstrument fInstrument; - PNeXusData fData; - vector< vector > fGroupedData; + PNeXusEntry1 *fNxEntry1; ///< NXentry for IDF 1 + PNeXusEntry2 *fNxEntry2; ///< NXentry for IDF 2 + + vector< vector > fGroupedHisto; virtual void Init(); - virtual void CleanUp(); virtual bool ErrorHandler(NXstatus status, int errCode, const string &errMsg); virtual NXstatus GetStringData(string &str); virtual NXstatus GetStringAttr(string attr, string &str); virtual int GetDataSize(int type); virtual NXstatus GetDoubleVectorData(vector &data); virtual NXstatus GetIntVectorData(vector &data); + + virtual int ReadFileIdf1(); + virtual int ReadFileIdf2(); + + virtual int WriteFileIdf1(const char* fileName, const NXaccess access); + virtual int WriteFileIdf2(const char* fileName, const NXaccess access); + virtual NXstatus GroupHistoData(); - virtual string TransformDate(string date, bool &ok); - virtual int GetMonth(const string month); + + virtual bool IsValidIdf1(bool strict); + virtual bool IsValidIdf2(bool strict); + + virtual bool SearchInGroup(string str, string tag, NXname &nxname, NXname &nxclass, int &dataType); }; #endif // _PNEXUS_H_ diff --git a/src/include/PMusr.h b/src/include/PMusr.h index 9dfe21db..5f62216f 100644 --- a/src/include/PMusr.h +++ b/src/include/PMusr.h @@ -609,6 +609,7 @@ typedef struct { UInt_t rebin; ///< holds the number of bins to be packed UInt_t compressionTag; ///< 0=no compression, 1=gzip compression, 2=bzip2 compression TString compressFileName; ///< holds the name of the outputfile name in case of compression is used + UInt_t idf; ///< IDF version for NeXus files. } PAny2ManyInfo; #endif // _PMUSR_H_ diff --git a/src/include/PRunDataHandler.h b/src/include/PRunDataHandler.h index 9ffc1f08..fdaa639b 100644 --- a/src/include/PRunDataHandler.h +++ b/src/include/PRunDataHandler.h @@ -96,6 +96,7 @@ class PRunDataHandler virtual TString GetFileName(const TString extension, Bool_t &ok); virtual TString FileNameFromTemplate(TString &fileNameTemplate, Int_t run, TString &year, Bool_t &ok); virtual TString GetMonth(Int_t month); + virtual void SplitTimeDate(TString timeDate, TString &time, TString &date, Bool_t &ok); }; #endif // _PRUNDATAHANDLER_H_ diff --git a/src/tests/nexus/Makefile b/src/tests/nexus/Makefile index e67c9ed5..b8595e49 100644 --- a/src/tests/nexus/Makefile +++ b/src/tests/nexus/Makefile @@ -11,7 +11,7 @@ LD = g++ LDFLAGS = -g LIBS = -L /usr/local/lib -lNeXus -LIBS += -L /opt/hdf5/lib -lhdf5 +LIBS += -L /usr/lib -lhdf5 EXEC = nexus_read_test diff --git a/src/tests/nexus/nexus_read_test.cpp b/src/tests/nexus/nexus_read_test.cpp index 9b2ebf43..9b421ad1 100644 --- a/src/tests/nexus/nexus_read_test.cpp +++ b/src/tests/nexus/nexus_read_test.cpp @@ -30,6 +30,7 @@ ***************************************************************************/ #include +#include #include #include @@ -37,8 +38,6 @@ #include using namespace std; -#include "napi.h" - #include "PNeXus.h" //--------------------------------------------------------------------------------------- @@ -46,12 +45,13 @@ using namespace std; void nexus_read_test_syntax() { cout << endl << ">>---------------------------------------------------------------------------------------"; - cout << endl << ">> usage: nexus_read_test "; + cout << endl << ">> usage: nexus_read_test [ ]"; cout << endl << ">> This will try to read a nexus-files and send the relevant"; cout << endl << ">> information to the standard output."; cout << endl << ">> At the same time the read file is written back to , where"; cout << endl << ">> the extension will be added based on the ."; cout << endl << ">> : hdf4, hdf5, xml"; + cout << endl << ">> : 1 | 2"; cout << endl << ">>---------------------------------------------------------------------------------------"; cout << endl << endl; } @@ -60,29 +60,39 @@ void nexus_read_test_syntax() int main(int argc, char *argv[]) { - if (argc != 4) { + if ((argc != 5) && (argc !=2)) { nexus_read_test_syntax(); return -1; } PNeXus *nxs_file = new PNeXus(argv[1]); - if (nxs_file->IsValid()) { + if (nxs_file->IsValid(true)) { nxs_file->Dump(); - char filename[128]; - if (strstr(argv[3], "hdf") || strstr(argv[3], "xml")) { - snprintf(filename, sizeof(filename), "%s.%s", argv[2], argv[3]); - } else { - cerr << endl << "**ERROR** unkown nexus write format found" << endl; - nexus_read_test_syntax(); - return -1; - } + if (argc == 5) { + long int idf = strtol(argv[4], (char **)NULL, 10); + if ((idf != 1) && (idf != 2)) { + if (nxs_file) + delete nxs_file; + nexus_read_test_syntax(); + return -1; + } - if (nxs_file->WriteFile(filename, argv[3]) != NX_OK) { - cerr << endl << nxs_file->GetErrorMsg() << " (" << nxs_file->GetErrorCode() << ")" << endl << endl; - } else { - cout << endl << "file " << filename << " written successfully." << endl << endl; + char filename[128]; + if (strstr(argv[3], "hdf") || strstr(argv[3], "xml")) { + snprintf(filename, sizeof(filename), "%s.%s", argv[2], argv[3]); + } else { + cerr << endl << "**ERROR** unkown nexus write format found" << endl; + nexus_read_test_syntax(); + return -1; + } + + if (nxs_file->WriteFile(filename, argv[3], (unsigned int)idf) != NX_OK) { + cerr << endl << nxs_file->GetErrorMsg() << " (" << nxs_file->GetErrorCode() << ")" << endl << endl; + } else { + cout << endl << "file " << filename << " written successfully." << endl << endl; + } } }