/** * Update the detector information from a NeXus file * @param nxFile :: Handle to a NeXus file where the root group has been opened */ void UpdateInstrumentFromFile::updateFromNeXus(::NeXus::File & nxFile) { try { nxFile.openGroup("isis_vms_compat","IXvms"); } catch(::NeXus::Exception&) { throw std::runtime_error("Unknown NeXus flavour. Cannot update instrument positions using this type of file"); } // Det ID std::vector<int32_t> detID; nxFile.openData("UDET"); nxFile.getData(detID); nxFile.closeData(); // Position information std::vector<float> l2, theta,phi; nxFile.openData("LEN2"); nxFile.getData(l2); nxFile.closeData(); nxFile.openData("TTHE"); nxFile.getData(theta); nxFile.closeData(); nxFile.openData("UT01"); nxFile.getData(phi); nxFile.closeData(); g_log.information() << "Setting detector postions from NeXus file.\n"; setDetectorPositions(detID, l2, theta, phi); }
/** Load the event_index field (a list of size of # of pulses giving the index in the event list for that pulse) * @param file :: File handle for the NeXus file * @param event_index :: ref to the vector */ void LoadBankFromDiskTask::loadEventIndex(::NeXus::File &file, std::vector<uint64_t> &event_index) { // Get the event_index (a list of size of # of pulses giving the index in // the event list for that pulse) file.openData("event_index"); // Must be uint64 if (file.getInfo().type == ::NeXus::UINT64) file.getData(event_index); else { m_loader.alg->getLogger().warning() << "Entry " << entry_name << "'s event_index field is not UINT64! It will be skipped.\n"; m_loadError = true; } file.closeData(); // Look for the sign that the bank is empty if (event_index.size() == 1) { if (event_index[0] == 0) { // One entry, only zero. This means NO events in this bank. m_loadError = true; m_loader.alg->getLogger().debug() << "Bank " << entry_name << " is empty.\n"; } } }
/** Try to load the "Veto_pulse" field in DASLogs * and convert it to a sample log. * * @param file :: open nexus file at the DASLogs group * @param workspace :: workspace to add to. */ void LoadNexusLogs::loadVetoPulses( ::NeXus::File &file, boost::shared_ptr<API::MatrixWorkspace> workspace) const { try { file.openGroup("Veto_pulse", "NXgroup"); } catch (::NeXus::Exception &) { // No group. This is common in older files return; } file.openData("veto_pulse_time"); // Load the start date/time as ISO8601 string. std::string start_time; file.getAttr("start_time", start_time); DateAndTime start(start_time); // Read the offsets std::vector<double> time_double; file.getData(time_double); // Fake values with zeroes. std::vector<double> values(time_double.size(), 0.0); TimeSeriesProperty<double> *tsp = new TimeSeriesProperty<double>("veto_pulse_time"); tsp->create(start, time_double, values); tsp->setUnits(""); // Add the log workspace->mutableRun().addProperty(tsp); file.closeData(); file.closeGroup(); }
/** * Fix the detector numbers if the defaults are not correct. Currently checks * the isis_vms_compat block and reads them from there if possible. * * @param det_ids :: An array of prefilled detector IDs * @param file :: A reference to the NeXus file opened at the root entry * @param spec_ids :: An array of spectrum numbers that the monitors have * @param nmonitors :: The size of the det_ids and spec_ids arrays */ void LoadNexusMonitors2::fixUDets(boost::scoped_array<detid_t> &det_ids, ::NeXus::File &file, const boost::scoped_array<specid_t> &spec_ids, const size_t nmonitors) const { try { file.openGroup("isis_vms_compat", "IXvms"); } catch (::NeXus::Exception &) { return; } // UDET file.openData("UDET"); std::vector<int32_t> udet; file.getData(udet); file.closeData(); // SPEC file.openData("SPEC"); std::vector<int32_t> spec; file.getData(spec); file.closeData(); // This is a little complicated: Each value in the spec_id array is a value // found in the // SPEC block of isis_vms_compat. The index that this value is found at then // corresponds // to the index within the UDET block that holds the detector ID std::vector<int32_t>::const_iterator beg = spec.begin(); for (size_t mon_index = 0; mon_index < nmonitors; ++mon_index) { std::vector<int32_t>::const_iterator itr = std::find(spec.begin(), spec.end(), spec_ids[mon_index]); if (itr == spec.end()) { det_ids[mon_index] = -1; continue; } std::vector<int32_t>::difference_type udet_index = std::distance(beg, itr); det_ids[mon_index] = udet[udet_index]; } file.closeGroup(); }
void LoadNexusLogs::loadNPeriods( ::NeXus::File &file, boost::shared_ptr<API::MatrixWorkspace> workspace) const { int value = 1; // Default to 1-period unless try { file.openGroup("periods", "IXperiods"); file.openData("number"); file.getData(&value); file.closeData(); file.closeGroup(); } catch (::NeXus::Exception &) { // Likely missing IXperiods. return; } API::Run &run = workspace->mutableRun(); const std::string nPeriodsLabel = "nperiods"; if (!run.hasProperty(nPeriodsLabel)) { run.addProperty(new PropertyWithValue<int>(nPeriodsLabel, value)); } }
bool MuonNexusReader::readMuonLogData(NeXus::File &handle) { const string NAME("name"); const string VALUES("values"); const string TIME("time"); // read name of Log data string dataName; handle.readData(NAME, dataName); // read data values try { handle.openData(VALUES); } catch (NeXus::Exception &) { g_log.warning() << "No " << VALUES << " set in " << handle.getPath() << "\n"; return false; } std::vector<float> values; std::vector<std::string> stringValues; bool isNumeric(false); NeXus::Info info = handle.getInfo(); if (info.type == NX_FLOAT32 && info.dims.size() == 1) { isNumeric = true; boost::scoped_array<float> dataVals(new float[info.dims[0]]); handle.getData(dataVals.get()); values.assign(dataVals.get(), dataVals.get() + info.dims[0]); stringValues.resize(info.dims[0]); // Leave empty } else if (info.type == NX_CHAR && info.dims.size() == 2) { boost::scoped_array<char> dataVals( new char[info.dims[0] * info.dims[1] + 1]); handle.getData(dataVals.get()); dataVals[info.dims[0] * info.dims[1]] = 0; for (int i = 0; i < info.dims[0]; ++i) { std::string str(&dataVals[i * info.dims[1]], &dataVals[(i + 1) * info.dims[1]]); stringValues.push_back(str); } values.resize(info.dims[0]); // Leave empty } else { // Leave both empty values.resize(info.dims[0]); stringValues.resize(info.dims[0]); } handle.closeData(); // read time values try { handle.openData(TIME); } catch (NeXus::Exception &) { g_log.warning() << "No " << TIME << " set in " << handle.getPath() << "\n"; return false; } info = handle.getInfo(); boost::scoped_array<float> timeVals(new float[info.dims[0]]); if (info.type == NX_FLOAT32 && info.dims.size() == 1) { handle.getData(timeVals.get()); } else { throw std::runtime_error( "Error in MuonNexusReader: expected float array for log times"); } handle.closeData(); // Add loaded values to vectors logNames.push_back(dataName); std::vector<float> tmp(timeVals.get(), timeVals.get() + info.dims[0]); logTimes.push_back(tmp); logType.push_back(isNumeric); logValues.push_back(values); logStringValues.push_back(stringValues); return true; }
/** * Load an SE log entry * @param file :: A reference to the NeXus file handle opened at the parent * group * @param entry_name :: The name of the log entry * @param workspace :: A pointer to the workspace to store the logs */ void LoadNexusLogs::loadSELog( ::NeXus::File &file, const std::string &entry_name, boost::shared_ptr<API::MatrixWorkspace> workspace) const { // Open the entry file.openGroup(entry_name, "IXseblock"); std::string propName = entry_name; if (workspace->run().hasProperty(propName)) { propName = "selog_" + propName; } // There are two possible entries: // value_log - A time series entry. This can contain a corrupt value entry // so if it does use the value one // value - A single value float entry Kernel::Property *logValue(nullptr); std::map<std::string, std::string> entries = file.getEntries(); if (entries.find("value_log") != entries.end()) { try { try { file.openGroup("value_log", "NXlog"); } catch (::NeXus::Exception &) { file.closeGroup(); throw; } logValue = createTimeSeries(file, propName); file.closeGroup(); } catch (::NeXus::Exception &e) { g_log.warning() << "IXseblock entry '" << entry_name << "' gave an error when loading " << "a time series:'" << e.what() << "'. Skipping entry\n"; file.closeGroup(); // value_log file.closeGroup(); // entry_name return; } } else if (entries.find("value") != entries.end()) { try { // This may have a larger dimension than 1 bit it has no time field so // take the first entry file.openData("value"); ::NeXus::Info info = file.getInfo(); if (info.type == ::NeXus::FLOAT32) { boost::scoped_array<float> value(new float[info.dims[0]]); file.getData(value.get()); file.closeData(); logValue = new Kernel::PropertyWithValue<double>( propName, static_cast<double>(value[0]), true); } else { file.closeGroup(); return; } } catch (::NeXus::Exception &e) { g_log.warning() << "IXseblock entry " << entry_name << " gave an error when loading " << "a single value:'" << e.what() << "'.\n"; file.closeData(); file.closeGroup(); return; } } else { g_log.warning() << "IXseblock entry " << entry_name << " cannot be read, skipping entry.\n"; file.closeGroup(); return; } workspace->mutableRun().addProperty(logValue); file.closeGroup(); }