Ejemplo n.º 1
0
/**  Performs asymmetry analysis on a loaded workspace
*   @param loadedWs :: [input] Workspace to apply analysis to
*   @param index :: [input] Vector index where results will be stored
*/
void PlotAsymmetryByLogValue::doAnalysis(Workspace_sptr loadedWs,
                                         size_t index) {

  // Check if workspace is a workspace group
  WorkspaceGroup_sptr group =
      boost::dynamic_pointer_cast<WorkspaceGroup>(loadedWs);

  // If it is not, we only have 'red' data
  if (!group) {
    MatrixWorkspace_sptr ws_red =
        boost::dynamic_pointer_cast<MatrixWorkspace>(loadedWs);

    double Y, E;
    calcIntAsymmetry(ws_red, Y, E);
    m_logValue[index] = getLogValue(*ws_red);
    m_redY[index] = Y;
    m_redE[index] = E;

  } else {
    // It is a group

    // Process red data
    MatrixWorkspace_sptr ws_red;
    try {
      ws_red = boost::dynamic_pointer_cast<MatrixWorkspace>(
          group->getItem(m_red - 1));
    } catch (std::out_of_range &) {
      throw std::out_of_range("Red period out of range");
    }
    double YR, ER;
    calcIntAsymmetry(ws_red, YR, ER);
    double logValue = getLogValue(*ws_red);
    m_logValue[index] = logValue;
    m_redY[index] = YR;
    m_redE[index] = ER;

    if (m_green != EMPTY_INT()) {
      // Process green period if supplied by user
      MatrixWorkspace_sptr ws_green;
      try {
        ws_green = boost::dynamic_pointer_cast<MatrixWorkspace>(
            group->getItem(m_green - 1));
      } catch (std::out_of_range &) {
        throw std::out_of_range("Green period out of range");
      }
      double YG, EG;
      calcIntAsymmetry(ws_green, YG, EG);
      // Red data
      m_redY[index] = YR;
      m_redE[index] = ER;
      // Green data
      m_greenY[index] = YG;
      m_greenE[index] = EG;
      // Sum
      m_sumY[index] = YR + YG;
      m_sumE[index] = sqrt(ER * ER + EG * EG);
      // Diff
      calcIntAsymmetry(ws_red, ws_green, YR, ER);
      m_diffY[index] = YR;
      m_diffE[index] = ER;
    }
  } // else loadedGroup
}
Ejemplo n.º 2
0
/**
*   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);

}