コード例 #1
0
ファイル: ReferenceFrame.cpp プロジェクト: DanNixon/mantid
/**
Convenience method for checking whether or not a vector is aligned
with the along beam vector.
@param v vector to be tested against along beam vector
@return result of whther the along beam and test vector are parallel.
*/
bool ReferenceFrame::isVectorPointingAlongBeam(const V3D &v) const {
  V3D vec = v;
  vec.normalize();

  // Normalized (unit) parallel vectors should produce a scalar product of 1
  return m_vecPointingAlongBeam.scalar_prod(vec) == 1;
}
コード例 #2
0
 void CacheGeometryRenderer::Initialize(int noPts, int noFaces, double* points, int* faces)const
 {
   (void) noPts; //Avoid compiler warning
   if (!boolDisplaylistCreated || glIsList(iDisplaylistId) == GL_FALSE)
   {
     iDisplaylistId = glGenLists(1);
     glNewList(iDisplaylistId, GL_COMPILE); //Construct display list for object representation
     glBegin(GL_TRIANGLES);
     int index1, index2, index3;
     V3D normal;
     for (int i = 0; i < noFaces; i++)
     {
       index1 = faces[i * 3] * 3;
       index2 = faces[i * 3 + 1] * 3;
       index3 = faces[i * 3 + 2] * 3;
       //Calculate normal and normalize
       V3D v1(points[index1], points[index1 + 1], points[index1 + 2]);
       V3D v2(points[index2], points[index2 + 1], points[index2 + 2]);
       V3D v3(points[index3], points[index3 + 1], points[index3 + 2]);
       normal = (v1 - v2).cross_prod(v2 - v3);
       normal.normalize();
       glNormal3d(normal[0], normal[1], normal[2]);
       glVertex3dv(points + index1);
       glVertex3dv(points + index2);
       glVertex3dv(points + index3);
     }
     glEnd();
     glEndList();
     boolDisplaylistCreated = true;
   }
 }
コード例 #3
0
ファイル: test_mlp.cpp プロジェクト: raghavkhanna/rovio
  MLPTesting(): c_(&camera_){
    static_assert(imgSize_*dx_*dy_<255,"imgSize to large for gradients");
    pixel_ = cv::Point2f(patchSize_/2+1,patchSize_/2+1);
    bearing_ = V3D(patchSize_/2+1,patchSize_/2+1,1);
    bearing_.normalize();
    c_.set_c(pixel_);
    warp_c_ << 0.1, 0.5, 0.7, -0.2;
    c_.set_warp_c(warp_c_);
    warp_nor_ = c_.get_warp_nor();

    stat_.localQualityRange_ = 3;
    stat_.localVisibilityRange_ = 4;
    stat_.minGlobalQualityRange_ = 5;

    img1_ = cv::Mat::zeros(imgSize_,imgSize_,CV_8UC1);
    uint8_t* img_ptr = (uint8_t*) img1_.data;
    for(int i=0;i<imgSize_;i++){
      for(int j=0;j<imgSize_;j++, ++img_ptr){
        *img_ptr = i*dy_+j*dx_;
      }
    }
    img2_ = cv::Mat::zeros(imgSize_,imgSize_,CV_8UC1);
    img_ptr = (uint8_t*) img2_.data;
    for(int i=0;i<imgSize_;i++){
      for(int j=0;j<imgSize_;j++, ++img_ptr){
        if(j<imgSize_/2 & i<imgSize_/2){
          *img_ptr = 0;
        } else {
          *img_ptr = 255;
        }
      }
    }
    pyr1_.computeFromImage(img1_);
    pyr2_.computeFromImage(img2_);
  }
コード例 #4
0
ファイル: PeaksOnSurface.cpp プロジェクト: spaceyatom/mantid
bool lineIntersectsSphere(const V3D &line, const V3D &lineStart,
                          const V3D &peakCenter, const double peakRadius) {
  V3D peakToStart = peakCenter - lineStart;
  V3D unitLine = line;
  unitLine.normalize();
  double proj = peakToStart.scalar_prod(unitLine); // All we are doing here is
                                                   // projecting the peak to
                                                   // segment start vector onto
                                                   // the segment itself.

  V3D closestPointOnSegment;
  if (proj <= 0) // The projection is outside the segment. So use the start
                 // point of the segment.
  {
    closestPointOnSegment = lineStart; // Start of line
  } else if (proj >= line.norm()) // The projection is greater than the segment
                                  // length. So use the end point of the
                                  // segment.
  {
    closestPointOnSegment = lineStart + line; // End of line.
  } else // The projection falls somewhere between the start and end of the line
         // segment.
  {
    V3D projectionVector = unitLine * proj;
    closestPointOnSegment = projectionVector + lineStart;
  }

  return (peakCenter - closestPointOnSegment).norm() <= peakRadius;
}
コード例 #5
0
/**
 * Creates a Cube
 * @param Point1 :: first point of the cube
 * @param Point2 :: second point of the cube
 * @param Point3 :: thrid point of the cube
 * @param Point4 :: fourth point of the cube
 */
void GluGeometryRenderer::CreateCube(const V3D &Point1, const V3D &Point2,
                                     const V3D &Point3, const V3D &Point4) {
  V3D vec0 = Point1;
  V3D vec1 = Point2 - Point1;
  V3D vec2 = Point3 - Point1;
  V3D vec3 = Point4 - Point1;
  V3D vertex[8];
  vertex[0] = vec0;
  vertex[1] = vec0 + vec3;
  vertex[2] = vec0 + vec3 + vec1;
  vertex[3] = vec0 + vec1;
  vertex[4] = vec0 + vec2;
  vertex[5] = vec0 + vec2 + vec3;
  vertex[6] = vec0 + vec2 + vec3 + vec1;
  vertex[7] = vec0 + vec1 + vec2;
  // int
  // faceindex[6][4]={{0,1,2,3},{0,3,7,4},{3,2,6,7},{2,1,5,6},{0,4,5,1},{4,7,6,5}};
  // int
  // faceindex[6][4]={{0,3,2,1},{0,4,7,3},{3,7,6,2},{2,6,5,1},{0,1,5,4},{4,5,6,7}};
  int faceindex[6][4] = {
      {0, 1, 2, 3}, // top
      {0, 3, 7, 4}, // left
      {3, 2, 6, 7}, // back
      {2, 1, 5, 6}, // right
      {0, 4, 5, 1}, // front
      {4, 7, 6, 5}, // bottom
  };
  V3D normal;
  // first face
  glBegin(GL_QUADS);
  for (auto &row : faceindex) {
    normal = (vertex[row[0]] - vertex[row[1]])
                 .cross_prod((vertex[row[0]] - vertex[row[2]]));
    normal.normalize();
    glNormal3d(normal[0], normal[1], normal[2]);
    for (int j = 0; j < 4; j++) {
      int ij = row[j];
      if (ij == 0)
        glTexCoord2i(0, 0);
      if (ij == 1)
        glTexCoord2i(1, 0);
      if (ij == 2)
        glTexCoord2i(1, 1);
      if (ij == 3)
        glTexCoord2i(0, 1);
      if (ij == 4)
        glTexCoord2i(0, 0);
      if (ij == 5)
        glTexCoord2i(1, 0);
      if (ij == 6)
        glTexCoord2i(1, 1);
      if (ij == 7)
        glTexCoord2i(0, 1);
      glVertex3d(vertex[ij][0], vertex[ij][1], vertex[ij][2]);
    }
  }
  glEnd();
}
コード例 #6
0
/**
 * Calculate the attenuation correction factor the volume given a start and
 * end point.
 * @param rng A reference to a PseudoRandomNumberGenerator producing
 * random number between [0,1]
 * @param startPos Origin of the initial track
 * @param endPos Final position of neutron after scattering (assumed to be
 * outside of the "volume")
 * @param lambdaBefore Wavelength, in \f$\\A^-1\f$, before scattering
 * @param lambdaAfter Wavelength, in \f$\\A^-1\f$, after scattering
 * @return The fraction of the beam that has been attenuated. A negative number
 * indicates the track was not valid.
 */
double MCInteractionVolume::calculateAbsorption(
    Kernel::PseudoRandomNumberGenerator &rng, const Kernel::V3D &startPos,
    const Kernel::V3D &endPos, double lambdaBefore, double lambdaAfter) const {
  // Generate scatter point. If there is an environment present then
  // first select whether the scattering occurs on the sample or the
  // environment. The attenuation for the path leading to the scatter point
  // is calculated in reverse, i.e. defining the track from the scatter pt
  // backwards for simplicity with how the Track object works. This avoids
  // having to understand exactly which object the scattering occurred in.
  V3D scatterPos;
  if (m_env && (rng.nextValue() > 0.5)) {
    scatterPos =
        m_env->generatePoint(rng, m_activeRegion, MAX_SCATTER_ATTEMPTS);
  } else {
    scatterPos = m_sample.generatePointInObject(rng, m_activeRegion,
                                                MAX_SCATTER_ATTEMPTS);
  }
  auto toStart = startPos - scatterPos;
  toStart.normalize();
  Track beforeScatter(scatterPos, toStart);
  int nlinks = m_sample.interceptSurface(beforeScatter);
  if (m_env) {
    nlinks += m_env->interceptSurfaces(beforeScatter);
  }
  // This should not happen but numerical precision means that it can
  // occasionally occur with tracks that are very close to the surface
  if (nlinks == 0) {
    return -1.0;
  }

  // Function to calculate total attenuation for a track
  auto calculateAttenuation = [](const Track &path, double lambda) {
    double factor(1.0);
    for (const auto &segment : path) {
      const double length = segment.distInsideObject;
      const auto &segObj = *(segment.object);
      const auto &segMat = segObj.material();
      factor *= attenuation(segMat.numberDensity(),
                            segMat.totalScatterXSection(lambda) +
                                segMat.absorbXSection(lambda),
                            length);
    }
    return factor;
  };

  // Now track to final destination
  V3D scatteredDirec = endPos - scatterPos;
  scatteredDirec.normalize();
  Track afterScatter(scatterPos, scatteredDirec);
  m_sample.interceptSurface(afterScatter);
  if (m_env) {
    m_env->interceptSurfaces(afterScatter);
  }
  return calculateAttenuation(beforeScatter, lambdaBefore) *
         calculateAttenuation(afterScatter, lambdaAfter);
}
コード例 #7
0
/// Calculate the distances traversed by the neutrons within the sample
/// @param detector :: The detector we are working on
/// @param L2s :: A vector of the sample-detector distance for  each segment of
/// the sample
void AbsorptionCorrection::calculateDistances(const IDetector &detector,
                                              std::vector<double> &L2s) const {
  V3D detectorPos(detector.getPos());
  if (detector.nDets() > 1) {
    // We need to make sure this is right for grouped detectors - should use
    // average theta & phi
    detectorPos.spherical(detectorPos.norm(),
                          detector.getTwoTheta(V3D(), V3D(0, 0, 1)) * 180.0 /
                              M_PI,
                          detector.getPhi() * 180.0 / M_PI);
  }

  for (size_t i = 0; i < m_numVolumeElements; ++i) {
    // Create track for distance in cylinder between scattering point and
    // detector
    V3D direction = detectorPos - m_elementPositions[i];
    direction.normalize();
    Track outgoing(m_elementPositions[i], direction);
    int temp = m_sampleObject->interceptSurface(outgoing);

    /* Most of the time, the number of hits is 1. Sometime, we have more than
     * one intersection due to
     * arithmetic imprecision. If it is the case, then selecting the first
     * intersection is valid.
     * In principle, one could check the consistency of all distances if hits is
     * larger than one by doing:
     * Mantid::Geometry::Track::LType::const_iterator it=outgoing.begin();
     * and looping until outgoing.end() checking the distances with it->Dist
     */
    // Not hitting the cylinder from inside, usually means detector is badly
    // defined,
    // i.e, position is (0,0,0).
    if (temp < 1) {
      // FOR NOW AT LEAST, JUST IGNORE THIS ERROR AND USE A ZERO PATH LENGTH,
      // WHICH I RECKON WILL MAKE A
      // NEGLIGIBLE DIFFERENCE ANYWAY (ALWAYS SEEMS TO HAPPEN WITH ELEMENT RIGHT
      // AT EDGE OF SAMPLE)
      L2s[i] = 0.0;

      // std::ostringstream message;
      // message << "Problem with detector at " << detectorPos << " ID:" <<
      // detector->getID() << '\n';
      // message << "This usually means that this detector is defined inside the
      // sample cylinder";
      // g_log.error(message.str());
      // throw std::runtime_error("Problem in
      // AbsorptionCorrection::calculateDistances");
    } else // The normal situation
    {
      L2s[i] = outgoing.cbegin()->distFromStart;
    }
  }
}
コード例 #8
0
/**  Set the U rotation matrix, to provide the transformation, which translate
  *an
  *  arbitrary vector V expressed in RLU (hkl)
  *  into another coordinate system defined by vectors u and v, expressed in RLU
  *(hkl)
  *  Author: Alex Buts
  *  @param u :: first vector of new coordinate system (in hkl units)
  *  @param v :: second vector of the new coordinate system
  *  @return the U matrix calculated
  *  The transformation from old coordinate system to new coordinate system is
  *performed by
  *  the whole UB matrix
  **/
const DblMatrix &OrientedLattice::setUFromVectors(const V3D &u, const V3D &v) {
  const DblMatrix &BMatrix = this->getB();
  V3D buVec = BMatrix * u;
  V3D bvVec = BMatrix * v;
  // try to make an orthonormal system
  if (buVec.norm2() < 1e-10)
    throw std::invalid_argument("|B.u|~0");
  if (bvVec.norm2() < 1e-10)
    throw std::invalid_argument("|B.v|~0");
  buVec.normalize(); // 1st unit vector, along Bu
  V3D bwVec = buVec.cross_prod(bvVec);
  if (bwVec.normalize() < 1e-5)
    throw std::invalid_argument(
        "u and v are parallel"); // 3rd unit vector, perpendicular to Bu,Bv
  bvVec = bwVec.cross_prod(
      buVec); // 2nd unit vector, perpendicular to Bu, in the Bu,Bv plane
  DblMatrix tau(3, 3), lab(3, 3), U(3, 3);
  /*lab      = U tau
  / 0 1 0 \     /bu[0] bv[0] bw[0]\
  | 0 0 1 | = U |bu[1] bv[1] bw[1]|
  \ 1 0 0 /     \bu[2] bv[2] bw[2]/
   */
  lab[0][1] = 1.;
  lab[1][2] = 1.;
  lab[2][0] = 1.;
  tau[0][0] = buVec[0];
  tau[0][1] = bvVec[0];
  tau[0][2] = bwVec[0];
  tau[1][0] = buVec[1];
  tau[1][1] = bvVec[1];
  tau[1][2] = bwVec[1];
  tau[2][0] = buVec[2];
  tau[2][1] = bvVec[2];
  tau[2][2] = bwVec[2];
  tau.Invert();
  U = lab * tau;
  this->setU(U);
  return getU();
}
コード例 #9
0
/**
 * Generate a random position within the final detector in the lab frame
 * @param nominalPos The poisiton of the centre point of the detector
 * @param energy The final energy of the neutron
 * @param scatterPt The position of the scatter event that lead to this
 * detector
 * @param direcBeforeSc Directional vector that lead to scatter point that hit
 * this detector
 * @param scang [Output] The value of the scattering angle for the generated
 * point
 * @param distToExit [Output] The distance covered within the object from
 * scatter to exit
 * @return A new position in the detector
 */
V3D VesuvioCalculateMS::generateDetectorPos(
    const V3D &nominalPos, const double energy, const V3D &scatterPt,
    const V3D &direcBeforeSc, double &scang, double &distToExit) const {
  // Inverse attenuation length (m-1) for vesuvio det.
  const double mu = 7430.0 / sqrt(energy);
  // Probability of detection in path thickness.
  const double ps = 1.0 - exp(-mu * m_detThick);
  V3D detPos;
  scang = 0.0;
  distToExit = 0.0;
  size_t ntries(0);
  do {
    // Beam direction by moving to front of "box"define by detector dimensions
    // and then
    // computing expected distance travelled based on probability
    detPos[m_beamIdx] = (nominalPos[m_beamIdx] - 0.5 * m_detThick) -
                        (log(1.0 - m_randgen->flat() * ps) / mu);
    // perturb away from nominal position
    detPos[m_acrossIdx] =
        nominalPos[m_acrossIdx] + (m_randgen->flat() - 0.5) * m_detWidth;
    detPos[m_upIdx] =
        nominalPos[m_upIdx] + (m_randgen->flat() - 0.5) * m_detHeight;

    // Distance to exit the sample for this order
    V3D scToDet = detPos - scatterPt;
    scToDet.normalize();
    Geometry::Track scatterToDet(scatterPt, scToDet);
    if (m_sampleShape->interceptSurface(scatterToDet) > 0) {
      scang = direcBeforeSc.angle(scToDet);
      const auto &link = scatterToDet.cbegin();
      distToExit = link->distInsideObject;
      break;
    }
    // if point is very close surface then there may be no valid intercept so
    // try again
    ++ntries;
  } while (ntries < MAX_SCATTER_PT_TRIES);
  if (ntries == MAX_SCATTER_PT_TRIES) {
    // Assume it is very close to the surface so that the distance travelled
    // would
    // be a neglible contribution
    distToExit = 0.0;
  }
  return detPos;
}
コード例 #10
0
void CacheGeometryRenderer::Initialize(int noPts, int noFaces, double *points,
                                       int *faces) const {
  (void)noPts; // Avoid compiler warning
  glBegin(GL_TRIANGLES);
  V3D normal;
  for (int i = 0; i < noFaces; i++) {
    int index1 = faces[i * 3] * 3;
    int index2 = faces[i * 3 + 1] * 3;
    int index3 = faces[i * 3 + 2] * 3;
    // Calculate normal and normalize
    V3D v1(points[index1], points[index1 + 1], points[index1 + 2]);
    V3D v2(points[index2], points[index2 + 1], points[index2 + 2]);
    V3D v3(points[index3], points[index3 + 1], points[index3 + 2]);
    normal = (v1 - v2).cross_prod(v2 - v3);
    normal.normalize();
    glNormal3d(normal[0], normal[1], normal[2]);
    glVertex3dv(points + index1);
    glVertex3dv(points + index2);
    glVertex3dv(points + index3);
  }
  glEnd();
}
コード例 #11
0
/** Corrects a spectra for the detector efficiency calculated from detector information
Gets the detector information and uses this to calculate its efficiency
*  @param spectraIn :: 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 DetectorEfficiencyCor::correctForEfficiency(int64_t spectraIn)
{
  IDetector_const_sptr det = m_inputWS->getDetector(spectraIn);
  if( det->isMonitor() || det->isMasked() )
  {
    return;
  }

  MantidVec & yout = m_outputWS->dataY(spectraIn);
  MantidVec & eout = m_outputWS->dataE(spectraIn);
  // Need the original values so this is not a reference
  const MantidVec yValues = m_inputWS->readY(spectraIn);
  const MantidVec eValues = m_inputWS->readE(spectraIn);

  // get a pointer to the detectors that created the spectrum
  const std::set<detid_t> dets = m_inputWS->getSpectrum(spectraIn)->getDetectorIDs();

  std::set<detid_t>::const_iterator it = dets.begin();
  std::set<detid_t>::const_iterator iend = dets.end();
  if ( it == iend )
  {
    throw Exception::NotFoundError("No detectors found", spectraIn);
  }
  
  // Storage for the reciprocal wave vectors that are calculated as the 
  //correction proceeds
  std::vector<double> oneOverWaveVectors(yValues.size());
  for( ; it != iend ; ++it )
  {
    IDetector_const_sptr det_member = m_inputWS->getInstrument()->getDetector(*it);
    
    Parameter_sptr par = m_paraMap->get(det_member.get(),"3He(atm)");
    if ( !par )
    {
      throw Exception::NotFoundError("3He(atm)", spectraIn);
    }
    const double atms = par->value<double>();
    par = m_paraMap->get(det_member.get(),"wallT(m)");
    if ( !par )
    {
      throw Exception::NotFoundError("wallT(m)", spectraIn);
    }
    const double wallThickness = par->value<double>();
    double detRadius(0.0);
    V3D detAxis;
    getDetectorGeometry(det_member, detRadius, detAxis);

   // now get the sin of the angle, it's the magnitude of the cross product of unit vector along the detector tube axis and a unit vector directed from the sample to the detector centre
    V3D vectorFromSample = det_member->getPos() - m_samplePos;
    vectorFromSample.normalize();
    Quat rot = det_member->getRotation();
    // rotate the original cylinder object axis to get the detector axis in the actual instrument
    rot.rotate(detAxis); 
    detAxis.normalize();
    // Scalar product is quicker than cross product
    double cosTheta = detAxis.scalar_prod(vectorFromSample);
    double sinTheta = std::sqrt(1.0 - cosTheta*cosTheta);
    // Detector constant
    const double det_const = g_helium_prefactor*(detRadius - wallThickness)*atms/sinTheta;

    MantidVec::const_iterator yinItr = yValues.begin();
    MantidVec::const_iterator einItr = eValues.begin();
    MantidVec::iterator youtItr = yout.begin();
    MantidVec::iterator eoutItr = eout.begin();
    MantidVec::const_iterator xItr = m_inputWS->readX(spectraIn).begin();
    std::vector<double>::iterator wavItr = oneOverWaveVectors.begin();

    for( ; youtItr != yout.end(); ++youtItr, ++eoutItr)
    {
      if( it == dets.begin() )
      {
        *youtItr = 0.0;
        *eoutItr = 0.0;
        *wavItr = calculateOneOverK(*xItr, *(xItr + 1 ));
      }
      const double oneOverWave = *wavItr;
      const double factor = 1.0/detectorEfficiency(det_const*oneOverWave);
      *youtItr += (*yinItr)*factor;
      *eoutItr += (*einItr)*factor;
      ++yinItr; ++einItr;
      ++xItr; ++wavItr;
    }
  }
}
コード例 #12
0
  /** Execute the algorithm.
   */
  void SaveIsawPeaks::exec()
  {
    // Section header
    std::string header = "2   SEQN    H    K    L     COL      ROW     CHAN        L2   2_THETA        AZ         WL         D      IPK          INTI    SIGI  RFLG";

    std::string filename = getPropertyValue("Filename");
    PeaksWorkspace_sptr ws = getProperty("InputWorkspace");
    std::vector<Peak> peaks = ws->getPeaks();

    // We must sort the peaks first by run, then bank #, and save the list of workspace indices of it
    typedef std::map<int, std::vector<size_t> > bankMap_t;
    typedef std::map<int, bankMap_t> runMap_t;
    std::set<int> uniqueBanks;
    runMap_t runMap;

    for (size_t i=0; i < peaks.size(); ++i)
    {
      Peak & p = peaks[i];
      int run = p.getRunNumber();
      int bank = 0;
      std::string bankName = p.getBankName();
      if (bankName.size() <= 4)
      {
        g_log.information() << "Could not interpret bank number of peak " << i << "(" << bankName << ")\n";
        continue;
      }
      // Take out the "bank" part of the bank name and convert to an int
      bankName = bankName.substr(4, bankName.size()-4);
      Strings::convert(bankName, bank);

      // Save in the map
      runMap[run][bank].push_back(i);
      // Track unique bank numbers
      uniqueBanks.insert(bank);
    }

    Instrument_const_sptr inst = ws->getInstrument();
    if (!inst) throw std::runtime_error("No instrument in PeaksWorkspace. Cannot save peaks file.");

    double l1; V3D beamline; double beamline_norm; V3D samplePos;
    inst->getInstrumentParameters(l1, beamline, beamline_norm, samplePos);

    std::ofstream out;
    bool append = getProperty("AppendFile");
    if (append)
    {
      out.open( filename.c_str(), std::ios::app);
    }
    else
    {
      out.open( filename.c_str());


    out << "Version: 2.0  Facility: SNS " ;
    out <<  " Instrument: " <<  inst->getName() <<  "  Date: " ;

    //TODO: The experiment date might be more useful than the instrument date.
    // For now, this allows the proper instrument to be loaded back after saving.
    Kernel::DateAndTime expDate = inst->getValidFromDate() + 1.0;
    out <<  expDate.to_ISO8601_string() << std::endl;

    out << "6         L1    T0_SHIFT" <<  std::endl;
    out << "7 "<< std::setw( 10 )  ;
    out <<   std::setprecision( 4 ) <<  std::fixed <<  ( l1*100 ) ;
    out << std::setw( 12 ) <<  std::setprecision( 3 ) <<  std::fixed  ;
    // Time offset of 0.00 for now
    out << "0.000" <<  std::endl;


    // ============================== Save .detcal info =========================================
    if (true)
    {
      out <<  "4 DETNUM  NROWS  NCOLS   WIDTH   HEIGHT   DEPTH   DETD   CenterX   CenterY   CenterZ    BaseX    BaseY    BaseZ      UpX      UpY      UpZ"
          <<  std::endl;
      // Here would save each detector...
      std::set<int>::iterator it;
      for (it = uniqueBanks.begin(); it != uniqueBanks.end(); it++)
      {
        // Build up the bank name
        int bank = *it;
        std::ostringstream mess;
        mess << "bank" << bank;
        std::string bankName = mess.str();
        // Retrieve it
        RectangularDetector_const_sptr det = boost::dynamic_pointer_cast<const RectangularDetector>(inst->getComponentByName(bankName));
        if (det)
        {
          // Center of the detector
          V3D center = det->getPos();
          // Distance to center of detector
          double detd = (center - inst->getSample()->getPos()).norm();

          // Base unit vector (along the horizontal, X axis)
          V3D base = det->getAtXY(det->xpixels()-1,0)->getPos() - det->getAtXY(0,0)->getPos();
          base.normalize();
          // Up unit vector (along the vertical, Y axis)
          V3D up = det->getAtXY(0,det->ypixels()-1)->getPos() - det->getAtXY(0,0)->getPos();
          up.normalize();

          // Write the line
          out << "5 "
           << std::setw(6) << std::right << bank << " "
           << std::setw(6) << std::right << det->xpixels() << " "
           << std::setw(6) << std::right << det->ypixels() << " "
           << std::setw(7) << std::right << std::fixed << std::setprecision(4) << 100.0*det->xsize() << " "
           << std::setw(7) << std::right << std::fixed << std::setprecision(4) << 100.0*det->ysize() << " "
           << "  0.2000 "
           << std::setw(6) << std::right << std::fixed << std::setprecision(2) << 100.0*detd << " "
           << std::setw(9) << std::right << std::fixed << std::setprecision(4) << 100.0*center.X() << " "
           << std::setw(9) << std::right << std::fixed << std::setprecision(4) << 100.0*center.Y() << " "
           << std::setw(9) << std::right << std::fixed << std::setprecision(4) << 100.0*center.Z() << " "
           << std::setw(8) << std::right << std::fixed << std::setprecision(5) << base.X() << " "
           << std::setw(8) << std::right << std::fixed << std::setprecision(5) << base.Y() << " "
           << std::setw(8) << std::right << std::fixed << std::setprecision(5) << base.Z() << " "
           << std::setw(8) << std::right << std::fixed << std::setprecision(5) << up.X() << " "
           << std::setw(8) << std::right << std::fixed << std::setprecision(5) << up.Y() << " "
           << std::setw(8) << std::right << std::fixed << std::setprecision(5) << up.Z() << " "
           << std::endl;

        }
      }
    }
    }


    // ============================== Save all Peaks =========================================
    // Sequence number
    int seqNum = 1;

    // Go in order of run numbers
    runMap_t::iterator runMap_it;
    for (runMap_it = runMap.begin(); runMap_it != runMap.end(); runMap_it++)
    {
      // Start of a new run
      int run = runMap_it->first;
      bankMap_t & bankMap = runMap_it->second;

      bankMap_t::iterator bankMap_it;
      for (bankMap_it = bankMap.begin(); bankMap_it != bankMap.end(); bankMap_it++)
      {
        // Start of a new bank.
        int bank = bankMap_it->first;
        std::vector<size_t> & ids = bankMap_it->second;

        if (ids.size() > 0)
        {
          // Write the bank header
          out << "0 NRUN DETNUM    CHI      PHI    OMEGA   MONCNT" << std::endl;
          out <<  "1" <<  std::setw( 5 ) <<  run <<  std::setw( 7 ) <<
              std::right <<  bank;

          // Determine goniometer angles by calculating from the goniometer matrix of a peak in the list
          Goniometer gon(peaks[ids[0]].getGoniometerMatrix());
          std::vector<double> angles = gon.getEulerAngles("yzy");

          double phi = angles[2];
          double chi = angles[1];
          double omega = angles[0];

          out  <<  std::setw( 7 ) <<  std::fixed <<  std::setprecision( 2 )  <<  chi << " ";
          out  <<  std::setw( 7 ) <<  std::fixed <<  std::setprecision( 2 )  <<  phi << " ";
          out  <<  std::setw( 7 ) <<  std::fixed <<  std::setprecision( 2 )  <<  omega << " ";
          out  <<  std::setw( 7 ) <<  (int)( 0 ) <<  std::endl;

          out << header << std::endl;

          // Go through each peak at this run / bank
          for (size_t i=0; i < ids.size(); i++)
          {
            size_t wi = ids[i];
            Peak & p = peaks[wi];

            // Sequence (run) number
            out <<  "3" <<  std::setw( 7 ) << seqNum;

            // HKL is flipped by -1 due to different q convention in ISAW vs mantid.
            out <<  std::setw( 5 ) << Utils::round(-p.getH())
                <<  std::setw( 5 ) << Utils::round(-p.getK())
                <<  std::setw( 5 ) << Utils::round(-p.getL());

            // Row/column
            out <<  std::setw( 8 ) <<  std::fixed << std::setprecision( 2 )
              << static_cast<double>(p.getCol()) << " ";

            out << std::setw( 8 ) << std::fixed << std::setprecision( 2 )
              << static_cast<double>(p.getRow()) << " ";

            out << std::setw( 8 ) << std::fixed << std::setprecision( 0 )
              << p.getTOF() << " ";


            out << std::setw( 9 ) << std::fixed << std::setprecision( 3 )
              << (p.getL2()*100.0) << " ";

            // This is the scattered beam direction
            V3D dir = p.getDetPos() - inst->getSample()->getPos();
            double scattering, azimuth;

            // Two-theta = polar angle = scattering angle = between +Z vector and the scattered beam
            scattering = dir.angle( V3D(0.0, 0.0, 1.0) );

            // "Azimuthal" angle: project the beam onto the XY plane, and measure the angle between that and the +X axis (right-handed)
            azimuth = atan2( dir.Y(), dir.X() );

            out << std::setw( 9 ) << std::fixed << std::setprecision( 5 )
              << scattering << " "; //two-theta scattering

            out << std::setw( 9 ) << std::fixed << std::setprecision( 5 )
              << azimuth << " ";

            out << std::setw( 10 ) << std::fixed << std::setprecision( 6 )
              << p.getWavelength() << " ";

            out << std::setw( 9 ) << std::fixed << std::setprecision( 4 )
              << p.getDSpacing() << " ";

            out << std::setw( 8 ) << std::fixed << int(p.getBinCount()) << std::setw( 10 ) << " "
              << std::fixed << std::setprecision( 2 ) << p.getIntensity() << " ";

            out << std::setw( 7 ) << std::fixed << std::setprecision( 2 )
              << p.getSigmaIntensity() << " ";

            int thisReflag = 310;
            out << std::setw( 5 ) << thisReflag;

            out << std::endl;

            // Count the sequence
            seqNum++;
          }
        }
      }
    }

    out.flush();
    out.close();

//    //REMOVE:
//    std::string line;
//    std::ifstream myfile (filename.c_str());
//    if (myfile.is_open())
//    {
//      while ( myfile.good() )
//      {
//        getline (myfile,line);
//        std::cout << line << std::endl;
//      }
//      myfile.close();
//    }


  }
コード例 #13
0
void SofQWCentre::exec() {
  using namespace Geometry;

  MatrixWorkspace_const_sptr inputWorkspace = getProperty("InputWorkspace");

  // Do the full check for common binning
  if (!WorkspaceHelpers::commonBoundaries(*inputWorkspace)) {
    g_log.error(
        "The input workspace must have common binning across all spectra");
    throw std::invalid_argument(
        "The input workspace must have common binning across all spectra");
  }

  std::vector<double> verticalAxis;
  MatrixWorkspace_sptr outputWorkspace = setUpOutputWorkspace(
      inputWorkspace, getProperty("QAxisBinning"), verticalAxis);
  setProperty("OutputWorkspace", outputWorkspace);

  // Holds the spectrum-detector mapping
  std::vector<specnum_t> specNumberMapping;
  std::vector<detid_t> detIDMapping;

  m_EmodeProperties.initCachedValues(*inputWorkspace, this);
  int emode = m_EmodeProperties.m_emode;

  // Get a pointer to the instrument contained in the workspace
  Instrument_const_sptr instrument = inputWorkspace->getInstrument();

  // Get the distance between the source and the sample (assume in metres)
  IComponent_const_sptr source = instrument->getSource();
  IComponent_const_sptr sample = instrument->getSample();
  V3D beamDir = sample->getPos() - source->getPos();
  beamDir.normalize();

  try {
    double l1 = source->getDistance(*sample);
    g_log.debug() << "Source-sample distance: " << l1 << '\n';
  } catch (Exception::NotFoundError &) {
    g_log.error("Unable to calculate source-sample distance");
    throw Exception::InstrumentDefinitionError(
        "Unable to calculate source-sample distance",
        inputWorkspace->getTitle());
  }

  // Conversion constant for E->k. k(A^-1) = sqrt(energyToK*E(meV))
  const double energyToK = 8.0 * M_PI * M_PI * PhysicalConstants::NeutronMass *
                           PhysicalConstants::meV * 1e-20 /
                           (PhysicalConstants::h * PhysicalConstants::h);

  // Loop over input workspace bins, reassigning data to correct bin in output
  // qw workspace
  const size_t numHists = inputWorkspace->getNumberHistograms();
  const size_t numBins = inputWorkspace->blocksize();
  Progress prog(this, 0.0, 1.0, numHists);
  for (int64_t i = 0; i < int64_t(numHists); ++i) {
    try {
      // Now get the detector object for this histogram
      IDetector_const_sptr spectrumDet = inputWorkspace->getDetector(i);
      if (spectrumDet->isMonitor())
        continue;

      const double efixed = m_EmodeProperties.getEFixed(*spectrumDet);

      // For inelastic scattering the simple relationship q=4*pi*sinTheta/lambda
      // does not hold. In order to
      // be completely general we must calculate the momentum transfer by
      // calculating the incident and final
      // wave vectors and then use |q| = sqrt[(ki - kf)*(ki - kf)]
      DetectorGroup_const_sptr detGroup =
          boost::dynamic_pointer_cast<const DetectorGroup>(spectrumDet);
      std::vector<IDetector_const_sptr> detectors;
      if (detGroup) {
        detectors = detGroup->getDetectors();
      } else {
        detectors.push_back(spectrumDet);
      }

      const size_t numDets = detectors.size();
      // cache to reduce number of static casts
      const double numDets_d = static_cast<double>(numDets);
      const auto &Y = inputWorkspace->y(i);
      const auto &E = inputWorkspace->e(i);
      const auto &X = inputWorkspace->x(i);

      // Loop over the detectors and for each bin calculate Q
      for (size_t idet = 0; idet < numDets; ++idet) {
        IDetector_const_sptr det = detectors[idet];
        // Calculate kf vector direction and then Q for each energy bin
        V3D scatterDir = (det->getPos() - sample->getPos());
        scatterDir.normalize();
        for (size_t j = 0; j < numBins; ++j) {
          const double deltaE = 0.5 * (X[j] + X[j + 1]);
          // Compute ki and kf wave vectors and therefore q = ki - kf
          double ei(0.0), ef(0.0);
          if (emode == 1) {
            ei = efixed;
            ef = efixed - deltaE;
            if (ef < 0) {
              std::string mess =
                  "Energy transfer requested in Direct mode exceeds incident "
                  "energy.\n Found for det ID: " +
                  std::to_string(idet) + " bin No " + std::to_string(j) +
                  " with Ei=" + boost::lexical_cast<std::string>(efixed) +
                  " and energy transfer: " +
                  boost::lexical_cast<std::string>(deltaE);
              throw std::runtime_error(mess);
            }
          } else {
            ei = efixed + deltaE;
            ef = efixed;
            if (ef < 0) {
              std::string mess =
                  "Incident energy of a neutron is negative. Are you trying to "
                  "process Direct data in Indirect mode?\n Found for det ID: " +
                  std::to_string(idet) + " bin No " + std::to_string(j) +
                  " with efied=" + boost::lexical_cast<std::string>(efixed) +
                  " and energy transfer: " +
                  boost::lexical_cast<std::string>(deltaE);
              throw std::runtime_error(mess);
            }
          }

          if (ei < 0)
            throw std::runtime_error(
                "Negative incident energy. Check binning.");

          const V3D ki = beamDir * sqrt(energyToK * ei);
          const V3D kf = scatterDir * (sqrt(energyToK * (ef)));
          const double q = (ki - kf).norm();

          // Test whether it's in range of the Q axis
          if (q < verticalAxis.front() || q > verticalAxis.back())
            continue;
          // Find which q bin this point lies in
          const MantidVec::difference_type qIndex =
              std::upper_bound(verticalAxis.begin(), verticalAxis.end(), q) -
              verticalAxis.begin() - 1;

          // Add this spectra-detector pair to the mapping
          specNumberMapping.push_back(
              outputWorkspace->getSpectrum(qIndex).getSpectrumNo());
          detIDMapping.push_back(det->getID());

          // And add the data and it's error to that bin, taking into account
          // the number of detectors contributing to this bin
          outputWorkspace->mutableY(qIndex)[j] += Y[j] / numDets_d;
          // Standard error on the average
          outputWorkspace->mutableE(qIndex)[j] =
              sqrt((pow(outputWorkspace->e(qIndex)[j], 2) + pow(E[j], 2)) /
                   numDets_d);
        }
      }

    } catch (Exception::NotFoundError &) {
      // Get to here if exception thrown when calculating distance to detector
      // Presumably, if we get to here the spectrum will be all zeroes anyway
      // (from conversion to E)
      continue;
    }
    prog.report();
  }

  // If the input workspace was a distribution, need to divide by q bin width
  if (inputWorkspace->isDistribution())
    this->makeDistribution(outputWorkspace, verticalAxis);

  // Set the output spectrum-detector mapping
  SpectrumDetectorMapping outputDetectorMap(specNumberMapping, detIDMapping);
  outputWorkspace->updateSpectraUsing(outputDetectorMap);

  // Replace any NaNs in outputWorkspace with zeroes
  if (this->getProperty("ReplaceNaNs")) {
    auto replaceNans = this->createChildAlgorithm("ReplaceSpecialValues");
    replaceNans->setChild(true);
    replaceNans->initialize();
    replaceNans->setProperty("InputWorkspace", outputWorkspace);
    replaceNans->setProperty("OutputWorkspace", outputWorkspace);
    replaceNans->setProperty("NaNValue", 0.0);
    replaceNans->setProperty("InfinityValue", 0.0);
    replaceNans->setProperty("BigNumberThreshold", DBL_MAX);
    replaceNans->execute();
  }
}
コード例 #14
0
ファイル: LoadIsawPeaks.cpp プロジェクト: trnielsen/mantid
  std::string  LoadIsawPeaks::ApplyCalibInfo(std::ifstream & in, std::string startChar,Geometry::Instrument_const_sptr instr_old, Geometry::Instrument_const_sptr instr,
      double &T0)
  {
    ParameterMap_sptr parMap1= instr_old->getParameterMap();

    ParameterMap_sptr parMap= instr->getParameterMap();


    while( in.good() && (startChar.size() <1 || startChar !="7") )
       {
         readToEndOfLine( in, true);
         startChar = getWord(in, false);
       }
     if( !(in.good()))
     {
       //g_log.error()<<"Peaks file has no time shift and L0 info"<<std::endl;
       throw std::invalid_argument("Peaks file has no time shift and L0 info");
     }
     std::string L1s= getWord(in,false);
     std::string T0s =getWord(in, false);
     if( L1s.length() < 1 || T0s.length() < 1)
     {
       g_log.error()<<"Missing L1 or Time offset"<<std::endl;
       throw std::invalid_argument("Missing L1 or Time offset");
     }
     double L1;
     try
     {
       std::istringstream iss( L1s+" "+T0s, std::istringstream::in);
       iss>>L1;
       iss>>T0;
       V3D sampPos=instr->getSample()->getPos();
       SCDCalibratePanels::FixUpSourceParameterMap(instr, L1/100, sampPos,parMap1);

     }catch(...)
     {
       g_log.error()<<"Invalid L1 or Time offset"<<std::endl;
       throw std::invalid_argument("Invalid L1 or Time offset");

     }

     readToEndOfLine( in, true);
     startChar = getWord(in , false);
     while( in.good() && (startChar.size() <1 || startChar !="5") )
            {
              readToEndOfLine( in, true);
              startChar = getWord(in, false);
            }

    if( !(in.good()))
    {
      g_log.error()<<"Peaks file has no detector panel info"<<std::endl;
      throw std::invalid_argument("Peaks file has no detector panel info");
    }


    while( startChar =="5")
    {

      std::string line;
      for( int i=0; i<16;i++)
      {
        std::string s= getWord(in, false);
        if( s.size() < 1)
        {
          g_log.error()<<"Not enough info to describe panel "<<std::endl;
          throw std::length_error("Not enough info to describe panel ");
        }
       line +=" "+s;;
      }

      readToEndOfLine(in, true);
      startChar = getWord( in, false);// blank lines ?? and # lines ignore

      std::istringstream iss( line, std::istringstream::in);
      int  bankNum,nrows,ncols;
      double width,height,depth,detD,Centx,Centy,Centz,Basex,Basey,Basez,
             Upx,Upy,Upz;
      try
      {
         iss>>bankNum>>nrows>>ncols>>width>>height>>depth>>detD
            >>Centx>>Centy>>Centz>>Basex>>Basey>>Basez
            >>Upx>>Upy>>Upz;
      }catch(...)
      {

        g_log.error()<<"incorrect type of data for panel "<<std::endl;
        throw std::length_error("incorrect type of data for panel ");
      }

      std::string SbankNum = boost::lexical_cast<std::string>(bankNum);

      std::string bankName = "bank"+SbankNum;
      boost::shared_ptr<const Geometry::IComponent> bank =instr_old->getComponentByName( bankName );

      if( !bank)
      {
        g_log.error()<<"There is no bank "<< bankName<<" in the instrument"<<std::endl;
        throw std::length_error("There is no bank "+ bankName+" in the instrument");
      }

      V3D dPos= V3D(Centx,Centy,Centz)/100.0- bank->getPos();
      V3D Base(Basex,Basey,Basez), Up(Upx,Upy,Upz);
      V3D ToSamp =Base.cross_prod(Up);
      Base.normalize();
      Up.normalize();
      ToSamp.normalize();
      Quat thisRot(Base,Up,ToSamp);
      Quat bankRot(bank->getRotation());
      bankRot.inverse();
      Quat dRot = thisRot*bankRot;

      boost::shared_ptr< const Geometry::RectangularDetector>bankR= boost::dynamic_pointer_cast
                         <const Geometry::RectangularDetector>( bank);

      double DetWScale = 1, DetHtScale = 1;
      if( bank)
      {
        DetWScale = width/bankR->xsize()/100;
        DetHtScale = height/bankR->ysize()/100;

      }
      std::vector<std::string> bankNames;
      bankNames.push_back(bankName);

      SCDCalibratePanels::FixUpBankParameterMap(bankNames,instr, dPos,
          dRot,DetWScale,DetHtScale , parMap1, false);

    }
    return startChar;
  }
コード例 #15
0
    void GoniometerAnglesFromPhiRotation::exec()
    {

      PeaksWorkspace_sptr PeaksRun1 = getProperty("PeaksWorkspace1");
      PeaksWorkspace_sptr PeaksRun2 = getProperty("PeaksWorkspace2");

      double Tolerance = getProperty("Tolerance");

      Kernel::Matrix<double> Gon1(3, 3);
      Kernel::Matrix<double> Gon2(3, 3);
      if (!CheckForOneRun(PeaksRun1, Gon1) || !CheckForOneRun(PeaksRun2, Gon2))
      {
        g_log.error("Each peaks workspace MUST have only one run");
        throw std::invalid_argument("Each peaks workspace MUST have only one run");
      }

      Kernel::Matrix<double> UB1, UB2;

      bool Run1HasOrientedLattice = true;
      if (!PeaksRun1->sample().hasOrientedLattice())
      {

        Run1HasOrientedLattice = false;

        const std::string fft("FindUBUsingFFT");
        API::IAlgorithm_sptr findUB = this->createChildAlgorithm(fft);
        findUB->initialize();
        findUB->setProperty<PeaksWorkspace_sptr>("PeaksWorkspace", getProperty("PeaksWorkspace1"));
        findUB->setProperty("MIND", (double) getProperty("MIND"));
        findUB->setProperty("MAXD", (double) getProperty("MAXD"));
        findUB->setProperty("Tolerance", Tolerance);

        findUB->executeAsChildAlg();

        if (!PeaksRun1->sample().hasOrientedLattice())
        {
          g_log.notice(std::string("Could not find UB for ") + std::string(PeaksRun1->name()));
          throw std::invalid_argument(
              std::string("Could not find UB for ") + std::string(PeaksRun1->name()));
        }

      }
      //-------------get UB raw :No goniometer----------------

      UB1 = PeaksRun1->sample().getOrientedLattice().getUB();

      UB1 = getUBRaw(UB1, Gon1);

      int N1;
      double avErrIndx, avErrAll;
      IndexRaw(PeaksRun1, UB1, N1, avErrIndx, avErrAll, Tolerance);

      if (N1 < .6 * PeaksRun1->getNumberPeaks())
      {
        g_log.notice(std::string("UB did not index well for ") + std::string(PeaksRun1->name()));
        throw std::invalid_argument(
            std::string("UB did not index well for ") + std::string(PeaksRun1->name()));
      }

      //----------------------------------------------

      Geometry::OrientedLattice lat2 = PeaksRun1->sample().getOrientedLattice();

      lat2.setUB(UB1);
      PeaksRun2->mutableSample().setOrientedLattice(&lat2);

      PeaksWorkspace_sptr Peakss = getProperty("PeaksWorkspace2");

      if (!Run1HasOrientedLattice)
        PeaksRun1->mutableSample().setOrientedLattice(NULL);

      double dphi = (double) getProperty("Phi2") - (double) getProperty("Run1Phi");
      Kernel::Matrix<double> Gon22(3, 3, true);

      for (int i = 0; i < PeaksRun2->getNumberPeaks(); i++)
      {
        PeaksRun2->getPeak(i).setGoniometerMatrix(Gon22);
      }

      int RunNum = PeaksRun2->getPeak(0).getRunNumber();
      std::string RunNumStr = boost::lexical_cast<std::string>(RunNum);
      int Npeaks = PeaksRun2->getNumberPeaks();

      std::vector<double> MinData(5); //n indexed, av err, phi, chi,omega
      MinData[0] = 0.0;
      std::vector<V3D> directionList = IndexingUtils::MakeHemisphereDirections(50);

      API::FrameworkManager::Instance();

      for (size_t d = 0; d < directionList.size(); d++)
        for (int sgn = 1; sgn > -2; sgn -= 2)
        {
          V3D dir = directionList[d];
          dir.normalize();
          Quat Q(sgn * dphi, dir);
          Q.normalize();
          Kernel::Matrix<double> Rot(Q.getRotation());

          Kernel::Matrix<double> UB2(Rot * UB1);

          int Nindexed;
          double avErrIndx, avErrAll;
          IndexRaw(PeaksRun2, Rot * UB1, Nindexed, avErrIndx, avErrAll, Tolerance);

          if (Nindexed > MinData[0])
          {
            MinData[0] = Nindexed;
            MinData[1] = sgn;
            MinData[2] = dir[0];

            MinData[3] = dir[1];
            MinData[4] = dir[2];
          }

        }

      g_log.debug()<<"Best direction unOptimized is ("<<(MinData[1]*MinData[2])<<","
          <<(MinData[1]*MinData[3])<<","<<(MinData[1]*MinData[4])<<")"<<std::endl;

      //----------------------- Optimize around best -------------------------------------------

      //               --------Create Workspace -------------------
      boost::shared_ptr<DataObjects::Workspace2D> ws = boost::dynamic_pointer_cast<
          DataObjects::Workspace2D>(
          WorkspaceFactory::Instance().create("Workspace2D", 1, 3 * Npeaks, 3 * Npeaks));
      MantidVecPtr Xvals, Yvals;

      for (int i = 0; i < Npeaks; ++i)
      {
        Xvals.access().push_back(i);
        Yvals.access().push_back(0.0);
        Xvals.access().push_back(i);
        Yvals.access().push_back(0.0);
        Xvals.access().push_back(i);
        Yvals.access().push_back(0.0);
      }
      ws->setX(0, Xvals);
      ws->setData(0, Yvals);

      //       -------------Set up other Fit function arguments------------------
      V3D dir(MinData[2], MinData[3], MinData[4]);
      dir.normalize();
      Quat Q(MinData[1] * dphi, dir);
      Q.normalize();
      Kernel::Matrix<double> Rot(Q.getRotation());

      Goniometer Gon(Rot);
      std::vector<double> omchiphi = Gon.getEulerAngles("yzy");
      MinData[2] = omchiphi[2];
      MinData[3] = omchiphi[1];
      MinData[4] = omchiphi[0];

      std::string FunctionArgs = "name=PeakHKLErrors, PeakWorkspaceName=" + PeaksRun2->name()
          + ",OptRuns=" + RunNumStr + ",phi" + RunNumStr + "="
          + boost::lexical_cast<std::string>(MinData[2]) + ",chi" + RunNumStr + "="
          + boost::lexical_cast<std::string>(MinData[3]) + ",omega" + RunNumStr + "="
          + boost::lexical_cast<std::string>(MinData[4]);

      std::string Constr = boost::lexical_cast<std::string>(MinData[2] - 5) + "<phi" + RunNumStr + "<"
          + boost::lexical_cast<std::string>(MinData[2] + 5);
      Constr += "," + boost::lexical_cast<std::string>(MinData[3] - 5) + "<chi" + RunNumStr + "<"
          + boost::lexical_cast<std::string>(MinData[3] + 5) + ",";

      Constr += boost::lexical_cast<std::string>(MinData[4] - 5) + "<omega" + RunNumStr + "<"
          + boost::lexical_cast<std::string>(MinData[4] + 5);

      std::string Ties =
          "SampleXOffset=0.0,SampleYOffset=0.0,SampleZOffset=0.0,GonRotx=0.0,GonRoty=0.0,GonRotz=0.0";

      boost::shared_ptr<Algorithm> Fit = createChildAlgorithm("Fit");

      Fit->initialize();
      Fit->setProperty("Function", FunctionArgs);
      Fit->setProperty("Ties", Ties);
      Fit->setProperty("Constraints", Constr);
      Fit->setProperty("InputWorkspace", ws);
      Fit->setProperty("CreateOutput", true);

      std::string outputName = "out";

      Fit->setProperty("Output", outputName);

      Fit->executeAsChildAlg();

      //std::string status = Fit->getProperty("OutputStatus");

      boost::shared_ptr<API::ITableWorkspace> results = Fit->getProperty("OutputParameters");
      double chisq = Fit->getProperty("OutputChi2overDoF");

      MinData[0] = chisq;
      MinData[2] = results->Double(6, 1);
      MinData[3] = results->Double(7, 1);
      MinData[4] = results->Double(8, 1);

      g_log.debug()<<"Best direction Optimized is ("<<(MinData[2])<<","
          <<(MinData[3])<<","<<(MinData[4])<<")\n";

      //          ---------------------Find number indexed -----------------------
      Quat Q1 = Quat(MinData[4], V3D(0, 1, 0)) * Quat(MinData[3], V3D(0, 0, 1))
          * Quat(MinData[2], V3D(0, 1, 0));

      int Nindexed;
      Kernel::Matrix<double> Mk(Q1.getRotation());
      IndexRaw(PeaksRun2, Mk * UB1, Nindexed, avErrIndx, avErrAll, Tolerance);

      //------------------------------------ Convert/Save Results -----------------------------

      double deg, ax1, ax2, ax3;
      Q1.getAngleAxis(deg, ax1, ax2, ax3);
      if (dphi * deg < 0)
      {
        deg = -deg;
        ax1 = -ax1;
        ax2 = -ax2;
        ax3 = -ax3;
      }

      double phi2 = (double) getProperty("Run1Phi") + dphi;
      double chi2 = acos(ax2) / M_PI * 180;
      double omega2 = atan2(ax3, -ax1) / M_PI * 180;

      g_log.notice() << "============================ Results ============================"
          << std::endl;
      g_log.notice() << "     phi,chi, and omega= (" << phi2 << "," << chi2 << "," << omega2 << ")"
          << std::endl;
      g_log.notice() << "     #indexed =" << Nindexed << std::endl;
      g_log.notice() << "              ==============================================" << std::endl;

      //std::cout << "============================ Results ============================" << std::endl;
     // std::cout << "     phi,chi, and omega= (" << phi2 << "," << chi2 << "," << omega2 << ")"
     //     << std::endl;
     // std::cout << "     #indexed =" << Nindexed << std::endl;
     // std::cout << "              ==============================================" << std::endl;

      setProperty("Phi2", phi2);
      setProperty("Chi2", chi2);
      setProperty("Omega2", omega2);

      setProperty("NIndexed", Nindexed);

      setProperty("AvErrIndex", avErrIndx);

      setProperty("AvErrAll", avErrAll);

      Q1 = Quat(omega2, V3D(0, 1, 0)) * Quat(chi2, V3D(0, 0, 1)) * Quat(phi2, V3D(0, 1, 0));
      Kernel::Matrix<double> Gon2a(Q1.getRotation());
      for (int i = 0; i < PeaksRun2->getNumberPeaks(); i++)
      {
        PeaksRun2->getPeak(i).setGoniometerMatrix(Gon2a);
      }

      OrientedLattice latt2(PeaksRun2->mutableSample().getOrientedLattice());
      //Kernel::Matrix<double> UB = latt2.getUB();
      Rot.Invert();
      Gon2a.Invert();
      latt2.setUB(Gon2a * Mk * UB1);

      PeaksRun2->mutableSample().setOrientedLattice(&latt2);
    }