/** * Load data about the sample * @param local_workspace :: The workspace to load the logs to. * @param entry :: The Nexus entry */ void LoadISISNexus2::loadSampleData(DataObjects::Workspace2D_sptr local_workspace, NXEntry & entry) { /// Sample geometry NXInt spb = entry.openNXInt("isis_vms_compat/SPB"); // Just load the index we need, not the whole block. The flag is the third value in spb.load(1, 2); int geom_id = spb[0]; local_workspace->mutableSample().setGeometryFlag(spb[0]); NXFloat rspb = entry.openNXFloat("isis_vms_compat/RSPB"); // Just load the indices we need, not the whole block. The values start from the 4th onward rspb.load(3, 3); double thick(rspb[0]), height(rspb[1]), width(rspb[2]); local_workspace->mutableSample().setThickness(thick); local_workspace->mutableSample().setHeight(height); local_workspace->mutableSample().setWidth(width); g_log.debug() << "Sample geometry - ID: " << geom_id << ", thickness: " << thick << ", height: " << height << ", width: " << width << "\n"; }
/**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; }