/** Method updates the column, which describes if current detector/spectra is
   masked
    It is used if one tries to process multiple workspaces obtained from a
   series of experiments  where the masked detectors can change */
void PreprocessDetectorsToMD::updateMasksState(
    const API::MatrixWorkspace_const_sptr &inputWS,
    DataObjects::TableWorkspace_sptr &targWS) {
  int *pMasksArray = targWS->getColDataArray<int>("detMask");
  if (!pMasksArray)
    throw std::invalid_argument(
        "target workspace " + targWS->getName() +
        " does not have defined masks column to update");

  size_t nHist = targWS->rowCount();
  const size_t nRows = inputWS->getNumberHistograms();
  if (nHist != nRows)
    throw std::invalid_argument(
        " source workspace " + inputWS->getName() + " and target workspace " +
        targWS->getName() +
        " are inconsistent as have different numner of detectors");

  uint32_t liveDetectorsCount(0);
  const auto &spectrumInfo = inputWS->spectrumInfo();
  for (size_t i = 0; i < nHist; i++) {
    if (!spectrumInfo.hasDetectors(i) || spectrumInfo.isMonitor(i))
      continue;

    // if masked detectors state is not used, masked detectors just ignored;
    bool maskDetector = spectrumInfo.isMasked(i);
    *(pMasksArray + liveDetectorsCount) = maskDetector ? 1 : 0;

    liveDetectorsCount++;
  }
}
Esempio n. 2
0
/** Create the table workspace containing experimental data
Each row is a data point measured in experiment
 * @brief LoadSpiceAscii::createDataWS
 * @param datalist
 * @param titles
 * @return
 */
API::ITableWorkspace_sptr LoadSpiceAscii::createDataWS(
    const std::vector<std::vector<std::string>> &datalist,
    const std::vector<std::string> &titles) {
  // Create a table workspace with columns defined
  DataObjects::TableWorkspace_sptr outws =
      boost::make_shared<DataObjects::TableWorkspace>();
  size_t ipt = -1;
  for (size_t i = 0; i < titles.size(); ++i) {
    if (titles[i].compare("Pt.") == 0) {
      outws->addColumn("int", titles[i]);
      ipt = i;
    } else {
      outws->addColumn("double", titles[i]);
    }
  }

  // Add rows
  size_t numrows = datalist.size();
  size_t numcols = outws->columnCount();
  for (size_t irow = 0; irow < numrows; ++irow) {
    TableRow newrow = outws->appendRow();
    for (size_t icol = 0; icol < numcols; ++icol) {
      std::string item = datalist[irow][icol];
      if (icol == ipt)
        newrow << atoi(item.c_str());
      else
        newrow << atof(item.c_str());
    }
  }

  ITableWorkspace_sptr tablews =
      boost::dynamic_pointer_cast<ITableWorkspace>(outws);
  return tablews;
}
    /** method calculates fake detectors positions in the situation when real detector information has been lost  */
    void PreprocessDetectorsToMD::buildFakeDetectorsPositions(const API::MatrixWorkspace_const_sptr &inputWS,DataObjects::TableWorkspace_sptr &targWS)
    {
      UNUSED_ARG(inputWS);
      // set sample-detector position equal to 1;
      targWS->logs()->addProperty<double>("L1",1.,true);
      // 
      targWS->logs()->addProperty<std::string>("InstrumentName","FakeInstrument",true);    
      targWS->logs()->addProperty<bool>("FakeDetectors",true,true);



      // get access to the workspace memory
      auto &sp2detMap  = targWS->getColVector<size_t>("spec2detMap");
      auto &detId      = targWS->getColVector<int32_t>("DetectorID");
      auto &detIDMap   = targWS->getColVector<size_t>("detIDMap");
      auto &L2         = targWS->getColVector<double>("L2");
      auto &TwoTheta   = targWS->getColVector<double>("TwoTheta");
      auto &Azimuthal  = targWS->getColVector<double>("Azimuthal");
      auto &detDir     = targWS->getColVector<Kernel::V3D>("DetDirections"); 
  //    auto &detMask    = targWS->getColVector<bool>("detMask");

      //// progress message appearance  
      size_t nHist = targWS->rowCount();
      targWS->logs()->addProperty<uint32_t>("ActualDetectorsNum",uint32_t(nHist),true);

      double polar(0);
      // Loop over the spectra
      for (size_t i = 0; i < nHist; i++)
      {
        sp2detMap[i]= i;
        detId[i]    = (detid_t)i;
        detIDMap[i] = i;
        L2[i]       = 1;

        TwoTheta[i] =  polar;
        Azimuthal[i] = 0;
        //this->SinThetaSq[i]= 0;

        double ez = 1.;
        double ex = 0.;
        double ey = 0.;

        detDir[i].setX(ex);
        detDir[i].setY(ey);
        detDir[i].setZ(ez);

      }
      // 
    }
/** Parse input TableWorkspace to get a list of detectors IDs of which detector
 * are already masked
  * @param masktablews :: TableWorkspace containing masking information
  * @param maskeddetectorids :: (output) vector of detector IDs that are masked
  */
void ExtractMaskToTable::parseMaskTable(
    DataObjects::TableWorkspace_sptr masktablews,
    std::vector<detid_t> &maskeddetectorids) {
  // Clear input
  maskeddetectorids.clear();

  // Check format of mask table workspace
  if (masktablews->columnCount() != 3) {
    g_log.error("Mask table workspace must have more than 3 columns.  First 3 "
                "must be Xmin, Xmax and Spectrum List.");
    return;
  } else {
    vector<string> colnames = masktablews->getColumnNames();
    vector<string> chkcolumans(3);
    chkcolumans[0] = "XMin";
    chkcolumans[1] = "XMax";
    chkcolumans[2] = "DetectorIDsList";
    for (int i = 0; i < 3; ++i) {
      if (colnames[i] != chkcolumans[i]) {
        g_log.error() << "Mask table workspace " << masktablews->name() << "'s "
                      << i << "-th column name is " << colnames[i]
                      << ", while it should be " << chkcolumans[i]
                      << ". MaskWorkspace is invalid"
                      << " and thus not used.\n";
        return;
      }
    }
  }

  // Parse each row
  size_t numrows = masktablews->rowCount();
  double xmin, xmax;
  string specliststr;
  for (size_t i = 0; i < numrows; ++i) {
    TableRow tmprow = masktablews->getRow(i);
    tmprow >> xmin >> xmax >> specliststr;

    vector<detid_t> tmpdetidvec;
    parseStringToVector(specliststr, tmpdetidvec);
    maskeddetectorids.insert(maskeddetectorids.end(), tmpdetidvec.begin(),
                             tmpdetidvec.end());
  }

  return;
}
Esempio n. 5
0
/** Method updates the column, which describes if current detector/spectra is
   masked
    It is used if one tries to process multiple workspaces obtained from a
   series of experiments  where the masked detectors can change */
void PreprocessDetectorsToMD::updateMasksState(
    const API::MatrixWorkspace_const_sptr &inputWS,
    DataObjects::TableWorkspace_sptr &targWS) {
  int *pMasksArray = targWS->getColDataArray<int>("detMask");
  if (!pMasksArray)
    throw std::invalid_argument(
        "target workspace " + targWS->getName() +
        " does not have defined masks column to update");

  size_t nHist = targWS->rowCount();
  const size_t nRows = inputWS->getNumberHistograms();
  if (nHist != nRows)
    throw std::invalid_argument(
        " source workspace " + inputWS->getName() + " and target workspace " +
        targWS->getName() +
        " are inconsistent as have different numner of detectors");

  uint32_t liveDetectorsCount(0);
  for (size_t i = 0; i < nHist; i++) {
    // get detector or detector group which corresponds to the spectra i
    Geometry::IDetector_const_sptr spDet;
    try {
      spDet = inputWS->getDetector(i);
    } catch (Kernel::Exception::NotFoundError &) {
      continue;
    }

    // Check that we aren't dealing with monitor...
    if (spDet->isMonitor())
      continue;

    // if masked detectors state is not used, masked detectors just ignored;
    bool maskDetector = spDet->isMasked();
    *(pMasksArray + liveDetectorsCount) = maskDetector ? 1 : 0;

    liveDetectorsCount++;
  }
}
/** method does preliminary calculations of the detectors positions to convert
results into k-dE space ;
and places the results into static cash to be used in subsequent calls to this
algorithm */
void PreprocessDetectorsToMD::processDetectorsPositions(
    const API::MatrixWorkspace_const_sptr &inputWS,
    DataObjects::TableWorkspace_sptr &targWS) {
  g_log.information()
      << "Preprocessing detector locations in a target reciprocal space\n";
  //
  Geometry::Instrument_const_sptr instrument = inputWS->getInstrument();
  // this->pBaseInstr                = instrument->baseInstrument();
  //
  Geometry::IComponent_const_sptr source = instrument->getSource();
  Geometry::IComponent_const_sptr sample = instrument->getSample();
  if ((!source) || (!sample)) {
    g_log.error() << " Instrument is not fully defined. Can not identify "
                     "source or sample\n";
    throw Kernel::Exception::InstrumentDefinitionError(
        "Instrument not sufficiently defined: failed to get source and/or "
        "sample");
  }

  // L1
  try {
    double L1 = source->getDistance(*sample);
    targWS->logs()->addProperty<double>("L1", L1, true);
    g_log.debug() << "Source-sample distance: " << L1 << '\n';
  } catch (Kernel::Exception::NotFoundError &) {
    throw Kernel::Exception::InstrumentDefinitionError(
        "Unable to calculate source-sample distance for workspace",
        inputWS->getTitle());
  }
  // Instrument name
  std::string InstrName = instrument->getName();
  targWS->logs()->addProperty<std::string>(
      "InstrumentName", InstrName,
      true); // "The name which should unique identify current instrument");
  targWS->logs()->addProperty<bool>("FakeDetectors", false, true);

  // get access to the workspace memory
  auto &sp2detMap = targWS->getColVector<size_t>("spec2detMap");
  auto &detId = targWS->getColVector<int32_t>("DetectorID");
  auto &detIDMap = targWS->getColVector<size_t>("detIDMap");
  auto &L2 = targWS->getColVector<double>("L2");
  auto &TwoTheta = targWS->getColVector<double>("TwoTheta");
  auto &Azimuthal = targWS->getColVector<double>("Azimuthal");
  auto &detDir = targWS->getColVector<Kernel::V3D>("DetDirections");

  // Efixed; do we need one and does one exist?
  double Efi = targWS->getLogs()->getPropertyValueAsType<double>("Ei");
  float *pEfixedArray(nullptr);
  const Geometry::ParameterMap &pmap = inputWS->constInstrumentParameters();
  if (m_getEFixed)
    pEfixedArray = targWS->getColDataArray<float>("eFixed");

  // check if one needs to generate masked detectors column.
  int *pMasksArray(nullptr);
  if (m_getIsMasked)
    pMasksArray = targWS->getColDataArray<int>("detMask");

  //// progress message appearance
  size_t div = 100;
  size_t nHist = targWS->rowCount();
  Mantid::API::Progress theProgress(this, 0, 1, nHist);
  //// Loop over the spectra
  uint32_t liveDetectorsCount(0);
  const auto &spectrumInfo = inputWS->spectrumInfo();
  for (size_t i = 0; i < nHist; i++) {
    sp2detMap[i] = std::numeric_limits<uint64_t>::quiet_NaN();
    detId[i] = std::numeric_limits<int32_t>::quiet_NaN();
    detIDMap[i] = std::numeric_limits<uint64_t>::quiet_NaN();
    L2[i] = std::numeric_limits<double>::quiet_NaN();
    TwoTheta[i] = std::numeric_limits<double>::quiet_NaN();
    Azimuthal[i] = std::numeric_limits<double>::quiet_NaN();
    //     detMask[i]  = true;

    if (!spectrumInfo.hasDetectors(i) || spectrumInfo.isMonitor(i))
      continue;

    // if masked detectors state is not used, masked detectors just ignored;
    bool maskDetector = spectrumInfo.isMasked(i);
    if (m_getIsMasked)
      *(pMasksArray + liveDetectorsCount) = maskDetector ? 1 : 0;
    else if (maskDetector)
      continue;

    const auto &spDet = spectrumInfo.detector(i);

    // calculate the requested values;
    sp2detMap[i] = liveDetectorsCount;
    detId[liveDetectorsCount] = int32_t(spDet.getID());
    detIDMap[liveDetectorsCount] = i;
    L2[liveDetectorsCount] = spectrumInfo.l2(i);

    double polar = spectrumInfo.twoTheta(i);
    double azim = spDet.getPhi();
    TwoTheta[liveDetectorsCount] = polar;
    Azimuthal[liveDetectorsCount] = azim;

    double sPhi = sin(polar);
    double ez = cos(polar);
    double ex = sPhi * cos(azim);
    double ey = sPhi * sin(azim);

    detDir[liveDetectorsCount].setX(ex);
    detDir[liveDetectorsCount].setY(ey);
    detDir[liveDetectorsCount].setZ(ez);

    // double sinTheta=sin(0.5*polar);
    // this->SinThetaSq[liveDetectorsCount]  = sinTheta*sinTheta;

    // specific code which should work and makes sense
    // for indirect instrument but may be deployed on any code with Ei property
    // defined;
    if (pEfixedArray) {
      try {
        Geometry::Parameter_sptr par = pmap.getRecursive(&spDet, "eFixed");
        if (par)
          Efi = par->value<double>();
      } catch (std::runtime_error &) {
      }
      // set efixed for each existing detector
      *(pEfixedArray + liveDetectorsCount) = static_cast<float>(Efi);
    }

    liveDetectorsCount++;
    if (i % div == 0)
      theProgress.report(i, "Preprocessing detectors");
  }
  targWS->logs()->addProperty<uint32_t>("ActualDetectorsNum",
                                        liveDetectorsCount, true);

  theProgress.report();
  g_log.information() << "Finished preprocessing detector locations. Found: "
                      << liveDetectorsCount << " detectors out of: " << nHist
                      << " histograms\n";
}
Esempio n. 7
0
    /**The method responsible for analyzing input workspace parameters and preprocessing detectors positions into reciprocal space
    *
    * @param InWS2D -- input Matrix workspace with defined instrument
    * @param dEModeRequested -- energy conversion mode (direct/indirect/elastic)
    * @param updateMasks  --  if full detector positions calculations or just update masking requested
    * @param OutWSName    -- the name for the preprocessed detectors workspace to have in the analysis data service
    * 
    * @return          shared pointer to the workspace with preprocessed detectors information. 
    */
    DataObjects::TableWorkspace_const_sptr ConvertToMDParent::preprocessDetectorsPositions( Mantid::API::MatrixWorkspace_const_sptr InWS2D,const std::string &dEModeRequested,
      bool updateMasks, const std::string & OutWSName)
    {

      DataObjects::TableWorkspace_sptr TargTableWS;
      Kernel::DeltaEMode::Type Emode;

      // Do we need to reuse output workspace
      bool storeInDataService(true);
      std::string tOutWSName(OutWSName);
      if(tOutWSName=="-"||tOutWSName.empty()) // TargTableWS is recalculated each time;
      {
        storeInDataService = false;
        tOutWSName = "ServiceTableWS";  // TODO: should be hidden?
      }
      else
      {
        storeInDataService = true;
      }

      // if output workspace exists in dataservice, we may try to use it
      if(storeInDataService && API::AnalysisDataService::Instance().doesExist(tOutWSName) ) 
      {
        TargTableWS = API::AnalysisDataService::Instance().retrieveWS<DataObjects::TableWorkspace>(tOutWSName);
        // get number of all histograms (may be masked or invalid)
        size_t nHist = InWS2D->getNumberHistograms();
        size_t nDetMap=TargTableWS->rowCount();
        if(nHist==nDetMap)
        {
          // let's take at least some precaution to ensure that instrument have not changed
          std::string currentWSInstrumentName = InWS2D->getInstrument()->getName();
          std::string oldInstrName            = TargTableWS->getLogs()->getPropertyValueAsType<std::string>("InstrumentName");

          if(oldInstrName==currentWSInstrumentName)
          { 
            if(!updateMasks) return TargTableWS;
            //Target workspace with preprocessed detectors exists and seems is correct one. 
            // We still need to update masked detectors information
            TargTableWS = this->runPreprocessDetectorsToMDChildUpdatingMasks(InWS2D,tOutWSName,dEModeRequested,Emode);
            return TargTableWS;
          }
        }
        else // there is a workspace in the data service with the same name but this ws is not suitable as target for this algorithm. 
        {    // Should delete this WS from the dataservice
          API::AnalysisDataService::Instance().remove(tOutWSName);
        }
      }
      // No result found in analysis data service or the result is unsatisfactory. Try to calculate target workspace.  

      TargTableWS =this->runPreprocessDetectorsToMDChildUpdatingMasks(InWS2D,tOutWSName,dEModeRequested,Emode);

      if(storeInDataService)
        API::AnalysisDataService::Instance().addOrReplace(tOutWSName,TargTableWS);
      //    else
      //      TargTableWS->setName(OutWSName);


      // check if we got what we wanted:

      // in direct or indirect mode input ws has to have input energy
      if(Emode==Kernel::DeltaEMode::Direct||Emode==Kernel::DeltaEMode::Indirect)
      {
        double   m_Ei  = TargTableWS->getLogs()->getPropertyValueAsType<double>("Ei");
        if(isNaN(m_Ei))
        {
          // Direct mode needs Ei
          if(Emode==Kernel::DeltaEMode::Direct)throw(std::invalid_argument("Input neutron's energy has to be defined in inelastic mode "));

          // Do we have at least something for Indirect?
          float *eFixed = TargTableWS->getColDataArray<float>("eFixed");
          if(!eFixed)
            throw(std::invalid_argument("Input neutron's energy has to be defined in inelastic mode "));

          uint32_t NDetectors = TargTableWS->getLogs()->getPropertyValueAsType<uint32_t>("ActualDetectorsNum");
          for(uint32_t i=0;i<NDetectors;i++)
            if(isNaN(*(eFixed+i)))throw(std::invalid_argument("Undefined eFixed energy for detector N: "+boost::lexical_cast<std::string>(i)));
        }
      }

      return TargTableWS;
    }
Esempio n. 8
0
  void MaskBinsFromTable::exec()
  {
    MatrixWorkspace_sptr inputWS = getProperty("InputWorkspace");
    DataObjects::TableWorkspace_sptr paramWS = getProperty("MaskingInformation");

    // 1. Check input table workspace and column order
    g_log.debug() << "Lines of parameters workspace = " << paramWS->rowCount() << std::endl;

    bool colname_specx = false;
    if (!paramWS)
    {
      throw std::invalid_argument("Input table workspace is not accepted.");
    }
    else
    {
      std::vector<std::string> colnames = paramWS->getColumnNames();
      // check colum name order
      if (colnames.size() < 3)
      {
        g_log.error() << "Input MaskingInformation table workspace has fewer than 3 columns.  " << colnames.size()
                      << " columns indeed" << std::endl;
        throw std::invalid_argument("MaskingInformation (TableWorkspace) has too few columns.");
      }
      if (colnames[0].compare("XMin") == 0)
      {
          // 1. Style XMin, XMax, SpectraList. Check rest
          if (colnames[1].compare("XMax") != 0 || colnames[2].compare("SpectraList") != 0)
          {
              g_log.error() << "INput MaskingInformation table workspace has wrong column order. " << std::endl;
              throw std::invalid_argument("MaskingInformation (TableWorkspace) has too few columns.");
          }
      }
      else if (colnames[0].compare("SpectraList") == 0)
      {
          // 2. Style SpectraList, XMin, XMax
          colname_specx = true;
          if (colnames[1].compare("XMin") != 0 || colnames[2].compare("XMax") != 0)
          {
              g_log.error() << "INput MaskingInformation table workspace has wrong column order. " << std::endl;
              throw std::invalid_argument("MaskingInformation (TableWorkspace) has too few columns.");
          }
      }
      else
      {
          g_log.error() << "INput MaskingInformation table workspace has wrong column order. " << std::endl;
          throw std::invalid_argument("MaskingInformation (TableWorkspace) has too few columns.");
      }
    }

    // 2. Loop over all rows
    bool firstloop = true;
    API::MatrixWorkspace_sptr outputws = this->getProperty("OutputWorkspace");

    for (size_t ib = 0; ib < paramWS->rowCount(); ++ib)
    {
      API::TableRow therow = paramWS->getRow(ib);
      double xmin, xmax;
      std::string speclist;
      if (colname_specx)
      {
          therow >> speclist >> xmin >> xmax;
      }
      else
      {
          therow >> xmin >> xmax >> speclist;
      }

      g_log.debug() << "Row " << ib << " XMin = " << xmin << "  XMax = " << xmax << " SpectraList = " << speclist << std::endl;

      API::IAlgorithm_sptr maskbins = this->createChildAlgorithm("MaskBins", 0, 0.3, true);
      maskbins->initialize();
      if (firstloop)
      {
        maskbins->setProperty("InputWorkspace", inputWS);
        firstloop = false;
      }
      else
      {
        maskbins->setProperty("InputWorkspace", outputws);
      }
      maskbins->setProperty("OutputWorkspace", outputws);
      maskbins->setPropertyValue("SpectraList", speclist);
      maskbins->setProperty("XMin", xmin);
      maskbins->setProperty("XMax", xmax);

      bool isexec = maskbins->execute();
      if (!isexec)
      {
        g_log.error() << "MaskBins() is not executed for row " << ib << std::endl;
        throw std::runtime_error("MaskBins() is not executed");
      }

      outputws = maskbins->getProperty("OutputWorkspace");
      if (!outputws)
      {
        g_log.error() << "OutputWorkspace is not retrieved for row " << ib << ". " << std::endl;
        throw std::runtime_error("OutputWorkspace is not got from MaskBins");
      }
    }