示例#1
0
void LoadDaveGrp::getData(std::vector<MantidVec *> &data,
    std::vector<MantidVec *> &errs)
{
  double data_val = 0.0;
  double err_val = 0.0;
  API::Progress progress(this, 0.0, 1.0, this->nGroups);
  for(int j = 0; j < this->nGroups; j++)
  {
    // Skip the group comment line
    this->readLine();
    // Read the data block
    MantidVec *d = new MantidVec();
    MantidVec *e = new MantidVec();
    for(std::size_t k = 0; k < static_cast<std::size_t>(this->xLength); k++)
    {
      this->readLine();
      std::istringstream is(this->line);
      is >> data_val >> err_val;
      d->push_back(data_val);
      e->push_back(err_val);
    }
    data.push_back(d);
    errs.push_back(e);
    progress.report();
  }
}
示例#2
0
    /**
     * Find the overlap of the inputWS with the given polygon
     * @param oldAxis1 :: Axis 1 bin boundaries from the input grid
     * @param oldAxis2 :: Axis 2 bin boundaries from the input grid
     * @param newPoly :: The new polygon to test
     * @returns A list of intersection locations with weights of the overlap
     */
    std::vector<Rebin2D::BinWithWeight> 
    Rebin2D::findIntersections(const MantidVec & oldAxis1, const MantidVec & oldAxis2,
                               const Geometry::ConvexPolygon & newPoly) const
    {
      std::vector<BinWithWeight> overlaps;
      overlaps.reserve(5); // Have a guess at a posible limit

      const size_t nxpoints(oldAxis1.size()-1), nypoints(oldAxis2.size()-1);
      const double yn_lo(newPoly[0].Y()), yn_hi(newPoly[1].Y());
      const double xn_lo(newPoly[0].X()), xn_hi(newPoly[2].X());
      for(size_t i = 0; i < nypoints; ++i)
      {
        const double yo_lo(oldAxis2[i]), yo_hi(oldAxis2[i+1]);
        // Check if there is a possibility of overlap
        if( yo_hi < yn_lo || yo_lo > yn_hi ) continue;
        for(size_t j = 0; j < nxpoints; ++j)
        {
          const double xo_lo(oldAxis1[j]), xo_hi(oldAxis1[j+1]);
          // Check if there is a possibility of overlap
          if( xo_hi < xn_lo || xo_lo > xn_hi ) continue;
          ConvexPolygon oldPoly(xo_lo, xo_hi, yo_lo, yo_hi);
          try
          {
            ConvexPolygon overlap = intersectionByLaszlo(newPoly, oldPoly);
            overlaps.push_back(BinWithWeight(i,j,overlap.area()/oldPoly.area()));
          }
          catch(Geometry::NoIntersectionException &)
          {}            
        }
      }
      return overlaps;
    }
示例#3
0
文件: Q1D2.cpp 项目: trnielsen/mantid
/** This is a slightly "clever" method as it makes some guesses about where is best
*  to look for the right Q bin based on the fact that the input Qs (calcualted from wavelengths) tend
*  to go down while the output Qs are always in accending order
*  @param[in] OutQs the array of output Q bin boundaries, this finds the bin that contains the QIn value
*  @param[in] QToFind the Q value to find the correct bin for
*  @param[in, out] loc points to the bin boundary (in the OutQs array) whos Q is higher than QToFind and higher by the smallest amount. Algorithm starts by checking the value of loc passed and then all the bins _downwards_ through the array
*/
void Q1D2::getQBinPlus1(const MantidVec & OutQs, const double QToFind, MantidVec::const_iterator & loc) const
{
  if ( loc != OutQs.end() )
  {
    while ( loc != OutQs.begin() )
    {
      if ( (QToFind >= *(loc-1)) && (QToFind < *loc) )
      {
        return;
      }
      --loc;
    }
    if ( QToFind < *loc )
    {
      //QToFind is outside the array leave loc == OutQs.begin()
      return;
    }
  }
  else //loc == OutQs.end()
  {
    if ( OutQs.empty() || QToFind > *(loc-1) )
    {
      //outside the array leave loc == OutQs.end()
      return;
    }
  }

  // we are lost, normally the order of the Q values means we only get here on the first iteration. It's slow
  loc = std::lower_bound(OutQs.begin(), OutQs.end(), QToFind);
}
示例#4
0
/** Deals with the (rare) case where the flightpath is longer than the reference
 *  Note that in this case both T1 & T2 will be greater than Tmax
 */
std::pair<int, int>
UnwrapMonitor::handleFrameOverlapped(const MantidVec &xdata, const double &Ld,
                                     std::vector<double> &tempX) {
  // Calculate the interval to exclude
  const double Dt = (m_Tmax - m_Tmin) * (1 - (m_LRef / Ld));
  // This gives us new minimum & maximum tof values
  const double minT = m_Tmin + Dt;
  const double maxT = m_Tmax - Dt;
  // Can have situation where Ld is so much larger than Lref that everything
  // would be excluded.
  // This is an invalid input - warn and leave spectrum unwrapped
  if (minT > maxT) {
    g_log.warning() << "Invalid input, Ld (" << Ld << ") >> Lref (" << m_LRef
                    << "). Current spectrum will not be unwrapped.\n";
    return std::make_pair(0, static_cast<int>(xdata.size() - 1));
  }

  int min = 0, max = static_cast<int>(xdata.size());
  for (unsigned int j = 0; j < m_XSize; ++j) {
    const double T = xdata[j];
    if (T < minT) {
      min = j + 1;
      tempX.erase(tempX.begin());
    } else if (T > maxT) {
      tempX.erase(tempX.end() - (max - j), tempX.end());
      max = j - 1;
      break;
    }
  }
  return std::make_pair(min, max);
}
示例#5
0
/** Calculates the rebin parameters in the case where the range of the second
 * workspace is
 *  entirely within that of the first workspace.
 *  'Inclusion' is used in the sense of a set being included in anothre.
 *  @param X1 ::     The bin boundaries from the first workspace
 *  @param i ::      Indicates the index in X1 immediately before the overlap
 * region starts
 *  @param X2 ::     The bin boundaries from the second workspace
 *  @param params :: A reference to the vector of rebinning parameters
 */
void MergeRuns::inclusionParams(const MantidVec &X1, int64_t &i,
                                const MantidVec &X2,
                                std::vector<double> &params) const {
    // First calculate the number of bins in each workspace that are in the
    // overlap region
    int64_t overlapbins1, overlapbins2;
    for (overlapbins1 = 1; X1[i + overlapbins1] < X2.back(); ++overlapbins1) {
    }
    //++overlapbins1;
    overlapbins2 = X2.size() - 1;

    // In the overlap region, we want to use whichever one has the larger bins (on
    // average)
    if (overlapbins1 + 1 <= overlapbins2) {
        // In the case where the first workspace has larger bins it's easy
        // - just add the rest of X1's bins
        for (; i < static_cast<int64_t>(X1.size()); ++i) {
            params.push_back(X1[i] - X1[i - 1]);
            params.push_back(X1[i]);
        }
    } else {
        // In this case we want all of X2's bins first (without the first and last
        // boundaries)
        for (size_t j = 1; j < X2.size() - 1; ++j) {
            params.push_back(X2[j] - params.back());
            params.push_back(X2[j]);
        }
        // And now those from X1 that lie above the overlap region
        i += overlapbins1;
        for (; i < static_cast<int64_t>(X1.size()); ++i) {
            params.push_back(X1[i] - params.back());
            params.push_back(X1[i]);
        }
    }
}
示例#6
0
/** Calculates the rebin parameters in the case where the bins of the two
 * workspaces intersect.
 *  'Intersect' is used in the sense of two intersecting sets.
 *  @param X1 ::     The bin boundaries from the first workspace
 *  @param i ::      Indicates the index in X1 immediately before the overlap
 * region starts
 *  @param X2 ::     The bin boundaries from the second workspace
 *  @param params :: A reference to the vector of rebinning parameters
 */
void MergeRuns::intersectionParams(const MantidVec &X1, int64_t &i,
                                   const MantidVec &X2,
                                   std::vector<double> &params) const {
    // First calculate the number of bins in each workspace that are in the
    // overlap region
    int64_t overlapbins1, overlapbins2;
    overlapbins1 = X1.size() - i;
    for (overlapbins2 = 0; X2[overlapbins2] < X1.back(); ++overlapbins2) {
    }

    // We want to use whichever one has the larger bins (on average)
    if (overlapbins1 < overlapbins2) {
        // In this case we want the rest of the bins from the first workspace.....
        for (; i < static_cast<int64_t>(X1.size()); ++i) {
            params.push_back(X1[i] - X1[i - 1]);
            params.push_back(X1[i]);
        }
        // Now remove the last bin & boundary
        params.pop_back();
        params.pop_back();
        // ....and then the non-overlap ones from the second workspace
        for (size_t j = overlapbins2; j < X2.size(); ++j) {
            params.push_back(X2[j] - params.back());
            params.push_back(X2[j]);
        }
    } else {
        // In this case we just have to add all the bins from the second workspace
        for (size_t j = 1; j < X2.size(); ++j) {
            params.push_back(X2[j] - params.back());
            params.push_back(X2[j]);
        }
    }
}
示例#7
0
 MantidVec
 operator()(const MantidVec &_Left,
            const MantidVec &_Right) const { // apply operator+ to operands
   MantidVec v(_Left.size());
   std::transform(_Left.begin(), _Left.end(), _Right.begin(), v.begin(),
                  SumGaussError<double>());
   return (v);
 }
示例#8
0
/**
 * load vectors onto a Workspace2D with 3 bins (the three components of the
 * vectors)
 * dataX for the origin of the vector (assumed (0,0,0) )
 * dataY for the tip of the vector
 * dataE is assumed (0,0,0), no errors
 * @param h5file file identifier
 * @param gws pointer to WorkspaceGroup being filled
 * @param sorting_indexes permutation of qvmod indexes to render it in
 * increasing order of momemtum transfer
 */
const MantidVec LoadSassena::loadQvectors(const hid_t &h5file,
                                          API::WorkspaceGroup_sptr gws,
                                          std::vector<int> &sorting_indexes) {

  const std::string gwsName = this->getPropertyValue("OutputWorkspace");
  const std::string setName("qvectors");

  hsize_t dims[3];
  if (dataSetInfo(h5file, setName, dims) < 0) {
    throw Kernel::Exception::FileError(
        "Unable to read " + setName + " dataset info:", m_filename);
  }
  int nq = static_cast<int>(dims[0]); // number of q-vectors
  double *buf = new double[nq * 3];
  this->dataSetDouble(h5file, "qvectors", buf);

  MantidVec qvmod; // store the modulus of the vector
  double *curr = buf;
  for (int iq = 0; iq < nq; iq++) {
    qvmod.push_back(
        sqrt(curr[0] * curr[0] + curr[1] * curr[1] + curr[2] * curr[2]));
    curr += 3;
  }

  if (getProperty("SortByQVectors")) {
    std::vector<mypair> qvmodpair;
    for (int iq = 0; iq < nq; iq++)
      qvmodpair.push_back(mypair(qvmod[iq], iq));
    std::sort(qvmodpair.begin(), qvmodpair.end(), compare);
    for (int iq = 0; iq < nq; iq++)
      sorting_indexes.push_back(qvmodpair[iq].second);
    std::sort(qvmod.begin(), qvmod.end());
  } else
    for (int iq = 0; iq < nq; iq++)
      sorting_indexes.push_back(iq);

  DataObjects::Workspace2D_sptr ws =
      boost::dynamic_pointer_cast<DataObjects::Workspace2D>(
          API::WorkspaceFactory::Instance().create("Workspace2D", nq, 3, 3));
  std::string wsName = gwsName + std::string("_") + setName;
  ws->setTitle(wsName);

  for (int iq = 0; iq < nq; iq++) {
    MantidVec &Y = ws->dataY(iq);
    const int index = sorting_indexes[iq];
    curr = buf + 3 * index;
    Y.assign(curr, curr + 3);
  }
  delete[] buf;

  ws->getAxis(0)->unit() = Kernel::UnitFactory::Instance().create(
      "MomentumTransfer"); // Set the Units

  this->registerWorkspace(
      gws, wsName, ws, "X-axis: origin of Q-vectors; Y-axis: tip of Q-vectors");
  return qvmod;
}
示例#9
0
/** Calculates the overall normalization factor.
 *  This multiplies result by (bin width * sum of monitor counts) / total frame
 * width.
 *  @param X The X vector
 *  @param Y The data vector
 *  @param E The error vector
 */
void NormaliseToMonitor::normalisationFactor(const MantidVec &X, MantidVec *Y,
                                             MantidVec *E) {
  const double monitorSum = std::accumulate(Y->begin(), Y->end(), 0.0);
  const double range = X.back() - X.front();
  MantidVec::size_type specLength = Y->size();
  for (MantidVec::size_type j = 0; j < specLength; ++j) {
    const double factor = range / ((X[j + 1] - X[j]) * monitorSum);
    (*Y)[j] *= factor;
    (*E)[j] *= factor;
  }
}
/// Returns vector with x-values of spectrum if MatrixWorkspace does not contain
/// histogram data.
MantidVec FunctionDomain1DSpectrumCreator::getVectorNonHistogram() const {
  const MantidVec wsXData = m_matrixWorkspace->readX(m_workspaceIndex);
  size_t wsXSize = wsXData.size();

  if (wsXSize < 1) {
    throw std::invalid_argument(
        "Workspace2D with less than one x-value cannot be processed.");
  }

  return MantidVec(wsXData);
}
示例#11
0
/**
 * @param tofMin Return value for minimum tof to be masked
 * @param tofMax Return value for maximum tof to be masked
 * @param tofPeak time-of-flight of the single crystal peak
 * @param tof tof-of-flight axis for the spectrum where the peak supposedly
 * exists
 */
void MaskPeaksWorkspace::getTofRange(double &tofMin, double &tofMax,
                                     const double tofPeak,
                                     const MantidVec &tof) {
  tofMin = tof.front();
  tofMax = tof.back() - 1;
  if (!isEmpty(m_tofMin)) {
    tofMin = tofPeak + m_tofMin;
  }
  if (!isEmpty(m_tofMax)) {
    tofMax = tofPeak + m_tofMax;
  }
}
示例#12
0
int UnwrapSNS::unwrapX(const MantidVec &datain, MantidVec &dataout,
                       const double &Ld) {
  MantidVec tempX_L; // lower half - to be frame wrapped
  tempX_L.reserve(m_XSize);
  tempX_L.clear();
  MantidVec tempX_U; // upper half - to not be frame wrapped
  tempX_U.reserve(m_XSize);
  tempX_U.clear();

  double filterVal = m_Tmin * Ld / m_LRef;
  dataout.clear();
  int specialBin = 0;
  for (int bin = 0; bin < m_XSize; ++bin) {
    // This is the time-of-flight value under consideration in the current
    // iteration of the loop
    const double tof = datain[bin];
    if (tof < filterVal) {
      tempX_L.push_back(tof + m_frameWidth);
      // Record the bins that fall in this range for copying over the data &
      // errors
      if (specialBin < bin)
        specialBin = bin;
    } else {
      tempX_U.push_back(tof);
    }
  } // loop over X values

  // now put it back into the vector supplied
  dataout.clear();
  dataout.insert(dataout.begin(), tempX_U.begin(), tempX_U.end());
  dataout.insert(dataout.end(), tempX_L.begin(), tempX_L.end());
  assert(datain.size() == dataout.size());

  return specialBin;
}
示例#13
0
/**
 * Get the start and end of the x-interval.
 * @param X :: The x-vector of a spectrum.
 * @param isHistogram :: Is the x-vector comming form a histogram? If it's true
 * the bin
 *   centres are used.
 * @return :: A pair of start x and end x.
 */
std::pair<double, double> WienerSmooth::getStartEnd(const MantidVec &X,
                                                    bool isHistogram) const {
  const size_t n = X.size();
  if (n < 3) {
    // 3 is the smallest number for this method to work without breaking
    throw std::runtime_error(
        "Number of bins/data points cannot be smaller than 3.");
  }
  if (isHistogram) {
    return std::make_pair((X[0] + X[1]) / 2, (X[n - 1] + X[n - 2]) / 2);
  }
  // else
  return std::make_pair(X.front(), X.back());
}
示例#14
0
/// Retrieve and check the Start/EndX parameters, if set
void Linear::setRange(const MantidVec& X, const MantidVec& Y)
{
  //read in the values that the user selected
  double startX = getProperty("StartX");
  double endX = getProperty("EndX");
  //If the user didn't a start default to the start of the data
  if ( isEmpty(startX) ) startX = X.front();
  //the default for the end is the end of the data
  if ( isEmpty(endX) ) endX = X.back();

  // Check the validity of startX
  if ( startX < X.front() )
  {
    g_log.warning("StartX out of range! Set to start of frame.");
    startX = X.front();
  }
  // Now get the corresponding bin boundary that comes before (or coincides with) this value
  for (m_minX = 0; X[m_minX+1] < startX; ++m_minX) {}

  // Check the validity of endX and get the bin boundary that come after (or coincides with) it
  if ( endX >= X.back() || endX < startX )
  {
    if ( endX != X.back() )
    {
      g_log.warning("EndX out of range! Set to end of frame");
      endX = X.back();
    }
    m_maxX = static_cast<int>(Y.size());
  }
  else
  {
    for (m_maxX = m_minX; X[m_maxX] < endX; ++m_maxX) {}
  }  
}
 /** Execute the algorithm.
  */
 void WeightedMeanOfWorkspace::exec()
 {
   MatrixWorkspace_sptr inputWS = this->getProperty("InputWorkspace");
   // Check if it is an event workspace
   EventWorkspace_const_sptr eventW = boost::dynamic_pointer_cast<const EventWorkspace>(inputWS);
   if (eventW != NULL)
   {
     throw std::runtime_error("WeightedMeanOfWorkspace cannot handle EventWorkspaces!");
   }
   // Create the output workspace
   MatrixWorkspace_sptr singleValued = WorkspaceFactory::Instance().create("WorkspaceSingleValue", 1, 1, 1);
   // Calculate weighted mean
   std::size_t numHists = inputWS->getNumberHistograms();
   double averageValue = 0.0;
   double weightSum = 0.0;
   for (std::size_t i = 0; i < numHists; ++i)
   {
     try
     {
       IDetector_const_sptr det = inputWS->getDetector(i);
       if( det->isMonitor() || det->isMasked() )
       {
         continue;
       }
     }
     catch (...)
     {
       // Swallow these if no instrument is found
       ;
     }
     MantidVec y = inputWS->dataY(i);
     MantidVec e = inputWS->dataE(i);
     double weight = 0.0;
     for (std::size_t j = 0; j < y.size(); ++j)
     {
       if (!boost::math::isnan(y[j]) && !boost::math::isinf(y[j]) &&
           !boost::math::isnan(e[j]) && !boost::math::isinf(e[j]))
       {
         weight = 1.0 / (e[j] * e[j]);
         averageValue += (y[j] * weight);
         weightSum += weight;
       }
     }
   }
   singleValued->dataX(0)[0] = 0.0;
   singleValued->dataY(0)[0] = averageValue / weightSum;
   singleValued->dataE(0)[0] = std::sqrt(weightSum);
   this->setProperty("OutputWorkspace", singleValued);
 }
示例#16
0
/**
 * Create workspace to store the structure factor.
 * First spectrum is the real part, second spectrum is the imaginary part
 * X values are the modulus of the Q-vectors
 * @param h5file file identifier
 * @param gws pointer to WorkspaceGroup being filled
 * @param setName string name of dataset
 * @param qvmod vector of Q-vectors' moduli
 * @param sorting_indexes permutation of qvmod indexes to render it in increasing order of momemtum transfer
 */
void LoadSassena::loadFQ(const hid_t& h5file, API::WorkspaceGroup_sptr gws, const std::string setName, const MantidVec &qvmod, const std::vector<int> &sorting_indexes)
{
  const std::string gwsName = this->getPropertyValue("OutputWorkspace");
  int nq = static_cast<int>( qvmod.size() ); //number of q-vectors

  DataObjects::Workspace2D_sptr ws = boost::dynamic_pointer_cast<DataObjects::Workspace2D>(API::WorkspaceFactory::Instance().create("Workspace2D", 2, nq, nq));
  const std::string wsName = gwsName + std::string("_") + setName;
  ws->setTitle(wsName);

  double* buf = new double[nq*2];
  this->dataSetDouble(h5file,setName,buf);
  MantidVec& re = ws->dataY(0); // store the real part
  ws->dataX(0) = qvmod;  //X-axis values are the modulus of the q vector
  MantidVec& im = ws->dataY(1); // store the imaginary part
  ws->dataX(1) = qvmod;
  double *curr = buf;
  for(int iq=0; iq<nq; iq++){
    const int index=sorting_indexes[iq];
    re[index]=curr[0];
    im[index]=curr[1];
    curr+=2;
  }
  delete[] buf;

  // Set the Units
  ws->getAxis(0)->unit() = Kernel::UnitFactory::Instance().create("MomentumTransfer");

  this->registerWorkspace(gws,wsName,ws, "X-axis: Q-vector modulus; Y-axis: intermediate structure factor");
}
示例#17
0
文件: Divide.cpp 项目: mcvine/mantid
void Divide::performBinaryOperation(const MantidVec &lhsX,
                                    const MantidVec &lhsY,
                                    const MantidVec &lhsE,
                                    const MantidVec &rhsY,
                                    const MantidVec &rhsE, MantidVec &YOut,
                                    MantidVec &EOut) {
  (void)lhsX; // Avoid compiler warning

  const int bins = static_cast<int>(lhsE.size());

  for (int j = 0; j < bins; ++j) {
    // Get references to the input Y's
    const double leftY = lhsY[j];
    const double rightY = rhsY[j];

    //  error dividing two uncorrelated numbers, re-arrange so that you don't
    //  get infinity if leftY==0 (when rightY=0 the Y value and the result will
    //  both be infinity)
    // (Sa/a)2 + (Sb/b)2 = (Sc/c)2
    // (Sa c/a)2 + (Sb c/b)2 = (Sc)2
    // = (Sa 1/b)2 + (Sb (a/b2))2
    // (Sc)2 = (1/b)2( (Sa)2 + (Sb a/b)2 )
    EOut[j] =
        sqrt(pow(lhsE[j], 2) + pow(leftY * rhsE[j] / rightY, 2)) / fabs(rightY);

    // Copy the result last in case one of the input workspaces is also any
    // output
    YOut[j] = leftY / rightY;
    ;
  }
}
示例#18
0
void WeightedMean::performBinaryOperation(const MantidVec& lhsX, const MantidVec& lhsY, const MantidVec& lhsE,
                                          const double rhsY, const double rhsE, MantidVec& YOut, MantidVec& EOut)
{
	UNUSED_ARG(lhsX);
  assert( lhsX.size() == 1 );
  // If we get here we've got two single column workspaces so it's easy.
  if (lhsE[0] > 0.0 && rhsE > 0.0)
  {
    const double err1 = lhsE[0]*lhsE[0];
    const double err2 = rhsE*rhsE;
    YOut[0] = (lhsY[0]/err1)+(rhsY/err2);
    EOut[0] = (err1*err2)/(err1+err2);
    YOut[0] *= EOut[0];
    EOut[0] = sqrt(EOut[0]); 
  }
  else if (lhsE[0] > 0.0 && rhsE <= 0.0)
  {
    YOut[0] = lhsY[0];
    EOut[0] = lhsE[0];
  }
  else if (lhsE[0] <= 0.0 && rhsE > 0.0)
  {
    YOut[0] = rhsY;
    EOut[0] = rhsE;
  }
  else
  {
    YOut[0] = 0.0;
    EOut[0] = 0.0;
  }
}
/**
 * @param xValues The X data for the fitted spectrum
 */
void ComptonScatteringCountRate::createPositivityCM(const MantidVec &xValues) {
  // -- Constraint matrix for J(y) > 0 --
  // The first N columns are filled with J(y) for each mass + N_h for the first
  // mass hermite
  // terms included + (n+1) for each termn the background of order n
  // The background columns are filled with x^j/error where j=(1,n+1)
  const size_t nrows(xValues.size());
  size_t nColsCMatrix(m_fixedParamIndices.size());
  m_cmatrix = Kernel::DblMatrix(nrows, nColsCMatrix);

  // Fill background values as they don't change at all
  if (m_bkgdPolyN > 0) {
    size_t polyStartCol = nColsCMatrix - m_bkgdPolyN - 1;
    for (size_t i = 0; i < nrows; ++i) // rows
    {
      double *row = m_cmatrix[i];
      const double &xi = xValues[i];
      const double &erri = m_errors[i];
      size_t polyN = m_bkgdPolyN;
      for (size_t j = polyStartCol; j < nColsCMatrix; ++j) // cols
      {
        row[j] = std::pow(xi, static_cast<double>(polyN)) / erri;
        --polyN;
      }
    }
  }
}
示例#20
0
文件: Divide.cpp 项目: mcvine/mantid
void Divide::performBinaryOperation(const MantidVec &lhsX,
                                    const MantidVec &lhsY,
                                    const MantidVec &lhsE, const double rhsY,
                                    const double rhsE, MantidVec &YOut,
                                    MantidVec &EOut) {
  (void)lhsX; // Avoid compiler warning

  if (rhsY == 0 && m_warnOnZeroDivide)
    g_log.warning() << "Division by zero: the RHS is a single-valued vector "
                       "with value zero."
                    << "\n";

  // Do the right-hand part of the error calculation just once
  const double rhsFactor = pow(rhsE / rhsY, 2);
  const int bins = static_cast<int>(lhsE.size());
  for (int j = 0; j < bins; ++j) {
    // Get reference to input Y
    const double leftY = lhsY[j];

    // see comment in the function above for the error formula
    EOut[j] = sqrt(pow(lhsE[j], 2) + pow(leftY, 2) * rhsFactor) / fabs(rhsY);
    // Copy the result last in case one of the input workspaces is also any
    // output
    YOut[j] = leftY / rhsY;
  }
}
/// Returns vector with x-values of spectrum if MatrixWorkspace contains
/// histogram data.
MantidVec FunctionDomain1DSpectrumCreator::getVectorHistogram() const {
  const MantidVec wsXData = m_matrixWorkspace->readX(m_workspaceIndex);
  size_t wsXSize = wsXData.size();

  if (wsXSize < 2) {
    throw std::invalid_argument("Histogram Workspace2D with less than two "
                                "x-values cannot be processed.");
  }

  MantidVec x(wsXSize - 1);

  for (size_t i = 0; i < x.size(); ++i) {
    x[i] = (wsXData[i] + wsXData[i + 1]) / 2.0;
  }

  return x;
}
示例#22
0
/** Read the specified number of entries from input file into the
*  the array that is passed
*  @param[in] nEntries the number of numbers to read
*  @param[out] output the contents of this will be replaced by the data read from the file
*/
void LoadRKH::readNumEntrys(const int nEntries, MantidVec & output)
{
    output.resize(nEntries);
    for( int i = 0; i < nEntries; ++i )
    {
        m_fileIn >> output[i];
    }
}
示例#23
0
/** Calculates Sn as estimator of scale for given vector
  *
  * This method implements a naive calculation of Sn, as defined by Rousseeuw
  *and Croux (http://dx.doi.org/10.2307%2F2291267).
  * In contrast to standard deviation, this is more robust towards outliers.
  *
  * @param begin :: Beginning of vector.
  * @param end :: End of vector.
  * @return Sn of supplied data.
  */
double PoldiPeakSearch::getSn(MantidVec::const_iterator begin,
                              MantidVec::const_iterator end) const {
  size_t numberOfPoints = std::distance(begin, end);
  MantidVec absoluteDifferenceMedians(numberOfPoints);

  PARALLEL_FOR_NO_WSP_CHECK()
  for (int i = 0; i < static_cast<int>(numberOfPoints); ++i) {
    double currentValue = *(begin + i);
    MantidVec temp;
    temp.reserve(numberOfPoints - 1);
    for (int j = 0; j < static_cast<int>(numberOfPoints); ++j) {
      if (j != i) {
        temp.push_back(fabs(*(begin + j) - currentValue));
      }
    }
    std::sort(temp.begin(), temp.end());

    absoluteDifferenceMedians[i] =
        getMedianFromSortedVector(temp.begin(), temp.end());
  }

  std::sort(absoluteDifferenceMedians.begin(), absoluteDifferenceMedians.end());

  return 1.1926 * getMedianFromSortedVector(absoluteDifferenceMedians.begin(),
                                            absoluteDifferenceMedians.end());
}
示例#24
0
/** Retrieves a vector with all counts that belong to the background
  *
  * In this method, a vector is assembled which contains all count data that is
  *considered to be background.
  * Whether a point is considered background depends on its distance to the
  *given peak positions.
  *
  * @param peakPositions :: Peak positions.
  * @param correlationCounts :: Vector with the complete correlation spectrum.
  * @return Vector only with counts that belong to the background.
  */
MantidVec PoldiPeakSearch::getBackground(
    std::list<MantidVec::const_iterator> peakPositions,
    const MantidVec &correlationCounts) const {
  size_t backgroundPoints =
      getNumberOfBackgroundPoints(peakPositions, correlationCounts);

  MantidVec background;
  background.reserve(backgroundPoints);

  for (MantidVec::const_iterator point = correlationCounts.begin() + 1;
       point != correlationCounts.end() - 1; ++point) {
    if (distanceToPeaksGreaterThanMinimum(peakPositions, point)) {
      background.push_back(*point);
    }
  }

  return background;
}
示例#25
0
/** Write data in SLOG format
  */
void SaveGSS::writeSLOGdata(const int bank, const bool MultiplyByBinWidth,
                            std::stringstream &out, const MantidVec &X,
                            const MantidVec &Y, const MantidVec &E) const {
  const size_t datasize = Y.size();
  double bc1 = X.front(); // minimum TOF in microseconds
  if (bc1 <= 0.) {
    throw std::runtime_error(
        "Cannot write out logarithmic data starting at zero");
  }
  double bc2 = 0.5 * (*(X.rbegin()) +
                      *(X.rbegin() + 1));      // maximum TOF (in microseconds?)
  double bc3 = (*(X.begin() + 1) - bc1) / bc1; // deltaT/T

  g_log.debug() << "SaveGSS(): Min TOF = " << bc1 << std::endl;

  writeBankLine(out, "SLOG", bank, datasize);
  out << std::fixed << " " << std::setprecision(0) << std::setw(10) << bc1
      << std::fixed << " " << std::setprecision(0) << std::setw(10) << bc2
      << std::fixed << " " << std::setprecision(7) << std::setw(10) << bc3
      << std::fixed << " 0 FXYE" << std::endl;

  for (size_t i = 0; i < datasize; i++) {
    double y = Y[i];
    double e = E[i];
    if (MultiplyByBinWidth) {
      // Multiple by bin width as
      double delta = X[i + 1] - X[i];
      y *= delta;
      e *= delta;
    }
    e = fixErrorValue(e);

    out << "  " << std::fixed << std::setprecision(9) << std::setw(20)
        << 0.5 * (X[i] + X[i + 1]) << "  " << std::fixed << std::setprecision(9)
        << std::setw(20) << y << "  " << std::fixed << std::setprecision(9)
        << std::setw(20) << e << std::setw(12) << " "
        << "\n"; // let it flush its own buffer
  }
  out << std::flush;

  return;
}
示例#26
0
    void PoissonErrors::performBinaryOperation(const MantidVec& lhsX, const MantidVec& lhsY, const MantidVec& lhsE,
                                               const double rhsY, const double rhsE, MantidVec& YOut, MantidVec& EOut)
    {
      (void) lhsE; (void) lhsX; //Avoid compiler warning

      assert( lhsX.size() == 1 );
      // If we get here we've got two single column workspaces so it's easy.
      YOut[0] = lhsY[0];
      
      const double fractional = rhsY ? rhsE/rhsY : 0.0;
      EOut[0] = fractional*lhsY[0];
    }
示例#27
0
文件: FFT.cpp 项目: liyulun/mantid
/**
 * Returns the phase shift to apply
 * If "AutoShift" is set, calculates this automatically as -X[N/2]
 * Otherwise, returns user-supplied "Shift" (or zero if none set)
 * @param xValues :: [input] Reference to X values of input workspace
 * @returns :: Phase shift
 */
double FFT::getPhaseShift(const MantidVec &xValues) {
  double shift = 0.0;
  const bool autoshift = getProperty("AutoShift");
  if (autoshift) {
    const size_t mid = xValues.size() / 2;
    shift = -xValues[mid];
  } else {
    shift = getProperty("Shift");
  }
  shift *= 2 * M_PI;
  return shift;
}
示例#28
0
/** Zeroes data (Y/E) at the end of a spectrum
 *  @param start :: The index to start zeroing at
 *  @param end ::   The index to end zeroing at
 *  @param Y ::     The data vector
 *  @param E ::     The error vector
 */
void RemoveBins::RemoveFromEnds(int start, int end, MantidVec& Y, MantidVec& E)
{
  if ( start ) --start;
  int size = static_cast<int>(Y.size());
  if ( end > size ) end = size;
  for (int j = start; j < end; ++j)
  {
    Y[j] = 0.0;
    E[j] = 0.0;
  }

  return;
}
示例#29
0
文件: Q1D2.cpp 项目: trnielsen/mantid
/** Divides the number of counts in each output Q bin by the wrighting ("number that would expected to arrive")
*  The errors are propogated using the uncorrolated error estimate for multiplication/division
*  @param[in] normSum the weighting for each bin
*  @param[in] normError2 square of the error on the normalization
*  @param[in, out] counts counts in each bin
*  @param[in, out] errors input the _square_ of the error on each bin, output the total error (unsquared)
*/
void Q1D2::normalize(const MantidVec & normSum, const MantidVec & normError2, MantidVec & counts, MantidVec & errors) const
{
  for (size_t k = 0; k < counts.size(); ++k)
  {
    // the normalisation is a = b/c where b = counts c =normalistion term
    const double c = normSum[k];
    const double a = counts[k] /= c;
    // when a = b/c, the formula for Da, the error on a, in terms of Db, etc. is (Da/a)^2 = (Db/b)^2 + (Dc/c)^2
    //(Da)^2 = ((Db/b)^2 + (Dc/c)^2)*(b^2/c^2) = ((Db/c)^2 + (b*Dc/c^2)^2) = (Db^2 + (b*Dc/c)^2)/c^2 = (Db^2 + (Dc*a)^2)/c^2
    //this will work as long as c>0, but then the above formula above can't deal with 0 either
    const double aOverc = a/c;
    errors[k] = std::sqrt(errors[k]/(c*c) + normError2[k]*aOverc*aOverc);
  }
}
/**
 * Calculate detector efficiency given a formula, the efficiency at the elastic line,
 * and a vector with energies.
 *  Efficiency = f(Ei-DeltaE) / f(Ei)
 * Hope all compilers supports the NRVO (otherwise will copy the output vector)
 * @param eff0 :: calculated eff0
 * @param formula :: formula to calculate efficiency (parsed from IDF)
 * @param xIn :: Energy bins vector (X axis)
 * @return a vector with the efficiencies
 */
MantidVec DetectorEfficiencyCorUser::calculateEfficiency(double eff0,
		const std::string& formula, const MantidVec& xIn) {

	MantidVec effOut(xIn.size() - 1); // x are bins and have more one value than y

	try {
		double e;
		mu::Parser p;
		p.DefineVar("e", &e);
		p.SetExpr(formula);

		// copied from Jaques Ollivier Code
		bool conditionForEnergy = std::min( std::abs( *std::min_element(xIn.begin(), xIn.end()) ) , m_Ei) < m_Ei;

		MantidVec::const_iterator xIn_it = xIn.begin(); // DeltaE
		MantidVec::iterator effOut_it = effOut.begin();
		for (; effOut_it != effOut.end(); ++xIn_it, ++effOut_it) {
			if (conditionForEnergy ) {
        // cppcheck cannot see that this is used by reference by muparser
        e =  std::fabs(m_Ei + *xIn_it);
			}
			else {
        // cppcheck cannot see that this is used by reference by muparser
        // cppcheck-suppress unreadVariable
				e =  std::fabs(m_Ei - *xIn_it);
			}
			double eff = p.Eval();
			*effOut_it = eff / eff0;
		}
		return effOut;
	} catch (mu::Parser::exception_type &e) {
		throw Kernel::Exception::InstrumentDefinitionError(
				"Error calculating formula from string. Muparser error message is: "
						+ e.GetMsg());
	}

}