void LoadSINQFocus::loadDataIntoTheWorkSpace(NeXus::NXEntry& entry) { // read in the data NXData dataGroup = entry.openNXData("merged"); NXInt data = dataGroup.openIntData(); data.load(); std::vector<double> timeBinning = m_loader.getTimeBinningFromNexusPath(entry, "merged/time_binning"); m_localWorkspace->dataX(0).assign(timeBinning.begin(),timeBinning.end()); Progress progress(this, 0, 1, m_numberOfTubes * m_numberOfPixelsPerTube); size_t spec = 0; for (size_t i = 0; i < m_numberOfTubes; ++i) { for (size_t j = 0; j < m_numberOfPixelsPerTube; ++j) { if (spec > 0) { // just copy the time binning axis to every spectra m_localWorkspace->dataX(spec) = m_localWorkspace->readX(0); } // Assign Y int* data_p = &data(static_cast<int>(i), static_cast<int>(j)); m_localWorkspace->dataY(spec).assign(data_p, data_p + m_numberOfChannels); // Assign Error MantidVec& E = m_localWorkspace->dataE(spec); std::transform(data_p, data_p + m_numberOfChannels, E.begin(), LoadSINQFocus::calculateError); ++spec; progress.report(); } } g_log.debug() << "Data loading into WS done...." << std::endl; }
/** * Loads the information contained in non-Spectra (ie, Text or Numeric) axis in the Nexus * file into the workspace. * @param local_workspace :: pointer to workspace object * @param data :: reference to the NeXuS data for the axis */ void LoadNexusProcessed::loadNonSpectraAxis(API::MatrixWorkspace_sptr local_workspace, NXData & data) { Mantid::API::Axis* axis = local_workspace->getAxis(1); if ( axis->isNumeric() ) { NXDouble axisData = data.openNXDouble("axis2"); axisData.load(); for ( int i = 0; i < static_cast<int>(axis->length()); i++ ) { axis->setValue(i, axisData[i]); } } else if ( axis->isText() ) { // We must cast the axis object to TextAxis so we may use ->setLabel Mantid::API::TextAxis* textAxis = dynamic_cast<Mantid::API::TextAxis*>(axis); NXChar axisData = data.openNXChar("axis2"); axisData.load(); std::string axisLabels = axisData(); // Use boost::tokenizer to split up the input boost::char_separator<char> sep("\n"); boost::tokenizer<boost::char_separator<char> > tokenizer(axisLabels, sep); boost::tokenizer<boost::char_separator<char> >::iterator tokIter; int i = 0; for ( tokIter = tokenizer.begin(); tokIter != tokenizer.end(); ++tokIter ) { textAxis->setLabel(i, *tokIter); ++i; } } }
/** * Read the bin masking information from the mantid_workspace_i/workspace group. * @param wksp_cls :: The data group * @param local_workspace :: The workspace to read into */ void LoadNexusProcessed::readBinMasking(NXData & wksp_cls, API::MatrixWorkspace_sptr local_workspace) { if (wksp_cls.getDataSetInfo("masked_spectra").stat == NX_ERROR) { return; } NXInt spec = wksp_cls.openNXInt("masked_spectra"); spec.load(); NXInt bins = wksp_cls.openNXInt("masked_bins"); bins.load(); NXDouble weights = wksp_cls.openNXDouble("mask_weights"); weights.load(); const int n = spec.dim0(); const int n1 = n - 1; for(int i = 0; i < n; ++i) { int si = spec(i,0); int j0 = spec(i,1); int j1 = i < n1 ? spec(i+1,1) : bins.dim0(); for(int j = j0; j < j1; ++j) { local_workspace->flagMasked(si,bins[j],weights[j]); } } }
/** * Load data from nexus file * * @param entry :: The Nexus file entry * @param monitorsData :: Monitors data already loaded * @param xVals :: X values */ void LoadILLReflectometry::loadData( NeXus::NXEntry &entry, const std::vector<std::vector<int>> &monitorsData, const std::vector<double> &xVals) { g_log.debug("Loading data..."); NXData dataGroup = entry.openNXData("data"); NXInt data = dataGroup.openIntData(); // load the counts from the file into memory data.load(); const size_t nb_monitors = monitorsData.size(); Progress progress(this, 0, 1, m_numberOfHistograms + nb_monitors); // write monitors if (!xVals.empty()) { HistogramData::BinEdges binEdges(xVals); // write data for (size_t j = 0; j < m_numberOfHistograms; ++j) { const int *data_p = &data(0, static_cast<int>(j), 0); const HistogramData::Counts counts(data_p, data_p + m_numberOfChannels); m_localWorkspace->setHistogram(j, binEdges, std::move(counts)); progress.report(); for (size_t im = 0; im < nb_monitors; ++im) { const int *monitor_p = monitorsData[im].data(); const HistogramData::Counts counts(monitor_p, monitor_p + m_numberOfChannels); m_localWorkspace->setHistogram(im + m_numberOfHistograms, binEdges, std::move(counts)); progress.report(); } } } else g_log.debug("Vector of x values is empty"); }
/** * Load monitors data found in nexus file * * @param entry :: The Nexus entry * */ std::vector<std::vector<int>> LoadILLReflectometry::loadMonitors(NeXus::NXEntry &entry) { // read in the data g_log.debug("Fetching monitor data..."); NXData dataGroup = entry.openNXData("monitor1/data"); NXInt data = dataGroup.openIntData(); // load the counts from the file into memory data.load(); std::vector<std::vector<int>> monitors( 1); // vector of monitors with one entry std::vector<int> monitor1(data(), data() + data.size()); monitors[0].swap(monitor1); // There is two monitors in data file, but the second one seems to be always 0 dataGroup = entry.openNXData("monitor2/data"); data = dataGroup.openIntData(); data.load(); std::vector<int> monitor2(data(), data() + data.size()); monitors.push_back(monitor2); return monitors; }
void LoadSINQFocus::initWorkSpace(NeXus::NXEntry& entry) { // read in the data NXData dataGroup = entry.openNXData("merged"); NXInt data = dataGroup.openIntData(); m_numberOfTubes = static_cast<size_t>(data.dim0()); m_numberOfPixelsPerTube = 1; m_numberOfChannels = static_cast<size_t>(data.dim1()); // dim0 * m_numberOfPixelsPerTube is the total number of detectors m_numberOfHistograms = m_numberOfTubes * m_numberOfPixelsPerTube; g_log.debug() << "NumberOfTubes: " << m_numberOfTubes << std::endl; g_log.debug() << "NumberOfPixelsPerTube: " << m_numberOfPixelsPerTube << std::endl; g_log.debug() << "NumberOfChannels: " << m_numberOfChannels << std::endl; // Now create the output workspace // Might need to get this value from the number of monitors in the Nexus file // params: // workspace type, // total number of spectra + (number of monitors = 0), // bin boundaries = m_numberOfChannels + 1 // Z/time dimension m_localWorkspace = WorkspaceFactory::Instance().create("Workspace2D", m_numberOfHistograms, m_numberOfChannels + 1, m_numberOfChannels); m_localWorkspace->getAxis(0)->unit() = UnitFactory::Instance().create( "TOF"); m_localWorkspace->setYUnitLabel("Counts"); }
/** * Load single monitor * * @param entry :: The Nexus entry * @param monitor_data :: A std::string containing the Nexus path to the monitor *data * @return monitor :: A std::vector containing monitor values */ std::vector<int> LoadILLReflectometry::loadSingleMonitor(NeXus::NXEntry &entry, const std::string &monitor_data) { NXData dataGroup = entry.openNXData(monitor_data); NXInt data = dataGroup.openIntData(); // load counts data.load(); return std::vector<int>(data(), data() + data.size()); }
/** * Load Data details (number of tubes, channels, etc) * @param entry First entry of nexus file */ void LoadILLReflectometry::loadDataDetails(NeXus::NXEntry &entry) { // read in the data NXData dataGroup = entry.openNXData("data"); NXInt data = dataGroup.openIntData(); m_numberOfTubes = static_cast<size_t>(data.dim0()); m_numberOfPixelsPerTube = static_cast<size_t>(data.dim1()); m_numberOfChannels = static_cast<size_t>(data.dim2()); }
size_t LoadILLSANS::loadDataIntoWorkspaceFromMonitors(NeXus::NXEntry &firstEntry, size_t firstIndex) { // let's find the monitors // For D33 should be monitor1 and monitor2 for (std::vector<NXClassInfo>::const_iterator it = firstEntry.groups().begin(); it != firstEntry.groups().end(); ++it) { if (it->nxclass == "NXmonitor") { NXData dataGroup = firstEntry.openNXData(it->nxname); NXInt data = dataGroup.openIntData(); data.load(); g_log.debug() << "Monitor: " << it->nxname << " dims = " << data.dim0() << "x" << data.dim1() << "x" << data.dim2() << '\n'; const size_t vectorSize = data.dim2() + 1; std::vector<double> positionsBinning; positionsBinning.reserve(vectorSize); for (size_t i = 0; i < vectorSize; i++) positionsBinning.push_back(static_cast<double>(i)); // Assign X m_localWorkspace->dataX(firstIndex) .assign(positionsBinning.begin(), positionsBinning.end()); // Assign Y m_localWorkspace->dataY(firstIndex).assign(data(), data() + data.dim2()); // Assign Error MantidVec &E = m_localWorkspace->dataE(firstIndex); std::transform(data(), data() + data.dim2(), E.begin(), LoadHelper::calculateStandardError); // Add average monitor counts to a property: double averageMonitorCounts = std::accumulate(data(), data() + data.dim2(), 0) / static_cast<double>(data.dim2()); // make sure the monitor has values! if (averageMonitorCounts > 0) { API::Run &runDetails = m_localWorkspace->mutableRun(); runDetails.addProperty("monitor", averageMonitorCounts, true); } firstIndex++; } } return firstIndex; }
/** * Load monitors data found in nexus file * * @param entry :: The Nexus entry * */ std::vector<std::vector<int>> LoadILLIndirect::loadMonitors(NeXus::NXEntry &entry) { // read in the data g_log.debug("Fetching monitor data..."); NXData dataGroup = entry.openNXData("monitor/data"); NXInt data = dataGroup.openIntData(); // load the counts from the file into memory data.load(); // For the moment, we are aware of only one monitor entry, but we keep the // generalized case of n monitors std::vector<std::vector<int>> monitors(1); std::vector<int> monitor(data(), data() + data.size()); monitors[0].swap(monitor); return monitors; }
void LoadLLB::loadDataIntoTheWorkSpace(NeXus::NXEntry &entry) { // read in the data NXData dataGroup = entry.openNXData("nxdata"); NXFloat data = dataGroup.openFloatData(); data.load(); // EPP int calculatedDetectorElasticPeakPosition = getDetectorElasticPeakPosition(data); std::vector<double> timeBinning = getTimeBinning(calculatedDetectorElasticPeakPosition, m_channelWidth); // Assign time bin to first X entry m_localWorkspace->dataX(0).assign(timeBinning.begin(), timeBinning.end()); Progress progress(this, 0, 1, m_numberOfTubes * m_numberOfPixelsPerTube); size_t spec = 0; for (size_t i = 0; i < m_numberOfTubes; ++i) { for (size_t j = 0; j < m_numberOfPixelsPerTube; ++j) { if (spec > 0) { // just copy the time binning axis to every spectra m_localWorkspace->dataX(spec) = m_localWorkspace->readX(0); } // Assign Y float *data_p = &data(static_cast<int>(i), static_cast<int>(j)); m_localWorkspace->dataY(spec).assign(data_p, data_p + m_numberOfChannels); // Assign Error MantidVec &E = m_localWorkspace->dataE(spec); std::transform(data_p, data_p + m_numberOfChannels, E.begin(), LoadLLB::calculateError); ++spec; progress.report(); } } g_log.debug() << "Data loading inti WS done....\n"; }
/** * Loads the mapping between index -> set of detector IDs * * If "detector_index", "detector_count" and "detector_list" are all present, * use these to get the mapping, otherwise spectrum number = detector ID * (one-to-one) * * The spectrum spectrum_index[i] maps to detector_count[i] detectors, whose * detector IDs are in detector_list starting at the index detector_index[i] * * @returns :: map of index -> detector IDs * @throws std::runtime_error if fails to read data from file */ std::map<int, std::set<int>> LoadMuonNexus2::loadDetectorMapping(const Mantid::NeXus::NXInt &spectrumIndex) { std::map<int, std::set<int>> mapping; const int nSpectra = spectrumIndex.dim0(); // Find and open the data group NXRoot root(getPropertyValue("Filename")); NXEntry entry = root.openEntry(m_entry_name); const std::string detectorName = [&entry]() { // Only the first NXdata found for (auto &group : entry.groups()) { std::string className = group.nxclass; if (className == "NXdata") { return group.nxname; } } throw std::runtime_error("No NXdata found in file"); }(); NXData dataGroup = entry.openNXData(detectorName); // Usually for muon data, detector id = spectrum number // If not, the optional groups "detector_index", "detector_list" and // "detector_count" will be present to map one to the other const bool hasDetectorMapping = dataGroup.containsDataSet("detector_index") && dataGroup.containsDataSet("detector_list") && dataGroup.containsDataSet("detector_count"); if (hasDetectorMapping) { // Read detector IDs try { const auto detIndex = dataGroup.openNXInt("detector_index"); const auto detCount = dataGroup.openNXInt("detector_count"); const auto detList = dataGroup.openNXInt("detector_list"); const int nSpectra = detIndex.dim0(); for (int i = 0; i < nSpectra; ++i) { const int start = detIndex[i]; const int nDetectors = detCount[i]; std::set<int> detIDs; for (int jDet = 0; jDet < nDetectors; ++jDet) { detIDs.insert(detList[start + jDet]); } mapping[i] = detIDs; } } catch (const ::NeXus::Exception &err) { // Throw a more user-friendly message std::ostringstream message; message << "Failed to read detector mapping: " << err.what(); throw std::runtime_error(message.str()); } } else { for (int i = 0; i < nSpectra; ++i) { mapping[i] = std::set<int>{spectrumIndex[i]}; } } return mapping; }
/** Load the event_workspace field * * @param wksp_cls * @param progressStart * @param progressRange * @return */ API::MatrixWorkspace_sptr LoadNexusProcessed::loadEventEntry(NXData & wksp_cls, NXDouble & xbins, const double& progressStart, const double& progressRange) { NXDataSetTyped<int64_t> indices_data = wksp_cls.openNXDataSet<int64_t>("indices"); indices_data.load(); boost::shared_array<int64_t> indices = indices_data.sharedBuffer(); int numspec = indices_data.dim0()-1; int num_xbins = xbins.dim0(); if (num_xbins < 2) num_xbins = 2; EventWorkspace_sptr ws = boost::dynamic_pointer_cast<EventWorkspace> (WorkspaceFactory::Instance().create("EventWorkspace", numspec, num_xbins, num_xbins-1)); // Set the YUnit label ws->setYUnit(indices_data.attributes("units")); std::string unitLabel = indices_data.attributes("unit_label"); if (unitLabel.empty()) unitLabel = indices_data.attributes("units"); ws->setYUnitLabel(unitLabel); //Handle optional fields. // TODO: Handle inconsistent sizes boost::shared_array<int64_t> pulsetimes; if (wksp_cls.isValid("pulsetime")) { NXDataSetTyped<int64_t> pulsetime = wksp_cls.openNXDataSet<int64_t>("pulsetime"); pulsetime.load(); pulsetimes = pulsetime.sharedBuffer(); } boost::shared_array<double> tofs; if (wksp_cls.isValid("tof")) { NXDouble tof = wksp_cls.openNXDouble("tof"); tof.load(); tofs = tof.sharedBuffer(); } boost::shared_array<float> error_squareds; if (wksp_cls.isValid("error_squared")) { NXFloat error_squared = wksp_cls.openNXFloat("error_squared"); error_squared.load(); error_squareds = error_squared.sharedBuffer(); } boost::shared_array<float> weights; if (wksp_cls.isValid("weight")) { NXFloat weight = wksp_cls.openNXFloat("weight"); weight.load(); weights = weight.sharedBuffer(); } // What type of event lists? EventType type = TOF; if (tofs && pulsetimes && weights && error_squareds) type = WEIGHTED; else if ((tofs && weights && error_squareds)) type = WEIGHTED_NOTIME; else if (pulsetimes && tofs) type = TOF; else throw std::runtime_error("Could not figure out the type of event list!"); // Create all the event lists PARALLEL_FOR_NO_WSP_CHECK() for (int wi=0; wi < numspec; wi++) { PARALLEL_START_INTERUPT_REGION int64_t index_start = indices[wi]; int64_t index_end = indices[wi+1]; if (index_end >= index_start) { EventList & el = ws->getEventList(wi); el.switchTo(type); // Allocate all the required memory el.reserve(index_end - index_start); el.clearDetectorIDs(); for (long i=index_start; i<index_end; i++) switch (type) { case TOF: el.addEventQuickly( TofEvent( tofs[i], DateAndTime(pulsetimes[i])) ); break; case WEIGHTED: el.addEventQuickly( WeightedEvent( tofs[i], DateAndTime(pulsetimes[i]), weights[i], error_squareds[i]) ); break; case WEIGHTED_NOTIME: el.addEventQuickly( WeightedEventNoTime( tofs[i], weights[i], error_squareds[i]) ); break; } // Set the X axis if (this->m_shared_bins) el.setX(this->m_xbins); else { MantidVec x; x.resize(xbins.dim0()); for (int i=0; i < xbins.dim0(); i++) x[i] = xbins(wi, i); el.setX(x); } } progress(progressStart + progressRange*(1.0/numspec)); PARALLEL_END_INTERUPT_REGION } PARALLEL_CHECK_INTERUPT_REGION // Clean up some stuff ws->doneAddingEventLists(); return ws; }
/** * Load a given period into the workspace * @param period :: The period number to load (starting from 1) * @param entry :: The opened root entry node for accessing the monitor and data nodes * @param local_workspace :: The workspace to place the data in */ void LoadISISNexus2::loadPeriodData(int64_t period, NXEntry & entry, DataObjects::Workspace2D_sptr local_workspace) { int64_t hist_index = 0; int64_t period_index(period - 1); int64_t first_monitor_spectrum = 0; if( !m_monitors.empty() ) { first_monitor_spectrum = m_monitors.begin()->first; hist_index = first_monitor_spectrum - 1; for(std::map<int64_t,std::string>::const_iterator it = m_monitors.begin(); it != m_monitors.end(); ++it) { NXData monitor = entry.openNXData(it->second); NXInt mondata = monitor.openIntData(); m_progress->report("Loading monitor"); mondata.load(1,static_cast<int>(period-1)); // TODO this is just wrong MantidVec& Y = local_workspace->dataY(hist_index); Y.assign(mondata(),mondata() + m_numberOfChannels); MantidVec& E = local_workspace->dataE(hist_index); std::transform(Y.begin(), Y.end(), E.begin(), dblSqrt); local_workspace->getAxis(1)->spectraNo(hist_index) = static_cast<specid_t>(it->first); NXFloat timeBins = monitor.openNXFloat("time_of_flight"); timeBins.load(); local_workspace->dataX(hist_index).assign(timeBins(),timeBins() + timeBins.dim0()); hist_index++; } if (first_monitor_spectrum > 1) { hist_index = 0; } } if( m_have_detector ) { NXData nxdata = entry.openNXData("detector_1"); NXDataSetTyped<int> data = nxdata.openIntData(); data.open(); //Start with thelist members that are lower than the required spectrum const int * const spec_begin = m_spec.get(); std::vector<int64_t>::iterator min_end = m_spec_list.end(); if( !m_spec_list.empty() ) { // If we have a list, by now it is ordered so first pull in the range below the starting block range // Note the reverse iteration as we want the last one if( m_range_supplied ) { min_end = std::find_if(m_spec_list.begin(), m_spec_list.end(), std::bind2nd(std::greater<int>(), m_spec_min)); } for( std::vector<int64_t>::iterator itr = m_spec_list.begin(); itr < min_end; ++itr ) { // Load each int64_t spectra_no = (*itr); // For this to work correctly, we assume that the spectrum list increases monotonically int64_t filestart = std::lower_bound(spec_begin,m_spec_end,spectra_no) - spec_begin; m_progress->report("Loading data"); loadBlock(data, static_cast<int64_t>(1), period_index, filestart, hist_index, spectra_no, local_workspace); } } if( m_range_supplied ) { // When reading in blocks we need to be careful that the range is exactly divisible by the blocksize // and if not have an extra read of the left overs const int64_t blocksize = 8; const int64_t rangesize = (m_spec_max - m_spec_min + 1) - m_monitors.size(); const int64_t fullblocks = rangesize / blocksize; int64_t read_stop = 0; int64_t spectra_no = m_spec_min; if (first_monitor_spectrum == 1) {// this if crudely checks whether the monitors are at the begining or end of the spectra spectra_no += static_cast<int>(m_monitors.size()); } // For this to work correctly, we assume that the spectrum list increases monotonically int64_t filestart = std::lower_bound(spec_begin,m_spec_end,spectra_no) - spec_begin; if( fullblocks > 0 ) { read_stop = (fullblocks * blocksize);// + m_monitors.size(); //RNT: I think monitors are excluded from the data //for( ; hist_index < read_stop; ) for(int64_t i = 0; i < fullblocks; ++i) { loadBlock(data, blocksize, period_index, filestart, hist_index, spectra_no, local_workspace); filestart += blocksize; } } int64_t finalblock = rangesize - (fullblocks * blocksize); if( finalblock > 0 ) { loadBlock(data, finalblock, period_index, filestart, hist_index, spectra_no, local_workspace); } } //Load in the last of the list indices for( std::vector<int64_t>::iterator itr = min_end; itr < m_spec_list.end(); ++itr ) { // Load each int64_t spectra_no = (*itr); // For this to work correctly, we assume that the spectrum list increases monotonically int64_t filestart = std::lower_bound(spec_begin,m_spec_end,spectra_no) - spec_begin; loadBlock(data, 1, period_index, filestart, hist_index, spectra_no, local_workspace); } } try { const std::string title = entry.getString("title"); local_workspace->setTitle(title); // write the title into the log file (run object) local_workspace->mutableRun().addProperty("run_title", title, true); } catch (std::runtime_error &) { g_log.debug() << "No title was found in the input file, " << getPropertyValue("Filename") << std::endl; } }
/** * Load a given period into the workspace * @param period :: The period number to load (starting from 1) * @param entry :: The opened root entry node for accessing the monitor and data * nodes * @param local_workspace :: The workspace to place the data in * @param update_spectra2det_mapping :: reset spectra-detector map to the one * calculated earlier. (Warning! -- this map has to be calculated correctly!) */ void LoadISISNexus2::loadPeriodData(int64_t period, NXEntry &entry, DataObjects::Workspace2D_sptr &local_workspace, bool update_spectra2det_mapping) { int64_t hist_index = 0; int64_t period_index(period - 1); // int64_t first_monitor_spectrum = 0; for (auto block = m_spectraBlocks.begin(); block != m_spectraBlocks.end(); ++block) { if (block->isMonitor) { NXData monitor = entry.openNXData(block->monName); NXInt mondata = monitor.openIntData(); m_progress->report("Loading monitor"); mondata.load(1, static_cast<int>(period - 1)); // TODO this is just wrong MantidVec &Y = local_workspace->dataY(hist_index); Y.assign(mondata(), mondata() + m_monBlockInfo.numberOfChannels); MantidVec &E = local_workspace->dataE(hist_index); std::transform(Y.begin(), Y.end(), E.begin(), dblSqrt); if (update_spectra2det_mapping) { // local_workspace->getAxis(1)->setValue(hist_index, // static_cast<specid_t>(it->first)); auto spec = local_workspace->getSpectrum(hist_index); specid_t specID = m_specInd2specNum_map.at(hist_index); spec->setDetectorIDs( m_spec2det_map.getDetectorIDsForSpectrumNo(specID)); spec->setSpectrumNo(specID); } NXFloat timeBins = monitor.openNXFloat("time_of_flight"); timeBins.load(); local_workspace->dataX(hist_index) .assign(timeBins(), timeBins() + timeBins.dim0()); hist_index++; } else if (m_have_detector) { NXData nxdata = entry.openNXData("detector_1"); NXDataSetTyped<int> data = nxdata.openIntData(); data.open(); // Start with the list members that are lower than the required spectrum const int *const spec_begin = m_spec.get(); // When reading in blocks we need to be careful that the range is exactly // divisible by the block-size // and if not have an extra read of the left overs const int64_t blocksize = 8; const int64_t rangesize = block->last - block->first + 1; const int64_t fullblocks = rangesize / blocksize; int64_t spectra_no = block->first; // For this to work correctly, we assume that the spectrum list increases // monotonically int64_t filestart = std::lower_bound(spec_begin, m_spec_end, spectra_no) - spec_begin; if (fullblocks > 0) { for (int64_t i = 0; i < fullblocks; ++i) { loadBlock(data, blocksize, period_index, filestart, hist_index, spectra_no, local_workspace); filestart += blocksize; } } int64_t finalblock = rangesize - (fullblocks * blocksize); if (finalblock > 0) { loadBlock(data, finalblock, period_index, filestart, hist_index, spectra_no, local_workspace); } } } try { const std::string title = entry.getString("title"); local_workspace->setTitle(title); // write the title into the log file (run object) local_workspace->mutableRun().addProperty("run_title", title, true); } catch (std::runtime_error &) { g_log.debug() << "No title was found in the input file, " << getPropertyValue("Filename") << std::endl; } }
/**Method takes input parameters which describe monitor loading and analyze *them against spectra/monitor block information in the file. * The result is the option if monitors can be loaded together with spectra or *mast be treated separately * and additional information on how to treat monitor spectra. * *@param entry :: entry to the NeXus file, opened at root folder *@param spectrum_index :: array of spectra indexes of the data present in *the file *@param ndets :: size of the spectrum index array *@param n_vms_compat_spectra :: number of data entries containing common time *bins (e.g. all spectra, or all spectra and monitors or some spectra (this is *not fully supported) *@param monitors :: map connecting monitor spectra ID against *monitor group name in the file. *@param excludeMonitors :: input property indicating if it is requested to *exclude monitors from the target workspace *@param separateMonitors :: input property indicating if it is requested to *load monitors separately (and exclude them from target data workspace this way) * *@param OvelapMonitors :: output property containing the list of monitors *ID for monitors, which are also included with spectra. *@return excludeMonitors :: indicator if monitors should or mast be excluded *from the main data workspace if they can not be loaded with the data * (contain different number of time channels) * */ bool LoadISISNexus2::findSpectraDetRangeInFile( NXEntry &entry, boost::shared_array<int> &spectrum_index, int64_t ndets, int64_t n_vms_compat_spectra, std::map<int64_t, std::string> &monitors, bool excludeMonitors, bool separateMonitors, std::map<int64_t, std::string> &OvelapMonitors) { OvelapMonitors.clear(); size_t nmons = monitors.size(); if (nmons > 0) { NXInt chans = entry.openNXInt(m_monitors.begin()->second + "/data"); m_monBlockInfo = DataBlock(chans); m_monBlockInfo.numberOfSpectra = nmons; // each monitor is in separate group // so number of spectra is equal to // number of groups. // identify monitor ID range. for (auto it = monitors.begin(); it != monitors.end(); it++) { int64_t mon_id = static_cast<int64_t>(it->first); if (m_monBlockInfo.spectraID_min > mon_id) m_monBlockInfo.spectraID_min = mon_id; if (m_monBlockInfo.spectraID_max < mon_id) m_monBlockInfo.spectraID_max = mon_id; } if (m_monBlockInfo.spectraID_max - m_monBlockInfo.spectraID_min + 1 != static_cast<int64_t>(nmons)) { g_log.warning() << "When trying to find the range of monitor spectra: " "non-consequent monitor ID-s in the monitor block. " "Unexpected situation for the loader\n"; } // at this stage we assume that the only going to load monitors m_loadBlockInfo = m_monBlockInfo; } if (ndets == 0) { separateMonitors = false; // only monitors in the main workspace. No // detectors. Will be loaded in the main workspace // Possible function exit point return separateMonitors; } // detectors are present in the file NXData nxData = entry.openNXData("detector_1"); NXInt data = nxData.openIntData(); m_detBlockInfo = DataBlock(data); // We assume again that this spectrum list ID increase monotonically m_detBlockInfo.spectraID_min = spectrum_index[0]; m_detBlockInfo.spectraID_max = spectrum_index[ndets - 1]; if (m_detBlockInfo.spectraID_max - m_detBlockInfo.spectraID_min + 1 != static_cast<int64_t>(m_detBlockInfo.numberOfSpectra)) { g_log.warning() << "When trying to find the range of monitor spectra: " "non-consequent spectra ID-s in the detectors block. " "Unexpected situation for the loader\n"; } m_loadBlockInfo = m_detBlockInfo; // now we are analyzing what is actually going or can be loaded bool removeMonitors = excludeMonitors || separateMonitors; if (((m_detBlockInfo.numberOfPeriods != m_monBlockInfo.numberOfPeriods) || (m_detBlockInfo.numberOfChannels != m_monBlockInfo.numberOfChannels)) && nmons > 0) { // detectors and monitors have different characteristics. Can be loaded only // to separate workspaces. if (!removeMonitors) { g_log.warning() << " Performing separate loading as can not load spectra " "and monitors in the single workspace:\n"; g_log.warning() << " Monitors data contain :" << m_monBlockInfo.numberOfChannels << " time channels and: " << m_monBlockInfo.numberOfPeriods << " period(s)\n"; g_log.warning() << " Spectra data contain :" << m_detBlockInfo.numberOfChannels << " time channels and: " << m_detBlockInfo.numberOfPeriods << " period(s)\n"; } separateMonitors = true; removeMonitors = true; } int64_t spectraID_min = std::min(m_monBlockInfo.spectraID_min, m_detBlockInfo.spectraID_min); int64_t spectraID_max = std::max(m_monBlockInfo.spectraID_max, m_detBlockInfo.spectraID_max); size_t totNumOfSpectra = m_monBlockInfo.numberOfSpectra + m_detBlockInfo.numberOfSpectra; if (!removeMonitors) { m_loadBlockInfo.numberOfSpectra = totNumOfSpectra; m_loadBlockInfo.spectraID_min = spectraID_min; m_loadBlockInfo.spectraID_max = spectraID_max; } if (separateMonitors) m_loadBlockInfo = m_detBlockInfo; // verify integrity of the monitor and detector information if ((totNumOfSpectra == static_cast<size_t>(n_vms_compat_spectra)) && (spectraID_max - spectraID_min + 1 == static_cast<int64_t>(n_vms_compat_spectra))) { // all information written in the file is correct, there are no spurious // spectra and detectors & monitors form continuous block on HDD return separateMonitors; } // something is wrong and we need to analyze spectra map. Currently we can // identify and manage the case when all monitor's spectra are written // together with detectors // make settings for this situation m_detBlockInfo.numberOfSpectra -= m_monBlockInfo.numberOfSpectra; m_loadBlockInfo.numberOfSpectra -= m_monBlockInfo.numberOfSpectra; std::map<int64_t, std::string> remaining_monitors; if (removeMonitors) { for (auto it = monitors.begin(); it != monitors.end(); it++) { if (it->first >= m_detBlockInfo.spectraID_min && it->first <= m_detBlockInfo.spectraID_max) { // monitors ID-s are // included with spectra // ID-s -- let's try not // to load it twice. OvelapMonitors.insert(*it); } else { remaining_monitors.insert(*it); } } } monitors.swap(remaining_monitors); return separateMonitors; }
/** * Load data found in nexus file * * @param entry :: The Nexus entry * @param monitorsData :: Monitors data already loaded * */ void LoadILLIndirect::loadDataIntoTheWorkSpace( NeXus::NXEntry &entry, std::vector<std::vector<int>> monitorsData) { // read in the data NXData dataGroup = entry.openNXData("data"); NXInt data = dataGroup.openIntData(); // load the counts from the file into memory data.load(); // Same for Simple Detectors NXData dataSDGroup = entry.openNXData("dataSD"); NXInt dataSD = dataSDGroup.openIntData(); // load the counts from the file into memory dataSD.load(); // Assign calculated bins to first X axis //// m_localWorkspace->dataX(0).assign(detectorTofBins.begin(), /// detectorTofBins.end()); size_t spec = 0; size_t nb_monitors = monitorsData.size(); size_t nb_SD_detectors = dataSD.dim0(); Progress progress(this, 0, 1, m_numberOfTubes * m_numberOfPixelsPerTube + nb_monitors + nb_SD_detectors); // Assign fake values to first X axis <<to be completed>> for (size_t i = 0; i <= m_numberOfChannels; ++i) { m_localWorkspace->dataX(0)[i] = double(i); } // First, Monitor for (size_t im = 0; im < nb_monitors; im++) { if (im > 0) { m_localWorkspace->dataX(im) = m_localWorkspace->readX(0); } // Assign Y int *monitor_p = monitorsData[im].data(); m_localWorkspace->dataY(im) .assign(monitor_p, monitor_p + m_numberOfChannels); progress.report(); } // Then Tubes for (size_t i = 0; i < m_numberOfTubes; ++i) { for (size_t j = 0; j < m_numberOfPixelsPerTube; ++j) { // just copy the time binning axis to every spectra m_localWorkspace->dataX(spec + nb_monitors) = m_localWorkspace->readX(0); // Assign Y int *data_p = &data(static_cast<int>(i), static_cast<int>(j), 0); m_localWorkspace->dataY(spec + nb_monitors) .assign(data_p, data_p + m_numberOfChannels); // Assign Error MantidVec &E = m_localWorkspace->dataE(spec + nb_monitors); std::transform(data_p, data_p + m_numberOfChannels, E.begin(), LoadILLIndirect::calculateError); ++spec; progress.report(); } } // for m_numberOfTubes // Then add Simple Detector (SD) for (int i = 0; i < dataSD.dim0(); ++i) { // just copy again the time binning axis to every spectra m_localWorkspace->dataX(spec + nb_monitors + i) = m_localWorkspace->readX(0); // Assign Y int *dataSD_p = &dataSD(i, 0, 0); m_localWorkspace->dataY(spec + nb_monitors + i) .assign(dataSD_p, dataSD_p + m_numberOfChannels); progress.report(); } } // LoadILLIndirect::loadDataIntoTheWorkSpace
/** * Load data found in nexus file * * @param entry :: The Nexus entry * @param monitorsData :: Monitors data already loaded * */ void LoadILLReflectometry::loadDataIntoTheWorkSpace( NeXus::NXEntry &entry, std::vector<std::vector<int>> monitorsData) { m_wavelength = entry.getFloat("wavelength"); double ei = m_loader.calculateEnergy(m_wavelength); m_localWorkspace->mutableRun().addProperty<double>("Ei", ei, true); // overwrite // read in the data NXData dataGroup = entry.openNXData("data"); NXInt data = dataGroup.openIntData(); // load the counts from the file into memory data.load(); // Assign calculated bins to first X axis //// m_localWorkspace->dataX(0).assign(detectorTofBins.begin(), /// detectorTofBins.end()); size_t spec = 0; size_t nb_monitors = monitorsData.size(); Progress progress(this, 0, 1, m_numberOfTubes * m_numberOfPixelsPerTube + nb_monitors); // Assign tof values to first X axis // 1) Get some parameters from nexus file and properties // Note : This should be changed following future D17/ILL nexus file // improvement. const std::string propTOF0 = "monitor1.time_of_flight_0"; auto tof_channel_width_prop = dynamic_cast<PropertyWithValue<double> *>( m_localWorkspace->run().getProperty(propTOF0)); if (!tof_channel_width_prop) throw std::runtime_error("Could not cast (interpret) the property " + propTOF0 + " (channel width) as a floating point " "value."); m_channelWidth = *tof_channel_width_prop; /* PAR1[95] */ const std::string propTOF2 = "monitor1.time_of_flight_2"; auto tof_delay_prop = dynamic_cast<PropertyWithValue<double> *>( m_localWorkspace->run().getProperty(propTOF2)); if (!tof_delay_prop) throw std::runtime_error("Could not cast (interpret) the property " + propTOF2 + " (ToF delay) as a floating point value."); double tof_delay = *tof_delay_prop; /* PAR1[96] */ double POFF = entry.getFloat("instrument/VirtualChopper/poff"); /* par1[54] */ double open_offset = entry.getFloat("instrument/VirtualChopper/open_offset"); /* par1[56] */ double mean_chop_1_phase = 0.0; double mean_chop_2_phase = 0.0; // [30/09/14] Test on availability of VirtualChopper data double chop1_speed = entry.getFloat( "instrument/VirtualChopper/chopper1_speed_average"); /* PAR2[109] */ if (chop1_speed != 0.0) { // Virtual Chopper entries are valid // double mean_chop_1_phase = // entry.getFloat("instrument/VirtualChopper/chopper1_phase_average"); /* // PAR2[110] */ // this entry seems to be wrong for now, we use the old one instead [YR // 5/06/2014] mean_chop_1_phase = entry.getFloat("instrument/Chopper1/phase"); mean_chop_2_phase = entry.getFloat( "instrument/VirtualChopper/chopper2_phase_average"); /* PAR2[114] */ } else { // Use Chopper values instead chop1_speed = entry.getFloat("instrument/Chopper1/rotation_speed"); /* PAR2[109] */ mean_chop_1_phase = entry.getFloat("instrument/Chopper1/phase"); mean_chop_2_phase = entry.getFloat("instrument/Chopper2/phase"); } g_log.debug() << "m_numberOfChannels: " << m_numberOfChannels << std::endl; g_log.debug() << "m_channelWidth: " << m_channelWidth << std::endl; g_log.debug() << "tof_delay: " << tof_delay << std::endl; g_log.debug() << "POFF: " << POFF << std::endl; g_log.debug() << "open_offset: " << open_offset << std::endl; g_log.debug() << "mean_chop_2_phase: " << mean_chop_2_phase << std::endl; g_log.debug() << "mean_chop_1_phase: " << mean_chop_1_phase << std::endl; g_log.debug() << "chop1_speed: " << chop1_speed << std::endl; double t_TOF2 = 0.0; if (chop1_speed == 0.0) { g_log.debug() << "Warning: chop1_speed is null." << std::endl; // stay with t_TOF2 to O.0 } else { // Thanks to Miguel Gonzales/ILL for this TOF formula t_TOF2 = -1.e6 * 60.0 * (POFF - 45.0 + mean_chop_2_phase - mean_chop_1_phase + open_offset) / (2.0 * 360 * chop1_speed); } g_log.debug() << "t_TOF2: " << t_TOF2 << std::endl; // 2) Compute tof values for (size_t timechannelnumber = 0; timechannelnumber <= m_numberOfChannels; ++timechannelnumber) { double t_TOF1 = (static_cast<int>(timechannelnumber) + 0.5) * m_channelWidth + tof_delay; m_localWorkspace->dataX(0)[timechannelnumber] = t_TOF1 + t_TOF2; } // Load monitors for (size_t im = 0; im < nb_monitors; im++) { if (im > 0) { m_localWorkspace->dataX(im) = m_localWorkspace->readX(0); } // Assign Y int *monitor_p = monitorsData[im].data(); m_localWorkspace->dataY(im) .assign(monitor_p, monitor_p + m_numberOfChannels); progress.report(); } // Then Tubes for (size_t i = 0; i < m_numberOfTubes; ++i) { for (size_t j = 0; j < m_numberOfPixelsPerTube; ++j) { // just copy the time binning axis to every spectra m_localWorkspace->dataX(spec + nb_monitors) = m_localWorkspace->readX(0); //// Assign Y int *data_p = &data(static_cast<int>(i), static_cast<int>(j), 0); m_localWorkspace->dataY(spec + nb_monitors) .assign(data_p, data_p + m_numberOfChannels); // Assign Error MantidVec &E = m_localWorkspace->dataE(spec + nb_monitors); std::transform(data_p, data_p + m_numberOfChannels, E.begin(), LoadHelper::calculateStandardError); ++spec; progress.report(); } } // for m_numberOfTubes } // LoadILLIndirect::loadDataIntoTheWorkSpace