void EnggDiffFittingModel::mergeTables( const API::ITableWorkspace_sptr tableToCopy, API::ITableWorkspace_sptr targetTable) const { for (size_t i = 0; i < tableToCopy->rowCount(); ++i) { API::TableRow rowToCopy = tableToCopy->getRow(i); API::TableRow newRow = targetTable->appendRow(); for (size_t j = 0; j < tableToCopy->columnCount(); ++j) { double valueToCopy; rowToCopy >> valueToCopy; newRow << valueToCopy; } } }
size_t LatticeDomainCreator::getDomainSize() const { API::IPeaksWorkspace_sptr peaksWorkspace = boost::dynamic_pointer_cast<IPeaksWorkspace>(m_workspace); if (peaksWorkspace) { return peaksWorkspace->getNumberPeaks(); } API::ITableWorkspace_sptr tableWorkspace = boost::dynamic_pointer_cast<ITableWorkspace>(m_workspace); if (tableWorkspace) { return tableWorkspace->rowCount(); } return 0; }
/* This function fills in a list of the row numbers starting 0 of the parameters in the table workspace, so one can find the position in a column of the value of the given parameter. */ void LoadFullprofResolution::getTableRowNumbers( const API::ITableWorkspace_sptr &tablews, std::map<std::string, size_t> ¶mmap) { parammap.clear(); size_t numrows = tablews->rowCount(); for (size_t i = 0; i < numrows; ++i) { TableRow row = tablews->getRow(i); std::string name; row >> name; parammap.emplace(name, i); } return; }
/** This method saves investigations to a table workspace * @param investigations :: a vector containing investigation data * @param outputws :: shared pointer to output workspace */ void CICatHelper::saveInvestigations( const std::vector<ns1__investigation *> &investigations, API::ITableWorkspace_sptr &outputws) { try { std::vector<ns1__investigation *>::const_iterator citr; for (citr = investigations.begin(); citr != investigations.end(); ++citr) { API::TableRow t = outputws->appendRow(); std::string id = std::to_string(*(*citr)->id); savetoTableWorkspace(&id, t); savetoTableWorkspace((*citr)->facility, t); savetoTableWorkspace((*citr)->title, t); savetoTableWorkspace((*citr)->instrument, t); savetoTableWorkspace((*citr)->invParamValue, t); std::string startDate = std::to_string(*(*citr)->invStartDate); savetoTableWorkspace(&startDate, t); std::string endDate = std::to_string(*(*citr)->invEndDate); savetoTableWorkspace(&endDate, t); std::string sessionID = m_session->getSessionId(); savetoTableWorkspace(&sessionID, t); } } catch (std::runtime_error &) { throw std::runtime_error( "Error when saving the ICat Search Results data to Workspace"); } }
/** Fits each spectrum in the workspace to f(x) = A * sin( w * x + p) * @param ws :: [input] The workspace to fit * @param freq :: [input] Hint for the frequency (w) * @param groupName :: [input] The name of the output workspace group * @param resTab :: [output] Table workspace storing the asymmetries and phases * @param resGroup :: [output] Workspace group storing the fitting results */ void CalMuonDetectorPhases::fitWorkspace(const API::MatrixWorkspace_sptr &ws, double freq, std::string groupName, API::ITableWorkspace_sptr &resTab, API::WorkspaceGroup_sptr &resGroup) { int nhist = static_cast<int>(ws->getNumberHistograms()); // Create the fitting function f(x) = A * sin ( w * x + p ) // The same function and initial parameters are used for each fit std::string funcStr = createFittingFunction(freq, true); // Set up results table resTab->addColumn("int", "Spectrum number"); resTab->addColumn("double", "Asymmetry"); resTab->addColumn("double", "Phase"); // Loop through fitting all spectra individually const static std::string success = "success"; for (int wsIndex = 0; wsIndex < nhist; wsIndex++) { reportProgress(wsIndex, nhist); auto fit = createChildAlgorithm("Fit"); fit->initialize(); fit->setPropertyValue("Function", funcStr); fit->setProperty("InputWorkspace", ws); fit->setProperty("WorkspaceIndex", wsIndex); fit->setProperty("CreateOutput", true); fit->setPropertyValue("Output", groupName); fit->execute(); std::string status = fit->getProperty("OutputStatus"); if (!fit->isExecuted() || status != success) { std::ostringstream error; error << "Fit failed for spectrum at workspace index " << wsIndex; error << ": " << status; throw std::runtime_error(error.str()); } API::MatrixWorkspace_sptr fitOut = fit->getProperty("OutputWorkspace"); resGroup->addWorkspace(fitOut); API::ITableWorkspace_sptr tab = fit->getProperty("OutputParameters"); // Now we have our fitting results stored in tab // but we need to extract the relevant information, i.e. // the detector phases (parameter 'p') and asymmetries ('A') const auto &spectrum = ws->getSpectrum(static_cast<size_t>(wsIndex)); extractDetectorInfo(tab, resTab, spectrum.getSpectrumNo()); } }
/** Read from the instrument file the dead wires and store the information in a TableWorkspace. If asked, the dead wires are removed from the data set. @param localWorkspace :: input raw data workspace, containing the information about the instrument @param outputws :: input dead wire liste workspace */ void PoldiRemoveDeadWires::runExcludWires3 ( DataObjects::Workspace2D_sptr &localWorkspace, API::ITableWorkspace_sptr &outputws ) { outputws->addColumn("int","DeadWires"); boost::shared_ptr<const Mantid::Geometry::IComponent> comp = localWorkspace->getInstrument()->getComponentByName("holder"); boost::shared_ptr<const Mantid::Geometry::ICompAssembly> bank = boost::dynamic_pointer_cast<const Mantid::Geometry::ICompAssembly>(comp); if (bank) { // Get a vector of children (recursively) std::vector<boost::shared_ptr<const Mantid::Geometry::IComponent> > children; bank->getChildren(children, true); std::vector<double> defaultDeadWires; int ewLine = 0; for (unsigned int it = 0; it < children.size(); ++it) { string wireName = children.at(it)->getName(); std::vector<boost::shared_ptr<const Mantid::Geometry::IComponent> > tyty = localWorkspace.get()->getInstrument().get()->getAllComponentsWithName(wireName); std::vector<double> tempWire = tyty[0]->getNumberParameter("excluded"); if(tempWire.size()>0) { int val = (int)tempWire[0]; g_log.debug() << "_poldi : dead wires :" << val << std::endl; defaultDeadWires.push_back(val); for(unsigned int j=0; j<m_channelsPerSpectrum; j++) { localWorkspace->maskBin(val-1,j,1); } ewLine++; TableRow t = outputws->appendRow(); t << val ; } } g_log.information() << "_poldi : dead wires set to 0 (nb:" << ewLine << ")" << std::endl; setProperty("nbExcludedWires",ewLine); } else { g_log.information() << "_poldi : no dead wire removed" << std::endl; } }
/** This method saves the search response( investigations )data to a table * workspace * @param response :: const reference to response object * @param outputws :: shared pointer to output workspace */ void CICatHelper::saveSearchRessults( const ns1__searchByAdvancedPaginationResponse &response, API::ITableWorkspace_sptr &outputws) { if (outputws->getColumnNames().empty()) { outputws->addColumn("str", "Investigation id"); outputws->addColumn("str", "Facility"); outputws->addColumn("str", "Title"); outputws->addColumn("str", "Instrument"); outputws->addColumn("str", "Run range"); outputws->addColumn("str", "Start date"); outputws->addColumn("str", "End date"); outputws->addColumn("str", "SessionID"); } saveInvestigations(response.return_, outputws); }
void SaveDiffFittingAscii::writeData(const API::ITableWorkspace_sptr workspace, std::ofstream &file, const size_t columnSize) { for (size_t rowIndex = 0; rowIndex < workspace->rowCount(); ++rowIndex) { TableRow row = workspace->getRow(rowIndex); for (size_t columnIndex = 0; columnIndex < columnSize; columnIndex++) { const auto row_str = boost::lexical_cast<std::string>(row.Double(columnIndex)); g_log.debug() << row_str << std::endl; if (columnIndex == columnSize - 1) writeVal(row_str, file, true); else writeVal(row_str, file, false); } } }
/** * Fit the asymmetry and return the frequency found. * Starting value for the frequency is taken from the hint. * If the fit fails, return the initial hint. * @param wsAsym :: [input] Workspace with asymmetry to fit * @return :: Frequency found from fit */ double CalMuonDetectorPhases::fitFrequencyFromAsymmetry( const API::MatrixWorkspace_sptr &wsAsym) { // Starting value for frequency is hint double hint = getFrequencyHint(); std::string funcStr = createFittingFunction(hint, false); double frequency = hint; std::string fitStatus = "success"; try { auto func = API::FunctionFactory::Instance().createInitialized(funcStr); auto fit = createChildAlgorithm("Fit"); fit->setProperty("Function", func); fit->setProperty("InputWorkspace", wsAsym); fit->setProperty("WorkspaceIndex", 0); fit->setProperty("CreateOutput", true); fit->setProperty("OutputParametersOnly", true); fit->setProperty("Output", "__Invisible"); fit->executeAsChildAlg(); fitStatus = fit->getPropertyValue("OutputStatus"); if (fitStatus == "success") { API::ITableWorkspace_sptr params = fit->getProperty("OutputParameters"); const size_t rows = params->rowCount(); static size_t colName(0), colValue(1); for (size_t iRow = 0; iRow < rows; iRow++) { if (params->cell<std::string>(iRow, colName) == "w") { frequency = params->cell<double>(iRow, colValue); break; } } } } catch (const std::exception &e) { // Report fit failure to user fitStatus = e.what(); } if (fitStatus != "success") { // Either failed, or threw an exception std::ostringstream message; message << "Fit failed (" << fitStatus << "), using omega hint = " << hint; g_log.error(message.str()); } return frequency; }
/** Extracts detector asymmetries and phases from fitting results * and adds a new row to the results table with them * @param paramTab :: [input] Output parameter table resulting from the fit * @param resultsTab :: [input] Results table to update with a new row * @param spectrumNumber :: [input] Spectrum number */ void CalMuonDetectorPhases::extractDetectorInfo( const API::ITableWorkspace_sptr ¶mTab, const API::ITableWorkspace_sptr &resultsTab, const specnum_t spectrumNumber) { double asym = paramTab->Double(0, 1); double phase = paramTab->Double(2, 1); // If asym<0, take the absolute value and add \pi to phase // f(x) = A * sin( w * x + p) = -A * sin( w * x + p + PI) if (asym < 0) { asym = -asym; phase = phase + M_PI; } // Now convert phases to interval [0, 2PI) int factor = static_cast<int>(floor(phase / 2 / M_PI)); if (factor) { phase = phase - factor * 2 * M_PI; } // Copy parameters to new row in results table API::TableRow row = resultsTab->appendRow(); row << static_cast<int>(spectrumNumber) << asym << phase; }
/** Execute the algorithm. */ void CreateEPP::exec() { API::MatrixWorkspace_sptr inputWS = getProperty(PropertyNames::INPUT_WORKSPACE); const auto &spectrumInfo = inputWS->spectrumInfo(); API::ITableWorkspace_sptr outputWS = API::WorkspaceFactory::Instance().createTable("TableWorkspace"); addEPPColumns(outputWS); const double sigma = getProperty(PropertyNames::SIGMA); const size_t spectraCount = spectrumInfo.size(); outputWS->setRowCount(spectraCount); const auto l1 = spectrumInfo.l1(); const double EFixed = inputWS->run().getPropertyAsSingleValue("Ei"); for (size_t i = 0; i < spectraCount; ++i) { const auto l2 = spectrumInfo.l2(i); const auto elasticTOF = Kernel::UnitConversion::run( "Energy", "TOF", EFixed, l1, l2, 0, Kernel::DeltaEMode::Direct, EFixed); outputWS->getRef<int>(ColumnNames::WS_INDEX, i) = static_cast<int>(i); outputWS->getRef<double>(ColumnNames::PEAK_CENTRE, i) = elasticTOF; outputWS->getRef<double>(ColumnNames::PEAK_CENTRE_ERR, i) = 0; outputWS->getRef<double>(ColumnNames::SIGMA, i) = sigma; outputWS->getRef<double>(ColumnNames::SIGMA_ERR, i) = 0; double height = 0; try { const auto elasticIndex = inputWS->binIndexOf(elasticTOF, i); height = inputWS->y(i)[elasticIndex]; } catch (std::out_of_range &) { std::ostringstream sout; sout << "EPP out of TOF range for workspace index " << i << ". Peak height set to zero."; g_log.warning() << sout.str(); } outputWS->getRef<double>(ColumnNames::HEIGHT, i) = height; outputWS->getRef<double>(ColumnNames::CHI_SQUARED, i) = 1; outputWS->getRef<std::string>(ColumnNames::STATUS, i) = "success"; } setProperty(PropertyNames::OUTPUT_WORKSPACE, outputWS); }
/** * Saves result from "getDataFiles" to workspace. * @param response :: result response from the catalog. * @param outputws :: shared pointer to datasets */ void ICat4Catalog::saveDataFiles(std::vector<xsd__anyType *> response, API::ITableWorkspace_sptr &outputws) { if (outputws->getColumnNames().empty()) { // Add rows headers to the output workspace. outputws->addColumn("str", "Name"); outputws->addColumn("str", "Location"); outputws->addColumn("str", "Create Time"); outputws->addColumn("long64", "Id"); outputws->addColumn("long64", "File size(bytes)"); outputws->addColumn("str", "File size"); outputws->addColumn("str", "Description"); } std::vector<xsd__anyType *>::const_iterator iter; for (iter = response.begin(); iter != response.end(); ++iter) { ns1__datafile *datafile = dynamic_cast<ns1__datafile *>(*iter); if (datafile) { API::TableRow table = outputws->appendRow(); // Now add the relevant investigation data to the table. savetoTableWorkspace(datafile->name, table); savetoTableWorkspace(datafile->location, table); std::string createDate = formatDateTime(*datafile->createTime, "%Y-%m-%d %H:%M:%S"); savetoTableWorkspace(&createDate, table); savetoTableWorkspace(datafile->id, table); savetoTableWorkspace(datafile->fileSize, table); std::string fileSize = bytesToString(*datafile->fileSize); savetoTableWorkspace(&fileSize, table); if (datafile->description) savetoTableWorkspace(datafile->description, table); } else { throw std::runtime_error("ICat4Catalog::saveDataFiles expected a " "datafile. Please contact the Mantid " "development team."); } } }
/** Executes the algorithm. Moving detectors of input workspace to positions indicated in table workspace * * @throw FileError Thrown if unable to get instrument from workspace, * table workspace is incompatible with instrument */ void ApplyCalibration::exec() { // Get pointers to the workspace, parameter map and table API::MatrixWorkspace_sptr inputWS = getProperty("Workspace"); m_pmap = &(inputWS->instrumentParameters()); // Avoids a copy if you get the reference before the instrument API::ITableWorkspace_sptr PosTable = getProperty("PositionTable"); Geometry::Instrument_const_sptr instrument = inputWS->getInstrument(); if(!instrument) { throw std::runtime_error("Workspace to apply calibration to has no defined instrument"); } size_t numDetector = PosTable->rowCount(); ColumnVector<int> detID = PosTable->getVector("Detector ID"); ColumnVector<V3D> detPos = PosTable->getVector("Detector Position"); // numDetector needs to be got as the number of rows in the table and the detID got from the (i)th row of table. for (size_t i = 0; i < numDetector; ++i) { setDetectorPosition(instrument, detID[i], detPos[i], false ); } // Ensure pointer is only valid for execution m_pmap = NULL; }
/** * Loops through the response vector and saves the datasets details to a table * workspace. * @param response :: A vector containing the results of the search query. * @param outputws :: Shared pointer to output workspace. */ void ICat4Catalog::saveDataSets(std::vector<xsd__anyType *> response, API::ITableWorkspace_sptr &outputws) { if (outputws->getColumnNames().empty()) { // Add rows headers to the output workspace. outputws->addColumn("long64", "ID"); outputws->addColumn("str", "Name"); outputws->addColumn("str", "Description"); outputws->addColumn("str", "Type"); outputws->addColumn("str", "Related investigation ID"); outputws->addColumn("size_t", "Number of datafiles"); } std::string emptyCell; for (auto &iter : response) { ns1__dataset *dataset = dynamic_cast<ns1__dataset *>(iter); if (dataset) { API::TableRow table = outputws->appendRow(); savetoTableWorkspace(dataset->id, table); savetoTableWorkspace(dataset->name, table); if (dataset->description) savetoTableWorkspace(dataset->description, table); else savetoTableWorkspace(&emptyCell, table); if (dataset->type) savetoTableWorkspace(dataset->type->name, table); else savetoTableWorkspace(&emptyCell, table); if (dataset->investigation) savetoTableWorkspace(dataset->investigation->name, table); else savetoTableWorkspace(&emptyCell, table); size_t datafileCount = dataset->datafiles.size(); savetoTableWorkspace(&datafileCount, table); } else { throw std::runtime_error("ICat4Catalog::saveDataSets expected a dataset. " "Please contact the Mantid development team."); } } }
/** This method loops through the response return_vector and saves the datasets details to a table workspace * @param response :: const reference to response object * @param outputws :: shred pointer to workspace * @returns shared pointer to table workspace which stores the data */ void CICatHelper::saveDataSets(const ns1__getInvestigationIncludesResponse& response,API::ITableWorkspace_sptr& outputws) { //create table workspace if (outputws->getColumnNames().empty()) { outputws->addColumn("str","Name");//File name outputws->addColumn("str","Status"); outputws->addColumn("str","Type"); outputws->addColumn("str","Description"); outputws->addColumn("long64","Sample Id"); } try { std::vector<ns1__dataset*> datasetVec; datasetVec.assign((response.return_)->datasetCollection.begin(),(response.return_)->datasetCollection.end()); std::vector<ns1__dataset*>::const_iterator dataset_citr; for(dataset_citr=datasetVec.begin();dataset_citr!=datasetVec.end();++dataset_citr) { API::TableRow t = outputws->appendRow(); // DataSet Name savetoTableWorkspace((*dataset_citr)->name,t); // DataSet Status savetoTableWorkspace((*dataset_citr)->datasetStatus,t); //DataSet Type savetoTableWorkspace((*dataset_citr)->datasetType,t); //DataSet Type savetoTableWorkspace((*dataset_citr)->description,t); //DataSet Type savetoTableWorkspace((*dataset_citr)->sampleId,t); } } catch(std::runtime_error& ) { throw; } //return outputws; }
/** * Parse the (optional) exp.ini file found on NOMAD * @param filename full path to a exp.ini file * @param wksp The table workspace to modify. */ void PDLoadCharacterizations::readExpIni(const std::string &filename, API::ITableWorkspace_sptr &wksp) { if (wksp->rowCount() == 0) throw std::runtime_error("Characterizations file does not have any " "characterizations information"); std::ifstream file(filename.c_str()); if (!file) { throw Exception::FileError("Unable to open file", filename); } // parse the file for (std::string line = Strings::getLine(file); !file.eof(); line = Strings::getLine(file)) { line = Strings::strip(line); // skip empty lines and "comments" if (line.empty()) continue; if (line.substr(0, 1) == "#") continue; // split the line and see if it has something meaningful std::vector<std::string> splitted; boost::split(splitted, line, boost::is_any_of("\t "), boost::token_compress_on); if (splitted.size() < 2) continue; // update the various charaterization runs if (splitted[0] == EXP_INI_VAN_KEY) { wksp->getRef<std::string>("vanadium", 0) = splitted[1]; } else if (splitted[0] == EXP_INI_EMPTY_KEY) { wksp->getRef<std::string>("container", 0) = splitted[1]; } else if (splitted[0] == EXP_INI_CAN_KEY) { wksp->getRef<std::string>("empty", 0) = splitted[1]; } } }
/** Load PhaseTable file to a vector of HistData. * @param phaseTable :: [input] phase table containing detector info * @param deadTimeTable :: [output] phase table containing dead times */ void PhaseQuadMuon::loadPhaseTable(API::ITableWorkspace_sptr phaseTable, API::ITableWorkspace_sptr deadTimeTable) { if ( phaseTable->rowCount() ) { if ( phaseTable->columnCount()<4 ) { throw std::invalid_argument("PhaseQuad: PhaseTable must contain at least four columns"); } // Check number of histograms in inputWs match number of detectors in phase table if (m_nHist != static_cast<int>(phaseTable->rowCount())) { throw std::runtime_error("PhaseQuad: Number of histograms in phase table does not match number of spectra in workspace"); } for (size_t i=0; i<phaseTable->rowCount(); ++i) { API::TableRow phaseRow = phaseTable->getRow(i); // The first three columns go to m_histData HistData tempHist; tempHist.detOK = phaseRow.Bool(0); tempHist.alpha = phaseRow.Double(1); tempHist.phi = phaseRow.Double(2); m_histData.push_back(tempHist); // The last column goes to deadTimeTable API::TableRow deadRow = deadTimeTable->appendRow(); deadRow << static_cast<int>(i)+1 << phaseRow.Double(3); } } else { throw std::invalid_argument("PhaseQuad: PhaseTable is empty"); } }
/** * Load a table */ API::Workspace_sptr LoadNexusProcessed::loadTableEntry(NXEntry & entry) { API::ITableWorkspace_sptr workspace; workspace = Mantid::API::WorkspaceFactory::Instance().createTable("TableWorkspace"); NXData nx_tw = entry.openNXData("table_workspace"); std::vector<double> values; bool hasNumberOfRowBeenSet = false; //int numberOfRows = 0; int columnNumber = 1; do { std::string str = "column_" + boost::lexical_cast<std::string>(columnNumber); NXInfo info = nx_tw.getDataSetInfo(str.c_str()); if (info.stat == NX_ERROR) { break; } if ( info.type == NX_FLOAT64 ) { NXDouble nxDouble = nx_tw.openNXDouble(str.c_str()); std::string columnTitle = nxDouble.attributes("name"); if (!columnTitle.empty()) { workspace->addColumn("double", columnTitle); nxDouble.load(); int length = nxDouble.dim0(); if ( !hasNumberOfRowBeenSet ) { workspace->setRowCount(length); hasNumberOfRowBeenSet = true; } for (int i = 0; i < length; i++) workspace->cell<double>(i,columnNumber-1) = *(nxDouble() + i); } } else if ( info.type == NX_CHAR ) { NXChar data = nx_tw.openNXChar(str.c_str()); std::string columnTitle = data.attributes("name"); if (!columnTitle.empty()) { workspace->addColumn("str", columnTitle); int nRows = info.dims[0]; if ( !hasNumberOfRowBeenSet ) { workspace->setRowCount(nRows); hasNumberOfRowBeenSet = true; } int maxStr = info.dims[1]; std::string fromCrap(maxStr,' '); data.load(); for (int iR = 0; iR < nRows; iR++) { for (int i = 0; i < maxStr; i++) fromCrap[i] = *(data()+i+maxStr*iR); workspace->cell<std::string>(iR,columnNumber-1) = fromCrap; } } } columnNumber++; } while ( 1 ); return boost::static_pointer_cast<API::Workspace>(workspace); }
/** Auto detecte the dead wires and store the information in the TableWorkspace. If asked, the dead wires are removed from the data set. @param localWorkspace :: input raw data workspace, containing the information about the instrument @param outputws :: input dead wire liste workspace */ void PoldiRemoveDeadWires::autoRemoveDeadWires ( DataObjects::Workspace2D_sptr &localWorkspace, API::ITableWorkspace_sptr &outputws ) { double autoDeadWiresThreshold = 0; autoDeadWiresThreshold = getProperty("BadWiresThreshold"); if(!autoDeadWiresThreshold) autoDeadWiresThreshold = m_defautDWThreshold; autoDeadWiresThreshold = 1.-autoDeadWiresThreshold; // double autoDeadWiresThreshold = 1-0.4; g_log.information() << "_poldi : auto removed wires : BadWiresThreshold:" << autoDeadWiresThreshold << std::endl; int count = 0; double minValue=INFINITY; unsigned int minPos = 0; bool checkContinue = true; std::vector<double> average(this->m_numberOfSpectra); double globalAverage = 0; //compute the average intensity per spectrum for(unsigned int i=0; i<this->m_numberOfSpectra; i++) { if(!localWorkspace.get()->hasMaskedBins(i)) { average.at(i) = 0; MantidVec& tempY = localWorkspace.get()->dataY(i); for(unsigned int j=0; j<this->m_channelsPerSpectrum; j++) { average.at(i) += tempY[j]; } average.at(i) /= static_cast<double>(this->m_channelsPerSpectrum); if(average[i]<minValue) { minValue = average[i]; minPos = i; } } } g_log.debug() << "_poldi : auto removed wires : average done" << std::endl; while(checkContinue) { checkContinue = false; minValue=INFINITY; minPos = 0; int n = 0; // find the minimum average position, the most probably wrong spectra for(unsigned int i=0; i<this->m_numberOfSpectra; i++) { if(!localWorkspace.get()->hasMaskedBins(i)) { globalAverage += average[i]; n++; if(average[i]<minValue) { minValue = average[i]; minPos = i; } } } globalAverage /=n; //applied the threshold to determine if a wires should be excluded //check if the wire is not already excluded if(!localWorkspace.get()->hasMaskedBins(minPos)) { if(average[minPos]<globalAverage*autoDeadWiresThreshold) { //mask the wires for(unsigned int j=0; j<this->m_channelsPerSpectrum; j++) { localWorkspace->maskBin(minPos,j,1); } count++; checkContinue = true; TableRow t = outputws->appendRow(); t << int(minPos) ; } } //applied the threshold to determine if a wires should be excluded //check if the wire is not already excluded if(!localWorkspace.get()->hasMaskedBins(minPos)) { //check the threshold on the left unsigned int left = minPos-1; //find the first used wires on the left while(localWorkspace.get()->hasMaskedBins(left) && left>0) { left--; } if(left>0 && average[minPos]<average[left]*autoDeadWiresThreshold) { //mask the wires for(unsigned int j=0; j<this->m_channelsPerSpectrum; j++) { localWorkspace->maskBin(minPos,j,1); } count++; checkContinue = true; TableRow t = outputws->appendRow(); t << int(minPos) ; } } if(!localWorkspace.get()->hasMaskedBins(minPos)) { //check the threshold on the right unsigned int right = minPos+1; //find the first used wires on the left while(localWorkspace.get()->hasMaskedBins(right) && right<this->m_numberOfSpectra) { right++; } if(right<m_numberOfSpectra-1 && average[minPos]<average[right]*autoDeadWiresThreshold) { //mask the wires for(unsigned int j=0; j<this->m_channelsPerSpectrum; j++) { localWorkspace->maskBin(minPos,j,1); } count++; checkContinue = true; TableRow t = outputws->appendRow(); t << int(minPos) ; } } } g_log.information() << "_poldi : auto removed wires (nb:" << count << ")" << std::endl; setProperty("nbAuteDeadWires",count); }
/** * Saves investigations to a table workspace. * @param response :: A vector containing the results of the search query. * @param outputws :: Shared pointer to output workspace. */ void ICat4Catalog::saveInvestigations(std::vector<xsd__anyType *> response, API::ITableWorkspace_sptr &outputws) { if (outputws->getColumnNames().empty()) { // Add rows headers to the output workspace. outputws->addColumn("long64", "DatabaseID"); outputws->addColumn("str", "InvestigationID"); outputws->addColumn("str", "Facility"); outputws->addColumn("str", "Title"); outputws->addColumn("str", "Instrument"); outputws->addColumn("str", "Run range"); outputws->addColumn("str", "Start date"); outputws->addColumn("str", "End date"); outputws->addColumn("str", "SessionID"); } // Add data to each row in the output workspace. std::vector<xsd__anyType *>::const_iterator iter; for (iter = response.begin(); iter != response.end(); ++iter) { // Cast from xsd__anyType to subclass (xsd__string). ns1__investigation *investigation = dynamic_cast<ns1__investigation *>(*iter); if (investigation) { API::TableRow table = outputws->appendRow(); // Used to insert an empty string into the cell if value does not exist. std::string emptyCell; // Now add the relevant investigation data to the table (They always // exist). savetoTableWorkspace(investigation->id, table); savetoTableWorkspace(investigation->name, table); savetoTableWorkspace(investigation->facility->name, table); savetoTableWorkspace(investigation->title, table); savetoTableWorkspace( investigation->investigationInstruments.at(0)->instrument->name, table); // Verify that the run parameters vector exist prior to doing anything. // Since some investigations may not have run parameters. if (!investigation->parameters.empty()) { savetoTableWorkspace(investigation->parameters[0]->stringValue, table); } else { savetoTableWorkspace(&emptyCell, table); } // Again, we need to check first if start and end date exist prior to // insertion. if (investigation->startDate) { std::string startDate = formatDateTime(*investigation->startDate, "%Y-%m-%d"); savetoTableWorkspace(&startDate, table); } else { savetoTableWorkspace(&emptyCell, table); } if (investigation->endDate) { std::string endDate = formatDateTime(*investigation->endDate, "%Y-%m-%d"); savetoTableWorkspace(&endDate, table); } else { savetoTableWorkspace(&emptyCell, table); } std::string sessionID = m_session->getSessionId(); savetoTableWorkspace(&sessionID, table); } else { throw std::runtime_error("ICat4Catalog::saveInvestigations expected an " "investigation. Please contact the Mantid " "development team."); } } }
/** Generate a list of peaks that meets= all the requirements for fitting offset * @param peakslist :: table workspace as the output of FindPeaks * @param wi :: workspace index of the spectrum * @param peakPositionRef :: reference peaks positions * @param peakPosToFit :: output of reference centres of the peaks used to fit * offset * @param peakPosFitted :: output of fitted centres of the peaks used to fit * offset * @param peakHeightFitted :: heights of the peaks used to fit offset * @param chisq :: chi squares of the peaks used to fit offset * @param useFitWindows :: boolean whether FitWindows is used * @param fitWindowsToUse :: fit windows * @param minD :: minimum d-spacing of the spectrum * @param maxD :: minimum d-spacing of the spectrum * @param deltaDovD :: delta(d)/d of the peak for fitting * @param dev_deltaDovD :: standard deviation of delta(d)/d of all the peaks in * the spectrum */ void GetDetOffsetsMultiPeaks::generatePeaksList( const API::ITableWorkspace_sptr &peakslist, int wi, const std::vector<double> &peakPositionRef, std::vector<double> &peakPosToFit, std::vector<double> &peakPosFitted, std::vector<double> &peakHeightFitted, std::vector<double> &chisq, bool useFitWindows, const std::vector<double> &fitWindowsToUse, const double minD, const double maxD, double &deltaDovD, double &dev_deltaDovD) { // FIXME - Need to make sure that the peakPositionRef and peakslist have the // same order of peaks // Check size_t numrows = peakslist->rowCount(); if (numrows != peakPositionRef.size()) { std::stringstream msg; msg << "Number of peaks in PeaksList (from FindPeaks=" << numrows << ") is not same as number of " << "referenced peaks' positions (" << peakPositionRef.size() << ")"; throw std::runtime_error(msg.str()); } std::vector<double> vec_widthDivPos; std::vector<double> vec_offsets; for (size_t i = 0; i < peakslist->rowCount(); ++i) { // Get peak value double centre = peakslist->getRef<double>("centre", i); double width = peakslist->getRef<double>("width", i); double height = peakslist->getRef<double>("height", i); double chi2 = peakslist->getRef<double>("chi2", i); // Identify whether this peak would be accepted to optimize offset // - peak position within D-range if (centre <= minD || centre >= maxD) { std::stringstream dbss; dbss << " wi = " << wi << " c = " << centre << " out of D-range "; g_log.debug(dbss.str()); continue; } // - rule out of peak with wrong position if (useFitWindows) { // outside peak fit window o if (centre <= fitWindowsToUse[2 * i] || centre >= fitWindowsToUse[2 * i + 1]) { std::stringstream dbss; dbss << " wi = " << wi << " c = " << centre << " out of fit window "; g_log.debug(dbss.str()); continue; } } // - check chi-square if (chi2 > m_maxChiSq || chi2 < 0) { std::stringstream dbss; dbss << " wi = " << wi << " c = " << centre << " chi2 = " << chi2 << ": Too large"; g_log.debug(dbss.str()); continue; } // - check peak height if (height < m_minPeakHeight) { g_log.debug() << " wi = " << wi << " c = " << centre << " h = " << height << ": Too low " << "\n"; continue; } // - check peak's resolution double widthdevpos = width / centre; if (m_hasInputResolution) { double recres = m_inputResolutionWS->readY(wi)[0]; double resmax = recres * m_maxResFactor; double resmin = recres * m_minResFactor; if (widthdevpos < resmin || widthdevpos > resmax) { std::stringstream dbss; dbss << " wi = " << wi << " c = " << centre << " Delta(d)/d = " << widthdevpos << " too far away from suggested value " << recres; g_log.debug(dbss.str()); continue; } } // background value double back_intercept = peakslist->getRef<double>("backgroundintercept", i); double back_slope = peakslist->getRef<double>("backgroundslope", i); double back_quad = peakslist->getRef<double>("A2", i); double background = back_intercept + back_slope * centre + back_quad * centre * centre; // Continue to identify whether this peak will be accepted // (e) peak signal/noise ratio if (height * FWHM_TO_SIGMA / width < 5.) continue; // (f) ban peaks that are not outside of error bars for the background if (height < 0.5 * std::sqrt(height + background)) continue; // - calcualte offsets as to determine the (z-value) double offset = fabs(peakPositionRef[i] / centre - 1); if (offset > m_maxOffset) { std::stringstream dbss; dbss << " wi = " << wi << " c = " << centre << " exceeds maximum offset. "; g_log.debug(dbss.str()); continue; } else vec_offsets.push_back(offset); // (g) calculate width/pos as to determine the (z-value) for constant // "width" - (delta d)/d // double widthdevpos = width/centre; vec_widthDivPos.push_back(widthdevpos); // g_log.debug() << " h:" << height << " c:" << centre << " w:" << // (width/(2.*std::sqrt(2.*std::log(2.)))) // << " b:" << background << " chisq:" << chi2 << "\n"; // Add peak to vectors double refcentre = peakPositionRef[i]; peakPosFitted.push_back(centre); peakPosToFit.push_back(refcentre); peakHeightFitted.push_back(height); chisq.push_back(chi2); } // Remove by Z-score on delta d/d std::vector<size_t> banned; std::vector<double> Zscore = getZscore(vec_widthDivPos); std::vector<double> Z_offset = getZscore(vec_offsets); for (size_t i = 0; i < peakPosFitted.size(); ++i) { if (Zscore[i] > 2.0 || Z_offset[i] > 2.0) { g_log.debug() << "Banning peak at " << peakPosFitted[i] << " in wkspindex = (no show)" // << wi << " sigma/d = " << vec_widthDivPos[i] << "\n"; banned.push_back(i); continue; } } // Delete banned peaks if (!banned.empty()) { g_log.debug() << "Deleting " << banned.size() << " of " << peakPosFitted.size() << " peaks in wkspindex = ??? " << "\n"; // << wi << "\n"; deletePeaks(banned, peakPosToFit, peakPosFitted, peakHeightFitted, chisq, vec_widthDivPos); } Statistics widthDivPos = getStatistics(vec_widthDivPos); deltaDovD = widthDivPos.mean; dev_deltaDovD = widthDivPos.standard_deviation; return; }
/** * This method loops through the response return_vector and saves the datafile * details to a table workspace * @param response :: const reference to response object * @param outputws :: shared pointer to table workspace which stores the data */ void CICatHelper::saveInvestigationIncludesResponse( const ns1__getInvestigationIncludesResponse &response, API::ITableWorkspace_sptr &outputws) { if (outputws->getColumnNames().empty()) { outputws->addColumn("str", "Name"); outputws->addColumn("str", "Location"); outputws->addColumn("str", "Create Time"); outputws->addColumn("long64", "Id"); outputws->addColumn("long64", "File size(bytes)"); outputws->addColumn("str", "File size"); outputws->addColumn("str", "Description"); } try { std::vector<ns1__dataset *> datasetVec; datasetVec.assign((response.return_)->datasetCollection.begin(), (response.return_)->datasetCollection.end()); if (datasetVec.empty()) { throw std::runtime_error("No data files exists in the ICAT database for " "the selected investigation"); } std::vector<ns1__dataset *>::const_iterator dataset_citr; for (dataset_citr = datasetVec.begin(); dataset_citr != datasetVec.end(); ++dataset_citr) { std::vector<ns1__datafile *> datafileVec; datafileVec.assign((*dataset_citr)->datafileCollection.begin(), (*dataset_citr)->datafileCollection.end()); if (datafileVec.empty()) { throw std::runtime_error("No data files exists in the ICAT database " "for the selected investigation "); } std::vector<ns1__datafile *>::const_iterator datafile_citr; for (datafile_citr = datafileVec.begin(); datafile_citr != datafileVec.end(); ++datafile_citr) { API::TableRow t = outputws->appendRow(); // File Name savetoTableWorkspace((*datafile_citr)->name, t); savetoTableWorkspace((*datafile_citr)->location, t); // File creation Time. std::string *creationtime = nullptr; if ((*datafile_citr)->datafileCreateTime != nullptr) { time_t crtime = *(*datafile_citr)->datafileCreateTime; char temp[25]; strftime(temp, 25, "%Y-%b-%d %H:%M:%S", localtime(&crtime)); std::string ftime(temp); creationtime = new std::string; creationtime->assign(ftime); } savetoTableWorkspace(creationtime, t); if (creationtime) delete creationtime; // savetoTableWorkspace((*datafile_citr)->id, t); LONG64 fileSize = boost::lexical_cast<LONG64>(*(*datafile_citr)->fileSize); savetoTableWorkspace(&fileSize, t); savetoTableWorkspace((*datafile_citr)->description, t); } } } catch (std::runtime_error &) { throw; } }
/** Load PhaseList file to a vector of HistData and a deadTimeTable. * @param filename :: [input] phase list .inf filename * @param deadTimeTable :: [output] table containing dead times */ void PhaseQuadMuon::loadPhaseList(const std::string& filename, API::ITableWorkspace_sptr deadTimeTable ) { std::ifstream input(filename.c_str(), std::ios_base::in); if (input.is_open()) { if ( input.eof() ) { throw Exception::FileError("PhaseQuad: File is empty.", filename); } else { std::string line; // Header of .INF file is as follows: // // Comment on the output file // Top row of numbers are: // #histos, typ. first good bin#, typ. bin# when pulse over, mean lag. // Tabulated numbers are, per histogram: // det ok, asymmetry, phase, lag, deadtime_c, deadtime_m. // std::getline( input, line ); // Skip first line in header std::getline( input, line ); // Skip second line std::getline( input, line ); // ... std::getline( input, line ); std::getline( input, line ); // Read first useful line int nHist; input >> nHist >> m_tValid >> m_tPulseOver >> m_meanLag; if (m_nHist!=nHist) { throw std::runtime_error("PhaseQuad: Number of histograms in phase list does not match number of spectra in workspace"); } // Read histogram data int cont=0; HistData tempData; double lag, dead, deadm; while( input >> tempData.detOK >> tempData.alpha >> tempData.phi >> lag >> dead >> deadm ) { m_histData.push_back (tempData); cont++; // Add dead time to deadTimeTable API::TableRow row = deadTimeTable->appendRow(); row << cont << dead; } if ( cont != m_nHist ) { if ( cont < m_nHist ) { throw Exception::FileError("PhaseQuad: Lines missing in phase list", filename); } else { throw Exception::FileError("PhaseQuad: Extra lines in phase list", filename); } } } } else { // Throw exception if file cannot be opened throw std::runtime_error("PhaseQuad: Unable to open PhaseList");
/** Forms the quadrature phase signal (squashogram) * @param ws :: [input] workspace containing the measured spectra * @param phase :: [input] table workspace containing the detector phases * @param n0 :: [input] vector containing the normalization constants * @return :: workspace containing the quadrature phase signal */ API::MatrixWorkspace_sptr PhaseQuadMuon::squash(const API::MatrixWorkspace_sptr &ws, const API::ITableWorkspace_sptr &phase, const std::vector<double> &n0) { // Poisson limit: below this number we consider we don't have enough // statistics // to apply sqrt(N). This is an arbitrary number used in the original code // provided by scientists double poissonLimit = 30.; size_t nspec = ws->getNumberHistograms(); size_t npoints = ws->blocksize(); // Muon life time in microseconds double muLife = PhysicalConstants::MuonLifetime * 1e6; if (n0.size() != nspec) { throw std::invalid_argument("Invalid normalization constants"); } // Get the maximum asymmetry double maxAsym = 0.; for (size_t h = 0; h < nspec; h++) { if (phase->Double(h, 1) > maxAsym) { maxAsym = phase->Double(h, 1); } } if (maxAsym == 0.0) { throw std::invalid_argument("Invalid detector asymmetries"); } std::vector<double> aj, bj; { // Calculate coefficients aj, bj double sxx = 0; double syy = 0; double sxy = 0; for (size_t h = 0; h < nspec; h++) { double asym = phase->Double(h, 1) / maxAsym; double phi = phase->Double(h, 2); double X = n0[h] * asym * cos(phi); double Y = n0[h] * asym * sin(phi); sxx += X * X; syy += Y * Y; sxy += X * Y; } double lam1 = 2 * syy / (sxx * syy - sxy * sxy); double mu1 = 2 * sxy / (sxy * sxy - sxx * syy); double lam2 = 2 * sxy / (sxy * sxy - sxx * syy); double mu2 = 2 * sxx / (sxx * syy - sxy * sxy); for (size_t h = 0; h < nspec; h++) { double asym = phase->Double(h, 1) / maxAsym; double phi = phase->Double(h, 2); double X = n0[h] * asym * cos(phi); double Y = n0[h] * asym * sin(phi); aj.push_back((lam1 * X + mu1 * Y) * 0.5); bj.push_back((lam2 * X + mu2 * Y) * 0.5); } } // First X value double X0 = ws->x(0).front(); // Create and populate output workspace API::MatrixWorkspace_sptr ows = API::WorkspaceFactory::Instance().create( "Workspace2D", 2, npoints + 1, npoints); // X ows->setSharedX(0, ws->sharedX(0)); ows->setSharedX(1, ws->sharedX(0)); // Phase quadrature auto &realY = ows->mutableY(0); auto &imagY = ows->mutableY(1); auto &realE = ows->mutableE(0); auto &imagE = ows->mutableE(1); for (size_t i = 0; i < npoints; i++) { for (size_t h = 0; h < nspec; h++) { // (X,Y,E) with exponential decay removed const double X = ws->x(h)[i]; const double Y = ws->y(h)[i] - n0[h] * exp(-(X - X0) / muLife); const double E = (ws->y(h)[i] > poissonLimit) ? ws->e(h)[i] : sqrt(n0[h] * exp(-(X - X0) / muLife)); realY[i] += aj[h] * Y; imagY[i] += bj[h] * Y; realE[i] += aj[h] * aj[h] * E * E; imagE[i] += bj[h] * bj[h] * E * E; } realE[i] = sqrt(realE[i]); imagE[i] = sqrt(imagE[i]); // Regain exponential decay const double X = ws->getSpectrum(0).x()[i]; const double e = exp(-(X - X0) / muLife); realY[i] /= e; imagY[i] /= e; realE[i] /= e; imagE[i] /= e; } return ows; }
/** Forms the quadrature phase signal (squashogram) * @param ws :: [input] workspace containing the measured spectra * @param phase :: [input] table workspace containing the detector phases * @param n0 :: [input] vector containing the normalization constants * @return :: workspace containing the quadrature phase signal */ API::MatrixWorkspace_sptr PhaseQuadMuon::squash(const API::MatrixWorkspace_sptr &ws, const API::ITableWorkspace_sptr &phase, const std::vector<double> &n0) { // Poisson limit: below this number we consider we don't have enough // statistics // to apply sqrt(N). This is an arbitrary number used in the original code // provided by scientists const double poissonLimit = 30.; // Muon life time in microseconds const double muLife = PhysicalConstants::MuonLifetime * 1e6; const size_t nspec = ws->getNumberHistograms(); if (n0.size() != nspec) { throw std::invalid_argument("Invalid normalization constants"); } auto names = phase->getColumnNames(); for (auto &name : names) { std::transform(name.begin(), name.end(), name.begin(), ::tolower); } auto phaseIndex = findName(phaseNames, names); auto asymmetryIndex = findName(asymmNames, names); // Get the maximum asymmetry double maxAsym = 0.; for (size_t h = 0; h < nspec; h++) { if (phase->Double(h, asymmetryIndex) > maxAsym && phase->Double(h, asymmetryIndex) != ASYMM_ERROR) { maxAsym = phase->Double(h, asymmetryIndex); } } if (maxAsym == 0.0) { throw std::invalid_argument("Invalid detector asymmetries"); } std::vector<bool> emptySpectrum; emptySpectrum.reserve(nspec); std::vector<double> aj, bj; { // Calculate coefficients aj, bj double sxx = 0.; double syy = 0.; double sxy = 0.; for (size_t h = 0; h < nspec; h++) { emptySpectrum.push_back( std::all_of(ws->y(h).begin(), ws->y(h).end(), [](double value) { return value == 0.; })); if (!emptySpectrum[h]) { const double asym = phase->Double(h, asymmetryIndex) / maxAsym; const double phi = phase->Double(h, phaseIndex); const double X = n0[h] * asym * cos(phi); const double Y = n0[h] * asym * sin(phi); sxx += X * X; syy += Y * Y; sxy += X * Y; } } const double lam1 = 2 * syy / (sxx * syy - sxy * sxy); const double mu1 = 2 * sxy / (sxy * sxy - sxx * syy); const double lam2 = 2 * sxy / (sxy * sxy - sxx * syy); const double mu2 = 2 * sxx / (sxx * syy - sxy * sxy); for (size_t h = 0; h < nspec; h++) { if (emptySpectrum[h]) { aj.push_back(0.0); bj.push_back(0.0); } else { const double asym = phase->Double(h, asymmetryIndex) / maxAsym; const double phi = phase->Double(h, phaseIndex); const double X = n0[h] * asym * cos(phi); const double Y = n0[h] * asym * sin(phi); aj.push_back((lam1 * X + mu1 * Y) * 0.5); bj.push_back((lam2 * X + mu2 * Y) * 0.5); } } } const size_t npoints = ws->blocksize(); // Create and populate output workspace API::MatrixWorkspace_sptr ows = API::WorkspaceFactory::Instance().create(ws, 2, npoints + 1, npoints); // X ows->setSharedX(0, ws->sharedX(0)); ows->setSharedX(1, ws->sharedX(0)); // Phase quadrature auto &realY = ows->mutableY(0); auto &imagY = ows->mutableY(1); auto &realE = ows->mutableE(0); auto &imagE = ows->mutableE(1); const auto xPointData = ws->histogram(0).points(); // First X value const double X0 = xPointData.front(); // calculate exponential decay outside of the loop std::vector<double> expDecay = xPointData.rawData(); std::transform(expDecay.begin(), expDecay.end(), expDecay.begin(), [X0, muLife](double x) { return exp(-(x - X0) / muLife); }); for (size_t i = 0; i < npoints; i++) { for (size_t h = 0; h < nspec; h++) { if (!emptySpectrum[h]) { // (X,Y,E) with exponential decay removed const double X = ws->x(h)[i]; const double exponential = n0[h] * exp(-(X - X0) / muLife); const double Y = ws->y(h)[i] - exponential; const double E = (ws->y(h)[i] > poissonLimit) ? ws->e(h)[i] : sqrt(exponential); realY[i] += aj[h] * Y; imagY[i] += bj[h] * Y; realE[i] += aj[h] * aj[h] * E * E; imagE[i] += bj[h] * bj[h] * E * E; } } realE[i] = sqrt(realE[i]); imagE[i] = sqrt(imagE[i]); // Regain exponential decay realY[i] /= expDecay[i]; imagY[i] /= expDecay[i]; realE[i] /= expDecay[i]; imagE[i] /= expDecay[i]; } // New Y axis label ows->setYUnit("Asymmetry"); return ows; }
/** * Calculates the EISF if the fit includes a Delta function * @param tableWs - The TableWorkspace to append the EISF calculation to */ void ConvolutionFitSequential::calculateEISF( API::ITableWorkspace_sptr &tableWs) { // Get height data from parameter table const auto columns = tableWs->getColumnNames(); const auto height = searchForFitParams("Height", columns).at(0); const auto heightErr = searchForFitParams("Height_Err", columns).at(0); auto heightY = tableWs->getColumn(height)->numeric_fill<>(); auto heightE = tableWs->getColumn(heightErr)->numeric_fill<>(); // Get amplitude column names const auto ampNames = searchForFitParams("Amplitude", columns); const auto ampErrorNames = searchForFitParams("Amplitude_Err", columns); // For each lorentzian, calculate EISF size_t maxSize = ampNames.size(); if (ampErrorNames.size() > maxSize) { maxSize = ampErrorNames.size(); } for (size_t i = 0; i < maxSize; i++) { // Get amplitude from column in table workspace const auto ampName = ampNames.at(i); auto ampY = tableWs->getColumn(ampName)->numeric_fill<>(); const auto ampErrorName = ampErrorNames.at(i); auto ampErr = tableWs->getColumn(ampErrorName)->numeric_fill<>(); // Calculate EISF and EISF error // total = heightY + ampY auto total = cloneVector(heightY); std::transform(total.begin(), total.end(), ampY.begin(), total.begin(), std::plus<double>()); // eisfY = heightY / total auto eisfY = cloneVector(heightY); std::transform(eisfY.begin(), eisfY.end(), total.begin(), eisfY.begin(), std::divides<double>()); // heightE squared auto heightESq = cloneVector(heightE); heightESq = squareVector(heightESq); // ampErr squared auto ampErrSq = cloneVector(ampErr); ampErrSq = squareVector(ampErrSq); // totalErr = heightE squared + ampErr squared auto totalErr = cloneVector(heightESq); std::transform(totalErr.begin(), totalErr.end(), ampErrSq.begin(), totalErr.begin(), std::plus<double>()); // heightY squared auto heightYSq = cloneVector(heightY); heightYSq = squareVector(heightYSq); // total Squared auto totalSq = cloneVector(total); totalSq = squareVector(totalSq); // errOverTotalSq = totalErr / total squared auto errOverTotalSq = cloneVector(totalErr); std::transform(errOverTotalSq.begin(), errOverTotalSq.end(), totalSq.begin(), errOverTotalSq.begin(), std::divides<double>()); // heightESqOverYSq = heightESq / heightYSq auto heightESqOverYSq = cloneVector(heightESq); std::transform(heightESqOverYSq.begin(), heightESqOverYSq.end(), heightYSq.begin(), heightESqOverYSq.begin(), std::divides<double>()); // sqrtESqOverYSq = squareRoot( heightESqOverYSq ) auto sqrtESqOverYSq = cloneVector(heightESqOverYSq); std::transform(sqrtESqOverYSq.begin(), sqrtESqOverYSq.end(), sqrtESqOverYSq.begin(), static_cast<double (*)(double)>(sqrt)); // eisfYSumRoot = eisfY * sqrtESqOverYSq auto eisfYSumRoot = cloneVector(eisfY); std::transform(eisfYSumRoot.begin(), eisfYSumRoot.end(), sqrtESqOverYSq.begin(), eisfYSumRoot.begin(), std::multiplies<double>()); // eisfErr = eisfYSumRoot + errOverTotalSq auto eisfErr = cloneVector(eisfYSumRoot); std::transform(eisfErr.begin(), eisfErr.end(), errOverTotalSq.begin(), eisfErr.begin(), std::plus<double>()); // Append the calculated values to the table workspace auto columnName = ampName.substr(0, (ampName.size() - std::string("Amplitude").size())); columnName += "EISF"; auto errorColumnName = ampErrorName.substr( 0, (ampErrorName.size() - std::string("Amplitude_Err").size())); errorColumnName += "EISF_Err"; tableWs->addColumn("double", columnName); tableWs->addColumn("double", errorColumnName); size_t maxEisf = eisfY.size(); if (eisfErr.size() > maxEisf) { maxEisf = eisfErr.size(); } Column_sptr col = tableWs->getColumn(columnName); Column_sptr errCol = tableWs->getColumn(errorColumnName); for (size_t j = 0; j < maxEisf; j++) { col->cell<double>(j) = eisfY.at(j); errCol->cell<double>(j) = eisfErr.at(j); } } }
/** Fits each spectrum in the workspace to f(x) = A * sin( w * x + p) * @param ws :: [input] The workspace to fit * @param freq :: [input] Hint for the frequency (w) * @param groupName :: [input] The name of the output workspace group * @param resTab :: [output] Table workspace storing the asymmetries and phases * @param resGroup :: [output] Workspace group storing the fitting results */ void CalMuonDetectorPhases::fitWorkspace(const API::MatrixWorkspace_sptr &ws, double freq, std::string groupName, API::ITableWorkspace_sptr resTab, API::WorkspaceGroup_sptr &resGroup) { int nhist = static_cast<int>(ws->getNumberHistograms()); // Create the fitting function f(x) = A * sin ( w * x + p ) // The same function and initial parameters are used for each fit std::string funcStr = createFittingFunction(freq, true); // Set up results table resTab->addColumn("int", "Spectrum number"); resTab->addColumn("double", "Asymmetry"); resTab->addColumn("double", "Phase"); const auto &indexInfo = ws->indexInfo(); // Loop through fitting all spectra individually const static std::string success = "success"; for (int wsIndex = 0; wsIndex < nhist; wsIndex++) { reportProgress(wsIndex, nhist); const auto &yValues = ws->y(wsIndex); auto emptySpectrum = std::all_of(yValues.begin(), yValues.end(), [](double value) { return value == 0.; }); if (emptySpectrum) { g_log.warning("Spectrum " + std::to_string(wsIndex) + " is empty"); TableWorkspace_sptr tab = boost::make_shared<TableWorkspace>(); tab->addColumn("str", "Name"); tab->addColumn("double", "Value"); tab->addColumn("double", "Error"); for (int j = 0; j < 4; j++) { API::TableRow row = tab->appendRow(); if (j == PHASE_ROW) { row << "dummy" << 0.0 << 0.0; } else { row << "dummy" << ASYMM_ERROR << 0.0; } } extractDetectorInfo(*tab, *resTab, indexInfo.spectrumNumber(wsIndex)); } else { auto fit = createChildAlgorithm("Fit"); fit->initialize(); fit->setPropertyValue("Function", funcStr); fit->setProperty("InputWorkspace", ws); fit->setProperty("WorkspaceIndex", wsIndex); fit->setProperty("CreateOutput", true); fit->setPropertyValue("Output", groupName); fit->execute(); std::string status = fit->getProperty("OutputStatus"); if (!fit->isExecuted()) { std::ostringstream error; error << "Fit failed for spectrum at workspace index " << wsIndex; error << ": " << status; throw std::runtime_error(error.str()); } else if (status != success) { g_log.warning("Fit failed for spectrum at workspace index " + std::to_string(wsIndex) + ": " + status); } API::MatrixWorkspace_sptr fitOut = fit->getProperty("OutputWorkspace"); resGroup->addWorkspace(fitOut); API::ITableWorkspace_sptr tab = fit->getProperty("OutputParameters"); // Now we have our fitting results stored in tab // but we need to extract the relevant information, i.e. // the detector phases (parameter 'p') and asymmetries ('A') extractDetectorInfo(*tab, *resTab, indexInfo.spectrumNumber(wsIndex)); } } }