コード例 #1
0
/** Executes the algorithm
 *  @throw Exception::FileError If the calibration file cannot be opened and read successfully
 *  @throw Exception::InstrumentDefinitionError If unable to obtain the source-sample distance
 */
void CaltoDspacemap::exec()
{
  MatrixWorkspace_sptr inputWS = getProperty("InputWorkspace");
  const std::string DFileName = getProperty("DspacemapFile");
  const std::string calFileName = getProperty("CalibrationFile");

  progress(0.0,"Reading calibration file");
  IAlgorithm_sptr alg = createSubAlgorithm("LoadCalFile", 0.0, 0.5, true);
  alg->setProperty("InputWorkspace", inputWS);
  alg->setPropertyValue("CalFilename", calFileName);
  alg->setProperty<bool>("MakeGroupingWorkspace", false);
  alg->setProperty<bool>("MakeOffsetsWorkspace", true);
  alg->setProperty<bool>("MakeMaskWorkspace", false);
  alg->setPropertyValue("WorkspaceName", "temp");
  alg->executeAsSubAlg();
  OffsetsWorkspace_sptr offsetsWS;
  offsetsWS = alg->getProperty("OutputOffsetsWorkspace");

  progress(0.5,"Saving dspacemap file");
  alg = createSubAlgorithm("SaveDspacemap", 0.5, 1.0, true);
  alg->setPropertyValue("DspacemapFile", DFileName);
  alg->setProperty<int>("PadDetID", getProperty("PadDetID"));
  alg->setProperty("InputWorkspace", offsetsWS);
  alg->executeAsSubAlg();
}
コード例 #2
0
    /**  Load logs from Nexus file. Logs are expected to be in
    *   /raw_data_1/runlog group of the file. Call to this method must be done
    *   within /raw_data_1 group.
    *   @param ws :: The workspace to load the logs to.
    *   @param period :: The period of this workspace
    */
    void LoadISISNexus2::loadLogs(DataObjects::Workspace2D_sptr ws, int period)
    {
      IAlgorithm_sptr alg = createSubAlgorithm("LoadNexusLogs", 0.0, 0.5);
      alg->setPropertyValue("Filename", this->getProperty("Filename"));
      alg->setProperty<MatrixWorkspace_sptr>("Workspace", ws);
      try
      {
        alg->executeAsSubAlg();
      }
      catch(std::runtime_error&)
      {
        g_log.warning() << "Unable to load run logs. There will be no log "
                        << "data associated with this workspace\n";
        return;
      }
      ws->populateInstrumentParameters();
      // If we loaded an icp_event log then create the necessary period logs 
      if( ws->run().hasProperty("icp_event") )
      {
        Kernel::Property *log = ws->run().getProperty("icp_event");
        LogParser parser(log);
        ws->mutableRun().addProperty(parser.createPeriodLog(period));
        ws->mutableRun().addProperty(parser.createAllPeriodsLog());
      }

    }
コード例 #3
0
void SphericalAbsorption::exec()
{
  // Retrieve the input workspace
  m_inputWS = getProperty("InputWorkspace");

  // Get the input parameters
  retrieveBaseProperties();

  // Create the output workspace
  MatrixWorkspace_sptr correctionFactors = WorkspaceFactory::Instance().create(m_inputWS);
  correctionFactors->isDistribution(true); // The output of this is a distribution
  correctionFactors->setYUnit(""); // Need to explicitly set YUnit to nothing
  correctionFactors->setYUnitLabel("Attenuation factor");
  double m_sphRadius = getProperty("SphericalSampleRadius"); // in cm


  IAlgorithm_sptr anvred = createSubAlgorithm("AnvredCorrection");
  anvred->setProperty<MatrixWorkspace_sptr>("InputWorkspace", m_inputWS);
  anvred->setProperty<MatrixWorkspace_sptr>("OutputWorkspace", correctionFactors);
  anvred->setProperty("PreserveEvents", true);
  anvred->setProperty("ReturnTransmissionOnly", true);
  anvred->setProperty("LinearScatteringCoef", m_refAtten);
  anvred->setProperty("LinearAbsorptionCoef", m_scattering);
  anvred->setProperty("Radius", m_sphRadius);
  anvred->executeAsSubAlg();
  // Get back the result
  correctionFactors = anvred->getProperty("OutputWorkspace");
  setProperty("OutputWorkspace", correctionFactors);

}
コード例 #4
0
  void DiffractionEventCalibrateDetectors::movedetector(double x, double y, double z, double rotx, double roty, double rotz,
      std::string detname, MatrixWorkspace_sptr inputW)
  {

    IAlgorithm_sptr alg1 = createSubAlgorithm("MoveInstrumentComponent");
    alg1->setProperty<MatrixWorkspace_sptr>("Workspace", inputW);
    alg1->setPropertyValue("ComponentName", detname);
    //Move in cm for small shifts
    alg1->setProperty("X", x*0.01);
    alg1->setProperty("Y", y*0.01);
    alg1->setProperty("Z", z*0.01);
    alg1->setPropertyValue("RelativePosition", "1");
    alg1->executeAsSubAlg();


    IAlgorithm_sptr algx = createSubAlgorithm("RotateInstrumentComponent");
    algx->setProperty<MatrixWorkspace_sptr>("Workspace", inputW);
    algx->setPropertyValue("ComponentName", detname);
    algx->setProperty("X", 1.0);
    algx->setProperty("Y", 0.0);
    algx->setProperty("Z", 0.0);
    algx->setProperty("Angle", rotx);
    algx->setPropertyValue("RelativeRotation", "1");
    algx->executeAsSubAlg();


    IAlgorithm_sptr algy = createSubAlgorithm("RotateInstrumentComponent");
    algy->setProperty<MatrixWorkspace_sptr>("Workspace", inputW);
    algy->setPropertyValue("ComponentName", detname);
    algy->setProperty("X", 0.0);
    algy->setProperty("Y", 1.0);
    algy->setProperty("Z", 0.0);
    algy->setProperty("Angle", roty);
    algy->setPropertyValue("RelativeRotation", "1");
    algy->executeAsSubAlg();

    IAlgorithm_sptr algz = createSubAlgorithm("RotateInstrumentComponent");
    algz->setProperty<MatrixWorkspace_sptr>("Workspace", inputW);
    algz->setPropertyValue("ComponentName", detname);
    algz->setProperty("X", 0.0);
    algz->setProperty("Y", 0.0);
    algz->setProperty("Z", 1.0);
    algz->setProperty("Angle", rotz);
    algz->setPropertyValue("RelativeRotation", "1");
    algz->executeAsSubAlg();
  }
コード例 #5
0
  /**
   * Run the MoveInstrumentComponent algorithm as a child algorithm
   * @param comp_name :: The component name
   * @param zshift :: The shift along the Z-axis
   * @param start_progress :: The starting percentage for progress reporting
   * @param end_progress :: The end percentage for progress reporting
   */
  void LoadLOQDistancesFromRaw::performMoveComponent(const std::string & comp_name, double zshift,
                 double start_progress, double end_progress)
  {
    IAlgorithm_sptr alg = createSubAlgorithm("MoveInstrumentComponent", start_progress, end_progress);
    alg->setPropertyValue("Workspace", getPropertyValue("InputWorkspace"));
    alg->setPropertyValue("ComponentName", comp_name);
    alg->setProperty("Z", zshift);
    alg->setPropertyValue("RelativePosition", "1");
    alg->executeAsSubAlg();

  }
コード例 #6
0
/// Calls CropWorkspace as a sub-algorithm to remove bins from the start or end of a square workspace
void RemoveBins::crop(const double& start, const double& end)
{
  IAlgorithm_sptr childAlg = createSubAlgorithm("CropWorkspace");
  childAlg->setProperty<MatrixWorkspace_sptr>("InputWorkspace", boost::const_pointer_cast<MatrixWorkspace>(m_inputWorkspace));
  childAlg->setProperty<double>("XMin", start);
  childAlg->setProperty<double>("XMax", end);
  childAlg->executeAsSubAlg();

  // Only get to here if successful
  // Assign the result to the output workspace property
  MatrixWorkspace_sptr outputWS = childAlg->getProperty("OutputWorkspace");
  setProperty("OutputWorkspace",outputWS);
  return;
}
コード例 #7
0
  void CloneMDWorkspace::doClone(const typename MDEventWorkspace<MDE, nd>::sptr ws)
  {
    std::string outWSName = getPropertyValue("OutputWorkspace");
    Progress prog(this, 0.0, 10.0, 100);
    BoxController_sptr bc = ws->getBoxController();

    if (!bc) throw std::runtime_error("Error with InputWorkspace: no BoxController!");
    if (bc->isFileBacked())
    {
      // Generate a new filename to copy to
      prog.report("Copying File");
      std::string originalFile = bc->getFilename();
      std::string outFilename = getPropertyValue("Filename");
      if (outFilename.empty())
      {
        // Auto-generated name
        Poco::Path path = Poco::Path(originalFile).absolute();
        std::string newName = path.getBaseName() + "_clone." + path.getExtension();
        path.setFileName(newName);
        outFilename = path.toString();
      }

      // Perform the copying
      g_log.notice() << "Cloned workspace file being copied to: " << outFilename << std::endl;
      Poco::File(originalFile).copyTo(outFilename);
      g_log.information() << "File copied successfully." << std::endl;

      // Now load it back
      IAlgorithm_sptr alg = createSubAlgorithm("LoadMD", 0.5, 1.0, false);
      alg->setPropertyValue("Filename", outFilename);
      alg->setPropertyValue("FileBackEnd", "1");
      alg->setPropertyValue("Memory", "0"); //TODO: How much memory?
      alg->setPropertyValue("OutputWorkspace", outWSName);
      alg->executeAsSubAlg();

      // Set the output workspace to this
      IMDEventWorkspace_sptr outWS = alg->getProperty("OutputWorkspace");
      this->setProperty("OutputWorkspace", outWS);
    }
    else
    {
      // Perform the clone in memory.
      boost::shared_ptr<MDEventWorkspace<MDE,nd> > outWS(new MDEventWorkspace<MDE,nd>(*ws));
      this->setProperty("OutputWorkspace", boost::dynamic_pointer_cast<IMDEventWorkspace>(outWS) );
    }
  }
コード例 #8
0
/// Move the detector according to the beam center
void EQSANSLoad::moveToBeamCenter()
{
  // Check that we have a beam center defined, otherwise set the
  // default beam center
  if (isEmpty(m_center_x) || isEmpty(m_center_y))
  {
    EQSANSInstrument::getDefaultBeamCenter(dataWS, m_center_x, m_center_y);
    g_log.information() << "No beam finding method: setting to default ["
      << Poco::NumberFormatter::format(m_center_x, 1) << ", "
      << Poco::NumberFormatter::format(m_center_y, 1) << "]" << std::endl;
    return;
  }

  // Check that the center of the detector really is at (0,0)
  int nx_pixels = (int)(dataWS->getInstrument()->getNumberParameter("number-of-x-pixels")[0]);
  int ny_pixels = (int)(dataWS->getInstrument()->getNumberParameter("number-of-y-pixels")[0]);
  V3D pixel_first = dataWS->getInstrument()->getDetector(0)->getPos();
  int detIDx = EQSANSInstrument::getDetectorFromPixel(nx_pixels-1, 0, dataWS);
  int detIDy = EQSANSInstrument::getDetectorFromPixel(0, ny_pixels-1, dataWS);

  V3D pixel_last_x = dataWS->getInstrument()->getDetector(detIDx)->getPos();
  V3D pixel_last_y = dataWS->getInstrument()->getDetector(detIDy)->getPos();
  double x_offset = (pixel_first.X()+pixel_last_x.X())/2.0;
  double y_offset = (pixel_first.Y()+pixel_last_y.Y())/2.0;
  double beam_ctr_x = 0.0;
  double beam_ctr_y = 0.0;
  EQSANSInstrument::getCoordinateFromPixel(m_center_x, m_center_y, dataWS, beam_ctr_x, beam_ctr_y);

  IAlgorithm_sptr mvAlg = createSubAlgorithm("MoveInstrumentComponent", 0.5, 0.50);
  mvAlg->setProperty<MatrixWorkspace_sptr>("Workspace", dataWS);
  mvAlg->setProperty("ComponentName", "detector1");
  mvAlg->setProperty("X", -x_offset-beam_ctr_x);
  mvAlg->setProperty("Y", -y_offset-beam_ctr_y);
  mvAlg->setProperty("RelativePosition", true);
  mvAlg->executeAsSubAlg();
  m_output_message += "   Beam center offset: " + Poco::NumberFormatter::format(x_offset)
      + ", " + Poco::NumberFormatter::format(y_offset) + " m\n";
  //m_output_message += "   Beam center in real-space: " + Poco::NumberFormatter::format(-x_offset-beam_ctr_x)
  //    + ", " + Poco::NumberFormatter::format(-y_offset-beam_ctr_y) + " m\n";
  g_log.information() << "Moving beam center to " << m_center_x << " " << m_center_y << std::endl;

  dataWS->mutableRun().addProperty("beam_center_x", m_center_x, "pixel", true);
  dataWS->mutableRun().addProperty("beam_center_y", m_center_y, "pixel", true);
  m_output_message += "   Beam center: " + Poco::NumberFormatter::format(m_center_x, 1)
      + ", " + Poco::NumberFormatter::format(m_center_y, 1) + "\n";
}
コード例 #9
0
/** Calls CropWorkspace as a sub-algorithm and passes to it the InputWorkspace property
*  @param specInd :: the index number of the histogram to extract
*  @param start :: the number of the first bin to include (starts counting bins at 0)
*  @param end :: the number of the last bin to include (starts counting bins at 0)
*  @throw out_of_range if start, end or specInd are set outside of the vaild range for the workspace
*  @throw runtime_error if the algorithm just falls over
*  @throw invalid_argument if the input workspace does not have common binning
*/
void GetEi::extractSpec(int64_t specInd, double start, double end)
{
  IAlgorithm_sptr childAlg =
    createSubAlgorithm("CropWorkspace", 100*m_fracCompl, 100*(m_fracCompl+CROP) );
  m_fracCompl += CROP;
  
  childAlg->setPropertyValue( "InputWorkspace",
                              getPropertyValue("InputWorkspace") );
  childAlg->setProperty( "XMin", start);
  childAlg->setProperty( "XMax", end);
  childAlg->setProperty( "StartWorkspaceIndex", specInd);
  childAlg->setProperty( "EndWorkspaceIndex", specInd);
  childAlg->executeAsSubAlg();

  m_tempWS = childAlg->getProperty("OutputWorkspace");

//DEBUGGING CODE uncomment out the line below if you want to see the TOF window that was analysed
//AnalysisDataService::Instance().addOrReplace("croped_dist_del", m_tempWS);
  progress(m_fracCompl);
  interruption_point();
}
コード例 #10
0
void EQSANSLoad::exec()
{
  // Read in default TOF cuts
  m_low_TOF_cut = getProperty("LowTOFCut");
  m_high_TOF_cut = getProperty("HighTOFCut");

  // Read in default beam center
  m_center_x = getProperty("BeamCenterX");
  m_center_y = getProperty("BeamCenterY");

  TableWorkspace_sptr reductionTable = getProperty("ReductionTableWorkspace");
  ReductionTableHandler reductionHandler(reductionTable);
  if (!reductionTable)
  {
    const std::string reductionTableName = getPropertyValue("ReductionTableWorkspace");
    if (reductionTableName.size()>0) setProperty("ReductionTableWorkspace", reductionHandler.getTable());
  }
  if (reductionHandler.findStringEntry("LoadAlgorithm").size()==0)
    reductionHandler.addEntry("LoadAlgorithm", toString());

  const std::string fileName = getPropertyValue("Filename");

  // Output log
  m_output_message = "";

  IAlgorithm_sptr loadAlg = createSubAlgorithm("LoadEventNexus", 0, 0.2);
  loadAlg->setProperty("Filename", fileName);
  loadAlg->executeAsSubAlg();
  IEventWorkspace_sptr dataWS_tmp = loadAlg->getProperty("OutputWorkspace");
  dataWS = boost::dynamic_pointer_cast<MatrixWorkspace>(dataWS_tmp);

  // Get the sample-detector distance
  double sdd = 0.0;
  const double sample_det_dist = getProperty("SampleDetectorDistance");
  if (!isEmpty(sample_det_dist))
  {
    sdd = sample_det_dist;
  } else {
    Mantid::Kernel::Property* prop = dataWS->run().getProperty("detectorZ");
    Mantid::Kernel::TimeSeriesProperty<double>* dp = dynamic_cast<Mantid::Kernel::TimeSeriesProperty<double>* >(prop);
    sdd = dp->getStatistics().mean;

    // Modify SDD according to offset if given
    const double sample_det_offset = getProperty("SampleDetectorDistanceOffset");
    if (!isEmpty(sample_det_offset))
    {
      sdd += sample_det_offset;
    }
  }
  dataWS->mutableRun().addProperty("sample_detector_distance", sdd, "mm", true);

  // Move the detector to its correct position
  IAlgorithm_sptr mvAlg = createSubAlgorithm("MoveInstrumentComponent", 0.2, 0.4);
  mvAlg->setProperty<MatrixWorkspace_sptr>("Workspace", dataWS);
  mvAlg->setProperty("ComponentName", "detector1");
  mvAlg->setProperty("Z", sdd/1000.0);
  mvAlg->setProperty("RelativePosition", false);
  mvAlg->executeAsSubAlg();
  g_log.information() << "Moving detector to " << sdd/1000.0 << std::endl;
  m_output_message += "   Detector position: " + Poco::NumberFormatter::format(sdd/1000.0, 3) + " m\n";

  // Get the run number so we can find the proper config file
  int run_number = 0;
  std::string config_file = "";
  if (dataWS->run().hasProperty("run_number"))
  {
    Mantid::Kernel::Property* prop = dataWS->run().getProperty("run_number");
    Mantid::Kernel::PropertyWithValue<std::string>* dp = dynamic_cast<Mantid::Kernel::PropertyWithValue<std::string>* >(prop);
    const std::string run_str = *dp;
    Poco::NumberParser::tryParse(run_str, run_number);
    // Find a proper config file
    config_file = findConfigFile(run_number);
  } else {
    g_log.error() << "Could not find run number for workspace " << getPropertyValue("OutputWorkspace") << std::endl;
    m_output_message += "   Could not find run number for data file\n";
  }

  // Process the config file
  bool use_config = getProperty("UseConfig");
  if (use_config && config_file.size()>0)
  {
    readConfigFile(config_file);
  } else if (use_config) {
    use_config = false;
    g_log.error() << "Cound not find config file for workspace " << getPropertyValue("OutputWorkspace") << std::endl;
    m_output_message += "   Could not find configuration file for run " + Poco::NumberFormatter::format(run_number) + "\n";
  }

  // If we use the config file, move the moderator position
  if (use_config)
  {
      if (m_moderator_position > -13.0)
        g_log.error() << "Moderator position seems close to the sample, please check" << std::endl;
      g_log.information() << "Moving moderator to " << m_moderator_position << std::endl;
      m_output_message += "   Moderator position: " + Poco::NumberFormatter::format(m_moderator_position, 3) + " m\n";
      mvAlg = createSubAlgorithm("MoveInstrumentComponent", 0.4, 0.45);
      mvAlg->setProperty<MatrixWorkspace_sptr>("Workspace", dataWS);
      mvAlg->setProperty("ComponentName", "moderator");
      mvAlg->setProperty("Z", m_moderator_position);
      mvAlg->setProperty("RelativePosition", false);
      mvAlg->executeAsSubAlg();
  }

  // Get source aperture radius
  getSourceSlitSize();

  // Move the beam center to its proper position
  moveToBeamCenter();

  // Modify TOF
  bool correct_for_flight_path = getProperty("CorrectForFlightPath");
  m_output_message += "   Flight path correction ";
  if (!correct_for_flight_path) m_output_message += "NOT ";
  m_output_message += "applied\n";
  DataObjects::EventWorkspace_sptr dataWS_evt = boost::dynamic_pointer_cast<EventWorkspace>(dataWS_tmp);
  IAlgorithm_sptr tofAlg = createSubAlgorithm("EQSANSTofStructure", 0.5, 0.7);
  tofAlg->setProperty<EventWorkspace_sptr>("InputWorkspace", dataWS_evt);
  tofAlg->setProperty("LowTOFCut", m_low_TOF_cut);
  tofAlg->setProperty("HighTOFCut", m_high_TOF_cut);
  tofAlg->setProperty("FlightPathCorrection", correct_for_flight_path);
  tofAlg->executeAsSubAlg();
  const double wl_min = tofAlg->getProperty("WavelengthMin");
  const double wl_max = tofAlg->getProperty("WavelengthMax");
  const bool frame_skipping = tofAlg->getProperty("FrameSkipping");
  dataWS->mutableRun().addProperty("wavelength_min", wl_min, "Angstrom", true);
  dataWS->mutableRun().addProperty("wavelength_max", wl_max, "Angstrom", true);
  dataWS->mutableRun().addProperty("is_frame_skipping", int(frame_skipping), true);
  double wl_combined_max = wl_max;
  m_output_message += "   Wavelength range: " + Poco::NumberFormatter::format(wl_min, 1)
      + " - " + Poco::NumberFormatter::format(wl_max, 1);
  if (frame_skipping)
  {
    const double wl_min2 = tofAlg->getProperty("WavelengthMinFrame2");
    const double wl_max2 = tofAlg->getProperty("WavelengthMaxFrame2");
    wl_combined_max = wl_max2;
    dataWS->mutableRun().addProperty("wavelength_min_frame2", wl_min2, "Angstrom", true);
    dataWS->mutableRun().addProperty("wavelength_max_frame2", wl_max2, "Angstrom", true);
    m_output_message += " and " + Poco::NumberFormatter::format(wl_min2, 1)
        + " - " + Poco::NumberFormatter::format(wl_max2, 1) + " Angstrom\n";
  } else
    m_output_message += " Angstrom\n";

  // Convert to wavelength
  const double ssd = fabs(dataWS->getInstrument()->getSource()->getPos().Z())*1000.0;
  const double conversion_factor = 3.9560346 / (sdd+ssd);
  m_output_message += "   TOF to wavelength conversion factor: " + Poco::NumberFormatter::format(conversion_factor) + "\n";
  IAlgorithm_sptr scAlg = createSubAlgorithm("ScaleX", 0.7, 0.71);
  scAlg->setProperty<MatrixWorkspace_sptr>("InputWorkspace", dataWS);
  scAlg->setProperty<MatrixWorkspace_sptr>("OutputWorkspace", dataWS);
  scAlg->setProperty("Factor", conversion_factor);
  scAlg->executeAsSubAlg();
  dataWS->getAxis(0)->setUnit("Wavelength");

  // Rebin so all the wavelength bins are aligned
  const bool preserveEvents = getProperty("PreserveEvents");
  std::string params = Poco::NumberFormatter::format(wl_min, 2)
      + ",0.1," + Poco::NumberFormatter::format(wl_combined_max, 2);
  IAlgorithm_sptr rebinAlg = createSubAlgorithm("Rebin", 0.71, 0.72);
  rebinAlg->setProperty<MatrixWorkspace_sptr>("InputWorkspace", dataWS);
  if (preserveEvents) rebinAlg->setProperty<MatrixWorkspace_sptr>("OutputWorkspace", dataWS);
  rebinAlg->setPropertyValue("Params", params);
  rebinAlg->setProperty("PreserveEvents", preserveEvents);
  rebinAlg->executeAsSubAlg();

  if (!preserveEvents) dataWS = rebinAlg->getProperty("OutputWorkspace");

  dataWS->mutableRun().addProperty("event_ws", getPropertyValue("OutputWorkspace"), true);
  setProperty<MatrixWorkspace_sptr>("OutputWorkspace", boost::dynamic_pointer_cast<MatrixWorkspace>(dataWS));
  setPropertyValue("OutputMessage", m_output_message);
}
コード例 #11
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;
  }