/** * 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); }
/** * 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) } }