/** * @brief IntegratePeaksCWSD::createPeakworkspace * @param peakCenter * @param mdws :: source MDEventWorkspace where the run numbers come from * @return */ DataObjects::PeaksWorkspace_sptr IntegratePeaksCWSD::createPeakworkspace(Kernel::V3D peakCenter, API::IMDEventWorkspace_sptr mdws) { g_log.notice("Create peak workspace for output ... ..."); // new peak workspace DataObjects::PeaksWorkspace_sptr peakws = boost::make_shared<DataObjects::PeaksWorkspace>(); // get number of runs size_t numruns = mdws->getNumExperimentInfo(); for (size_t i_run = 0; i_run < numruns; ++i_run) { // get experiment info for run number, instrument and peak count API::ExperimentInfo_const_sptr expinfo = mdws->getExperimentInfo(static_cast<uint16_t>(i_run)); int runnumber = expinfo->getRunNumber(); // FIXME - This is a hack for HB3A's run number issue std::map<int, double>::iterator miter = m_runPeakCountsMap.find(runnumber % 1000); double peakcount(0); if (miter != m_runPeakCountsMap.end()) { peakcount = miter->second; g_log.notice() << "[DB] Get peak count of run " << runnumber << " as " << peakcount << "\n"; } else { g_log.notice() << "[DB] Unable to find run " << runnumber << " in peak count map." << "\n"; } // Create and add a new peak to peak workspace DataObjects::Peak newpeak; try { Geometry::Instrument_const_sptr instrument = expinfo->getInstrument(); newpeak.setInstrument(instrument); newpeak.setGoniometerMatrix(expinfo->run().getGoniometerMatrix()); } catch (std::exception) { throw std::runtime_error( "Unable to set instrument and goniometer matrix."); } newpeak.setQSampleFrame(peakCenter); newpeak.setRunNumber(runnumber); newpeak.setIntensity(peakcount * m_scaleFactor); peakws->addPeak(newpeak); } g_log.notice("Peak workspace is generated.... "); return peakws; }
/** * Copy over the metadata from the input matrix workspace to output MDEventWorkspace * @param mdEventWS :: The output MDEventWorkspace where metadata are copied to. The source of the metadata is the input matrix workspace * */ void ConvertToMD::copyMetaData(API::IMDEventWorkspace_sptr &mdEventWS) const { // found detector which is not a monitor to get proper bin boundaries. size_t spectra_index(0); bool dector_found(false); for(size_t i=0;i<m_InWS2D->getNumberHistograms(); ++i) { try { auto det=m_InWS2D->getDetector(i); if (!det->isMonitor()) { spectra_index=i; dector_found = true; g_log.debug()<<"Using spectra N "<<i<< " as the source of the bin boundaries for the resolution corrections \n"; break; } } catch(...) {} } if (!dector_found) g_log.warning()<<"No detectors in the workspace are associated with spectra. Using spectrum 0 trying to retrieve the bin boundaries \n"; // retrieve representative bin boundaries MantidVec binBoundaries = m_InWS2D->readX(spectra_index); // check if the boundaries transformation is necessary if (m_Convertor->getUnitConversionHelper().isUnitConverted()) { if( !dynamic_cast<DataObjects::EventWorkspace *>(m_InWS2D.get())) { g_log.information()<<" ConvertToMD converts input workspace units, but the bin boundaries are copied from the first workspace spectra. The resolution estimates can be incorrect if unit conversion depends on spectra number.\n"; UnitsConversionHelper &unitConv = m_Convertor->getUnitConversionHelper(); unitConv.updateConversion(spectra_index); for(size_t i=0;i<binBoundaries.size();i++) { binBoundaries[i] =unitConv.convertUnits(binBoundaries[i]); } } // sort bin boundaries in case if unit transformation have swapped them. if (binBoundaries[0]>binBoundaries[binBoundaries.size()-1]) { g_log.information()<<"Bin boundaries are not arranged monotonously. Sorting performed\n"; std::sort(binBoundaries.begin(),binBoundaries.end()); } } // Replacement for SpectraDetectorMap::createIDGroupsMap using the ISpectrum objects instead auto mapping = boost::make_shared<det2group_map>(); for ( size_t i = 0; i < m_InWS2D->getNumberHistograms(); ++i ) { const auto& dets = m_InWS2D->getSpectrum(i)->getDetectorIDs(); if(!dets.empty()) { std::vector<detid_t> id_vector; std::copy(dets.begin(), dets.end(), std::back_inserter(id_vector)); mapping->insert(std::make_pair(id_vector.front(), id_vector)); } } uint16_t nexpts = mdEventWS->getNumExperimentInfo(); for(uint16_t i = 0; i < nexpts; ++i) { ExperimentInfo_sptr expt = mdEventWS->getExperimentInfo(i); expt->mutableRun().storeHistogramBinBoundaries(binBoundaries); expt->cacheDetectorGroupings(*mapping); } }
/** * Copy over the metadata from the input matrix workspace to output *MDEventWorkspace * @param mdEventWS :: The output MDEventWorkspace where metadata are copied to. *The source of the metadata is the input matrix workspace * */ void ConvertToMD::copyMetaData(API::IMDEventWorkspace_sptr &mdEventWS) const { // found detector which is not a monitor to get proper bin boundaries. size_t spectra_index(0); bool detector_found(false); const auto &spectrumInfo = m_InWS2D->spectrumInfo(); for (size_t i = 0; i < m_InWS2D->getNumberHistograms(); ++i) { if (spectrumInfo.hasDetectors(i) && !spectrumInfo.isMonitor(i)) { spectra_index = i; detector_found = true; g_log.debug() << "Using spectra N " << i << " as the source of the bin " "boundaries for the resolution corrections \n"; break; } } if (!detector_found) { g_log.information() << "No spectra in the workspace have detectors associated " "with them. Storing bin boundaries from first spectrum for" "resolution calculation\n"; } // retrieve representative bin boundaries auto binBoundaries = m_InWS2D->x(spectra_index); // check if the boundaries transformation is necessary if (m_Convertor->getUnitConversionHelper().isUnitConverted()) { if (!dynamic_cast<DataObjects::EventWorkspace *>(m_InWS2D.get())) { g_log.information() << " ConvertToMD converts input workspace units, but " "the bin boundaries are copied from the first " "workspace spectra. The resolution estimates can " "be incorrect if unit conversion depends on " "spectra number.\n"; UnitsConversionHelper &unitConv = m_Convertor->getUnitConversionHelper(); unitConv.updateConversion(spectra_index); for (auto &binBoundary : binBoundaries) { binBoundary = unitConv.convertUnits(binBoundary); } } // sort bin boundaries in case if unit transformation have swapped them. if (binBoundaries[0] > binBoundaries.back()) { g_log.information() << "Bin boundaries are not arranged monotonously. " "Sorting performed\n"; std::sort(binBoundaries.begin(), binBoundaries.end()); } } // Replacement for SpectraDetectorMap::createIDGroupsMap using the ISpectrum // objects instead auto mapping = boost::make_shared<det2group_map>(); for (size_t i = 0; i < m_InWS2D->getNumberHistograms(); ++i) { const auto &dets = m_InWS2D->getSpectrum(i).getDetectorIDs(); if (!dets.empty()) mapping->emplace(*dets.begin(), dets); } // The last experiment info should always be the one that refers // to latest converting workspace. All others should have had this // information set already uint16_t nexpts = mdEventWS->getNumExperimentInfo(); if (nexpts > 0) { ExperimentInfo_sptr expt = mdEventWS->getExperimentInfo(static_cast<uint16_t>(nexpts - 1)); expt->mutableRun().storeHistogramBinBoundaries(binBoundaries.rawData()); expt->cacheDetectorGroupings(*mapping); } }