示例#1
0
/**
 * @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;
}
示例#2
0
/**
 * Add the fake data to the given workspace
 * @param workspace A pointer to MD event workspace to fill using the object
 * parameters
 */
void FakeMD::fill(API::IMDEventWorkspace_sptr workspace) {
  setupDetectorCache(*workspace);

  CALL_MDEVENT_FUNCTION(this->addFakePeak, workspace)
  CALL_MDEVENT_FUNCTION(this->addFakeUniformData, workspace)

  // Mark that events were added, so the file back end (if any) needs updating
  workspace->setFileNeedsUpdating(true);
}
示例#3
0
/**
* Create new MD workspace and set up its box controller using algorithm's box
* controllers properties
* @param targWSDescr :: Description of workspace to create
* @param filebackend :: true if the workspace will have a file back end
* @param filename :: file to use for file back end of workspace
* @return :: Shared pointer for the created workspace
*/
API::IMDEventWorkspace_sptr
ConvertToMD::createNewMDWorkspace(const MDWSDescription &targWSDescr,
                                  const bool filebackend,
                                  const std::string &filename) {
  // create new md workspace and set internal shared pointer of m_OutWSWrapper
  // to this workspace
  API::IMDEventWorkspace_sptr spws =
      m_OutWSWrapper->createEmptyMDWS(targWSDescr);
  if (!spws) {
    g_log.error() << "can not create target event workspace with :"
                  << targWSDescr.nDimensions() << " dimensions\n";
    throw(std::invalid_argument("can not create target workspace"));
  }
  // Build up the box controller
  Mantid::API::BoxController_sptr bc =
      m_OutWSWrapper->pWorkspace()->getBoxController();
  // Build up the box controller, using the properties in
  // BoxControllerSettingsAlgorithm
  this->setBoxController(bc, m_InWS2D->getInstrument());
  if (filebackend) {
    setupFileBackend(filename, m_OutWSWrapper->pWorkspace());
  }

  // Check if the user want sto force a top level split or not
  bool topLevelSplittingChecked = this->getProperty("TopLevelSplitting");

  if (topLevelSplittingChecked) {
    // Perform initial split with the forced settings
    setupTopLevelSplitting(bc);
  }

  // split boxes;
  spws->splitBox();

  // Do we split more due to MinRecursionDepth?
  int minDepth = this->getProperty("MinRecursionDepth");
  int maxDepth = this->getProperty("MaxRecursionDepth");
  if (minDepth > maxDepth)
    throw std::invalid_argument(
        "MinRecursionDepth must be >= MaxRecursionDepth ");
  spws->setMinRecursionDepth(size_t(minDepth));

  return spws;
}
示例#4
0
    /**
    * Create new MD workspace and set up its box controller using algorithm's box controllers properties
    * @param targWSDescr
    * @return
    */
    API::IMDEventWorkspace_sptr ConvertToMD::createNewMDWorkspace(const MDEvents::MDWSDescription &targWSDescr)
    {
      // create new md workspace and set internal shared pointer of m_OutWSWrapper to this workspace
      API::IMDEventWorkspace_sptr spws = m_OutWSWrapper->createEmptyMDWS(targWSDescr);
      if(!spws)
      {
        g_log.error()<<"can not create target event workspace with :"<<targWSDescr.nDimensions()<<" dimensions\n";
        throw(std::invalid_argument("can not create target workspace"));
      }
      // Build up the box controller
      Mantid::API::BoxController_sptr bc = m_OutWSWrapper->pWorkspace()->getBoxController();
      // Build up the box controller, using the properties in BoxControllerSettingsAlgorithm
      this->setBoxController(bc, m_InWS2D->getInstrument());
      // split boxes;
      spws->splitBox();
      // Do we split more due to MinRecursionDepth?
      int minDepth = this->getProperty("MinRecursionDepth");
      int maxDepth = this->getProperty("MaxRecursionDepth");
      if (minDepth>maxDepth) throw std::invalid_argument("MinRecursionDepth must be >= MaxRecursionDepth ");
      spws->setMinRecursionDepth(size_t(minDepth));  

      return spws;

    }
示例#5
0
    /** handle the input parameters and build target workspace description as function of input parameters 
    * @param spws shared pointer to target MD workspace (just created or already existing)
    * @param QModReq -- mode to convert momentum
    * @param dEModReq -- mode to convert energy 
    * @param otherDimNames -- the vector of additional dimensions names (if any)
    * @param dimMin     -- the vector of minimal values for all dimensions of the workspace; on input it is copied from the algorithm parameters, on output 
    it is defined from MD workspace of matrix workspace depending on how well input parameters are defined 
    * @param dimMax     -- the vector of maximal values for all dimensions of the workspace; is set up similarly to dimMin
    * @param QFrame      -- in Q3D case this describes target coordinate system and is ignored in any other caste
    * @param convertTo_  -- The parameter describing Q-scaling transformations
    * @param targWSDescr -- the resulting class used to interpret all parameters together and used to describe selected transformation. 
    */ 
    bool ConvertToMD::buildTargetWSDescription(API::IMDEventWorkspace_sptr spws,const std::string &QModReq,const std::string &dEModReq,const std::vector<std::string> &otherDimNames,
      std::vector<double> &dimMin, std::vector<double> &dimMax,
      const std::string &QFrame,const std::string &convertTo_,MDEvents::MDWSDescription &targWSDescr)
    {
      // ------- Is there need to create new output workspace?  
      bool createNewTargetWs =doWeNeedNewTargetWorkspace(spws);

      if (createNewTargetWs )
      {
        targWSDescr.m_buildingNewWorkspace = true;
        // find min-max dimensions values -- either take them from input parameters or identify the defaults if input parameters are not defined
        this->findMinMax(m_InWS2D,QModReq,dEModReq,QFrame,convertTo_,otherDimNames,dimMin,dimMax);
      }
      else // get min/max from existing MD workspace ignoring input min/max values
      {
        targWSDescr.m_buildingNewWorkspace = false;
        size_t NDims = spws->getNumDims();
        dimMin.resize(NDims);
        dimMax.resize(NDims);
        for(size_t i=0;i<NDims;i++)
        {
          const Geometry::IMDDimension *pDim = spws->getDimension(i).get();
          dimMin[i]  = pDim->getMinimum();
          dimMax[i]  = pDim->getMaximum();
        }

      }

      // verify that the number min/max values is equivalent to the number of dimensions defined by properties and min is less max
      targWSDescr.setMinMax(dimMin,dimMax);   
      targWSDescr.buildFromMatrixWS(m_InWS2D,QModReq,dEModReq,otherDimNames);

      bool LorentzCorrections = getProperty("LorentzCorrection");
      targWSDescr.setLorentsCorr(LorentzCorrections);

      // instantiate class, responsible for defining Mslice-type projection
      MDEvents::MDWSTransform MsliceProj;
      //identify if u,v are present among input parameters and use defaults if not
      std::vector<double> ut = getProperty("UProj");
      std::vector<double> vt = getProperty("VProj");
      std::vector<double> wt = getProperty("WProj");
      try
      {  
        // otherwise input uv are ignored -> later it can be modified to set ub matrix if no given, but this may over-complicate things. 
        MsliceProj.setUVvectors(ut,vt,wt);   
      }
      catch(std::invalid_argument &)
      {     g_log.error() << "The projections are coplanar. Will use defaults [1,0,0],[0,1,0] and [0,0,1]" << std::endl;     }

      if(createNewTargetWs)
      {

        // check if we are working in powder mode
        // set up target coordinate system and identify/set the (multi) dimension's names to use
        targWSDescr.m_RotMatrix = MsliceProj.getTransfMatrix(targWSDescr,QFrame,convertTo_);           
      }
      else // user input is mainly ignored and everything is in old MD workspace
      {  
        // dimensions are already build, so build MDWS description from existing workspace
        MDEvents::MDWSDescription oldWSDescr;
        oldWSDescr.buildFromMDWS(spws);

        // some conversion parameters can not be defined by the target workspace. They have to be retrieved from the input workspace 
        // and derived from input parameters. 
        oldWSDescr.setUpMissingParameters(targWSDescr);      
        // set up target coordinate system and the dimension names/units
        oldWSDescr.m_RotMatrix = MsliceProj.getTransfMatrix(oldWSDescr,QFrame,convertTo_);   

        // check inconsistencies, if the existing workspace can be used as target workspace. 
        oldWSDescr.checkWSCorresponsMDWorkspace(targWSDescr);
        // reset new ws description name
        targWSDescr =oldWSDescr;
      }
      return createNewTargetWs;
    }
示例#6
0
    /**
    * 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);
      }


    }
示例#7
0
/** handle the input parameters and build target workspace description as
function of input parameters
* @param spws shared pointer to target MD workspace (just created or already
existing)
* @param QModReq -- mode to convert momentum
* @param dEModReq -- mode to convert energy
* @param otherDimNames -- the vector of additional dimensions names (if any)
* @param dimMin     -- the vector of minimal values for all dimensions of the
workspace; on input it is copied from the algorithm parameters, on output
it is defined from MD workspace of matrix workspace depending on how well input
parameters are defined
* @param dimMax     -- the vector of maximal values for all dimensions of the
workspace; is set up similarly to dimMin
* @param QFrame      -- in Q3D case this describes target coordinate system and
is ignored in any other case
* @param convertTo_  -- The parameter describing Q-scaling transformations
* @param targWSDescr -- the resulting class used to interpret all parameters
together and used to describe selected transformation.
*/
bool ConvertToMD::buildTargetWSDescription(
    API::IMDEventWorkspace_sptr spws, const std::string &QModReq,
    const std::string &dEModReq, const std::vector<std::string> &otherDimNames,
    std::vector<double> &dimMin, std::vector<double> &dimMax,
    const std::string &QFrame, const std::string &convertTo_,
    MDAlgorithms::MDWSDescription &targWSDescr) {
  // ------- Is there need to create new output workspace?
  bool createNewTargetWs = doWeNeedNewTargetWorkspace(spws);
  std::vector<int> split_into;

  if (createNewTargetWs) {
    targWSDescr.m_buildingNewWorkspace = true;
    // find min-max dimensions values -- either take them from input parameters
    // or identify the defaults if input parameters are not defined
    this->findMinMax(m_InWS2D, QModReq, dEModReq, QFrame, convertTo_,
                     otherDimNames, dimMin, dimMax);
    // set number of bins each dimension split into.
    split_into = this->getProperty("SplitInto");
  } else // get min/max from existing MD workspace ignoring input min/max values
  {
    targWSDescr.m_buildingNewWorkspace = false;
    size_t NDims = spws->getNumDims();
    dimMin.resize(NDims);
    dimMax.resize(NDims);
    split_into.resize(NDims);
    for (size_t i = 0; i < NDims; i++) {
      const Geometry::IMDDimension *pDim = spws->getDimension(i).get();
      dimMin[i] = pDim->getMinimum();
      dimMax[i] = pDim->getMaximum();
      // number of dimension
      split_into[i] = static_cast<int>(pDim->getNBins());
    }
  }

  // verify that the number min/max values is equivalent to the number of
  // dimensions defined by properties and min is less max
  targWSDescr.setMinMax(dimMin, dimMax);
  targWSDescr.buildFromMatrixWS(m_InWS2D, QModReq, dEModReq, otherDimNames);
  targWSDescr.setNumBins(split_into);

  bool LorentzCorrections = getProperty("LorentzCorrection");
  targWSDescr.setLorentsCorr(LorentzCorrections);

  double m_AbsMin = getProperty("AbsMinQ");
  targWSDescr.setAbsMin(m_AbsMin);

  // Set optional projections for Q3D mode
  MDAlgorithms::MDWSTransform MsliceProj;
  if (QModReq == MDTransfQ3D().transfID()) {
    try {
      // otherwise input uv are ignored -> later it can be modified to set ub
      // matrix if no given, but this may over-complicate things.
      MsliceProj.setUVvectors(getProperty("UProj"), getProperty("VProj"),
                              getProperty("WProj"));
    } catch (std::invalid_argument &) {
      g_log.warning() << "The projections are coplanar. Will use defaults "
                         "[1,0,0],[0,1,0] and [0,0,1]\n";
    }
  } else {
    auto warnIfSet = [this](const std::string &propName) {
      Property *prop = this->getProperty(propName);
      if (!prop->isDefault()) {
        g_log.warning(propName + " value ignored with QDimensions != " +
                      MDTransfQ3D().transfID());
      }
    };
    for (const auto &name : {"UProj", "VProj", "WProj"}) {
      warnIfSet(name);
    }
  }

  if (createNewTargetWs) {

    // check if we are working in powder mode
    // set up target coordinate system and identify/set the (multi) dimension's
    // names to use
    targWSDescr.m_RotMatrix =
        MsliceProj.getTransfMatrix(targWSDescr, QFrame, convertTo_);
  } else // user input is mainly ignored and everything is in old MD workspace
  {
    // dimensions are already build, so build MDWS description from existing
    // workspace
    MDAlgorithms::MDWSDescription oldWSDescr;
    oldWSDescr.buildFromMDWS(spws);

    // some conversion parameters can not be defined by the target workspace.
    // They have to be retrieved from the input workspace
    // and derived from input parameters.
    oldWSDescr.setUpMissingParameters(targWSDescr);
    // set up target coordinate system and the dimension names/units
    oldWSDescr.m_RotMatrix =
        MsliceProj.getTransfMatrix(oldWSDescr, QFrame, convertTo_);

    // check inconsistencies, if the existing workspace can be used as target
    // workspace.
    oldWSDescr.checkWSCorresponsMDWorkspace(targWSDescr);
    // reset new ws description name
    targWSDescr = oldWSDescr;
  }
  return createNewTargetWs;
}
示例#8
0
/**
* 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);
  }
}