Beispiel #1
0
/** Gets the distances between the source and detectors whose IDs you pass to it
*  @param WS :: the input workspace
*  @param mon0Spec :: Spectrum number of the output from the first monitor
*  @param mon1Spec :: Spectrum number of the output from the second monitor
*  @param monitor0Dist :: the calculated distance to the detector whose ID was passed to this function first
*  @param monitor1Dist :: calculated distance to the detector whose ID was passed to this function second
*  @throw NotFoundError if no detector is found for the detector ID given
*  @throw runtime_error if there is a problem with the SpectraDetectorMap
*/
void GetEi::getGeometry(API::MatrixWorkspace_const_sptr WS, specid_t mon0Spec, specid_t mon1Spec, double &monitor0Dist, double &monitor1Dist) const
{
  const IObjComponent_const_sptr source = WS->getInstrument()->getSource();

  // retrieve a pointer to the first detector and get its distance
  size_t monWI = 0;
  try
  {
    monWI = WS->getIndexFromSpectrumNumber(mon0Spec);
  }
  catch (std::runtime_error &)
  {
    g_log.error() << "Could not find the workspace index for the monitor at spectrum " << mon0Spec << "\n";
    g_log.error() << "Error retrieving data for the first monitor" << std::endl;
    throw std::bad_cast();
  }
  const std::set<detid_t> & dets = WS->getSpectrum(monWI)->getDetectorIDs();

  if ( dets.size() != 1 )
  {
    g_log.error() << "The detector for spectrum number " << mon0Spec << " was either not found or is a group, grouped monitors are not supported by this algorithm\n";
    g_log.error() << "Error retrieving data for the first monitor" << std::endl;
    throw std::bad_cast();
  }
  IDetector_const_sptr det = WS->getInstrument()->getDetector(*dets.begin());
  monitor0Dist = det->getDistance(*(source.get()));

  // repeat for the second detector
  try
  {
    monWI = WS->getIndexFromSpectrumNumber(mon0Spec);
  }
  catch (std::runtime_error &)
  {
    g_log.error() << "Could not find the workspace index for the monitor at spectrum " << mon0Spec << "\n";
    g_log.error() << "Error retrieving data for the second monitor\n";
    throw std::bad_cast();
  }
  const std::set<detid_t> & dets2 = WS->getSpectrum(monWI)->getDetectorIDs();
  if ( dets2.size() != 1 )
  {
    g_log.error() << "The detector for spectrum number " << mon1Spec << " was either not found or is a group, grouped monitors are not supported by this algorithm\n";
    g_log.error() << "Error retrieving data for the second monitor\n";
    throw std::bad_cast();
  }
  det = WS->getInstrument()->getDetector(*dets2.begin());
  monitor1Dist = det->getDistance(*(source.get()));
}
/**
 * Cache frequently accessed values
 * @param instrument : The instrument for this run
 * @param detID : The det ID for this observation
 */
void CachedExperimentInfo::initCaches(
    const Geometry::Instrument_const_sptr &instrument, const detid_t detID) {
  // Throws if detector does not exist
  // Takes into account possible detector mapping
  IDetector_const_sptr det = m_exptInfo.getDetectorByID(detID);

  // Instrument distances
  boost::shared_ptr<const ReferenceFrame> refFrame =
      instrument->getReferenceFrame();
  m_beam = refFrame->pointingAlongBeam();
  m_up = refFrame->pointingUp();
  m_horiz = refFrame->pointingHorizontal();

  IComponent_const_sptr source = instrument->getSource();
  IComponent_const_sptr sample = instrument->getSample();
  IComponent_const_sptr aperture =
      instrument->getComponentByName("aperture", 1);
  if (!aperture) {
    throw std::invalid_argument(
        "No component named \"aperture\" found in instrument.");
  }
  IObjComponent_const_sptr firstChopper = instrument->getChopperPoint(0);
  const Kernel::V3D samplePos = sample->getPos();
  const Kernel::V3D beamDir = samplePos - source->getPos();

  // Cache
  m_twoTheta = det->getTwoTheta(samplePos, beamDir);
  m_phi = det->getPhi();
  m_modToChop = firstChopper->getDistance(*source);
  m_apertureToChop = firstChopper->getDistance(*aperture);
  m_chopToSample = sample->getDistance(*firstChopper);
  m_sampleToDet = det->getDistance(*sample);

  // Aperture
  Geometry::BoundingBox apertureBox;
  aperture->getBoundingBox(apertureBox);
  if (apertureBox.isNull()) {
    throw std::invalid_argument("CachedExperimentInfo::initCaches - Aperture "
                                "has no bounding box, cannot sample from it");
  }
  m_apertureSize.first = apertureBox.maxPoint()[0] - apertureBox.minPoint()[0];
  m_apertureSize.second = apertureBox.maxPoint()[1] - apertureBox.minPoint()[1];

  // Sample volume
  const API::Sample &sampleDescription = m_exptInfo.sample();
  const Geometry::Object &shape = sampleDescription.getShape();
  m_sampleWidths = shape.getBoundingBox().width();

  // Detector volume
  // Make sure it encompasses all possible detectors
  det->getBoundingBox(m_detBox);
  if (m_detBox.isNull()) {
    throw std::invalid_argument("CachedExperimentInfo::initCaches - Detector "
                                "has no bounding box, cannot sample from it. "
                                "ID:" +
                                boost::lexical_cast<std::string>(det->getID()));
  }

  const double rad2deg = 180. / M_PI;
  const double thetaInDegs = twoTheta() * rad2deg;
  const double phiInDegs = phi() * rad2deg;

  m_gonimeter = new Goniometer;
  m_gonimeter->makeUniversalGoniometer();
  m_gonimeter->setRotationAngle("phi", thetaInDegs);
  m_gonimeter->setRotationAngle("chi", phiInDegs);
  m_sampleToDetMatrix =
      m_exptInfo.sample().getOrientedLattice().getU() * m_gonimeter->getR();

  // EFixed
  m_efixed = m_exptInfo.getEFixed(det);
}
Beispiel #3
0
  /** Executes the algorithm
  *
  *  @throw runtime_error Thrown if algorithm cannot execute
  */
  void DiffractionEventCalibrateDetectors::exec()
  {
    // Try to retrieve optional properties
    const int maxIterations = getProperty("MaxIterations");
    const double peakOpt = getProperty("LocationOfPeakToOptimize");

    // Get the input workspace
    EventWorkspace_const_sptr inputW = getProperty("InputWorkspace");

     // retrieve the properties
    const std::string rb_params=getProperty("Params");

    //Get some stuff from the input workspace
    Instrument_const_sptr inst = inputW->getInstrument();

    //Build a list of Rectangular Detectors
    std::vector<boost::shared_ptr<RectangularDetector> > detList;
    // --------- Loading only one bank ----------------------------------
    std::string onebank = getProperty("BankName");
    bool doOneBank = (onebank != ""); 
    for (int i=0; i < inst->nelements(); i++)
    {
      boost::shared_ptr<RectangularDetector> det;
      boost::shared_ptr<ICompAssembly> assem;
      boost::shared_ptr<ICompAssembly> assem2;
  
      det = boost::dynamic_pointer_cast<RectangularDetector>( (*inst)[i] );
      if (det)
      {
        if (det->getName().compare(onebank) == 0) detList.push_back(det); 
        if (!doOneBank) detList.push_back(det); 
      }
      else
      {
        //Also, look in the first sub-level for RectangularDetectors (e.g. PG3).
        // We are not doing a full recursive search since that will be very long for lots of pixels.
        assem = boost::dynamic_pointer_cast<ICompAssembly>( (*inst)[i] );
        if (assem)
        {
          for (int j=0; j < assem->nelements(); j++)
          {
            det = boost::dynamic_pointer_cast<RectangularDetector>( (*assem)[j] );
            if (det)
            {
              if (det->getName().compare(onebank) == 0) detList.push_back(det); 
              if (!doOneBank) detList.push_back(det); 
  
            }
            else
            {
              //Also, look in the second sub-level for RectangularDetectors (e.g. PG3).
              // We are not doing a full recursive search since that will be very long for lots of pixels.
              assem2 = boost::dynamic_pointer_cast<ICompAssembly>( (*assem)[j] );
              if (assem2)
              {
                for (int k=0; k < assem2->nelements(); k++)
                {
                  det = boost::dynamic_pointer_cast<RectangularDetector>( (*assem2)[k] );
                  if (det)
                  {
                    if (det->getName().compare(onebank) == 0) detList.push_back(det); 
                    if (!doOneBank) detList.push_back(det); 
                  }
                }
              }
            }
          }
        }
      }
    }


    // set-up minimizer

    std::string inname = getProperty("InputWorkspace");
    std::string outname = inname+"2"; //getProperty("OutputWorkspace");

    IAlgorithm_sptr algS = createSubAlgorithm("SortEvents");
    algS->setPropertyValue("InputWorkspace",inname);
    algS->setPropertyValue("SortBy", "X Value");
    algS->executeAsSubAlg();
    inputW=algS->getProperty("InputWorkspace");

    //Write DetCal File
    double baseX,baseY,baseZ,upX,upY,upZ;

    std::string filename=getProperty("DetCalFilename");
    std::fstream outfile;
    outfile.open(filename.c_str(), std::ios::out);

    if(detList.size() > 1) 
    {
      outfile << "#\n";
      outfile << "#  Mantid Optimized .DetCal file for SNAP with TWO detector panels\n";
      outfile << "#  Old Panel, nominal size and distance at -90 degrees.\n";
      outfile << "#  New Panel, nominal size and distance at +90 degrees.\n";
      outfile << "#\n";
      outfile << "# Lengths are in centimeters.\n";
      outfile << "# Base and up give directions of unit vectors for a local\n";
      outfile << "# x,y coordinate system on the face of the detector.\n";
      outfile << "#\n";
      std::time_t current_t = DateAndTime::get_current_time().to_time_t() ;
      std::tm * current = gmtime( &current_t );
      outfile << "# "<<asctime (current) <<"\n";
      outfile << "#\n";
      outfile << "6         L1     T0_SHIFT\n";
      IObjComponent_const_sptr source = inst->getSource();
      IObjComponent_const_sptr sample = inst->getSample();
      outfile << "7  "<<source->getDistance(*sample)*100<<"            0\n";
      outfile << "4 DETNUM  NROWS  NCOLS  WIDTH   HEIGHT   DEPTH   DETD   CenterX   CenterY   CenterZ    BaseX    BaseY    BaseZ      UpX      UpY      UpZ\n";
    }

    Progress prog(this,0.0,1.0,detList.size());
    for (int det=0; det < static_cast<int>(detList.size()); det++)
    {
      std::string par[6];
      par[0]=detList[det]->getName();
      par[1]=inname;
      par[2]=outname;
      std::ostringstream strpeakOpt;
      strpeakOpt<<peakOpt;
      par[3]=strpeakOpt.str();
      par[4]=rb_params;

      // --- Create a GroupingWorkspace for this detector name ------
      CPUTimer tim;
      IAlgorithm_sptr alg2 = AlgorithmFactory::Instance().create("CreateGroupingWorkspace", 1);
      alg2->initialize();
      alg2->setPropertyValue("InputWorkspace", getPropertyValue("InputWorkspace"));
      alg2->setPropertyValue("GroupNames", detList[det]->getName());
      std::string groupWSName = "group_" + detList[det]->getName();
      alg2->setPropertyValue("OutputWorkspace", groupWSName);
      alg2->executeAsSubAlg();
      par[5] = groupWSName;
      std::cout << tim << " to CreateGroupingWorkspace" << std::endl;

      const gsl_multimin_fminimizer_type *T =
      gsl_multimin_fminimizer_nmsimplex;
      gsl_multimin_fminimizer *s = NULL;
      gsl_vector *ss, *x;
      gsl_multimin_function minex_func;

      // finally do the fitting

      int nopt = 6;
      int iter = 0;
      int status = 0;
      double size;
 
      /* Starting point */
      x = gsl_vector_alloc (nopt);
      gsl_vector_set (x, 0, 0.0);
      gsl_vector_set (x, 1, 0.0);
      gsl_vector_set (x, 2, 0.0);
      gsl_vector_set (x, 3, 0.0);
      gsl_vector_set (x, 4, 0.0);
      gsl_vector_set (x, 5, 0.0);

      /* Set initial step sizes to 0.1 */
      ss = gsl_vector_alloc (nopt);
      gsl_vector_set_all (ss, 0.1);

      /* Initialize method and iterate */
      minex_func.n = nopt;
      minex_func.f = &Mantid::Algorithms::gsl_costFunction;
      minex_func.params = &par;

      s = gsl_multimin_fminimizer_alloc (T, nopt);
      gsl_multimin_fminimizer_set (s, &minex_func, x, ss);

      do
      {
        iter++;
        status = gsl_multimin_fminimizer_iterate(s);

        if (status)
          break;

        size = gsl_multimin_fminimizer_size (s);
        status = gsl_multimin_test_size (size, 1e-2);

      }
      while (status == GSL_CONTINUE && iter < maxIterations && s->fval != -0.000 );

      // Output summary to log file
      if (s->fval != -0.000) movedetector(gsl_vector_get (s->x, 0), gsl_vector_get (s->x, 1), gsl_vector_get (s->x, 2),
         gsl_vector_get (s->x, 3), gsl_vector_get (s->x, 4), gsl_vector_get (s->x, 5), par[0], getProperty("InputWorkspace"));
      else 
      {
        gsl_vector_set (s->x, 0, 0.0);
        gsl_vector_set (s->x, 1, 0.0);
        gsl_vector_set (s->x, 2, 0.0);
        gsl_vector_set (s->x, 3, 0.0);
        gsl_vector_set (s->x, 4, 0.0);
        gsl_vector_set (s->x, 5, 0.0);
      }

      std::string reportOfDiffractionEventCalibrateDetectors = gsl_strerror(status);
      if (s->fval == -0.000) reportOfDiffractionEventCalibrateDetectors = "No events";

      g_log.information() << "Detector = " << det << "\n" <<
        "Method used = " << "Simplex" << "\n" <<
        "Iteration = " << iter << "\n" <<
        "Status = " << reportOfDiffractionEventCalibrateDetectors << "\n" <<
        "Minimize PeakLoc-" << peakOpt << " = " << s->fval << "\n";
      //Move in cm for small shifts
      g_log.information() << "Move (X)   = " << gsl_vector_get (s->x, 0)*0.01 << "  \n";
      g_log.information() << "Move (Y)   = " << gsl_vector_get (s->x, 1)*0.01 << "  \n";
      g_log.information() << "Move (Z)   = " << gsl_vector_get (s->x, 2)*0.01 << "  \n";
      g_log.information() << "Rotate (X) = " << gsl_vector_get (s->x, 3) << "  \n";
      g_log.information() << "Rotate (Y) = " << gsl_vector_get (s->x, 4) << "  \n";
      g_log.information() << "Rotate (Z) = " << gsl_vector_get (s->x, 5) << "  \n";


      Kernel::V3D CalCenter=V3D(gsl_vector_get (s->x, 0)*0.01,
        gsl_vector_get (s->x, 1)*0.01, gsl_vector_get (s->x, 2)*0.01);
      Kernel::V3D Center=detList[det]->getPos()+CalCenter;
      int pixmax = detList[det]->xpixels()-1;
      int pixmid = (detList[det]->ypixels()-1)/2;
      BoundingBox box;
      detList[det]->getAtXY(pixmax, pixmid)->getBoundingBox(box);
      baseX = box.xMax();
      baseY = box.yMax();
      baseZ = box.zMax();
      Kernel::V3D Base=V3D(baseX,baseY,baseZ)+CalCenter;
      pixmid = (detList[det]->xpixels()-1)/2;
      pixmax = detList[det]->ypixels()-1;
      detList[det]->getAtXY(pixmid, pixmax)->getBoundingBox(box);
      upX = box.xMax();
      upY = box.yMax();
      upZ = box.zMax();
      Kernel::V3D Up=V3D(upX,upY,upZ)+CalCenter;
      Base-=Center;
      Up-=Center;
      //Rotate around x
      baseX = Base[0];
      baseY = Base[1];
      baseZ = Base[2];
      double deg2rad=M_PI/180.0;
      double angle = gsl_vector_get (s->x, 3)*deg2rad;
      Base=V3D(baseX,baseY*cos(angle)-baseZ*sin(angle),
        baseY*sin(angle)+baseZ*cos(angle));
      upX = Up[0];
      upY = Up[1];
      upZ = Up[2];
      Up=V3D(upX,upY*cos(angle)-upZ*sin(angle),
        upY*sin(angle)+upZ*cos(angle));
      //Rotate around y
      baseX = Base[0];
      baseY = Base[1];
      baseZ = Base[2];
      angle = gsl_vector_get (s->x, 4)*deg2rad;
      Base=V3D(baseZ*sin(angle)+baseX*cos(angle),
        baseY,baseZ*cos(angle)-baseX*sin(angle));
      upX = Up[0];
      upY = Up[1];
      upZ = Up[2];
      Up=V3D(upZ*cos(angle)-upX*sin(angle),upY,
        upZ*sin(angle)+upX*cos(angle));
      //Rotate around z
      baseX = Base[0];
      baseY = Base[1];
      baseZ = Base[2];
      angle = gsl_vector_get (s->x, 5)*deg2rad;
      Base=V3D(baseX*cos(angle)-baseY*sin(angle),
        baseX*sin(angle)+baseY*cos(angle),baseZ);
      upX = Up[0];
      upY = Up[1];
      upZ = Up[2];
      Up=V3D(upX*cos(angle)-upY*sin(angle),
        upX*sin(angle)+upY*cos(angle),upZ);
      Base.normalize();
      Up.normalize();
      Center*=100.0;
      // << det+1  << "  " 
      outfile << "5  " 
       << detList[det]->getName().substr(4)  << "  " 
       << detList[det]->xpixels() << "  " 
       << detList[det]->ypixels() << "  " 
       << 100.0*detList[det]->xsize() << "  " 
       << 100.0*detList[det]->ysize() << "  " 
       << "0.2000" << "  " 
       << Center.norm() << "  " ;
      Center.write(outfile);
      outfile << "  ";
      Base.write(outfile);
      outfile << "  ";
      Up.write(outfile);
      outfile << "\n";

      // clean up dynamically allocated gsl stuff
      gsl_vector_free(x);
      gsl_vector_free(ss);
      gsl_multimin_fminimizer_free (s);

      // Remove the now-unneeded grouping workspace
      AnalysisDataService::Instance().remove(groupWSName);
      prog.report(detList[det]->getName());
    }

    // Closing
    outfile.close();

    return;
  }