/**
*   Executes the algorithm
*/
void PlotAsymmetryByLogValue::exec()
{
    m_forward_list = getProperty("ForwardSpectra");
    m_backward_list = getProperty("BackwardSpectra");
    m_autogroup = ( m_forward_list.size() == 0 && m_backward_list.size() == 0);

    //double alpha = getProperty("Alpha");

    std::string logName = getProperty("LogValue");

    int red = getProperty("Red");
    int green = getProperty("Green");

    std::string stype = getProperty("Type");
    m_int = stype == "Integral";

    std::string firstFN = getProperty("FirstRun");
    std::string lastFN = getProperty("LastRun");

    std::string ext = firstFN.substr(firstFN.find_last_of("."));

    firstFN.erase(firstFN.size()-4);
    lastFN.erase(lastFN.size()-4);

    std::string fnBase = firstFN;
    size_t i = fnBase.size()-1;
    while(isdigit(fnBase[i]))  i--;
    if (i == fnBase.size()-1)
    {
        g_log.error("File name must end with a number.");
        throw Exception::FileError("File name must end with a number.",firstFN);
    }
    fnBase.erase(i+1);

    firstFN.erase(0,fnBase.size());
    lastFN.erase(0,fnBase.size());

    size_t is = atoi(firstFN.c_str());  // starting run number
    size_t ie = atoi(lastFN.c_str());   // last run number
    int w  = static_cast<int>(firstFN.size());

    // The number of runs
    size_t npoints = ie - is + 1;

    // Create the 2D workspace for the output
    int nplots = green != EMPTY_INT() ? 4 : 1;
    MatrixWorkspace_sptr outWS = WorkspaceFactory::Instance().create("Workspace2D",
                                 nplots,          //  the number of plots
                                 npoints,    //  the number of data points on a plot
                                 npoints     //  it's not a histogram
                                                                    );
    TextAxis* tAxis = new TextAxis(nplots);
    if (nplots == 1)
    {
        tAxis->setLabel(0,"Asymmetry");
    }
    else
    {
        tAxis->setLabel(0,"Red-Green");
        tAxis->setLabel(1,"Red");
        tAxis->setLabel(2,"Green");
        tAxis->setLabel(3,"Red+Green");
    }
    outWS->replaceAxis(1,tAxis);

    Progress progress(this,0,1,ie-is+2);
    for(size_t i=is; i<=ie; i++)
    {
        std::ostringstream fn,fnn;
        fnn << std::setw(w) << std::setfill('0') << i ;
        fn << fnBase << fnn.str() << ext;

        // Load a muon nexus file with auto_group set to true
        IAlgorithm_sptr loadNexus = createChildAlgorithm("LoadMuonNexus");
        loadNexus->setPropertyValue("Filename", fn.str());
        loadNexus->setPropertyValue("OutputWorkspace","tmp"+fnn.str());
        if (m_autogroup)
            loadNexus->setPropertyValue("AutoGroup","1");
        loadNexus->execute();

        std::string wsProp = "OutputWorkspace";

        DataObjects::Workspace2D_sptr ws_red;
        DataObjects::Workspace2D_sptr ws_green;

        // Run through the periods of the loaded file and do calculations on the selected ones
        Workspace_sptr tmp = loadNexus->getProperty(wsProp);
        WorkspaceGroup_sptr wsGroup = boost::dynamic_pointer_cast<WorkspaceGroup>(tmp);
        if (!wsGroup)
        {
            ws_red = boost::dynamic_pointer_cast<DataObjects::Workspace2D>(tmp);
            TimeSeriesProperty<double>* logp =
                dynamic_cast<TimeSeriesProperty<double>*>(ws_red->run().getLogData(logName));
            if (!logp)
            {
                throw std::invalid_argument("Log "+logName+" does not exist or not a double type");
            }
            double Y,E;
            calcIntAsymmetry(ws_red,Y,E);
            outWS->dataY(0)[i-is] = Y;
            outWS->dataX(0)[i-is] = logp->lastValue();
            outWS->dataE(0)[i-is] = E;
        }
        else
        {

            for( int period = 1; period <= wsGroup->getNumberOfEntries(); ++period )
            {
                std::stringstream suffix;
                suffix << period;
                wsProp = "OutputWorkspace_" + suffix.str();// form the property name for higher periods
                // Do only one period
                if (green == EMPTY_INT() && period == red)
                {
                    Workspace_sptr tmpff = loadNexus->getProperty(wsProp);
                    ws_red = boost::dynamic_pointer_cast<DataObjects::Workspace2D>(tmpff);
                    TimeSeriesProperty<double>* logp =
                        dynamic_cast<TimeSeriesProperty<double>*>(ws_red->run().getLogData(logName));
                    if (!logp)
                    {
                        throw std::invalid_argument("Log "+logName+" does not exist or not a double type");
                    }
                    double Y,E;
                    calcIntAsymmetry(ws_red,Y,E);
                    outWS->dataY(0)[i-is] = Y;
                    outWS->dataX(0)[i-is] = logp->lastValue();
                    outWS->dataE(0)[i-is] = E;
                }
                else // red & green
                {
                    if (period == red)
                    {
                        Workspace_sptr temp = loadNexus->getProperty(wsProp);
                        ws_red = boost::dynamic_pointer_cast<Workspace2D>(temp);
                    }
                    if (period == green)
                    {
                        Workspace_sptr temp = loadNexus->getProperty(wsProp);
                        ws_green = boost::dynamic_pointer_cast<Workspace2D>(temp);
                    }
                }

            }
            // red & green claculation
            if (green != EMPTY_INT())
            {
                if (!ws_red || !ws_green)
                    throw std::invalid_argument("Red or green period is out of range");
                TimeSeriesProperty<double>* logp =
                    dynamic_cast<TimeSeriesProperty<double>*>(ws_red->run().getLogData(logName));
                if (!logp)
                {
                    throw std::invalid_argument("Log "+logName+" does not exist or not a double type");
                }
                double Y,E;
                double Y1,E1;
                calcIntAsymmetry(ws_red,Y,E);
                calcIntAsymmetry(ws_green,Y1,E1);
                outWS->dataY(1)[i-is] = Y;
                outWS->dataX(1)[i-is] = logp->lastValue();
                outWS->dataE(1)[i-is] = E;

                outWS->dataY(2)[i-is] = Y1;
                outWS->dataX(2)[i-is] = logp->lastValue();
                outWS->dataE(2)[i-is] = E1;

                outWS->dataY(3)[i-is] = Y + Y1;
                outWS->dataX(3)[i-is] = logp->lastValue();
                outWS->dataE(3)[i-is] = sqrt(E*E+E1*E1);

                // move to last for safety since some grouping takes place in the
                // calcIntAsymmetry call below
                calcIntAsymmetry(ws_red,ws_green,Y,E);
                outWS->dataY(0)[i-is] = Y;
                outWS->dataX(0)[i-is] = logp->lastValue();
                outWS->dataE(0)[i-is] = E;
            }
            else if (!ws_red)
                throw std::invalid_argument("Red period is out of range");

        }
        progress.report();
    }

    outWS->getAxis(0)->title() = logName;
    outWS->setYUnitLabel("Asymmetry");

    // Assign the result to the output workspace property
    setProperty("OutputWorkspace", outWS);

}
Exemple #2
0
    /** 
    *   Executes the algorithm
    */
    void PlotPeakByLogValue::exec()
    {

      // Create a list of the input workspace
      const std::vector<InputData> wsNames = makeNames();

      std::string fun = getPropertyValue("Function");
      //int wi = getProperty("WorkspaceIndex");
      std::string logName = getProperty("LogValue");
      bool sequential = getPropertyValue("FitType") == "Sequential";

      bool isDataName = false; // if true first output column is of type string and is the data source name
      ITableWorkspace_sptr result = WorkspaceFactory::Instance().createTable("TableWorkspace");
      if (logName == "SourceName")
      {
        result->addColumn("str","Source name");
        isDataName = true;
      }
      else if (logName.empty())
      {
        result->addColumn("double","axis-1");
      }
      else
      {
        result->addColumn("double",logName);
      }
      // Create an instance of the fitting function to obtain the names of fitting parameters
      IFitFunction* ifun = FunctionFactory::Instance().createInitialized(fun);
      if (!ifun)
      {
        throw std::invalid_argument("Fitting function failed to initialize");
      }
      for(size_t iPar=0;iPar<ifun->nParams();++iPar)
      {
        result->addColumn("double",ifun->parameterName(iPar));
        result->addColumn("double",ifun->parameterName(iPar)+"_Err");
      }
      result->addColumn("double","Chi_squared");
      delete ifun;
      setProperty("OutputWorkspace",result);

      double dProg = 1./static_cast<double>(wsNames.size());
      double Prog = 0.;
      for(int i=0;i<static_cast<int>(wsNames.size());++i)
      {
        InputData data = getWorkspace(wsNames[i]);

        if (!data.ws)
        {
          g_log.warning() << "Cannot access workspace " << wsNames[i].name << '\n';
          continue;
        }

        if (data.i < 0 && data.indx.empty())
        {
          g_log.warning() << "Zero spectra selected for fitting in workspace " << wsNames[i].name << '\n';
          continue;
        }

        int j,jend;
        if (data.i >= 0)
        {
          j = data.i;
          jend = j + 1;
        }
        else
        {// no need to check data.indx.empty()
          j = data.indx.front();
          jend = data.indx.back() + 1;
        }

        dProg /= abs(jend - j);
        for(;j < jend;++j)
        {

          // Find the log value: it is either a log-file value or simply the workspace number
          double logValue;
          if (logName.empty())
          {
            API::Axis* axis = data.ws->getAxis(1);
            logValue = (*axis)(j);
          }
          else if (logName != "SourceName")
          {
            Kernel::Property* prop = data.ws->run().getLogData(logName);
            if (!prop)
            {
              throw std::invalid_argument("Log value "+logName+" does not exist");
            }
            TimeSeriesProperty<double>* logp = 
              dynamic_cast<TimeSeriesProperty<double>*>(prop); 
            logValue = logp->lastValue();
          }

          std::string resFun = fun;
          std::vector<double> errors;
          double chi2;

          try
          {
            // Fit the function
            API::IAlgorithm_sptr fit = createSubAlgorithm("Fit");
            fit->initialize();
            fit->setProperty("InputWorkspace",data.ws);
            //fit->setPropertyValue("InputWorkspace",data.ws->getName());
            fit->setProperty("WorkspaceIndex",j);
            fit->setPropertyValue("Function",fun);
            fit->setPropertyValue("StartX",getPropertyValue("StartX"));
            fit->setPropertyValue("EndX",getPropertyValue("EndX"));
            fit->setPropertyValue("Minimizer",getPropertyValue("Minimizer"));
            fit->setPropertyValue("CostFunction",getPropertyValue("CostFunction"));
            fit->execute();
            resFun = fit->getPropertyValue("Function");
            errors = fit->getProperty("Errors");
            chi2 = fit->getProperty("OutputChi2overDoF");
          }
          catch(...)
          {
            g_log.error("Error in Fit subalgorithm");
            throw;
          }

          if (sequential)
          {
            fun = resFun;
          }

          // Extract the fitted parameters and put them into the result table
          TableRow row = result->appendRow();
          if (isDataName)
          {
            row << wsNames[i].name;
          }
          else
          {
            row << logValue;
          }
          ifun = FunctionFactory::Instance().createInitialized(resFun);
          for(size_t iPar=0;iPar<ifun->nParams();++iPar)
          {
            row << ifun->getParameter(iPar) << errors[iPar];
          }
          row << chi2;
          delete ifun;
          Prog += dProg;
          progress(Prog);
          interruption_point();
        } // for(;j < jend;++j)
      }
    }