Esempio n. 1
0
  /** Executes the algorithm
  *
  *  @throw runtime_error Thrown if algorithm cannot execute
  */
  void Fit::exec()
  {
    // this is to make it work with AlgorithmProxy
    if (!m_domainCreator)
    {
      setFunction();
      addWorkspaces();
    }

    std::string ties = getPropertyValue("Ties");
    if (!ties.empty())
    {
      m_function->addTies(ties);
    }
    std::string contstraints = getPropertyValue("Constraints");
    if (!contstraints.empty())
    {
      m_function->addConstraints(contstraints);
    }
    
    // prepare the function for a fit
    m_function->setUpForFit();

    API::FunctionDomain_sptr domain;
    API::FunctionValues_sptr values; // TODO: should values be part of domain?
    m_domainCreator->ignoreInvalidData(getProperty("IgnoreInvalidData"));
    m_domainCreator->createDomain(domain,values);

    // do something with the function which may depend on workspace
    m_domainCreator->initFunction(m_function);

    // get the minimizer
    std::string minimizerName = getPropertyValue("Minimizer");
    API::IFuncMinimizer_sptr minimizer = API::FuncMinimizerFactory::Instance().createMinimizer(minimizerName);

    // Try to retrieve optional properties
    const int maxIterations = getProperty("MaxIterations");

    // get the cost function which must be a CostFuncFitting
    boost::shared_ptr<CostFuncFitting> costFunc = boost::dynamic_pointer_cast<CostFuncFitting>(
      API::CostFunctionFactory::Instance().create(getPropertyValue("CostFunction"))
      );

    costFunc->setFittingFunction(m_function,domain,values);
    minimizer->initialize(costFunc);

    const int64_t nsteps = maxIterations*m_function->estimateNoProgressCalls();
    API::Progress prog(this,0.0,1.0,nsteps);
    m_function->setProgressReporter(&prog);

    // do the fitting until success or iteration limit is reached
    size_t iter = 0;
    bool success = false;
    std::string errorString;
    g_log.debug("Starting minimizer iteration\n");
    while (static_cast<int>(iter) < maxIterations)
    {
      iter++;
      g_log.debug() << "Starting iteration " << iter << "\n";
      m_function->iterationStarting();
      if ( !minimizer->iterate() )
      {
        errorString = minimizer->getError();
        g_log.debug() << "Iteration stopped. Minimizer status string=" << errorString << "\n";

        success = errorString.empty() || errorString == "success";
        if (success)
        {
          errorString = "success";
        }
        break;
      }
      prog.report();
      m_function->iterationFinished();
      if(g_log.is(Kernel::Logger::Priority::PRIO_INFORMATION))
      {
        g_log.debug() << "Iteration " << iter << ", cost function = " << minimizer->costFunctionVal() << "\n";
      }
    }
    g_log.debug() << "Number of minimizer iterations=" << iter << "\n";

    if (static_cast<int>(iter) >= maxIterations)
    {
      if ( !errorString.empty() )
      {
        errorString += '\n';
      }
      errorString += "Failed to converge after " + boost::lexical_cast<std::string>(maxIterations) + " iterations.";
    }

    // return the status flag
    setPropertyValue("OutputStatus",errorString);

    // degrees of freedom
    size_t dof = domain->size() - costFunc->nParams();
    if (dof == 0) dof = 1;
    double rawcostfuncval = minimizer->costFunctionVal();
    double finalCostFuncVal = rawcostfuncval / double(dof);

    setProperty("OutputChi2overDoF",finalCostFuncVal);

    // fit ended, creating output

    // get the workspace 
    API::Workspace_const_sptr ws = getProperty("InputWorkspace");

    bool doCreateOutput = getProperty("CreateOutput");
    std::string baseName = getPropertyValue("Output");
    if ( !baseName.empty() )
    {
      doCreateOutput = true;
    }
    bool doCalcErrors = getProperty("CalcErrors");
    if ( doCreateOutput )
    {
      doCalcErrors = true;
    }
    if ( costFunc->nParams() == 0 )
    {
      doCalcErrors = false;
    }

    GSLMatrix covar;
    if ( doCalcErrors )
    {
      // Calculate the covariance matrix and the errors.
      costFunc->calCovarianceMatrix(covar);
      costFunc->calFittingErrors( covar, rawcostfuncval );
    }

    if (doCreateOutput)
    {
      if (baseName.empty())
      {
        baseName = ws->name();
        if (baseName.empty())
        {
          baseName = "Output";
        }
      }
      baseName += "_";

        declareProperty(
          new API::WorkspaceProperty<API::ITableWorkspace>("OutputNormalisedCovarianceMatrix","",Kernel::Direction::Output),
          "The name of the TableWorkspace in which to store the final covariance matrix" );
        setPropertyValue("OutputNormalisedCovarianceMatrix",baseName+"NormalisedCovarianceMatrix");

        Mantid::API::ITableWorkspace_sptr covariance = Mantid::API::WorkspaceFactory::Instance().createTable("TableWorkspace");
        covariance->addColumn("str","Name");
        // set plot type to Label = 6
        covariance->getColumn(covariance->columnCount()-1)->setPlotType(6);
        //std::vector<std::string> paramThatAreFitted; // used for populating 1st "name" column
        for(size_t i=0; i < m_function->nParams(); i++)
        {
          if (m_function->isActive(i)) 
          {
            covariance->addColumn("double",m_function->parameterName(i));
            //paramThatAreFitted.push_back(m_function->parameterName(i));
          }
        }

        size_t np = m_function->nParams();
        size_t ia = 0;
        for(size_t i = 0; i < np; i++)
        {
          if (m_function->isFixed(i)) continue;
          Mantid::API::TableRow row = covariance->appendRow();
          row << m_function->parameterName(i);
          size_t ja = 0;
          for(size_t j = 0; j < np; j++)
          {
            if (m_function->isFixed(j)) continue;
            if (j == i)
              row << 100.0;
            else
            {
              row << 100.0*covar.get(ia,ja)/sqrt(covar.get(ia,ia)*covar.get(ja,ja));
            }
            ++ja;
          }
          ++ia;
        }

        setProperty("OutputNormalisedCovarianceMatrix",covariance);

      // create output parameter table workspace to store final fit parameters 
      // including error estimates if derivative of fitting function defined

      declareProperty(
        new API::WorkspaceProperty<API::ITableWorkspace>("OutputParameters","",Kernel::Direction::Output),
        "The name of the TableWorkspace in which to store the final fit parameters" );

      setPropertyValue("OutputParameters",baseName+"Parameters");

      Mantid::API::ITableWorkspace_sptr result = Mantid::API::WorkspaceFactory::Instance().createTable("TableWorkspace");
      result->addColumn("str","Name");
      // set plot type to Label = 6
      result->getColumn(result->columnCount()-1)->setPlotType(6);
      result->addColumn("double","Value");
      result->addColumn("double","Error");
      // yErr = 5
      result->getColumn(result->columnCount()-1)->setPlotType(5);

      for(size_t i=0;i<m_function->nParams();i++)
      {
        Mantid::API::TableRow row = result->appendRow();
        row << m_function->parameterName(i) 
            << m_function->getParameter(i)
            << m_function->getError(i);
      }
      // Add chi-squared value at the end of parameter table
      Mantid::API::TableRow row = result->appendRow();
#if 1
      std::string costfuncname = getPropertyValue("CostFunction");
      if (costfuncname == "Rwp")
        row << "Cost function value" << rawcostfuncval;
      else
        row << "Cost function value" << finalCostFuncVal;
      setProperty("OutputParameters",result);
#else
      row << "Cost function value" << finalCostFuncVal;
      Mantid::API::TableRow row2 = result->appendRow();
      std::string name(getPropertyValue("CostFunction"));
      name += " value";
      row2 << name << rawcostfuncval;
#endif

      setProperty("OutputParameters",result);

      bool outputParametersOnly = getProperty("OutputParametersOnly");

      if ( !outputParametersOnly )
      {
        const bool unrollComposites = getProperty("OutputCompositeMembers");
        bool convolveMembers = existsProperty("ConvolveMembers");
        if ( convolveMembers )
        {
            convolveMembers = getProperty("ConvolveMembers");
        }
        m_domainCreator->separateCompositeMembersInOutput(unrollComposites,convolveMembers);
        m_domainCreator->createOutputWorkspace(baseName,m_function,domain,values);
      }

    }

  }
Esempio n. 2
0
// Test move method
void testMoveMethod01()
{
    // Test with a variety of object types in the From ResponseData
    // Build the class
    CIMClass CIMclass1 = buildClass();

    // Build a CIM Instance. NOTE: key is defaulted in class

    CIMInstance CIMInst1 = CIMclass1.buildInstance(true, true,
                                                   CIMPropertyList());

        // Clone the instance and change key
    CIMInstance CIMInst2 = CIMInst1.clone();
    setPropertyValue(CIMInst2, "id", 2);

    CIMInstance CIMInst3 = CIMInst1.clone();
    setPropertyValue(CIMInst3, "id", 3);
    CIMInstance CIMInst4 = CIMInst1.clone();
    setPropertyValue(CIMInst4, "id", 4);

    // build CIMInstance array
    Array<CIMInstance> CIMInstArray;
    CIMInstArray.append(CIMInst1);
    CIMInstArray.append(CIMInst2);
    CIMInstArray.append(CIMInst3);
    CIMInstArray.append(CIMInst3);
    {
        // Create from CIMReponseData object
        CIMResponseData crdFrom = CIMResponseData(
            CIMResponseData::RESP_INSTANCES);

        // Append an array of CIMInstances
        crdFrom.appendInstances(CIMInstArray);
        VCOUT << crdFrom.size() << endl;
        PEGASUS_TEST_ASSERT(crdFrom.size() == 4);

        // Move the objects < what is in from crd
        CIMResponseData crdTo = CIMResponseData(
            CIMResponseData::RESP_INSTANCES);
        PEGASUS_TEST_ASSERT(testMoveObjects(crdTo, crdFrom, 2));
        PEGASUS_TEST_ASSERT(crdFrom.size() == 2);
        PEGASUS_TEST_ASSERT(crdTo.size() == 2);

        // request move of more that exists.  Moves all
        CIMResponseData crdTo1 = CIMResponseData(
            CIMResponseData::RESP_INSTANCES);
        PEGASUS_TEST_ASSERT(testMoveObjects(crdTo1, crdFrom, 8));
        PEGASUS_TEST_ASSERT(crdFrom.size() == 0);
        PEGASUS_TEST_ASSERT(crdTo1.size() == 2);
    }

    // move exactly all and then none
    {
        // Create from CIMReponseData object
        CIMResponseData crdFrom = CIMResponseData(
            CIMResponseData::RESP_INSTANCES);

        // Append an array of CIMInstances
        crdFrom.appendInstances(CIMInstArray);
        VCOUT << crdFrom.size() << endl;
        PEGASUS_TEST_ASSERT(crdFrom.size() == 4);

        // Move the objects < what is in from crd
        CIMResponseData crdTo = CIMResponseData(
            CIMResponseData::RESP_INSTANCES);
        PEGASUS_TEST_ASSERT(testMoveObjects(crdTo, crdFrom, 4));
        PEGASUS_TEST_ASSERT(crdFrom.size() == 0);
        PEGASUS_TEST_ASSERT(crdTo.size() == 4);

        // request move of more that exists.  Moves all r
        CIMResponseData crdTo1 = CIMResponseData(
            CIMResponseData::RESP_INSTANCES);
        PEGASUS_TEST_ASSERT(testMoveObjects(crdTo1, crdFrom, 8));
        PEGASUS_TEST_ASSERT(crdFrom.size() == 0);
        VCOUT << "Error: bad size() = " << crdTo1.size() << endl;
        PEGASUS_TEST_ASSERT(crdTo1.size() == 0);
    }

    // request move more than total
    {
        // Create from CIMReponseData object
        CIMResponseData crdFrom = CIMResponseData(
            CIMResponseData::RESP_INSTANCES);

        // Append an array of CIMInstances
        crdFrom.appendInstances(CIMInstArray);
        VCOUT << crdFrom.size() << endl;
        PEGASUS_TEST_ASSERT(crdFrom.size() == 4);

        // Move the objects < what is in from crd
        CIMResponseData crdTo = CIMResponseData(
            CIMResponseData::RESP_INSTANCES);
        PEGASUS_TEST_ASSERT(testMoveObjects(crdTo, crdFrom, 9));
        PEGASUS_TEST_ASSERT(crdFrom.size() == 0);
        PEGASUS_TEST_ASSERT(crdTo.size() == 4);
    }
}
Esempio n. 3
0
void EQSANSLoad::exec()
{
  // Verify the validity of the inputs
  //TODO: this should be done by the new data management algorithm used for
  // live data reduction (when it's implemented...)
  const std::string fileName = getPropertyValue("Filename");
  EventWorkspace_sptr inputEventWS = getProperty("InputWorkspace");
  if (fileName.size()==0 && !inputEventWS)
  {
    g_log.error() << "EQSANSLoad input error: Either a valid file path or an input workspace must be provided" << std::endl;
    throw std::runtime_error("EQSANSLoad input error: Either a valid file path or an input workspace must be provided");
  }
  else if (fileName.size()>0 && inputEventWS)
  {
    g_log.error() << "EQSANSLoad input error: Either a valid file path or an input workspace must be provided, but not both" << std::endl;
    throw std::runtime_error("EQSANSLoad input error: Either a valid file path or an input workspace must be provided, but not both");
  }

  // Read in default TOF cuts
  const bool skipTOFCorrection = getProperty("SkipTOFCorrection");
  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");
  const bool noBeamCenter = getProperty("NoBeamCenter");

  // Reduction property manager
  const std::string reductionManagerName = getProperty("ReductionProperties");
  boost::shared_ptr<PropertyManager> reductionManager;
  if (PropertyManagerDataService::Instance().doesExist(reductionManagerName))
  {
    reductionManager = PropertyManagerDataService::Instance().retrieve(reductionManagerName);
  }
  else
  {
    reductionManager = boost::make_shared<PropertyManager>();
    PropertyManagerDataService::Instance().addOrReplace(reductionManagerName, reductionManager);
  }

  if (!reductionManager->existsProperty("LoadAlgorithm"))
  {
    AlgorithmProperty *loadProp = new AlgorithmProperty("LoadAlgorithm");
    setPropertyValue("InputWorkspace", "");
    setProperty("NoBeamCenter", false);
    loadProp->setValue(toString());
    reductionManager->declareProperty(loadProp);
  }

  if (!reductionManager->existsProperty("InstrumentName"))
  {
    reductionManager->declareProperty(new PropertyWithValue<std::string>("InstrumentName", "EQSANS") );
  }

  // Output log
  m_output_message = "";

  // Check whether we need to load the data
  if (!inputEventWS)
  {
    const bool loadMonitors = getProperty("LoadMonitors");
    IAlgorithm_sptr loadAlg = createChildAlgorithm("LoadEventNexus", 0, 0.2);
    loadAlg->setProperty("LoadMonitors", loadMonitors);
    loadAlg->setProperty("MonitorsAsEvents", false);
    loadAlg->setProperty("Filename", fileName);
    if (skipTOFCorrection)
    {
      if (m_low_TOF_cut>0.0) loadAlg->setProperty("FilterByTofMin", m_low_TOF_cut);
      if (m_high_TOF_cut>0.0) loadAlg->setProperty("FilterByTofMax", m_high_TOF_cut);
    }
    loadAlg->execute();
    IEventWorkspace_sptr dataWS_asWks = loadAlg->getProperty("OutputWorkspace");
    dataWS = boost::dynamic_pointer_cast<MatrixWorkspace>(dataWS_asWks);

    // Get monitor workspace as necessary
    std::string mon_wsname = getPropertyValue("OutputWorkspace")+"_monitors";
    if (loadMonitors && loadAlg->existsProperty("MonitorWorkspace"))
    {
      MatrixWorkspace_sptr monWS = loadAlg->getProperty("MonitorWorkspace");
      declareProperty(new WorkspaceProperty<>("MonitorWorkspace",
          mon_wsname, Direction::Output), "Monitors from the Event NeXus file");
      setProperty("MonitorWorkspace", monWS);
    }
  } else {
    MatrixWorkspace_sptr outputWS = getProperty("OutputWorkspace");
    EventWorkspace_sptr outputEventWS = boost::dynamic_pointer_cast<EventWorkspace>(outputWS);
    if (inputEventWS != outputEventWS)
    {
      IAlgorithm_sptr copyAlg = createChildAlgorithm("CloneWorkspace", 0, 0.2);
      copyAlg->setProperty("InputWorkspace", inputEventWS);
      copyAlg->executeAsChildAlg();
      Workspace_sptr dataWS_asWks = copyAlg->getProperty("OutputWorkspace");
      dataWS = boost::dynamic_pointer_cast<MatrixWorkspace>(dataWS_asWks);
    } else {
      dataWS = boost::dynamic_pointer_cast<MatrixWorkspace>(inputEventWS);
    }
  }

  // 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 {
    if (!dataWS->run().hasProperty("detectorZ"))
    {
      g_log.error() << "Could not determine Z position: the SampleDetectorDistance property was not set "
          "and the run logs do not contain the detectorZ property" << std::endl;
      throw std::invalid_argument("Could not determine Z position: stopping execution");
    }
    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 = createChildAlgorithm("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->executeAsChildAlg();
  g_log.information() << "Moving detector to " << sdd/1000.0 << " meters" << 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)
  {
    // Special case to force reading the beam center from the config file
    // We're adding this to be compatible with the original EQSANS load
    // written in python
    if (m_center_x==0.0 && m_center_y==0.0)
    {
      setProperty("UseConfigBeam", true);
    }

    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 = createChildAlgorithm("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->executeAsChildAlg();
  }

  // Get source aperture radius
  getSourceSlitSize();

  // Move the beam center to its proper position
  if (!noBeamCenter)
  {
    if (isEmpty(m_center_x) || isEmpty(m_center_y))
    {
      if (reductionManager->existsProperty("LatestBeamCenterX") &&
          reductionManager->existsProperty("LatestBeamCenterY"))
      {
        m_center_x = reductionManager->getProperty("LatestBeamCenterX");
        m_center_y = reductionManager->getProperty("LatestBeamCenterY");
      }
    }
    moveToBeamCenter();

    // Add beam center to reduction properties, as the last beam center position that was used.
    // This will give us our default position next time.
    if (!reductionManager->existsProperty("LatestBeamCenterX"))
      reductionManager->declareProperty(new PropertyWithValue<double>("LatestBeamCenterX", m_center_x) );
    else reductionManager->setProperty("LatestBeamCenterX", m_center_x);
    if (!reductionManager->existsProperty("LatestBeamCenterY"))
      reductionManager->declareProperty(new PropertyWithValue<double>("LatestBeamCenterY", m_center_y) );
    else reductionManager->setProperty("LatestBeamCenterY", m_center_y);
  }

  // Modify TOF
  const bool correct_for_flight_path = getProperty("CorrectForFlightPath");
  double wl_min = 0.0;
  double wl_max = 0.0;
  double wl_combined_max = 0.0;
  if (skipTOFCorrection)
  {
    m_output_message += "    Skipping EQSANS TOF correction: assuming a single frame\n";
    dataWS->mutableRun().addProperty("is_frame_skipping", 0, true);
    if (correct_for_flight_path)
    {
      g_log.error() << "CorrectForFlightPath and SkipTOFCorrection can't be set to true at the same time" << std::endl;
      m_output_message += "    Skipped flight path correction: see error log\n";
    }
  }
  else
  {
    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);
    IAlgorithm_sptr tofAlg = createChildAlgorithm("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->executeAsChildAlg();
    wl_min = tofAlg->getProperty("WavelengthMin");
    wl_max = tofAlg->getProperty("WavelengthMax");
    if (wl_min != wl_min || wl_max != wl_max)
    {
      g_log.error() << "Bad wavelength range" << std::endl;
      g_log.error() << m_output_message << std::endl;
    }

    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);
    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";

  if (skipTOFCorrection)
  {
    DataObjects::EventWorkspace_sptr dataWS_evt = boost::dynamic_pointer_cast<EventWorkspace>(dataWS);
    if (dataWS_evt->getNumberEvents()==0)
      throw std::invalid_argument("No event to process: check your TOF cuts");
    wl_min = dataWS_evt->getTofMin()*conversion_factor;
    wl_max = dataWS_evt->getTofMax()*conversion_factor;
    wl_combined_max = wl_max;
    g_log.information() << "Wavelength range: " << wl_min << " to " << wl_max << std::endl;
    dataWS->mutableRun().addProperty("wavelength_min", wl_min, "Angstrom", true);
    dataWS->mutableRun().addProperty("wavelength_max", wl_max, "Angstrom", true);
  }

  IAlgorithm_sptr scAlg = createChildAlgorithm("ScaleX", 0.7, 0.71);
  scAlg->setProperty<MatrixWorkspace_sptr>("InputWorkspace", dataWS);
  scAlg->setProperty<MatrixWorkspace_sptr>("OutputWorkspace", dataWS);
  scAlg->setProperty("Factor", conversion_factor);
  scAlg->executeAsChildAlg();
  dataWS->getAxis(0)->setUnit("Wavelength");

  // Rebin so all the wavelength bins are aligned
  const bool preserveEvents = getProperty("PreserveEvents");
  const double wl_step = getProperty("WavelengthStep");
  std::string params = Poco::NumberFormatter::format(wl_min, 2) + ","
		  + Poco::NumberFormatter::format(wl_step, 2) + ","
		  + Poco::NumberFormatter::format(wl_combined_max, 2);
  IAlgorithm_sptr rebinAlg = createChildAlgorithm("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->executeAsChildAlg();

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

  dataWS->mutableRun().addProperty("event_ws", getPropertyValue("OutputWorkspace"), true);
  setProperty<MatrixWorkspace_sptr>("OutputWorkspace", boost::dynamic_pointer_cast<MatrixWorkspace>(dataWS));
  //m_output_message = "Loaded " + fileName + '\n' + m_output_message;
  setPropertyValue("OutputMessage", m_output_message);
}
void DataBus::AbstractClient::processSetClientPropertyValueRequestPacket(const Packet &packet)
{
    // Check if registered
    if (m_registered == false)
    {
        // Error, can't send a response if not registered
        return;
    }

    // Check destination
    if (packet.getDestination() != m_clientId)
    {
        // Error, invalid destination
        return;
    }

    // Get Property ID and Value
    quint8 propertyId;
    Value propertyValue;

    if (SetClientPropertyValueRequestPacket::parse(packet,
                                                   &propertyId,
                                                   &propertyValue) == false)
    {
        // Error, failed to parse packet
        return;
    }

    // Set Property Value
    quint8 returnStatus = RETURN_STATUS_SUCCESS;

    if (setPropertyValue(propertyId, propertyValue) == false)
    {
        // Error, failed to get property value
        returnStatus = RETURN_STATUS_INVALID_PROPERTY_ID;
    }

    // Create response
    Packet responsePacket;

    if (SetClientPropertyValueResponsePacket::create(m_clientId,
                                                     packet.getSource(),
                                                     packet.getPacketId(),
                                                     propertyId,
                                                     returnStatus,
                                                     &responsePacket) == false)
    {
        // Error, failed to create packet
        return;
    }

    // Send Response
    if (sendPacket(responsePacket) == false)
    {
        // Error, failed to create packet
        return;
    }

    // Success
    return;
}
Esempio n. 5
0
void FontFace::setPropertyFromString(const String& s, CSSPropertyID propertyID, ExceptionState& es)
{
    RefPtr<CSSValue> value = parseCSSValue(s, propertyID);
    if (!value || !setPropertyValue(value, propertyID))
        es.throwDOMException(SyntaxError);
}
Esempio n. 6
0
bool FontFace::setPropertyFromStyle(const StylePropertySet* properties, CSSPropertyID propertyID)
{
    return setPropertyValue(properties->getPropertyCSSValue(propertyID), propertyID);
}
Esempio n. 7
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);
}
Esempio n. 8
0
//----------------------------------------------------------------------------------------------
/// Examine the chi squared as a function of fitting parameters and estimate
/// errors for each parameter.
void CalculateChiSquared::estimateErrors() {
  // Number of fiting parameters
  auto nParams = m_function->nParams();
  // Create an output table for displaying slices of the chi squared and
  // the probabilitydensity function
  auto pdfTable = API::WorkspaceFactory::Instance().createTable();

  std::string baseName = getProperty("Output");
  if (baseName.empty()) {
    baseName = "CalculateChiSquared";
  }
  declareProperty(new API::WorkspaceProperty<API::ITableWorkspace>(
                      "PDFs", "", Kernel::Direction::Output),
                  "The name of the TableWorkspace in which to store the "
                  "pdfs of fit parameters");
  setPropertyValue("PDFs", baseName + "_pdf");
  setProperty("PDFs", pdfTable);

  // Create an output table for displaying the parameter errors.
  auto errorsTable = API::WorkspaceFactory::Instance().createTable();
  auto nameColumn = errorsTable->addColumn("str", "Parameter");
  auto valueColumn = errorsTable->addColumn("double", "Value");
  auto minValueColumn = errorsTable->addColumn("double", "Value at Min");
  auto leftErrColumn = errorsTable->addColumn("double", "Left Error");
  auto rightErrColumn = errorsTable->addColumn("double", "Right Error");
  auto quadraticErrColumn = errorsTable->addColumn("double", "Quadratic Error");
  auto chiMinColumn = errorsTable->addColumn("double", "Chi2 Min");
  errorsTable->setRowCount(nParams);
  declareProperty(new API::WorkspaceProperty<API::ITableWorkspace>(
                      "Errors", "", Kernel::Direction::Output),
                  "The name of the TableWorkspace in which to store the "
                  "values and errors of fit parameters");
  setPropertyValue("Errors", baseName + "_errors");
  setProperty("Errors", errorsTable);

  // Calculate initial values
  double chiSquared = 0.0;
  double chiSquaredWeighted = 0.0;
  double dof = 0;
  API::FunctionDomain_sptr domain;
  API::FunctionValues_sptr values;
  m_domainCreator->createDomain(domain, values);
  calcChiSquared(*m_function, nParams, *domain, *values, chiSquared,
                 chiSquaredWeighted, dof);
  // Value of chi squared for current parameters in m_function
  double chi0 = chiSquared;
  // Fit data variance
  double sigma2 = chiSquared / dof;
  bool useWeighted = getProperty("Weighted");

  if (useWeighted) {
    chi0 = chiSquaredWeighted;
    sigma2 = 0.0;
  }

  if (g_log.is(Kernel::Logger::Priority::PRIO_DEBUG)) {
    g_log.debug() << "chi0=" << chi0 << std::endl;
    g_log.debug() << "sigma2=" << sigma2 << std::endl;
    g_log.debug() << "dof=" << dof << std::endl;
  }

  // Parameter bounds that define a volume in the parameter
  // space within which the chi squared is being examined.
  GSLVector lBounds(nParams);
  GSLVector rBounds(nParams);

  // Number of points in lines for plotting
  size_t n = 100;
  pdfTable->setRowCount(n);
  const double fac = 1e-4;

  // Loop over each parameter
  for (size_t ip = 0; ip < nParams; ++ip) {

    // Add columns for the parameter to the pdf table.
    auto parName = m_function->parameterName(ip);
    nameColumn->read(ip, parName);
    // Parameter values
    auto col1 = pdfTable->addColumn("double", parName);
    col1->setPlotType(1);
    // Chi squared values
    auto col2 = pdfTable->addColumn("double", parName + "_chi2");
    col2->setPlotType(2);
    // PDF values
    auto col3 = pdfTable->addColumn("double", parName + "_pdf");
    col3->setPlotType(2);

    double par0 = m_function->getParameter(ip);
    double shift = fabs(par0 * fac);
    if (shift == 0.0) {
      shift = fac;
    }

    // Make a slice along this parameter
    GSLVector dir(nParams);
    dir.zero();
    dir[ip] = 1.0;
    ChiSlice slice(*m_function, dir, *domain, *values, chi0, sigma2);

    // Find the bounds withn which the PDF is significantly above zero.
    // The bounds are defined relative to par0:
    //   par0 + lBound is the lowest value of the parameter (lBound <= 0)
    //   par0 + rBound is the highest value of the parameter (rBound >= 0)
    double lBound = slice.findBound(-shift);
    double rBound = slice.findBound(shift);
    lBounds[ip] = lBound;
    rBounds[ip] = rBound;

    // Approximate the slice with a polynomial.
    // P is a vector of values of the polynomial at special points.
    // A is a vector of Chebyshev expansion coefficients.
    // The polynomial is defined on interval [lBound, rBound]
    // The value of the polynomial at 0 == chi squared at par0
    std::vector<double> P, A;
    bool ok = true;
    auto base = slice.makeApprox(lBound, rBound, P, A, ok);
    if (!ok) {
      g_log.warning() << "Approximation failed for parameter " << ip
                      << std::endl;
    }
    if (g_log.is(Kernel::Logger::Priority::PRIO_DEBUG)) {
      g_log.debug() << "Parameter " << ip << std::endl;
      g_log.debug() << "Slice approximated by polynomial of order "
                    << base->size() - 1;
      g_log.debug() << " between " << lBound << " and " << rBound << std::endl;
    }

    // Write n slice points into the output table.
    double dp = (rBound - lBound) / static_cast<double>(n);
    for (size_t i = 0; i < n; ++i) {
      double par = lBound + dp * static_cast<double>(i);
      double chi = base->eval(par, P);
      col1->fromDouble(i, par0 + par);
      col2->fromDouble(i, chi);
    }

    // Check if par0 is a minimum point of the chi squared
    std::vector<double> AD;
    // Calculate the derivative polynomial.
    // AD are the Chebyshev expansion of the derivative.
    base->derivative(A, AD);
    // Find the roots of the derivative polynomial
    std::vector<double> minima = base->roots(AD);
    if (minima.empty()) {
      minima.push_back(par0);
    }

    if (g_log.is(Kernel::Logger::Priority::PRIO_DEBUG)) {
      g_log.debug() << "Minima: ";
    }

    // If only 1 extremum is found assume (without checking) that it's a
    // minimum.
    // If there are more than 1, find the one with the smallest chi^2.
    double chiMin = std::numeric_limits<double>::max();
    double parMin = par0;
    for (size_t i = 0; i < minima.size(); ++i) {
      double value = base->eval(minima[i], P);
      if (g_log.is(Kernel::Logger::Priority::PRIO_DEBUG)) {
        g_log.debug() << minima[i] << " (" << value << ") ";
      }
      if (value < chiMin) {
        chiMin = value;
        parMin = minima[i];
      }
    }
    if (g_log.is(Kernel::Logger::Priority::PRIO_DEBUG)) {
      g_log.debug() << std::endl;
      g_log.debug() << "Smallest minimum at " << parMin << " is " << chiMin
                    << std::endl;
    }

    // Points of intersections with line chi^2 = 1/2 give an estimate of
    // the standard deviation of this parameter if it's uncorrelated with the
    // others.
    A[0] -= 0.5; // Now A are the coefficients of the original polynomial
                 // shifted down by 1/2.
    std::vector<double> roots = base->roots(A);
    std::sort(roots.begin(), roots.end());

    if (roots.empty()) {
      // Something went wrong; use the whole interval.
      roots.resize(2);
      roots[0] = lBound;
      roots[1] = rBound;
    } else if (roots.size() == 1) {
      // Only one root found; use a bound for the other root.
      if (roots.front() < 0) {
        roots.push_back(rBound);
      } else {
        roots.insert(roots.begin(), lBound);
      }
    } else if (roots.size() > 2) {
      // More than 2 roots; use the smallest and the biggest
      auto smallest = roots.front();
      auto biggest = roots.back();
      roots.resize(2);
      roots[0] = smallest;
      roots[1] = biggest;
    }

    if (g_log.is(Kernel::Logger::Priority::PRIO_DEBUG)) {
      g_log.debug() << "Roots: ";
      for (size_t i = 0; i < roots.size(); ++i) {
        g_log.debug() << roots[i] << ' ';
      }
      g_log.debug() << std::endl;
    }

    // Output parameter info to the table.
    valueColumn->fromDouble(ip, par0);
    minValueColumn->fromDouble(ip, par0 + parMin);
    leftErrColumn->fromDouble(ip, roots[0] - parMin);
    rightErrColumn->fromDouble(ip, roots[1] - parMin);
    chiMinColumn->fromDouble(ip, chiMin);

    // Output the PDF
    for (size_t i = 0; i < n; ++i) {
      double chi = col2->toDouble(i);
      col3->fromDouble(i, exp(-chi + chiMin));
    }

    // make sure function parameters don't change.
    m_function->setParameter(ip, par0);
  }

  // Improve estimates for standard deviations.
  // If parameters are correlated the found deviations
  // most likely underestimate the true values.
  unfixParameters();
  GSLJacobian J(m_function, values->size());
  m_function->functionDeriv(*domain, J);
  refixParameters();
  // Calculate the hessian at the current point.
  GSLMatrix H;
  if (useWeighted) {
    H.resize(nParams, nParams);
    for (size_t i = 0; i < nParams; ++i) {
      for (size_t j = i; j < nParams; ++j) {
        double h = 0.0;
        for (size_t k = 0; k < values->size(); ++k) {
          double w = values->getFitWeight(k);
          h += J.get(k, i) * J.get(k, j) * w * w;
        }
        H.set(i, j, h);
        if (i != j) {
          H.set(j, i, h);
        }
      }
    }
  } else {
    H = Tr(J.matrix()) * J.matrix();
  }
  // Square roots of the diagonals of the covariance matrix give
  // the standard deviations in the quadratic approximation of the chi^2.
  GSLMatrix V(H);
  if (!useWeighted) {
    V *= 1. / sigma2;
  }
  V.invert();
  // In a non-quadratic asymmetric case the following procedure can give a
  // better result:
  // Find the direction in which the chi^2 changes slowest and the positive and
  // negative deviations in that direction. The change in a parameter at those
  // points can be a better estimate for the standard deviation.
  GSLVector v(nParams);
  GSLMatrix Q(nParams, nParams);
  // One of the eigenvectors of the hessian is the direction of the slowest
  // change.
  H.eigenSystem(v, Q);

  // Loop over the eigenvectors
  for (size_t i = 0; i < nParams; ++i) {
    auto dir = Q.copyColumn(i);
    if (g_log.is(Kernel::Logger::Priority::PRIO_DEBUG)) {
      g_log.debug() << "Direction " << i << std::endl;
      g_log.debug() << dir << std::endl;
    }
    // Make a slice in that direction
    ChiSlice slice(*m_function, dir, *domain, *values, chi0, sigma2);
    double rBound0 = dir.dot(rBounds);
    double lBound0 = dir.dot(lBounds);
    if (g_log.is(Kernel::Logger::Priority::PRIO_DEBUG)) {
      g_log.debug() << "lBound " << lBound0 << std::endl;
      g_log.debug() << "rBound " << rBound0 << std::endl;
    }
    double lBound = slice.findBound(lBound0);
    double rBound = slice.findBound(rBound0);
    std::vector<double> P, A;
    // Use a polynomial approximation
    bool ok = true;
    auto base = slice.makeApprox(lBound, rBound, P, A, ok);
    if (!ok) {
      g_log.warning() << "Approximation failed in direction " << i << std::endl;
    }
    // Find the deviation points where the chi^2 = 1/2
    A[0] -= 0.5;
    std::vector<double> roots = base->roots(A);
    std::sort(roots.begin(), roots.end());
    // Sort out the roots
    auto nRoots = roots.size();
    if (nRoots == 0) {
      roots.resize(2, 0.0);
    } else if (nRoots == 1) {
      if (roots.front() > 0.0) {
        roots.insert(roots.begin(), 0.0);
      } else {
        roots.push_back(0.0);
      }
    } else if (nRoots > 2) {
      roots[1] = roots.back();
      roots.resize(2);
    }
    if (g_log.is(Kernel::Logger::Priority::PRIO_DEBUG)) {
      g_log.debug() << "Roots " << roots[0] << " (" << slice(roots[0]) << ") "
                    << roots[1] << " (" << slice(roots[1]) << ") " << std::endl;
    }
    // Loop over the parameters and see if there deviations along
    // this direction is greater than any previous value.
    for (size_t ip = 0; ip < nParams; ++ip) {
      auto lError = roots.front() * dir[ip];
      auto rError = roots.back() * dir[ip];
      if (lError > rError) {
        std::swap(lError, rError);
      }
      if (lError < leftErrColumn->toDouble(ip)) {
        if (g_log.is(Kernel::Logger::Priority::PRIO_DEBUG)) {
          g_log.debug() << "  left for  " << ip << ' ' << lError << ' '
                        << leftErrColumn->toDouble(ip) << std::endl;
        }
        leftErrColumn->fromDouble(ip, lError);
      }
      if (rError > rightErrColumn->toDouble(ip)) {
        if (g_log.is(Kernel::Logger::Priority::PRIO_DEBUG)) {
          g_log.debug() << "  right for " << ip << ' ' << rError << ' '
                        << rightErrColumn->toDouble(ip) << std::endl;
        }
        rightErrColumn->fromDouble(ip, rError);
      }
    }
    // Output the quadratic estimate for comparrison.
    quadraticErrColumn->fromDouble(i, sqrt(V.get(i, i)));
  }
}
Esempio n. 9
0
  /** Executes the algorithm
  *
  *  @throw runtime_error Thrown if algorithm cannot execute
  */
  void GenericFit::exec()
  {
    // Try to retrieve optional properties
    const int maxInterations = getProperty("MaxIterations");

    Progress prog(this,0.0,1.0,maxInterations?maxInterations:1);

    std::string funIni = getProperty("Function");
    m_function.reset( API::FunctionFactory::Instance().createInitialized(funIni) );

    if (m_function.get() == NULL)
    {
      throw std::runtime_error("Function was not set.");
    }

    prog.report("Setting workspace");
    API::Workspace_sptr ws = getProperty("InputWorkspace");
    std::string input = getProperty("Input");
    m_function->setWorkspace(ws,input);

    prog.report("Setting minimizer");
    // force initial parameters to satisfy constraints of function
    m_function->setParametersToSatisfyConstraints();

    // check if derivative defined in derived class
    bool isDerivDefined = true;
    try
    {
      m_function->functionDeriv(NULL);
    }
    catch (Exception::NotImplementedError&)
    {
      isDerivDefined = false;
    }

    // What minimizer to use
    std::string methodUsed = getProperty("Minimizer");
    if ( !isDerivDefined && methodUsed.compare("Simplex") != 0 )
    {
      methodUsed = "Simplex";
      g_log.information() << "No derivatives available for this fitting function"
                          << " therefore Simplex method used for fitting\n";
    }

    // set-up minimizer

    std::string costFunction = getProperty("CostFunction");
    IFuncMinimizer* minimizer = FuncMinimizerFactory::Instance().createUnwrapped(methodUsed);
    minimizer->initialize(m_function.get(), costFunction);

    // create and populate data containers. Warn user if nData < nParam 
    // since as a rule of thumb this is required as a minimum to obtained 'accurate'
    // fitting parameter values.

    const size_t nParam = m_function->nActive();
    const size_t nData = m_function->dataSize();
    if (nParam == 0)
    {
      g_log.error("There are no active parameters.");
      setProperty("OutputChi2overDoF", minimizer->costFunctionVal());
      throw std::runtime_error("There are no active parameters.");
    }
    if (nData == 0)
    {
      g_log.error("The data set is empty.");
      throw std::runtime_error("The data set is empty.");
    }
    if (nData < nParam)
    {
      g_log.error("Number of data points less than number of parameters to be fitted.");
      throw std::runtime_error("Number of data points less than number of parameters to be fitted.");
    }

    // finally do the fitting

    int iter = 0;
    int status = 0;
    double finalCostFuncVal = 0.0;
    double dof = static_cast<double>(nData - nParam);  // dof stands for degrees of freedom

    // Standard least-squares used if derivative function defined otherwise simplex
    if ( methodUsed.compare("Simplex") != 0 )
    {
      status = GSL_CONTINUE;
      while (status == GSL_CONTINUE && iter < maxInterations)
      {
        iter++;

        status = minimizer->iterate();

        if (status != GSL_SUCCESS && minimizer->hasConverged() != GSL_SUCCESS)
        { 
          // From experience it is found that gsl_multifit_fdfsolver_iterate occasionally get
          // stock - even after having achieved a sensible fit. This seem in particular to be a
          // problem on Linux. For now only fall back to Simplex if iter = 1 or 2, i.e.   
          // gsl_multifit_fdfsolver_iterate has failed on the first or second hurdle
          if (iter < 3)
          {
            g_log.warning() << "GenericFit algorithm using " << methodUsed << " failed "
              << "reporting the following: " << gsl_strerror(status) << "\n"
              << "Try using Simplex method instead\n";
            methodUsed = "Simplex";
            delete minimizer;
            minimizer = FuncMinimizerFactory::Instance().createUnwrapped(methodUsed);
            minimizer->initialize(m_function.get(), costFunction);
            iter = 0;
          }
          break;
        }
        
        status = minimizer->hasConverged();
        prog.report("Iteration "+boost::lexical_cast<std::string>(iter));
      }

      finalCostFuncVal = minimizer->costFunctionVal() / dof;
    }


    if ( methodUsed.compare("Simplex") == 0 )
    {
      status = GSL_CONTINUE;
      while (status == GSL_CONTINUE && iter < maxInterations)
      {
        iter++;
        status = minimizer->iterate();

        if (status)  // break if error
        {
          // if failed at first iteration try reducing the initial step size
          if (iter == 1)
          { 
            g_log.information() << "Simplex step size reduced to 0.1\n";
            delete minimizer;
            SimplexMinimizer* sm = new SimplexMinimizer;
            sm->initialize(m_function.get(), costFunction);
            sm->resetSize(0.1, m_function.get(), costFunction);
            minimizer = sm;
            status = GSL_CONTINUE;
            continue;
          }
          break;
        }

        status = minimizer->hasConverged();
        prog.report("Iteration "+boost::lexical_cast<std::string>(iter));
      }

      finalCostFuncVal = minimizer->costFunctionVal() / dof;
    }

    // Output summary to log file

    std::string reportOfFit = gsl_strerror(status);

    g_log.information() << "Method used = " << methodUsed << "\n" <<
      "Iteration = " << iter << "\n";
    Mantid::API::ICostFunction* costfun 
     = Mantid::API::CostFunctionFactory::Instance().createUnwrapped(costFunction);
    if ( reportOfFit == "success" )
      g_log.notice() << reportOfFit << "  " << costfun->shortName() << 
         " (" << costfun->name() << ") = " << finalCostFuncVal << "\n";
    else
      g_log.warning() << reportOfFit << "  " << costfun->shortName() << 
         " (" << costfun->name() << ") = " << finalCostFuncVal << "\n";
    for (size_t i = 0; i < m_function->nParams(); i++)
    {
      g_log.debug() << m_function->parameterName(i) << " = " << m_function->getParameter(i) << "  \n";
    }


    // also output summary to properties

    setProperty("OutputStatus", reportOfFit);
    setProperty("OutputChi2overDoF", finalCostFuncVal);
    setProperty("Minimizer", methodUsed);
    setPropertyValue("Function",*m_function);
    

    // if Output property is specified output additional workspaces

    std::vector<double> standardDeviations;
    std::string output = getProperty("Output");
    gsl_matrix *covar(NULL);

    // only if derivative is defined for fitting function create covariance matrix output workspace
    if ( isDerivDefined )    
    {
      // calculate covariance matrix
      covar = gsl_matrix_alloc (nParam, nParam);
      minimizer->calCovarianceMatrix( 0.0, covar);

      // take standard deviations to be the square root of the diagonal elements of
      // the covariance matrix
      int iPNotFixed = 0;
      for(size_t i=0; i < m_function->nParams(); i++)
      {
        standardDeviations.push_back(1.0);
        if (m_function->isActive(i))
        {
          standardDeviations[i] = sqrt(gsl_matrix_get(covar,iPNotFixed,iPNotFixed));
          if (m_function->activeParameter(iPNotFixed) != m_function->getParameter(m_function->indexOfActive(iPNotFixed)))
          {// it means the active param is not the same as declared but transformed
            standardDeviations[i] *= fabs(transformationDerivative(iPNotFixed));
          }
          iPNotFixed++;
        }
      }
    }

    if (!output.empty())
    {
      // only if derivative is defined for fitting function create covariance matrix output workspace
      if ( isDerivDefined )    
      {
        // Create covariance matrix output workspace
        declareProperty(
          new WorkspaceProperty<API::ITableWorkspace>("OutputNormalisedCovarianceMatrix","",Direction::Output),
          "The name of the TableWorkspace in which to store the final covariance matrix" );
        setPropertyValue("OutputNormalisedCovarianceMatrix",output+"_NormalisedCovarianceMatrix");

        Mantid::API::ITableWorkspace_sptr m_covariance = Mantid::API::WorkspaceFactory::Instance().createTable("TableWorkspace");
        m_covariance->addColumn("str","Name");
        std::vector<std::string> paramThatAreFitted; // used for populating 1st "name" column
        for(size_t i=0; i < m_function->nParams(); i++)
        {
          if (m_function->isActive(i)) 
          {
            m_covariance->addColumn("double",m_function->parameterName(i));
            paramThatAreFitted.push_back(m_function->parameterName(i));
          }
        }

        for(size_t i=0; i<nParam; i++)
        {
          Mantid::API::TableRow row = m_covariance->appendRow();
          row << paramThatAreFitted[i];
          for(size_t j=0; j<nParam; j++)
          {
            if (j == i)
              row << 100.0;
            else
            {
              row << 100.0*gsl_matrix_get(covar,i,j)/sqrt(gsl_matrix_get(covar,i,i)*gsl_matrix_get(covar,j,j));
            }
          }
        }

        setProperty("OutputNormalisedCovarianceMatrix",m_covariance);
      }

      // create output parameter table workspace to store final fit parameters 
      // including error estimates if derivative of fitting function defined

      declareProperty(
        new WorkspaceProperty<API::ITableWorkspace>("OutputParameters","",Direction::Output),
        "The name of the TableWorkspace in which to store the final fit parameters" );

      setPropertyValue("OutputParameters",output+"_Parameters");

      Mantid::API::ITableWorkspace_sptr m_result = Mantid::API::WorkspaceFactory::Instance().createTable("TableWorkspace");
      m_result->addColumn("str","Name");
      m_result->addColumn("double","Value");
      if ( isDerivDefined ) 
        m_result->addColumn("double","Error");

      for(size_t i=0;i<m_function->nParams();i++)
      {
        Mantid::API::TableRow row = m_result->appendRow();
        row << m_function->parameterName(i) << m_function->getParameter(i);
        if ( isDerivDefined && m_function->isActive(i)) 
        {
          row << standardDeviations[i];
        }
      }
      // Add chi-squared value at the end of parameter table
      Mantid::API::TableRow row = m_result->appendRow();
      row << "Cost function value" << finalCostFuncVal;      
      setProperty("OutputParameters",m_result);


      if ( isDerivDefined ) 
        gsl_matrix_free(covar);
    }

    // Add Parameters, Errors and ParameterNames properties to output so they can be queried on the algorithm.
    declareProperty(new ArrayProperty<double> ("Parameters",new NullValidator<std::vector<double> >,Direction::Output));
    declareProperty(new ArrayProperty<double> ("Errors",new NullValidator<std::vector<double> >,Direction::Output));
    declareProperty(new ArrayProperty<std::string> ("ParameterNames",new NullValidator<std::vector<std::string> >,Direction::Output));
    std::vector<double> params,errors;
    std::vector<std::string> parNames;

    for(size_t i=0;i<m_function->nParams();i++)
    {
      parNames.push_back(m_function->parameterName(i));
      params.push_back(m_function->getParameter(i));
      if (!standardDeviations.empty())
      {
        errors.push_back(standardDeviations[i]);
      }
      else
      {
        errors.push_back(0.);
      }
    }
    setProperty("Parameters",params);
    setProperty("Errors",errors);
    setProperty("ParameterNames",parNames);
    
    // minimizer may have dynamically allocated memory hence make sure this memory is freed up
    delete minimizer;

    return;
  }
void HFIRDarkCurrentSubtraction::exec()
{
  std::string output_message = "";
  // Reduction property manager
  const std::string reductionManagerName = getProperty("ReductionProperties");
  boost::shared_ptr<PropertyManager> reductionManager;
  if (PropertyManagerDataService::Instance().doesExist(reductionManagerName))
  {
    reductionManager = PropertyManagerDataService::Instance().retrieve(reductionManagerName);
  }
  else
  {
    reductionManager = boost::make_shared<PropertyManager>();
    PropertyManagerDataService::Instance().addOrReplace(reductionManagerName, reductionManager);
  }

  // If the load algorithm isn't in the reduction properties, add it
  const bool persistent = getProperty("PersistentCorrection");
  if (!reductionManager->existsProperty("DarkCurrentAlgorithm") && persistent)
  {
    AlgorithmProperty *algProp = new AlgorithmProperty("DarkCurrentAlgorithm");
    algProp->setValue(toString());
    reductionManager->declareProperty(algProp);
  }

  Progress progress(this,0.0,1.0,10);

  MatrixWorkspace_sptr inputWS = getProperty("InputWorkspace");
  const std::string fileName = getPropertyValue("Filename");
  MatrixWorkspace_sptr darkWS;
  std::string darkWSName = getPropertyValue("OutputDarkCurrentWorkspace");

  progress.report("Subtracting dark current");

  // Look for an entry for the dark current in the reduction table
  Poco::Path path(fileName);
  const std::string entryName = "DarkCurrent"+path.getBaseName();

  if (reductionManager->existsProperty(entryName))
  {
    darkWS = reductionManager->getProperty(entryName);
    darkWSName = reductionManager->getPropertyValue(entryName);
    output_message += darkWSName + '\n';
  } else {
    // Load the dark current if we don't have it already
    if (darkWSName.size()==0)
    {
      darkWSName = "__dark_current_"+path.getBaseName();
      setPropertyValue("OutputDarkCurrentWorkspace", darkWSName);
    }

    IAlgorithm_sptr loadAlg;
    if (!reductionManager->existsProperty("LoadAlgorithm"))
    {
      loadAlg = createChildAlgorithm("HFIRLoad", 0.1, 0.3);
      loadAlg->setProperty("Filename", fileName);
      loadAlg->setProperty("ReductionProperties", reductionManagerName);
      loadAlg->executeAsChildAlg();
    } else {
      IAlgorithm_sptr loadAlg0 = reductionManager->getProperty("LoadAlgorithm");
      const std::string loadString = loadAlg0->toString();
      loadAlg = Algorithm::fromString(loadString);
      loadAlg->setChild(true);
      loadAlg->setProperty("Filename", fileName);
      loadAlg->setProperty("ReductionProperties", reductionManagerName);
      loadAlg->setPropertyValue("OutputWorkspace", darkWSName);
      loadAlg->execute();
    }
    darkWS = loadAlg->getProperty("OutputWorkspace");
    output_message += "\n   Loaded " + fileName + "\n";
    if (loadAlg->existsProperty("OutputMessage"))
    {
      std::string msg = loadAlg->getPropertyValue("OutputMessage");
      output_message += "   |" + Poco::replace(msg, "\n", "\n   |") + "\n";
    }

    setProperty("OutputDarkCurrentWorkspace", darkWS);
    reductionManager->declareProperty(new WorkspaceProperty<>(entryName,"",Direction::Output));
    reductionManager->setPropertyValue(entryName, darkWSName);
    reductionManager->setProperty(entryName, darkWS);
  }
  progress.report(3, "Loaded dark current");

  // Perform subtraction
  double darkTimer = getCountingTime(darkWS);
  double dataTimer = getCountingTime(inputWS);
  IAlgorithm_sptr scaleAlg = createChildAlgorithm("Scale", 0.3, 0.5);
  scaleAlg->setProperty("InputWorkspace", darkWS);
  scaleAlg->setProperty("Factor", dataTimer/darkTimer);
  scaleAlg->setProperty("Operation", "Multiply");
  scaleAlg->executeAsChildAlg();
  MatrixWorkspace_sptr scaledDarkWS = scaleAlg->getProperty("OutputWorkspace");

  // Zero out timer and monitor so that we don't subtract them out
  for(size_t i=0; i<scaledDarkWS->dataY(0).size(); i++)
  {
    scaledDarkWS->dataY(DEFAULT_TIMER_ID)[i]=0.0;
    scaledDarkWS->dataE(DEFAULT_TIMER_ID)[i]=0.0;
    scaledDarkWS->dataY(DEFAULT_MONITOR_ID)[i]=0.0;
    scaledDarkWS->dataE(DEFAULT_MONITOR_ID)[i]=0.0;
  }
  IAlgorithm_sptr minusAlg = createChildAlgorithm("Minus", 0.5, 0.7);
  minusAlg->setProperty("LHSWorkspace", inputWS);
  minusAlg->setProperty("RHSWorkspace", scaledDarkWS);
  MatrixWorkspace_sptr outputWS = getProperty("OutputWorkspace");
  minusAlg->setProperty("OutputWorkspace", outputWS);
  minusAlg->executeAsChildAlg();
  MatrixWorkspace_sptr correctedWS = minusAlg->getProperty("OutputWorkspace");
  setProperty("OutputWorkspace", correctedWS);
  setProperty("OutputMessage", "Dark current subtracted: "+output_message);

  progress.report("Subtracted dark current");
}
AnimatableValueKeyframe::AnimatableValueKeyframe(const AnimatableValueKeyframe& copyFrom)
    : Keyframe(copyFrom.m_offset, copyFrom.m_composite, copyFrom.m_easing)
{
    for (PropertyValueMap::const_iterator iter = copyFrom.m_propertyValues.begin(); iter != copyFrom.m_propertyValues.end(); ++iter)
        setPropertyValue(iter->key, iter->value.get());
}
Esempio n. 12
0
	bool CameraGigeSdkIc::grabSingleImage(Frame &frame, int camID){

		// Retrieve a list with the video capture devices connected to the computer.
		DShowLib::Grabber::tVidCapDevListPtr pVidCapDevList = m_pGrabber->getAvailableVideoCaptureDevices();
		
		if(pVidCapDevList == 0 || pVidCapDevList->empty()){

			cout << "No device available." << endl;
			return false;

		}else{

			// Print available devices.
			int numCam = -1;
			for(int i = 0; i < pVidCapDevList->size(); i++){
				
				cout << "(" << i << ") " << pVidCapDevList->at(i).c_str() << endl;

				if(camID == i){
					numCam = i; 
					break;
				}

			}

			if(numCam == -1){

				return false;

			}else{

				// Open the selected video capture device.
				m_pGrabber->openDev(pVidCapDevList->at(numCam));

				/*cout << "Available video formats : " << endl;

				DShowLib::Grabber::tVidFmtDescListPtr DecriptionList;

				DecriptionList = m_pGrabber->getAvailableVideoFormatDescs();

				for( DShowLib::Grabber::tVidFmtDescList::iterator pDescription = DecriptionList->begin(); pDescription != DecriptionList->end(); pDescription++ )
				{
					printf("%s\n", (*pDescription)->toString().c_str());
				}*/
				
				DShowLib::tFrameHandlerSinkPtr pSink;

				cout << "Current bits per pixel : " << m_pGrabber->getVideoFormat().getBitsPerPixel() << endl;

				

				switch(frame.getBitDepth()){
					
					case MONO_8 :

						m_pGrabber->setVideoFormat("Y8 (1280x960-1280x960)");

						// Set the image buffer format to eY800. eY800 means monochrome, 8 bits (1 byte) per pixel.
						// Let the sink create a matching MemBufferCollection with 1 buffer.
						pSink = DShowLib::FrameHandlerSink::create( DShowLib::eY800, 1 );

						break;

					case MONO_12 :
						
						m_pGrabber->setVideoFormat("Y16 (1280x960-1280x960)");

						// Disable overlay.
						// http://www.theimagingsourceforums.com/archive/index.php/t-319880.html
						m_pGrabber->setOverlayBitmapPathPosition(DShowLib::ePP_NONE);

						// Set the image buffer format to eY16. eY16 means monochrome, 16 bits (2 byte) per pixel.
						// Let the sink create a matching MemBufferCollection with 1 buffer.
						pSink = DShowLib::FrameHandlerSink::create( DShowLib::eY16, 1 );

						break;
						
					default:
												
						return false;

						break;
				}

				cout << "New video format : " << m_pGrabber->getVideoFormat().getBitsPerPixel() << endl;
 
				// Get properties.
				_DSHOWLIB_NAMESPACE::tIVCDPropertyItemsPtr pItems = m_pGrabber->getAvailableVCDProperties();

				// Set Exposure time.
				int exposure = frame.getExposure();
								
				long eMin  = getPropertyRangeMin(DShowLib::VCDID_Exposure, pItems);
				long eMax  = getPropertyRangeMax(DShowLib::VCDID_Exposure, pItems);
				long e = getPropertyValue(DShowLib::VCDID_Exposure, pItems);

				cout << "Previous exposure time value : " << e << endl;

				if(exposure <= eMax && exposure >= eMin){

					setPropertyValue(DShowLib::VCDID_Exposure, (long)exposure, pItems);
					cout << "New exposure time value : " << getPropertyValue(DShowLib::VCDID_Exposure, pItems) << endl;

				}else{

					cout << "Fail to set exposure. Available range value is " << eMin << " to " << eMax << endl;
					return false;
				}

				// Set Gain (db)
				int gain = frame.getGain();
								
				long gMin  = getPropertyRangeMin(DShowLib::VCDID_Gain, pItems);
				long gMax  = getPropertyRangeMax(DShowLib::VCDID_Gain, pItems);
				long g = getPropertyValue(DShowLib::VCDID_Gain, pItems);

				cout << "Previous gain value : " << g << endl;

				if(gain <= gMax && gain >= gMin){

					setPropertyValue(DShowLib::VCDID_Gain, (long)gain, pItems);
					cout << "New gain value : " << getPropertyValue(DShowLib::VCDID_Gain, pItems) << endl;

				}else{

					cout << "Fail to set gain. Available range value is " << gMin << " to " << gMax << endl;
					return false;
				}

				
				// Set the sink.
				m_pGrabber->setSinkType(pSink);
				
				// We use snap mode.
				pSink->setSnapMode(true);

		

				// Prepare the live mode, to get the output size if the sink.
				if(!m_pGrabber->prepareLive(false)){

					std::cerr << "Could not render the VideoFormat into a eY800 sink.";
					return false;
				}

				// Retrieve the output type and dimension of the handler sink.
				// The dimension of the sink could be different from the VideoFormat, when
				// you use filters.
				DShowLib::FrameTypeInfo info;
				pSink->getOutputFrameType(info);
				cout << info.getBitsPerPixel() << endl;

				Mat newImg;
				DShowLib::Grabber::tMemBufferCollectionPtr pCollection;

				switch(info.getBitsPerPixel()){
					
					case 8 :

						{

							newImg = Mat(info.dim.cy, info.dim.cx, CV_8UC1, Scalar(0));
							BYTE* pBuf[1];
							// Allocate image buffers of the above calculate buffer size.
							pBuf[0] = new BYTE[info.buffersize];

							// Create a new MemBuffer collection that uses our own image buffers.
							pCollection = DShowLib::MemBufferCollection::create( info, 1, pBuf );
							if( pCollection == 0 || !pSink->setMemBufferCollection(pCollection)){

								std::cerr << "Could not set the new MemBufferCollection, because types do not match.";
								return false;

							}

							m_pGrabber->startLive(false);

							pSink->snapImages(1);
					
							memcpy(newImg.ptr(), pBuf[0], info.buffersize);

						}

						break;

					case 16 :

						{

							newImg = Mat(info.dim.cy, info.dim.cx, CV_16UC1, Scalar(0));
							BYTE * pBuf[1];
							// Allocate image buffers of the above calculate buffer size.
							pBuf[0] = new BYTE[info.buffersize];

							// Create a new MemBuffer collection that uses our own image buffers.
							pCollection = DShowLib::MemBufferCollection::create(info, 1, pBuf);
							if(pCollection == 0 || !pSink->setMemBufferCollection(pCollection)){

								std::cerr << "Could not set the new MemBufferCollection, because types do not match.";
								return false;

							}

							m_pGrabber->startLive(false);

							pSink->snapImages(1);

							memcpy(newImg.ptr(), pBuf[0], info.buffersize);

						}

						break;
						
					default:
												
						return false;

						break;
				}

				m_pGrabber->stopLive();

				m_pGrabber->closeDev();

				//Timestamping.
				string acquisitionDate = TimeDate::localDateTime(microsec_clock::universal_time(),"%Y:%m:%d:%H:%M:%S");
				boost::posix_time::ptime time = boost::posix_time::microsec_clock::universal_time();
				string acqDateInMicrosec = to_iso_extended_string(time);

                frame = Frame(newImg, 0, 0, acquisitionDate);
                frame.setAcqDateMicro(acqDateInMicrosec);
                frame.setFPS(0);

				//cout << "save " << endl;
				//pCollection->save( "yio*.bmp" );

				double minVal, maxVal;
				minMaxLoc(newImg, &minVal, &maxVal);

				cout << "minVal :" << minVal << endl;
				cout << "maxVal :" << maxVal << endl;
				
				unsigned short * ptr;

				double t = (double)getTickCount();

				for(int i = 0; i < newImg.rows; i++){

					ptr = newImg.ptr<unsigned short>(i);

					for(int j = 0; j < newImg.cols; j++){

						ptr[j] = ptr[j] >> 4;

					}
				}	

				t = (((double)getTickCount() - t )/getTickFrequency())*1000;

				cout << "time decalage : " << t << endl;
				
				minMaxLoc(newImg, &minVal, &maxVal);

				cout << "minVal :" << minVal << endl;
				cout << "maxVal :" << maxVal << endl;

			}
		}

		return true;
	}
Esempio n. 13
0
/** Executes the algorithm
 *
 *  @throw runtime_error Thrown if algorithm cannot execute
 */
void Fit1D::exec()
{

  // Custom initialization
  prepare();

  // check if derivative defined in derived class
  bool isDerivDefined = true;
  gsl_matrix * M = NULL;
  try
  {
    const std::vector<double> inTest(m_parameterNames.size(),1.0);
    std::vector<double> outTest(m_parameterNames.size());
    const double xValuesTest = 0;
    JacobianImpl J;
    M = gsl_matrix_alloc(m_parameterNames.size(),1);
    J.setJ(M);
    // note nData set to zero (last argument) hence this should avoid further memory problems
    functionDeriv(&(inTest.front()), &J, &xValuesTest, 0);
  }
  catch (Exception::NotImplementedError&)
  {
    isDerivDefined = false;
  }
  gsl_matrix_free(M);

  // Try to retrieve optional properties
  int histNumber = getProperty("WorkspaceIndex");
  const int maxInterations = getProperty("MaxIterations");

  // Get the input workspace
  MatrixWorkspace_const_sptr localworkspace = getProperty("InputWorkspace");

  // number of histogram is equal to the number of spectra
  const size_t numberOfSpectra = localworkspace->getNumberHistograms();
  // Check that the index given is valid
  if ( histNumber >= static_cast<int>(numberOfSpectra) )
  {
    g_log.warning("Invalid Workspace index given, using first Workspace");
    histNumber = 0;
  }

  // Retrieve the spectrum into a vector
  const MantidVec& XValues = localworkspace->readX(histNumber);
  const MantidVec& YValues = localworkspace->readY(histNumber);
  const MantidVec& YErrors = localworkspace->readE(histNumber);

  //Read in the fitting range data that we were sent
  double startX = getProperty("StartX");
  double endX = getProperty("EndX");
  //check if the values had been set, otherwise use defaults
  if ( isEmpty( startX ) )
  {
    startX = XValues.front();
    modifyStartOfRange(startX); // does nothing by default but derived class may provide a more intelligent value
  }
  if ( isEmpty( endX ) )
  {
    endX = XValues.back();
    modifyEndOfRange(endX); // does nothing by default but derived class may previde a more intelligent value
  }

  int m_minX;
  int m_maxX;

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

  // Check the validity of endX and get the bin boundary that come after (or coincides with) it
  if ( endX >= XValues.back() || endX < startX )
  {
    g_log.warning("EndX out of range! Set to end of frame");
    endX = XValues.back();
    m_maxX = static_cast<int>(YValues.size());
  }
  else
  {
    for (m_maxX = m_minX; XValues[m_maxX] < endX; ++m_maxX) {}
  }

  afterDataRangedDetermined(m_minX, m_maxX);

  // create and populate GSL data container warn user if l_data.n < l_data.p 
  // since as a rule of thumb this is required as a minimum to obtained 'accurate'
  // fitting parameter values.

  FitData l_data(this,getProperty("Fix"));

  l_data.n = m_maxX - m_minX; // m_minX and m_maxX are array index markers. I.e. e.g. 0 & 19.
  if (l_data.n == 0)
  {
    g_log.error("The data set is empty.");
    throw std::runtime_error("The data set is empty.");
  }
  if (l_data.n < l_data.p)
  {
    g_log.error("Number of data points less than number of parameters to be fitted.");
    throw std::runtime_error("Number of data points less than number of parameters to be fitted.");
  }
  l_data.X = new double[l_data.n];
  l_data.sigmaData = new double[l_data.n];
  l_data.forSimplexLSwrap = new double[l_data.n];
  l_data.parameters = new double[nParams()];

  // check if histogram data in which case use mid points of histogram bins

  const bool isHistogram = localworkspace->isHistogramData();
  for (unsigned int i = 0; i < l_data.n; ++i)
  {
    if (isHistogram)
      l_data.X[i] = 0.5*(XValues[m_minX+i]+XValues[m_minX+i+1]); // take mid-point if histogram bin
    else
      l_data.X[i] = XValues[m_minX+i];
  }

  l_data.Y = &YValues[m_minX];

  // check that no error is negative or zero
  for (unsigned int i = 0; i < l_data.n; ++i)
  {
    if (YErrors[m_minX+i] <= 0.0)
    {
      l_data.sigmaData[i] = 1.0;
    }
    else
      l_data.sigmaData[i] = YErrors[m_minX+i];
  }


  // create array of fitted parameter. Take these to those input by the user. However, for doing the
  // underlying fitting it might be more efficient to actually perform the fitting on some of other
  // form of the fitted parameters. For instance, take the Gaussian sigma parameter. In practice it
  // in fact more efficient to perform the fitting not on sigma but 1/sigma^2. The methods 
  // modifyInitialFittedParameters() and modifyFinalFittedParameters() are used to allow for this;
  // by default these function do nothing.

  m_fittedParameter.clear();
  for (size_t i = 0; i < nParams(); i++)
  {
      m_fittedParameter.push_back(getProperty(m_parameterNames[i]));
  }
  modifyInitialFittedParameters(m_fittedParameter); // does nothing except if overwritten by derived class
  for (size_t i = 0; i < nParams(); i++)
  {
      l_data.parameters[i] = m_fittedParameter[i];
  }


  // set-up initial guess for fit parameters

  gsl_vector *initFuncArg;
  initFuncArg = gsl_vector_alloc(l_data.p);

  for (size_t i = 0,j = 0; i < nParams(); i++)
  {
      if (l_data.active[i])
          gsl_vector_set(initFuncArg, j++, m_fittedParameter[i]);
  }


  // set-up GSL container to be used with GSL simplex algorithm

  gsl_multimin_function gslSimplexContainer;
  gslSimplexContainer.n = l_data.p;  // n here refers to number of parameters
  gslSimplexContainer.f = &gsl_costFunction;
  gslSimplexContainer.params = &l_data;


  // set-up GSL least squares container

  gsl_multifit_function_fdf f;
  f.f = &gsl_f;
  f.df = &gsl_df;
  f.fdf = &gsl_fdf;
  f.n = l_data.n;
  f.p = l_data.p;
  f.params = &l_data;

  // set-up remaining GSL machinery for least squared

  const gsl_multifit_fdfsolver_type *T = gsl_multifit_fdfsolver_lmsder;
  gsl_multifit_fdfsolver *s = NULL;
  if (isDerivDefined)
  {
    s = gsl_multifit_fdfsolver_alloc(T, l_data.n, l_data.p);
    gsl_multifit_fdfsolver_set(s, &f, initFuncArg);
  }

  // set-up remaining GSL machinery to use simplex algorithm

  const gsl_multimin_fminimizer_type *simplexType = gsl_multimin_fminimizer_nmsimplex;
  gsl_multimin_fminimizer *simplexMinimizer = NULL;
  gsl_vector *simplexStepSize = NULL;
  if (!isDerivDefined)
  {
    simplexMinimizer = gsl_multimin_fminimizer_alloc(simplexType, l_data.p);
    simplexStepSize = gsl_vector_alloc(l_data.p);
    gsl_vector_set_all (simplexStepSize, 1.0);  // is this always a sensible starting step size?
    gsl_multimin_fminimizer_set(simplexMinimizer, &gslSimplexContainer, initFuncArg, simplexStepSize);
  }

  // finally do the fitting

  int iter = 0;
  int status;
  double size; // for simplex algorithm
  double finalCostFuncVal;
  double dof = static_cast<double>(l_data.n - l_data.p);  // dof stands for degrees of freedom

  // Standard least-squares used if derivative function defined otherwise simplex
  Progress prog(this,0.0,1.0,maxInterations);
  if (isDerivDefined)
  {
	  
    do
    {
      iter++;
      status = gsl_multifit_fdfsolver_iterate(s);

      if (status)  // break if error
        break;

      status = gsl_multifit_test_delta(s->dx, s->x, 1e-4, 1e-4);
	  prog.report();
    }
    while (status == GSL_CONTINUE && iter < maxInterations);

    double chi = gsl_blas_dnrm2(s->f);
    finalCostFuncVal = chi*chi / dof;

    // put final converged fitting values back into m_fittedParameter
    for (size_t i = 0, j = 0; i < nParams(); i++)
      if (l_data.active[i])
          m_fittedParameter[i] = gsl_vector_get(s->x,j++);
  }
  else
  {
    do
    {
      iter++;
      status = gsl_multimin_fminimizer_iterate(simplexMinimizer);

      if (status)  // break if error
        break;

      size = gsl_multimin_fminimizer_size(simplexMinimizer);
      status = gsl_multimin_test_size(size, 1e-2);
	  prog.report();
    }
    while (status == GSL_CONTINUE && iter < maxInterations);

    finalCostFuncVal = simplexMinimizer->fval / dof;

    // put final converged fitting values back into m_fittedParameter
    for (unsigned int i = 0, j = 0; i < m_fittedParameter.size(); i++)
      if (l_data.active[i])
          m_fittedParameter[i] = gsl_vector_get(simplexMinimizer->x,j++);
  }

  modifyFinalFittedParameters(m_fittedParameter);   // do nothing except if overwritten by derived class


  // Output summary to log file

  std::string reportOfFit = gsl_strerror(status);

  g_log.information() << "Iteration = " << iter << "\n" <<
    "Status = " << reportOfFit << "\n" <<
    "Chi^2/DoF = " << finalCostFuncVal << "\n";
  for (size_t i = 0; i < m_fittedParameter.size(); i++)
    g_log.information() << m_parameterNames[i] << " = " << m_fittedParameter[i] << "  \n";


  // also output summary to properties

  setProperty("OutputStatus", reportOfFit);
  setProperty("OutputChi2overDoF", finalCostFuncVal);
  for (size_t i = 0; i < m_fittedParameter.size(); i++)
    setProperty(m_parameterNames[i], m_fittedParameter[i]);


  std::string output = getProperty("Output");
  if (!output.empty())
  {
    // calculate covariance matrix if derivatives available

    gsl_matrix *covar(NULL);
    std::vector<double> standardDeviations;
    std::vector<double> sdExtended;
    if (isDerivDefined)    
    {
      covar = gsl_matrix_alloc (l_data.p, l_data.p);
      gsl_multifit_covar (s->J, 0.0, covar);

      int iPNotFixed = 0;
      for(size_t i=0;i<nParams();i++)
      {
        sdExtended.push_back(1.0);
        if (l_data.active[i])
        {
          sdExtended[i] = sqrt(gsl_matrix_get(covar,iPNotFixed,iPNotFixed));
          iPNotFixed++;
        }
      }
      modifyFinalFittedParameters(sdExtended);
      for(size_t i=0;i<nParams();i++)
        if (l_data.active[i])
          standardDeviations.push_back(sdExtended[i]);

      declareProperty(
        new WorkspaceProperty<API::ITableWorkspace>("OutputNormalisedCovarianceMatrix","",Direction::Output),
        "The name of the TableWorkspace in which to store the final covariance matrix" );
      setPropertyValue("OutputNormalisedCovarianceMatrix",output+"_NormalisedCovarianceMatrix");

      Mantid::API::ITableWorkspace_sptr m_covariance = Mantid::API::WorkspaceFactory::Instance().createTable("TableWorkspace");
      m_covariance->addColumn("str","Name");
      std::vector<std::string> paramThatAreFitted; // used for populating 1st "name" column
      for(size_t i=0;i<nParams();i++) 
      {
        if (l_data.active[i]) 
        {
          m_covariance->addColumn("double",m_parameterNames[i]);
          paramThatAreFitted.push_back(m_parameterNames[i]);
        }
      }

      for(size_t i=0;i<l_data.p;i++) 
      {

        Mantid::API::TableRow row = m_covariance->appendRow();
        row << paramThatAreFitted[i];
        for(size_t j=0;j<l_data.p;j++)
        {
          if (j == i)
            row << 1.0;
          else
          {
            row << 100.0*gsl_matrix_get(covar,i,j)/sqrt(gsl_matrix_get(covar,i,i)*gsl_matrix_get(covar,j,j));
          }
        }
      }

      setProperty("OutputNormalisedCovarianceMatrix",m_covariance);
    }



    declareProperty(
      new WorkspaceProperty<API::ITableWorkspace>("OutputParameters","",Direction::Output),
      "The name of the TableWorkspace in which to store the final fit parameters" );
    declareProperty(new WorkspaceProperty<MatrixWorkspace>("OutputWorkspace","",Direction::Output), 
      "Name of the output Workspace holding resulting simlated spectrum");

    setPropertyValue("OutputParameters",output+"_Parameters");
    setPropertyValue("OutputWorkspace",output+"_Workspace");

    // Save the final fit parameters in the output table workspace
    Mantid::API::ITableWorkspace_sptr m_result = Mantid::API::WorkspaceFactory::Instance().createTable("TableWorkspace");
    m_result->addColumn("str","Name");
    m_result->addColumn("double","Value");
    if (isDerivDefined) 
      m_result->addColumn("double","Error");
    Mantid::API::TableRow row = m_result->appendRow();
    row << "Chi^2/DoF" << finalCostFuncVal;

    for(size_t i=0;i<nParams();i++)
    {
      Mantid::API::TableRow row = m_result->appendRow();
      row << m_parameterNames[i] << m_fittedParameter[i];
      if (isDerivDefined && l_data.active[i]) 
      {
        // perhaps want to scale standard deviations with sqrt(finalCostFuncVal)
        row << sdExtended[i];
      }
    }
    setProperty("OutputParameters",m_result);

    // Save the fitted and simulated spectra in the output workspace
    MatrixWorkspace_const_sptr inputWorkspace = getProperty("InputWorkspace");
    int iSpec = getProperty("WorkspaceIndex");
    const MantidVec& inputX = inputWorkspace->readX(iSpec);
    const MantidVec& inputY = inputWorkspace->readY(iSpec);

    int histN = isHistogram ? 1 : 0;
    Mantid::DataObjects::Workspace2D_sptr ws = boost::dynamic_pointer_cast<Mantid::DataObjects::Workspace2D>
      (
         Mantid::API::WorkspaceFactory::Instance().create(
                     "Workspace2D",
                     3,
                     l_data.n + histN,
                     l_data.n)
      );
    ws->setTitle("");
    ws->getAxis(0)->unit() = inputWorkspace->getAxis(0)->unit();//    UnitFactory::Instance().create("TOF");

    for(int i=0;i<3;i++)
      ws->dataX(i).assign(inputX.begin()+m_minX,inputX.begin()+m_maxX+histN);

    ws->dataY(0).assign(inputY.begin()+m_minX,inputY.begin()+m_maxX);

    MantidVec& Y = ws->dataY(1);
    MantidVec& E = ws->dataY(2);


    double* lOut = new double[l_data.n];  // to capture output from call to function()
    modifyInitialFittedParameters(m_fittedParameter); // does nothing except if overwritten by derived class
    function(&m_fittedParameter[0], lOut, l_data.X, l_data.n);
    modifyInitialFittedParameters(m_fittedParameter); // reverse the effect of modifyInitialFittedParameters - if any 

    for(unsigned int i=0; i<l_data.n; i++) 
    {
      Y[i] = lOut[i]; 
      E[i] = l_data.Y[i] - Y[i];
    }

    delete [] lOut; 

    setProperty("OutputWorkspace",boost::dynamic_pointer_cast<MatrixWorkspace>(ws));

    if (isDerivDefined) 
      gsl_matrix_free(covar);
  }

  // clean up dynamically allocated gsl stuff

  if (isDerivDefined)
    gsl_multifit_fdfsolver_free(s);
  else
  {
    gsl_vector_free(simplexStepSize);
    gsl_multimin_fminimizer_free(simplexMinimizer);
  }

  delete [] l_data.X;
  delete [] l_data.sigmaData;
  delete [] l_data.forSimplexLSwrap;
  delete [] l_data.parameters;
  gsl_vector_free (initFuncArg);

  return;
}
Esempio n. 14
0
// test the size() function for various types of set and append of object to
// the response data object. Test set and append of single type.
void testSizeMethod()
{
    // Test with a variety of object types in the From ResponseData
    // Build the class
    CIMClass CIMclass1 = buildClass();

    // Build a CIM Instance. NOTE: key is defaulted in class

    CIMInstance CIMInst1 = CIMclass1.buildInstance(true, true,
                                                   CIMPropertyList());

        // Clone the instance and change key
    CIMInstance CIMInst2 = CIMInst1.clone();
    setPropertyValue(CIMInst2, "id", 2);

    CIMInstance CIMInst3 = CIMInst1.clone();
    setPropertyValue(CIMInst3, "id", 3);
    CIMInstance CIMInst4 = CIMInst1.clone();
    setPropertyValue(CIMInst4, "id", 4);

    // build CIMInstance array
    Array<CIMInstance> CIMInstArray;
    CIMInstArray.append(CIMInst1);
    CIMInstArray.append(CIMInst2);
    CIMInstArray.append(CIMInst3);
    CIMInstArray.append(CIMInst3);

    // Build SCMO instances
    SCMOClass SCMO_CSClass(CIMclass1);

    VCOUT << "Creating SCMOInstance from CIMInstance" << endl;
    SCMOInstance SCMO_CSInstance3(SCMO_CSClass,CIMInst3);
    SCMOInstance SCMO_CSInstance4(SCMO_CSClass,CIMInst4);

    // Create array of 2 SCMO Instances
    Array<SCMOInstance> SCMOInstArray;
    SCMOInstArray.append(SCMO_CSInstance3);
    SCMOInstArray.append(SCMO_CSInstance4);

    // tests with CIM objects (C++ Interface)
    {
        CIMResponseData crd = CIMResponseData(CIMResponseData::RESP_INSTANCES);

        crd.setInstances(CIMInstArray);
        PEGASUS_TEST_ASSERT(crd.size() == 4);
        crd.appendInstances(CIMInstArray);
        PEGASUS_TEST_ASSERT(crd.size() == 8);
        crd.appendInstance(CIMInst1);
        PEGASUS_TEST_ASSERT(crd.size() == 9);
        crd.appendSCMO(SCMOInstArray);
        PEGASUS_TEST_ASSERT(crd.size() == 11);
        PEGASUS_TEST_ASSERT(crd.valid());
    }

    {
        CIMResponseData crd = CIMResponseData(CIMResponseData::RESP_INSTANCES);

        crd.setInstance(CIMInst1);
        PEGASUS_TEST_ASSERT(crd.size() == 1);
        crd.appendInstances(CIMInstArray);
        PEGASUS_TEST_ASSERT(crd.size() == 5);
        crd.appendInstance(CIMInst1);
        PEGASUS_TEST_ASSERT(crd.size() == 6);
        crd.appendSCMO(SCMOInstArray);
        PEGASUS_TEST_ASSERT(crd.size() == 8);
        PEGASUS_TEST_ASSERT(crd.valid());
    }

    // test with objects
    {
        CIMResponseData crd = CIMResponseData(CIMResponseData::RESP_OBJECTS);
        Array<CIMObject> x;
        x.append((CIMObject)CIMInst1);
        x.append((CIMObject)CIMInst2);

        // Append an array of CIMInstances
        crd.setObjects(x);
        PEGASUS_TEST_ASSERT(crd.size() == 2);
        crd.appendObject((CIMObject)CIMInst1);
        PEGASUS_TEST_ASSERT(crd.size() == 3);
        PEGASUS_TEST_ASSERT(crd.valid());
    }

    // test with SCMOInst
    {
        CIMResponseData crd = CIMResponseData(CIMResponseData::RESP_INSTANCES);
        crd.setSCMO(SCMOInstArray);
        PEGASUS_TEST_ASSERT(crd.size() == 2);
        crd.appendSCMO(SCMOInstArray);
        PEGASUS_TEST_ASSERT(crd.size() == 4);
        PEGASUS_TEST_ASSERT(crd.valid());
    }

    {
        // Create array of 2 SCMO Instances
        Array<SCMOInstance> SCMOInstArray;
        SCMOInstArray.append(SCMO_CSInstance3);
        SCMOInstArray.append(SCMO_CSInstance4);

        CIMResponseData crd = CIMResponseData(CIMResponseData::RESP_INSTANCES);
        crd.appendSCMO(SCMOInstArray);
        PEGASUS_TEST_ASSERT(crd.size() == 2);
        crd.appendSCMO(SCMOInstArray);
        PEGASUS_TEST_ASSERT(crd.size() == 4);
        PEGASUS_TEST_ASSERT(crd.valid());
    }

    // Test with path objects
    String s1  = "//atp:77/root/cimv25:"
      "TennisPlayer.last=\"Rafter\",first=\"Patrick\"";
    String s2 = "//atp:77/root/cimv25:"
          "TennisPlayer.first=\"Patrick\",last=\"Rafter\"";
    CIMObjectPath r1 = s1;
    CIMObjectPath r2 = s2;
    Array<CIMObjectPath> refArray;
    refArray.append(r1);
    refArray.append(r2);
    refArray.append(r1);
    refArray.append(r2);

    CIMResponseData crd = CIMResponseData(CIMResponseData::RESP_OBJECTPATHS);
    crd.setInstanceNames(refArray);
    PEGASUS_TEST_ASSERT(crd.size() == 4);
    PEGASUS_TEST_ASSERT(crd.valid());

    // KS_TBD There is not appendinstancenames today in ResponseData
    //crd.appendInstanceNames(refArray);


    // Test with XML and binary
    {

    }

}
Esempio n. 15
0
void FontFace::setPropertyFromString(const Document* document, const String& s, CSSPropertyID propertyID, ExceptionState& exceptionState)
{
    RefPtrWillBeRawPtr<CSSValue> value = parseCSSValue(document, s, propertyID);
    if (!value || !setPropertyValue(value, propertyID))
        exceptionState.throwDOMException(SyntaxError, "Failed to set '" + s + "' as a property value.");
}
Esempio n. 16
0
// test size method and moveObjects method
void test02()
{
    // Test with a variety of object types in the From ResponseData
    // Build the class
    CIMClass CIMclass1 = buildClass();

    // Build a CIM Instance. NOTE: key is defaulted in class

    CIMInstance CIMInst1 = CIMclass1.buildInstance(true, true,
                                                   CIMPropertyList());

        // Clone the instance and change key
    CIMInstance CIMInst2 = CIMInst1.clone();
    setPropertyValue(CIMInst2, "id", 2);

    CIMInstance CIMInst3 = CIMInst1.clone();
    setPropertyValue(CIMInst3, "id", 3);
    CIMInstance CIMInst4 = CIMInst1.clone();
    setPropertyValue(CIMInst4, "id", 4);

    // build CIMInstance array
    Array<CIMInstance> CIMInstArray;
    CIMInstArray.append(CIMInst1);
    CIMInstArray.append(CIMInst2);

    // Build SCMO instances
    SCMOClass SCMO_CSClass(CIMclass1);

    VCOUT << "Creating SCMOInstance from CIMInstance" << endl;
    SCMOInstance SCMO_CSInstance3(SCMO_CSClass,CIMInst3);
    SCMOInstance SCMO_CSInstance4(SCMO_CSClass,CIMInst4);

    // Create array of 2 SCMO Instances
    Array<SCMOInstance> SCMOInstArray;
    SCMOInstArray.append(SCMO_CSInstance3);
    SCMOInstArray.append(SCMO_CSInstance4);

    // Create CIMReponseData object
    CIMResponseData crd1 = CIMResponseData(CIMResponseData::RESP_INSTANCES);
    PEGASUS_TEST_ASSERT(crd1.valid());
    // set SCMO array into the object
    crd1.setSCMO(SCMOInstArray);

    PEGASUS_TEST_ASSERT(crd1.valid());

    VCOUT << crd1.size() << endl;
    PEGASUS_TEST_ASSERT(crd1.size() == 2);

    // append a CIM Instance
    crd1.appendInstance(CIMInst1);

    PEGASUS_TEST_ASSERT(crd1.valid());
    VCOUT << crd1.size() << endl;
    PEGASUS_TEST_ASSERT(crd1.size() == 3);

    // Append an array of CIMInstances
    crd1.appendInstances(CIMInstArray);

    PEGASUS_TEST_ASSERT(crd1.valid());
    VCOUT << crd1.size() << endl;
    PEGASUS_TEST_ASSERT(crd1.size() == 5);

    CIMResponseData crdTo = CIMResponseData(CIMResponseData::RESP_INSTANCES);

    VCOUT << "Before from =  " << crd1.size() << ", to = "
        << crdTo.size() << endl;

    PEGASUS_TEST_ASSERT(crdTo.valid());
    Uint32 rtn = crdTo.moveObjects(crd1, 3);
    VCOUT << "After from = " <<  crd1.size() << ", to = "
        << crdTo.size() << endl;

    PEGASUS_TEST_ASSERT(crdTo.valid());
    PEGASUS_TEST_ASSERT(crd1.valid());

    PEGASUS_TEST_ASSERT(rtn ==3);
    PEGASUS_TEST_ASSERT(crd1.size() == 2);
    PEGASUS_TEST_ASSERT(crdTo.size() == 3);

    CIMResponseData crdTo2 = CIMResponseData(CIMResponseData::RESP_INSTANCES);
    VCOUT << "Before from =  " << crd1.size() << ", to = "
        << crdTo2.size() << endl;
    Uint32 rtn2 = crdTo2.moveObjects(crd1, 9);
    VCOUT << "After from = " <<  crd1.size() << ", to = "
        << crdTo2.size() << endl;
    PEGASUS_TEST_ASSERT(rtn2 ==2);
    PEGASUS_TEST_ASSERT(crd1.size() == 0);
    PEGASUS_TEST_ASSERT(crdTo2.size() == 2);

    PEGASUS_TEST_ASSERT(crd1.valid());
    PEGASUS_TEST_ASSERT(crdTo2.valid());

    // Repeat the test but starting with set CIM Instance Array to start
    // Create CIMReponseData object
    CIMResponseData crd2 = CIMResponseData(CIMResponseData::RESP_INSTANCES);
    crd2.setInstances(CIMInstArray);
    PEGASUS_TEST_ASSERT(crd2.size() == 2);
    PEGASUS_TEST_ASSERT(crd2.valid());

    crd2.appendInstance(CIMInst1);

    VCOUT << crd2.size() << endl;
    PEGASUS_TEST_ASSERT(crd2.size() == 3);

    crd2.appendSCMO(SCMOInstArray);
    PEGASUS_TEST_ASSERT(crd2.valid());

    VCOUT << crd2.size() << endl;
    PEGASUS_TEST_ASSERT(crd2.size() == 5);

    // Test XML formatting.

    CIMResponseData crd3 = CIMResponseData(CIMResponseData::RESP_INSTANCES);

    // set CIM instances into the responseData.
    crd3.appendInstances(CIMInstArray);

    VCOUT << "crd3 size " << crd3.size() << endl;
    PEGASUS_TEST_ASSERT(crd3.size() == 2);

    // Confirm that we can encode into a buffer.
    Buffer buf1;
    crd3.encodeXmlResponse(buf1, true);
    PEGASUS_TEST_ASSERT(crd3.size() == 2);

    CIMBuffer bufa;
    crd3.encodeInternalXmlResponse(bufa, true);

    CIMResponseData crd4 = CIMResponseData(CIMResponseData::RESP_INSTANCES);
////  The following fails. Apparently not enough data in the buffer. Think it
////  is the namespace from the buffer that does not exist.
////  FUTURE. Check this but not important since the real test is in the msg
////  serializer and deserializer.
////  PEGASUS_TEST_ASSERT(crd4.setXml(bufa));
////  cout << "crd4 size: " << crd4.size() << endl;
////  PEGASUS_TEST_ASSERT(crd4.size() == 4);

}
void SANSSensitivityCorrection::exec() {
  // Output log
  m_output_message = "";

  Progress progress(this, 0.0, 1.0, 10);

  // Reduction property manager
  const std::string reductionManagerName = getProperty("ReductionProperties");
  boost::shared_ptr<PropertyManager> reductionManager;
  if (PropertyManagerDataService::Instance().doesExist(reductionManagerName)) {
    reductionManager =
        PropertyManagerDataService::Instance().retrieve(reductionManagerName);
  } else {
    reductionManager = boost::make_shared<PropertyManager>();
    PropertyManagerDataService::Instance().addOrReplace(reductionManagerName,
                                                        reductionManager);
  }

  if (!reductionManager->existsProperty("SensitivityAlgorithm")) {
    auto algProp = make_unique<AlgorithmProperty>("SensitivityAlgorithm");
    algProp->setValue(toString());
    reductionManager->declareProperty(std::move(algProp));
  }

  progress.report("Loading sensitivity file");
  const std::string fileName = getPropertyValue("Filename");

  // Look for an entry for the dark current in the reduction table
  Poco::Path path(fileName);
  const std::string entryName = "Sensitivity" + path.getBaseName();
  MatrixWorkspace_sptr floodWS;
  std::string floodWSName = "__sensitivity_" + path.getBaseName();

  if (reductionManager->existsProperty(entryName)) {
    std::string wsName = reductionManager->getPropertyValue(entryName);
    floodWS = boost::dynamic_pointer_cast<MatrixWorkspace>(
        AnalysisDataService::Instance().retrieveWS<MatrixWorkspace>(wsName));
    m_output_message += "   |Using " + wsName + "\n";
    g_log.debug()
        << "SANSSensitivityCorrection :: Using sensitivity workspace: "
        << wsName << "\n";
  } else {
    // Load the flood field if we don't have it already
    // First, try to determine whether we need to load data or a sensitivity
    // workspace...
    if (!floodWS && fileCheck(fileName)) {
      g_log.debug() << "SANSSensitivityCorrection :: Loading sensitivity file: "
                    << fileName << "\n";
      IAlgorithm_sptr loadAlg = createChildAlgorithm("Load", 0.1, 0.3);
      loadAlg->setProperty("Filename", fileName);
      loadAlg->executeAsChildAlg();
      Workspace_sptr floodWS_ws = loadAlg->getProperty("OutputWorkspace");
      floodWS = boost::dynamic_pointer_cast<MatrixWorkspace>(floodWS_ws);

      // Check that it's really a sensitivity file
      if (!floodWS->run().hasProperty("is_sensitivity")) {
        // Reset pointer
        floodWS.reset();
        g_log.error() << "A processed Mantid workspace was loaded but it "
                         "wasn't a sensitivity file!\n";
      }
    }

    // ... if we don't, just load the data and process it
    if (!floodWS) {
      // Read in default beam center
      double center_x = getProperty("BeamCenterX");
      double center_y = getProperty("BeamCenterY");
      if (isEmpty(center_x) || isEmpty(center_y)) {
        if (reductionManager->existsProperty("LatestBeamCenterX") &&
            reductionManager->existsProperty("LatestBeamCenterY")) {
          center_x = reductionManager->getProperty("LatestBeamCenterX");
          center_y = reductionManager->getProperty("LatestBeamCenterY");
          m_output_message +=
              "   |Setting beam center to [" +
              Poco::NumberFormatter::format(center_x, 1) + ", " +
              Poco::NumberFormatter::format(center_y, 1) + "]\n";
        } else
          m_output_message += "   |No beam center provided: skipping!\n";
      }

      const std::string rawFloodWSName = "__flood_data_" + path.getBaseName();
      MatrixWorkspace_sptr rawFloodWS;
      if (!reductionManager->existsProperty("LoadAlgorithm")) {
        IAlgorithm_sptr loadAlg = createChildAlgorithm("Load", 0.1, 0.3);
        loadAlg->setProperty("Filename", fileName);
        if (!isEmpty(center_x) && loadAlg->existsProperty("BeamCenterX"))
          loadAlg->setProperty("BeamCenterX", center_x);
        if (!isEmpty(center_y) && loadAlg->existsProperty("BeamCenterY"))
          loadAlg->setProperty("BeamCenterY", center_y);
        loadAlg->setPropertyValue("OutputWorkspace", rawFloodWSName);
        loadAlg->executeAsChildAlg();
        Workspace_sptr tmpWS = loadAlg->getProperty("OutputWorkspace");
        rawFloodWS = boost::dynamic_pointer_cast<MatrixWorkspace>(tmpWS);
        m_output_message += "   | Loaded " + fileName + " (Load algorithm)\n";
      } else {
        // Get load algorithm as a string so that we can create a completely
        // new proxy and ensure that we don't overwrite existing properties
        IAlgorithm_sptr loadAlg0 =
            reductionManager->getProperty("LoadAlgorithm");
        const std::string loadString = loadAlg0->toString();
        IAlgorithm_sptr loadAlg = Algorithm::fromString(loadString);
        loadAlg->setChild(true);
        loadAlg->setProperty("Filename", fileName);
        loadAlg->setPropertyValue("OutputWorkspace", rawFloodWSName);
        if (!isEmpty(center_x) && loadAlg->existsProperty("BeamCenterX"))
          loadAlg->setProperty("BeamCenterX", center_x);
        if (!isEmpty(center_y) && loadAlg->existsProperty("BeamCenterY"))
          loadAlg->setProperty("BeamCenterY", center_y);
        loadAlg->execute();
        rawFloodWS = loadAlg->getProperty("OutputWorkspace");
        m_output_message += "   |Loaded " + fileName + "\n";
        if (loadAlg->existsProperty("OutputMessage")) {
          std::string msg = loadAlg->getPropertyValue("OutputMessage");
          m_output_message +=
              "   |" + Poco::replace(msg, "\n", "\n   |") + "\n";
        }
      }

      // Check whether we just loaded a flood field data set, or the actual
      // sensitivity
      if (!rawFloodWS->run().hasProperty("is_sensitivity")) {
        const std::string darkCurrentFile = getPropertyValue("DarkCurrentFile");

        // Look for a dark current subtraction algorithm
        std::string dark_result;
        if (reductionManager->existsProperty("DarkCurrentAlgorithm")) {
          IAlgorithm_sptr darkAlg =
              reductionManager->getProperty("DarkCurrentAlgorithm");
          darkAlg->setChild(true);
          darkAlg->setProperty("InputWorkspace", rawFloodWS);
          darkAlg->setProperty("OutputWorkspace", rawFloodWS);

          // Execute as-is if we use the sample dark current, otherwise check
          // whether a dark current file was provided.
          // Otherwise do nothing
          if (getProperty("UseSampleDC")) {
            darkAlg->execute();
            if (darkAlg->existsProperty("OutputMessage"))
              dark_result = darkAlg->getPropertyValue("OutputMessage");
          } else if (!darkCurrentFile.empty()) {
            darkAlg->setProperty("Filename", darkCurrentFile);
            darkAlg->setProperty("PersistentCorrection", false);
            darkAlg->execute();
            if (darkAlg->existsProperty("OutputMessage"))
              dark_result = darkAlg->getPropertyValue("OutputMessage");
            else
              dark_result = "   Dark current subtracted\n";
          }
        } else if (!darkCurrentFile.empty()) {
          // We need to subtract the dark current for the flood field but no
          // dark
          // current subtraction was set for the sample! Use the default dark
          // current algorithm if we can find it.
          if (reductionManager->existsProperty("DefaultDarkCurrentAlgorithm")) {
            IAlgorithm_sptr darkAlg =
                reductionManager->getProperty("DefaultDarkCurrentAlgorithm");
            darkAlg->setChild(true);
            darkAlg->setProperty("InputWorkspace", rawFloodWS);
            darkAlg->setProperty("OutputWorkspace", rawFloodWS);
            darkAlg->setProperty("Filename", darkCurrentFile);
            darkAlg->setProperty("PersistentCorrection", false);
            darkAlg->execute();
            if (darkAlg->existsProperty("OutputMessage"))
              dark_result = darkAlg->getPropertyValue("OutputMessage");
          } else {
            // We are running out of options
            g_log.error() << "No dark current algorithm provided to load ["
                          << getPropertyValue("DarkCurrentFile")
                          << "]: skipped!\n";
            dark_result = "   No dark current algorithm provided: skipped\n";
          }
        }
        m_output_message +=
            "   |" + Poco::replace(dark_result, "\n", "\n   |") + "\n";

        // Look for solid angle correction algorithm
        if (reductionManager->existsProperty("SANSSolidAngleCorrection")) {
          IAlgorithm_sptr solidAlg =
              reductionManager->getProperty("SANSSolidAngleCorrection");
          solidAlg->setChild(true);
          solidAlg->setProperty("InputWorkspace", rawFloodWS);
          solidAlg->setProperty("OutputWorkspace", rawFloodWS);
          solidAlg->execute();
          std::string msg = "Solid angle correction applied\n";
          if (solidAlg->existsProperty("OutputMessage"))
            msg = solidAlg->getPropertyValue("OutputMessage");
          m_output_message +=
              "   |" + Poco::replace(msg, "\n", "\n   |") + "\n";
        }

        // Apply transmission correction as needed
        double floodTransmissionValue = getProperty("FloodTransmissionValue");
        double floodTransmissionError = getProperty("FloodTransmissionError");

        if (!isEmpty(floodTransmissionValue)) {
          g_log.debug() << "SANSSensitivityCorrection :: Applying transmission "
                           "to flood field\n";
          IAlgorithm_sptr transAlg =
              createChildAlgorithm("ApplyTransmissionCorrection");
          transAlg->setProperty("InputWorkspace", rawFloodWS);
          transAlg->setProperty("OutputWorkspace", rawFloodWS);
          transAlg->setProperty("TransmissionValue", floodTransmissionValue);
          transAlg->setProperty("TransmissionError", floodTransmissionError);
          transAlg->setProperty("ThetaDependent", true);
          transAlg->execute();
          rawFloodWS = transAlg->getProperty("OutputWorkspace");
          m_output_message += "   |Applied transmission to flood field\n";
        }

        // Calculate detector sensitivity
        IAlgorithm_sptr effAlg = createChildAlgorithm("CalculateEfficiency");
        effAlg->setProperty("InputWorkspace", rawFloodWS);

        const double minEff = getProperty("MinEfficiency");
        const double maxEff = getProperty("MaxEfficiency");
        const std::string maskFullComponent =
            getPropertyValue("MaskedFullComponent");
        const std::string maskEdges = getPropertyValue("MaskedEdges");
        const std::string maskComponent = getPropertyValue("MaskedComponent");

        effAlg->setProperty("MinEfficiency", minEff);
        effAlg->setProperty("MaxEfficiency", maxEff);
        effAlg->setProperty("MaskedFullComponent", maskFullComponent);
        effAlg->setProperty("MaskedEdges", maskEdges);
        effAlg->setProperty("MaskedComponent", maskComponent);
        effAlg->execute();
        floodWS = effAlg->getProperty("OutputWorkspace");
      } else {
        floodWS = rawFloodWS;
      }
      // Patch as needed
      if (reductionManager->existsProperty("SensitivityPatchAlgorithm")) {
        IAlgorithm_sptr patchAlg =
            reductionManager->getProperty("SensitivityPatchAlgorithm");
        patchAlg->setChild(true);
        patchAlg->setProperty("Workspace", floodWS);
        patchAlg->execute();
        m_output_message += "   |Sensitivity patch applied\n";
      }

      floodWS->mutableRun().addProperty("is_sensitivity", 1, "", true);
    }
    std::string floodWSOutputName =
        getPropertyValue("OutputSensitivityWorkspace");
    if (floodWSOutputName.empty()) {
      setPropertyValue("OutputSensitivityWorkspace", floodWSName);
      AnalysisDataService::Instance().addOrReplace(floodWSName, floodWS);
      reductionManager->declareProperty(
          Kernel::make_unique<WorkspaceProperty<>>(entryName, floodWSName,
                                                   Direction::InOut));
      reductionManager->setPropertyValue(entryName, floodWSName);
      reductionManager->setProperty(entryName, floodWS);
    }
    setProperty("OutputSensitivityWorkspace", floodWS);
  }

  progress.report(3, "Loaded flood field");

  // Check whether we need to apply the correction to a workspace
  MatrixWorkspace_sptr inputWS = getProperty("InputWorkspace");
  if (inputWS) {
    // Divide sample data by detector efficiency
    IAlgorithm_sptr divideAlg = createChildAlgorithm("Divide", 0.6, 0.7);
    divideAlg->setProperty("LHSWorkspace", inputWS);
    divideAlg->setProperty("RHSWorkspace", floodWS);
    divideAlg->executeAsChildAlg();
    MatrixWorkspace_sptr outputWS = divideAlg->getProperty("OutputWorkspace");

    // Copy over the efficiency's masked pixels to the reduced workspace
    IAlgorithm_sptr maskAlg = createChildAlgorithm("MaskDetectors", 0.75, 0.85);
    maskAlg->setProperty("Workspace", outputWS);
    maskAlg->setProperty("MaskedWorkspace", floodWS);
    maskAlg->executeAsChildAlg();

    setProperty("OutputWorkspace", outputWS);
  }
  setProperty("OutputMessage",
              "Sensitivity correction computed\n" + m_output_message);

  progress.report("Performed sensitivity correction");
}