void MantidMatrix::setup(Mantid::API::MatrixWorkspace_const_sptr ws, int start, int end) { if (!ws) { QMessageBox::critical(0, "WorkspaceMatrixModel error", "2D workspace expected."); m_rows = 0; m_cols = 0; m_startRow = 0; m_endRow = 0; return; } m_workspace = ws; m_workspaceTotalHist = static_cast<int>(ws->getNumberHistograms()); m_startRow = (start < 0 || start >= m_workspaceTotalHist) ? 0 : start; m_endRow = (end < 0 || end >= m_workspaceTotalHist || end < start) ? m_workspaceTotalHist - 1 : end; m_rows = m_endRow - m_startRow + 1; m_cols = static_cast<int>(ws->blocksize()); if (ws->isHistogramData()) m_histogram = true; connect(this, SIGNAL(needsUpdating()), this, SLOT(repaintAll())); m_bk_color = QColor(128, 255, 255); m_matrix_icon = getQPixmap("mantid_matrix_xpm"); m_column_width = 100; }
/** * Sum counts in detectors for purposes of rough plotting against the units on the x-axis. * Assumes that all spectra share the x vector. * * @param dets :: A list of detector IDs to sum. * @param x :: (output) Time of flight values (or whatever values the x axis has) to plot against. * @param y :: (output) The sums of the counts for each bin. */ void InstrumentActor::sumDetectorsUniform(QList<int>& dets, std::vector<double>&x, std::vector<double>&y) const { size_t wi; bool isDataEmpty = dets.isEmpty(); if ( !isDataEmpty ) { try { wi = getWorkspaceIndex( dets[0] ); } catch (Mantid::Kernel::Exception::NotFoundError &) { isDataEmpty = true; // Detector doesn't have a workspace index relating to it } } if ( isDataEmpty ) { x.clear(); y.clear(); return; } // find the bins inside the integration range size_t imin,imax; getBinMinMaxIndex(wi,imin,imax); Mantid::API::MatrixWorkspace_const_sptr ws = getWorkspace(); const Mantid::MantidVec& X = ws->readX(wi); x.assign(X.begin() + imin, X.begin() + imax); if ( ws->isHistogramData() ) { // calculate the bin centres std::transform(x.begin(),x.end(),X.begin() + imin + 1,x.begin(),std::plus<double>()); std::transform(x.begin(),x.end(),x.begin(),std::bind2nd(std::divides<double>(),2.0)); } y.resize(x.size(),0); // sum the spectra foreach(int id, dets) { try { size_t index = getWorkspaceIndex( id ); const Mantid::MantidVec& Y = ws->readY(index); std::transform(y.begin(),y.end(),Y.begin() + imin,y.begin(),std::plus<double>()); } catch (Mantid::Kernel::Exception::NotFoundError &) { continue; // Detector doesn't have a workspace index relating to it } } }
/** * Find the offsets in the spectrum's x vector of the bounds of integration. * @param wi :: The works[ace index of the spectrum. * @param imin :: Index of the lower bound: x_min == readX(wi)[imin] * @param imax :: Index of the upper bound: x_max == readX(wi)[imax] */ void InstrumentActor::getBinMinMaxIndex( size_t wi, size_t& imin, size_t& imax ) const { Mantid::API::MatrixWorkspace_const_sptr ws = getWorkspace(); const Mantid::MantidVec& x = ws->readX(wi); Mantid::MantidVec::const_iterator x_begin = x.begin(); Mantid::MantidVec::const_iterator x_end = x.end(); if (x_begin == x_end) { throw std::runtime_error("No bins found to plot"); } if (ws->isHistogramData()) { --x_end; } if ( wholeRange() ) { imin = 0; imax = static_cast<size_t>(x_end - x_begin); } else { Mantid::MantidVec::const_iterator x_from = std::lower_bound( x_begin, x_end, minBinValue() ); Mantid::MantidVec::const_iterator x_to = std::upper_bound( x_begin, x_end, maxBinValue() ); imin = static_cast<size_t>(x_from - x_begin); imax = static_cast<size_t>(x_to - x_begin); if (imax <= imin) { if (x_from == x_end) { --x_from; x_to = x_end; } else { x_to = x_from + 1; } imin = static_cast<size_t>(x_from - x_begin); imax = static_cast<size_t>(x_to - x_begin); } } }
/** * @param g :: The Graph widget which will display the curve * @param distr :: True for a distribution * @param style :: The curve type to use */ void MantidMatrixCurve::init(Graph *g, bool distr, GraphOptions::CurveType style) { // Will throw if name not found but return NULL ptr if the type is incorrect MatrixWorkspace_const_sptr workspace = AnalysisDataService::Instance().retrieveWS<MatrixWorkspace>( m_wsName.toStdString()); if (!workspace) // The respective *Data classes will check for index validity { std::stringstream ss; ss << "Workspace named '" << m_wsName.toStdString() << "' found but it is not a MatrixWorkspace. ID='" << AnalysisDataService::Instance().retrieve(m_wsName.toStdString())->id() << "'"; throw std::invalid_argument(ss.str()); } // Set the curve name if it the non-naming constructor was called if (this->title().isEmpty()) { // If there's only one spectrum in the workspace, title is simply workspace // name if (workspace->getNumberHistograms() == 1) this->setTitle(m_wsName); else this->setTitle(createCurveName(workspace)); } Mantid::API::MatrixWorkspace_const_sptr matrixWS = boost::dynamic_pointer_cast<const Mantid::API::MatrixWorkspace>( workspace); // we need to censor the data if there is a log scale because it can't deal // with negative values, only the y-axis has been found to be problem so far const bool log = g->isLog(QwtPlot::yLeft); // Y units are the same for both spectrum and bin plots, e.g. counts m_yUnits.reset(new Mantid::Kernel::Units::Label(matrixWS->YUnit(), matrixWS->YUnitLabel())); if (m_indexType == Spectrum) // Spectrum plot { QwtWorkspaceSpectrumData data(*matrixWS, m_index, log, distr); setData(data); // For spectrum plots, X axis are actual X axis, e.g. TOF m_xUnits = matrixWS->getAxis(0)->unit(); } else // Bin plot { QwtWorkspaceBinData data(*matrixWS, m_index, log); setData(data); // For bin plots, X axis are "spectra axis", e.g. spectra numbers m_xUnits = matrixWS->getAxis(1)->unit(); } if (!m_xUnits) { m_xUnits.reset(new Mantid::Kernel::Units::Empty()); } int lineWidth = 1; MultiLayer *ml = dynamic_cast<MultiLayer *>(g->parent()->parent()->parent()); if (ml && (style == GraphOptions::Unspecified || ml->applicationWindow()->applyCurveStyleToMantid)) { applyStyleChoice(style, ml, lineWidth); } else if (matrixWS->isHistogramData() && !matrixWS->isDistribution()) { setStyle(QwtPlotCurve::Steps); setCurveAttribute( Inverted, true); // this is the Steps style modifier that makes horizontal steps } else { setStyle(QwtPlotCurve::Lines); } g->insertCurve(this, lineWidth); // set the option to draw all error bars from the global settings if (hasErrorBars()) { setErrorBars(true, g->multiLayer()->applicationWindow()->drawAllErrors); } // Initialise error bar colour to match curve colour m_errorSettings->m_color = pen().color(); m_errorSettings->setWidth(pen().widthF()); connect(g, SIGNAL(axisScaleChanged(int, bool)), this, SLOT(axisScaleChanged(int, bool))); observePostDelete(); connect(this, SIGNAL(resetData(const QString &)), this, SLOT(dataReset(const QString &))); observeAfterReplace(); observeADSClear(); }