예제 #1
0
void CalculateDIFC::calculate() {
  Instrument_const_sptr instrument = m_inputWS->getInstrument();

  SpecialWorkspace2D_sptr localWS =
      boost::dynamic_pointer_cast<SpecialWorkspace2D>(m_outputWS);

  double l1;
  Kernel::V3D beamline, samplePos;
  double beamline_norm;
  instrument->getInstrumentParameters(l1, beamline, beamline_norm, samplePos);

  // To get all the detector ID's
  detid2det_map allDetectors;
  instrument->getDetectors(allDetectors);

  // Now go through all
  detid2det_map::const_iterator it = allDetectors.begin();
  for (; it != allDetectors.end(); ++it) {
    Geometry::IDetector_const_sptr det = it->second;
    if ((!det->isMasked()) && (!det->isMonitor())) {
      const detid_t detID = it->first;
      double offset = 0.;
      if (m_offsetsWS)
        offset = m_offsetsWS->getValue(detID, 0.);

      double difc = Geometry::Instrument::calcConversion(
          l1, beamline, beamline_norm, samplePos, det, offset);
      difc = 1. / difc; // calcConversion gives 1/DIFC
      localWS->setValue(detID, difc);
    }
  }

}
예제 #2
0
void CalculateDIFC::calculate(API::Progress &progress,
                              API::MatrixWorkspace_sptr &outputWs,
                              DataObjects::OffsetsWorkspace_sptr &offsetsWS,
                              double l1, double beamlineNorm,
                              Kernel::V3D &beamline, Kernel::V3D &samplePos,
                              detid2det_map &allDetectors) {
  SpecialWorkspace2D_sptr localWS =
      boost::dynamic_pointer_cast<SpecialWorkspace2D>(outputWs);

  // Now go through all
  detid2det_map::const_iterator it = allDetectors.begin();
  for (; it != allDetectors.end(); ++it) {
    Geometry::IDetector_const_sptr det = it->second;
    if ((!det->isMasked()) && (!det->isMonitor())) {
      const detid_t detID = it->first;
      double offset = 0.;
      if (offsetsWS)
        offset = offsetsWS->getValue(detID, 0.);

      double difc = Geometry::Instrument::calcConversion(
          l1, beamline, beamlineNorm, samplePos, det, offset);
      difc = 1. / difc; // calcConversion gives 1/DIFC
      localWS->setValue(detID, difc);
    }

    progress.report("Calculate DIFC");
  }
}
예제 #3
0
/**
 * Corrects a spectra for the detector efficiency calculated from detector
 * information. Gets the detector information and uses this to calculate its
 * efficiency
 *  @param spectraIndex :: index of the spectrum to get the efficiency for
 *  @throw invalid_argument if the shape of a detector is isn't a cylinder
 *  aligned along one axis
 *  @throw runtime_error if the SpectraDetectorMap has not been filled
 *  @throw NotFoundError if the detector or its gas pressure or wall thickness
 *  were not found
 */
void He3TubeEfficiency::correctForEfficiency(std::size_t spectraIndex)
{
  Geometry::IDetector_const_sptr det = this->inputWS->getDetector(spectraIndex);
  if( det->isMonitor() || det->isMasked() )
  {
    return;
  }

  const double exp_constant = this->calculateExponential(spectraIndex, det);
  const double scale = this->getProperty("ScaleFactor");

  Mantid::MantidVec &yout = this->outputWS->dataY(spectraIndex);
  Mantid::MantidVec &eout = this->outputWS->dataE(spectraIndex);
  // Need the original values so this is not a reference
  const Mantid::MantidVec yValues = this->inputWS->readY(spectraIndex);
  const Mantid::MantidVec eValues = this->inputWS->readE(spectraIndex);

  std::vector<double>::const_iterator yinItr = yValues.begin();
  std::vector<double>::const_iterator einItr = eValues.begin();
  Mantid::MantidVec::const_iterator xItr = this->inputWS->readX(spectraIndex).begin();
  Mantid::MantidVec::iterator youtItr = yout.begin();
  Mantid::MantidVec::iterator eoutItr = eout.begin();

  for( ; youtItr != yout.end(); ++youtItr, ++eoutItr)
  {
    const double wavelength = (*xItr + *(xItr + 1)) / 2.0;
    const double effcorr = this->detectorEfficiency(exp_constant * wavelength, scale);
    *youtItr = (*yinItr) * effcorr;
    *eoutItr = (*einItr) * effcorr;
    ++yinItr; ++einItr;
    ++xItr;
  }

  return;
}
예제 #4
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++;
  }
}
예제 #5
0
/**
*  Move the user selected spectra in the input workspace into groups in the output workspace
*  @param inputWS :: user selected input workspace for the algorithm
*  @param outputWS :: user selected output workspace for the algorithm
*  @param prog4Copy :: the amount of algorithm progress to attribute to moving a single spectra
*  @return number of new grouped spectra
*/
size_t GroupDetectors2::formGroupsEvent( DataObjects::EventWorkspace_const_sptr inputWS, DataObjects::EventWorkspace_sptr  outputWS,
            const double prog4Copy)
{
  // get "Behaviour" string
  const std::string behaviour = getProperty("Behaviour");
  int bhv = 0;
  if ( behaviour == "Average" ) bhv = 1;

  API::MatrixWorkspace_sptr beh = API::WorkspaceFactory::Instance().create(
    "Workspace2D", static_cast<int>(m_GroupSpecInds.size()), 1, 1);

  g_log.debug() << name() << ": Preparing to group spectra into " << m_GroupSpecInds.size() << " groups\n";


  // where we are copying spectra to, we start copying to the start of the output workspace
  size_t outIndex = 0;
  // Only used for averaging behaviour. We may have a 1:1 map where a Divide would be waste as it would be just dividing by 1
  bool requireDivide(false);
  for ( storage_map::const_iterator it = m_GroupSpecInds.begin(); it != m_GroupSpecInds.end() ; ++it )
  {
    // This is the grouped spectrum
    EventList & outEL = outputWS->getEventList(outIndex);

    // The spectrum number of the group is the key
    outEL.setSpectrumNo(it->first);
    // Start fresh with no detector IDs
    outEL.clearDetectorIDs();

    // the Y values and errors from spectra being grouped are combined in the output spectrum
    // Keep track of number of detectors required for masking
    size_t nonMaskedSpectra(0);
    beh->dataX(outIndex)[0] = 0.0;
    beh->dataE(outIndex)[0] = 0.0;
    for( std::vector<size_t>::const_iterator wsIter = it->second.begin(); wsIter != it->second.end(); ++wsIter)
    {
      const size_t originalWI = *wsIter;

      const EventList & fromEL=inputWS->getEventList(originalWI);
      //Add the event lists with the operator
      outEL += fromEL;


      // detectors to add to the output spectrum
      outEL.addDetectorIDs(fromEL.getDetectorIDs() );
      try
      {
        Geometry::IDetector_const_sptr det = inputWS->getDetector(originalWI);
        if( !det->isMasked() ) ++nonMaskedSpectra;
      }
      catch(Exception::NotFoundError&)
      {
        // If a detector cannot be found, it cannot be masked
        ++nonMaskedSpectra;
      }
    }
    if( nonMaskedSpectra == 0 ) ++nonMaskedSpectra; // Avoid possible divide by zero
    if(!requireDivide) requireDivide = (nonMaskedSpectra > 1);
    beh->dataY(outIndex)[0] = static_cast<double>(nonMaskedSpectra);

    // make regular progress reports and check for cancelling the algorithm
    if ( outIndex % INTERVAL == 0 )
    {
      m_FracCompl += INTERVAL*prog4Copy;
      if ( m_FracCompl > 1.0 )
        m_FracCompl = 1.0;
      progress(m_FracCompl);
      interruption_point();
    }
    outIndex ++;
  }

  // Refresh the spectraDetectorMap
  outputWS->doneAddingEventLists();

  if ( bhv == 1 && requireDivide )
  {
    g_log.debug() << "Running Divide algorithm to perform averaging.\n";
    Mantid::API::IAlgorithm_sptr divide = createChildAlgorithm("Divide");
    divide->initialize();
    divide->setProperty<API::MatrixWorkspace_sptr>("LHSWorkspace", outputWS);
    divide->setProperty<API::MatrixWorkspace_sptr>("RHSWorkspace", beh);
    divide->setProperty<API::MatrixWorkspace_sptr>("OutputWorkspace", outputWS);
    divide->execute();
  }


  g_log.debug() << name() << " created " << outIndex << " new grouped spectra\n";
  return outIndex;
}
예제 #6
0
/**
*  Move the user selected spectra in the input workspace into groups in the output workspace
*  @param inputWS :: user selected input workspace for the algorithm
*  @param outputWS :: user selected output workspace for the algorithm
*  @param prog4Copy :: the amount of algorithm progress to attribute to moving a single spectra
*  @return number of new grouped spectra
*/
size_t GroupDetectors2::formGroups( API::MatrixWorkspace_const_sptr inputWS, API::MatrixWorkspace_sptr outputWS, 
            const double prog4Copy)
{
  // get "Behaviour" string
  const std::string behaviour = getProperty("Behaviour");
  int bhv = 0;
  if ( behaviour == "Average" ) bhv = 1;

  API::MatrixWorkspace_sptr beh = API::WorkspaceFactory::Instance().create(
    "Workspace2D", static_cast<int>(m_GroupSpecInds.size()), 1, 1);

  g_log.debug() << name() << ": Preparing to group spectra into " << m_GroupSpecInds.size() << " groups\n";

  // where we are copying spectra to, we start copying to the start of the output workspace
  size_t outIndex = 0;
  // Only used for averaging behaviour. We may have a 1:1 map where a Divide would be waste as it would be just dividing by 1
  bool requireDivide(false);
  for ( storage_map::const_iterator it = m_GroupSpecInds.begin(); it != m_GroupSpecInds.end() ; ++it )
  {
    // This is the grouped spectrum
    ISpectrum * outSpec = outputWS->getSpectrum(outIndex);

    // The spectrum number of the group is the key
    outSpec->setSpectrumNo(it->first);
    // Start fresh with no detector IDs
    outSpec->clearDetectorIDs();

    // Copy over X data from first spectrum, the bin boundaries for all spectra are assumed to be the same here
    outSpec->dataX() = inputWS->readX(0);

    // the Y values and errors from spectra being grouped are combined in the output spectrum
    // Keep track of number of detectors required for masking
    size_t nonMaskedSpectra(0);
    beh->dataX(outIndex)[0] = 0.0;
    beh->dataE(outIndex)[0] = 0.0;
    for( std::vector<size_t>::const_iterator wsIter = it->second.begin(); wsIter != it->second.end(); ++wsIter)
    {
      const size_t originalWI = *wsIter;

      // detectors to add to firstSpecNum
      const ISpectrum * fromSpectrum = inputWS->getSpectrum(originalWI);

      // Add up all the Y spectra and store the result in the first one
      // Need to keep the next 3 lines inside loop for now until ManagedWorkspace mru-list works properly
      MantidVec &firstY = outSpec->dataY();
      MantidVec::iterator fYit;
      MantidVec::iterator fEit = outSpec->dataE().begin();
      MantidVec::const_iterator Yit = fromSpectrum->dataY().begin();
      MantidVec::const_iterator Eit = fromSpectrum->dataE().begin();
      for (fYit = firstY.begin(); fYit != firstY.end(); ++fYit, ++fEit, ++Yit, ++Eit)
      {
        *fYit += *Yit;
        // Assume 'normal' (i.e. Gaussian) combination of errors
        *fEit = std::sqrt( (*fEit)*(*fEit) + (*Eit)*(*Eit) );
      }

      // detectors to add to the output spectrum
      outSpec->addDetectorIDs(fromSpectrum->getDetectorIDs() );
      try
      {
        Geometry::IDetector_const_sptr det = inputWS->getDetector(originalWI);
        if( !det->isMasked() ) ++nonMaskedSpectra;
      }
      catch(Exception::NotFoundError&)
      {
        // If a detector cannot be found, it cannot be masked
        ++nonMaskedSpectra;
      }
    }
    if( nonMaskedSpectra == 0 ) ++nonMaskedSpectra; // Avoid possible divide by zero
    if(!requireDivide) requireDivide = (nonMaskedSpectra > 1);
    beh->dataY(outIndex)[0] = static_cast<double>(nonMaskedSpectra);

    // make regular progress reports and check for cancelling the algorithm
    if ( outIndex % INTERVAL == 0 )
    {
      m_FracCompl += INTERVAL*prog4Copy;
      if ( m_FracCompl > 1.0 )
        m_FracCompl = 1.0;
      progress(m_FracCompl);
      interruption_point();
    }
    outIndex ++;
  }
  
  // Refresh the spectraDetectorMap
  outputWS->generateSpectraMap();

  if ( bhv == 1 && requireDivide )
  {
    g_log.debug() << "Running Divide algorithm to perform averaging.\n";
    Mantid::API::IAlgorithm_sptr divide = createChildAlgorithm("Divide");
    divide->initialize();
    divide->setProperty<API::MatrixWorkspace_sptr>("LHSWorkspace", outputWS);
    divide->setProperty<API::MatrixWorkspace_sptr>("RHSWorkspace", beh);
    divide->setProperty<API::MatrixWorkspace_sptr>("OutputWorkspace", outputWS);
    divide->execute();
  }

  g_log.debug() << name() << " created " << outIndex << " new grouped spectra\n";
  return outIndex;
}
예제 #7
0
/** Executes the algorithm
 *@param localworkspace :: the input workspace
 *@param indices :: set of indices to sum up
 */
void SumSpectra::execEvent(EventWorkspace_const_sptr localworkspace,
                           std::set<int> &indices) {
  // Make a brand new EventWorkspace
  EventWorkspace_sptr outputWorkspace =
      boost::dynamic_pointer_cast<EventWorkspace>(
          API::WorkspaceFactory::Instance().create("EventWorkspace", 1, 2, 1));
  // Copy geometry over.
  API::WorkspaceFactory::Instance().initializeFromParent(localworkspace,
                                                         outputWorkspace, true);

  Progress progress(this, 0, 1, indices.size());

  // Get the pointer to the output event list
  EventList &outEL = outputWorkspace->getEventList(0);
  outEL.setSpectrumNo(m_outSpecId);
  outEL.clearDetectorIDs();

  // Loop over spectra
  std::set<int>::iterator it;
  size_t numSpectra(0);
  size_t numMasked(0);
  size_t numZeros(0);
  // for (int i = m_minSpec; i <= m_maxSpec; ++i)
  for (it = indices.begin(); it != indices.end(); ++it) {
    int i = *it;
    // Don't go outside the range.
    if ((i >= m_numberOfSpectra) || (i < 0)) {
      g_log.error() << "Invalid index " << i
                    << " was specified. Sum was aborted.\n";
      break;
    }

    try {
      // Get the detector object for this spectrum
      Geometry::IDetector_const_sptr det = localworkspace->getDetector(i);
      // Skip monitors, if the property is set to do so
      if (!m_keepMonitors && det->isMonitor())
        continue;
      // Skip masked detectors
      if (det->isMasked()) {
        numMasked++;
        continue;
      }
    } catch (...) {
      // if the detector not found just carry on
    }
    numSpectra++;

    // Add the event lists with the operator
    const EventList &tOutEL = localworkspace->getEventList(i);
    if (tOutEL.empty()) {
      ++numZeros;
    }
    outEL += tOutEL;

    progress.report();
  }

  // Set all X bins on the output
  cow_ptr<MantidVec> XValues;
  XValues.access() = localworkspace->readX(0);
  outputWorkspace->setAllX(XValues);

  outputWorkspace->mutableRun().addProperty("NumAllSpectra", int(numSpectra),
                                            "", true);
  outputWorkspace->mutableRun().addProperty("NumMaskSpectra", int(numMasked),
                                            "", true);
  outputWorkspace->mutableRun().addProperty("NumZeroSpectra", int(numZeros), "",
                                            true);

  // Assign it to the output workspace property
  setProperty("OutputWorkspace",
              boost::dynamic_pointer_cast<MatrixWorkspace>(outputWorkspace));
}
예제 #8
0
/**
 * This function handles the logic for summing RebinnedOutput workspaces.
 * @param outputWorkspace the workspace to hold the summed input
 * @param progress the progress indicator
 * @param numSpectra
 * @param numMasked
 * @param numZeros
 */
void SumSpectra::doRebinnedOutput(MatrixWorkspace_sptr outputWorkspace,
                                  Progress &progress, size_t &numSpectra,
                                  size_t &numMasked, size_t &numZeros) {
  // Get a copy of the input workspace
  MatrixWorkspace_sptr temp = getProperty("InputWorkspace");

  // First, we need to clean the input workspace for nan's and inf's in order
  // to treat the data correctly later. This will create a new private
  // workspace that will be retrieved as mutable.
  IAlgorithm_sptr alg = this->createChildAlgorithm("ReplaceSpecialValues");
  alg->setProperty<MatrixWorkspace_sptr>("InputWorkspace", temp);
  std::string outName = "_" + temp->getName() + "_clean";
  alg->setProperty("OutputWorkspace", outName);
  alg->setProperty("NaNValue", 0.0);
  alg->setProperty("NaNError", 0.0);
  alg->setProperty("InfinityValue", 0.0);
  alg->setProperty("InfinityError", 0.0);
  alg->executeAsChildAlg();
  MatrixWorkspace_sptr localworkspace = alg->getProperty("OutputWorkspace");

  // Transform to real workspace types
  RebinnedOutput_sptr inWS =
      boost::dynamic_pointer_cast<RebinnedOutput>(localworkspace);
  RebinnedOutput_sptr outWS =
      boost::dynamic_pointer_cast<RebinnedOutput>(outputWorkspace);

  // Get references to the output workspaces's data vectors
  ISpectrum *outSpec = outputWorkspace->getSpectrum(0);
  MantidVec &YSum = outSpec->dataY();
  MantidVec &YError = outSpec->dataE();
  MantidVec &FracSum = outWS->dataF(0);
  MantidVec Weight;
  std::vector<size_t> nZeros;
  if (m_calculateWeightedSum) {
    Weight.assign(YSum.size(), 0);
    nZeros.assign(YSum.size(), 0);
  }
  numSpectra = 0;
  numMasked = 0;
  numZeros = 0;

  // Loop over spectra
  std::set<int>::iterator it;
  // for (int i = m_minSpec; i <= m_maxSpec; ++i)
  for (it = m_indices.begin(); it != m_indices.end(); ++it) {
    int i = *it;
    // Don't go outside the range.
    if ((i >= m_numberOfSpectra) || (i < 0)) {
      g_log.error() << "Invalid index " << i
                    << " was specified. Sum was aborted.\n";
      break;
    }

    try {
      // Get the detector object for this spectrum
      Geometry::IDetector_const_sptr det = localworkspace->getDetector(i);
      // Skip monitors, if the property is set to do so
      if (!m_keepMonitors && det->isMonitor())
        continue;
      // Skip masked detectors
      if (det->isMasked()) {
        numMasked++;
        continue;
      }
    } catch (...) {
      // if the detector not found just carry on
    }
    numSpectra++;

    // Retrieve the spectrum into a vector
    const MantidVec &YValues = localworkspace->readY(i);
    const MantidVec &YErrors = localworkspace->readE(i);
    const MantidVec &FracArea = inWS->readF(i);

    if (m_calculateWeightedSum) {
      for (int k = 0; k < this->m_yLength; ++k) {
        if (YErrors[k] != 0) {
          double errsq = YErrors[k] * YErrors[k] * FracArea[k] * FracArea[k];
          YError[k] += errsq;
          Weight[k] += 1. / errsq;
          YSum[k] += YValues[k] * FracArea[k] / errsq;
          FracSum[k] += FracArea[k];
        } else {
          nZeros[k]++;
          FracSum[k] += FracArea[k];
        }
      }
    } else {
      for (int k = 0; k < this->m_yLength; ++k) {
        YSum[k] += YValues[k] * FracArea[k];
        YError[k] += YErrors[k] * YErrors[k] * FracArea[k] * FracArea[k];
        FracSum[k] += FracArea[k];
      }
    }

    // Map all the detectors onto the spectrum of the output
    outSpec->addDetectorIDs(localworkspace->getSpectrum(i)->getDetectorIDs());

    progress.report();
  }

  if (m_calculateWeightedSum) {
    numZeros = 0;
    for (size_t i = 0; i < Weight.size(); i++) {
      if (nZeros[i] == 0)
        YSum[i] *= double(numSpectra) / Weight[i];
      else
        numZeros += nZeros[i];
    }
  }

  // Create the correct representation
  outWS->finalize();
}
예제 #9
0
/**
 * This function deals with the logic necessary for summing a Workspace2D.
 * @param localworkspace The input workspace for summing.
 * @param outSpec The spectrum for the summed output.
 * @param progress The progress indicator.
 * @param numSpectra The number of spectra contributed to the sum.
 * @param numMasked The spectra dropped from the summations because they are
 * masked.
 * @param numZeros The number of zero bins in histogram workspace or empty
 * spectra for event workspace.
 */
void SumSpectra::doWorkspace2D(MatrixWorkspace_const_sptr localworkspace,
                               ISpectrum *outSpec, Progress &progress,
                               size_t &numSpectra, size_t &numMasked,
                               size_t &numZeros) {
  // Get references to the output workspaces's data vectors
  MantidVec &YSum = outSpec->dataY();
  MantidVec &YError = outSpec->dataE();

  MantidVec Weight;
  std::vector<size_t> nZeros;
  if (m_calculateWeightedSum) {
    Weight.assign(YSum.size(), 0);
    nZeros.assign(YSum.size(), 0);
  }
  numSpectra = 0;
  numMasked = 0;
  numZeros = 0;

  // Loop over spectra
  std::set<int>::iterator it;
  // for (int i = m_minSpec; i <= m_maxSpec; ++i)
  for (it = this->m_indices.begin(); it != this->m_indices.end(); ++it) {
    int i = *it;
    // Don't go outside the range.
    if ((i >= this->m_numberOfSpectra) || (i < 0)) {
      g_log.error() << "Invalid index " << i
                    << " was specified. Sum was aborted.\n";
      break;
    }

    try {
      // Get the detector object for this spectrum
      Geometry::IDetector_const_sptr det = localworkspace->getDetector(i);
      // Skip monitors, if the property is set to do so
      if (!m_keepMonitors && det->isMonitor())
        continue;
      // Skip masked detectors
      if (det->isMasked()) {
        numMasked++;
        continue;
      }
    } catch (...) {
      // if the detector not found just carry on
    }
    numSpectra++;

    // Retrieve the spectrum into a vector
    const MantidVec &YValues = localworkspace->readY(i);
    const MantidVec &YErrors = localworkspace->readE(i);
    if (m_calculateWeightedSum) {
      for (int k = 0; k < this->m_yLength; ++k) {
        if (YErrors[k] != 0) {
          double errsq = YErrors[k] * YErrors[k];
          YError[k] += errsq;
          Weight[k] += 1. / errsq;
          YSum[k] += YValues[k] / errsq;
        } else {
          nZeros[k]++;
        }
      }
    } else {
      for (int k = 0; k < this->m_yLength; ++k) {
        YSum[k] += YValues[k];
        YError[k] += YErrors[k] * YErrors[k];
      }
    }

    // Map all the detectors onto the spectrum of the output
    outSpec->addDetectorIDs(localworkspace->getSpectrum(i)->getDetectorIDs());

    progress.report();
  }

  if (m_calculateWeightedSum) {
    numZeros = 0;
    for (size_t i = 0; i < Weight.size(); i++) {
      if (nZeros[i] == 0)
        YSum[i] *= double(numSpectra) / Weight[i];
      else
        numZeros += nZeros[i];
    }
  }
}
예제 #10
0
파일: SaveGSS.cpp 프로젝트: nimgould/mantid
/** Write GSAS file based on user-specified request
  */
void SaveGSS::writeGSASFile(const std::string &outfilename, bool append,
                            int basebanknumber, bool multiplybybinwidth,
                            bool split, const std::string &outputFormat) {
  // Initialize the file stream
  using std::ios_base;
  ios_base::openmode mode =
      (append ? (ios_base::out | ios_base::app) : ios_base::out);

  // Instrument related
  Geometry::Instrument_const_sptr instrument = inputWS->getInstrument();
  Geometry::IComponent_const_sptr source;
  Geometry::IComponent_const_sptr sample;
  bool has_instrument = false;
  if (instrument != NULL) {
    source = instrument->getSource();
    sample = instrument->getSample();
    if (source && sample)
      has_instrument = true;
  }

  // Write GSAS file for each histogram (spectrum)
  std::stringstream outbuffer;

  int nHist = static_cast<int>(inputWS->getNumberHistograms());
  Progress p(this, 0.0, 1.0, nHist);

  for (int iws = 0; iws < nHist; iws++) {
    // Determine whether to skip the spectrum due to being masked
    if (has_instrument) {
      try {
        Geometry::IDetector_const_sptr det =
            inputWS->getDetector(static_cast<size_t>(iws));
        if (det->isMasked())
          continue;
      } catch (const Kernel::Exception::NotFoundError &) {
        has_instrument = false;
        g_log.warning() << "There is no detector associated with spectrum "
                        << iws
                        << ". Workspace is treated as NO-INSTRUMENT case. \n";
      }
    }

    // Obtain detector information
    double l1, l2, tth, difc;
    if (has_instrument)
      getFocusedPos(inputWS, iws, l1, l2, tth, difc);
    else
      l1 = l2 = tth = difc = 0;
    g_log.debug() << "Spectrum " << iws << ": L1 = " << l1 << "  L2 = " << l2
                  << "  2theta = " << tth << "\n";

    std::stringstream tmpbuffer;

    // Header: 2 cases requires header: (1) first bank in non-append mode and
    // (2) split
    g_log.debug() << "[DB9933] Append = " << append << ", split = " << split
                  << "\n";

    bool writeheader = false;
    std::string splitfilename("");
    if (!split && iws == 0 && !append) {
      // Non-split mode and first spectrum and in non-append mode
      writeheader = true;
    } else if (split) {
      std::stringstream number;
      number << "-" << iws;

      Poco::Path path(outfilename);
      std::string basename = path.getBaseName(); // Filename minus extension
      std::string ext = path.getExtension();
      // Chop off filename
      path.makeParent();
      path.append(basename + number.str() + "." + ext);
      Poco::File fileobj(path);
      const bool exists = fileobj.exists();
      if (!exists || !append)
        writeheader = true;
      if (fileobj.exists() && !append)
        g_log.warning() << "File " << path.getFileName()
                        << " exists and will be overwritten."
                        << "\n";
      splitfilename = path.toString();
    }

    // Create header
    if (writeheader)
      writeHeaders(outputFormat, tmpbuffer, l1);

    // Write bank header
    if (has_instrument) {
      tmpbuffer << "# Total flight path " << (l1 + l2) << "m, tth "
                << (tth * 180. / M_PI) << "deg, DIFC " << difc << "\n";
    }
    tmpbuffer << "# Data for spectrum :" << iws << "\n";

    // Determine bank number into GSAS file
    int bankid;
    if (m_useSpecAsBank) {
      bankid = static_cast<int>(inputWS->getSpectrum(iws)->getSpectrumNo());
    } else {
      bankid = basebanknumber + iws;
    }

    // Write data
    if (RALF.compare(outputFormat) == 0) {
      this->writeRALFdata(bankid, multiplybybinwidth, tmpbuffer,
                          inputWS->readX(iws), inputWS->readY(iws),
                          inputWS->readE(iws));
    } else if (SLOG.compare(outputFormat) == 0) {
      this->writeSLOGdata(bankid, multiplybybinwidth, tmpbuffer,
                          inputWS->readX(iws), inputWS->readY(iws),
                          inputWS->readE(iws));
    } else {
      throw std::runtime_error("Cannot write to the unknown " + outputFormat +
                               "output format");
    }

    // Write out to file if necessary
    if (split) {
      // Create a new file name and a new file with ofstream
      std::ofstream out;
      out.open(splitfilename.c_str(), mode);
      out.write(tmpbuffer.str().c_str(), tmpbuffer.str().size());
      out.close();
    } else {
      outbuffer << tmpbuffer.str();
    }

    p.report();

  } // ENDFOR (iws)

  // Write file
  if (!split) {
    std::ofstream out;
    out.open(outfilename.c_str(), mode);
    out.write(outbuffer.str().c_str(), outbuffer.str().length());
    out.close();
  }

  return;
}
예제 #11
0
/** 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 << std::endl;
  } 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);
  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;

    // 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();
    if (m_getIsMasked)
      *(pMasksArray + liveDetectorsCount) = maskDetector ? 1 : 0;
    else if (maskDetector)
      continue;

    // calculate the requested values;
    sp2detMap[i] = liveDetectorsCount;
    detId[liveDetectorsCount] = int32_t(spDet->getID());
    detIDMap[liveDetectorsCount] = i;
    L2[liveDetectorsCount] = spDet->getDistance(*sample);

    double polar = inputWS->detectorTwoTheta(spDet);
    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.get(), "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";
}