/** * Determine the minimum and maximum spectra ids. * * @param axis The axis to search through. * @param min The minimum id (output). * @param max The maximum id (output). */ void getMinMax(MatrixWorkspace_const_sptr ws, specid_t& min, specid_t& max) { specid_t temp; size_t length = ws->getNumberHistograms(); // initial values min = max = ws->getSpectrum(0)->getSpectrumNo(); for (size_t i = 0; i < length; i++) { temp = ws->getSpectrum(i)->getSpectrumNo(); // Adjust min/max if (temp < min) min = temp; if (temp > max) max = temp; } }
/** Initialise a workspace from its parent * This sets values such as title, instrument, units, sample, spectramap. * This does NOT copy any data. * * @param parent :: the parent workspace * @param child :: the child workspace * @param differentSize :: A flag to indicate if the two workspace will be different sizes */ void WorkspaceFactoryImpl::initializeFromParent(const MatrixWorkspace_const_sptr parent, const MatrixWorkspace_sptr child, const bool differentSize) const { child->setTitle(parent->getTitle()); child->setComment(parent->getComment()); child->setInstrument(parent->getInstrument()); // This call also copies the SHARED POINTER to the parameter map // This call will (should) perform a COPY of the parameter map. child->instrumentParameters(); child->m_sample = parent->m_sample; child->m_run = parent->m_run; child->setYUnit(parent->m_YUnit); child->setYUnitLabel(parent->m_YUnitLabel); child->isDistribution(parent->isDistribution()); // Only copy the axes over if new sizes are not given if ( !differentSize ) { // Only copy mask map if same size for now. Later will need to check continued validity. child->m_masks = parent->m_masks; } // Same number of histograms = copy over the spectra data if (parent->getNumberHistograms() == child->getNumberHistograms()) { for (size_t wi=0; wi<parent->getNumberHistograms(); wi++) { ISpectrum * childSpec = child->getSpectrum(wi); const ISpectrum * parentSpec = parent->getSpectrum(wi); // Copy spectrum number and detector IDs childSpec->copyInfoFrom(*parentSpec); } } // deal with axis for (size_t i = 0; i < parent->m_axes.size(); ++i) { const size_t newAxisLength = child->getAxis(i)->length(); const size_t oldAxisLength = parent->getAxis(i)->length(); if ( !differentSize || newAxisLength == oldAxisLength ) { // Need to delete the existing axis created in init above delete child->m_axes[i]; // Now set to a copy of the parent workspace's axis child->m_axes[i] = parent->m_axes[i]->clone(child.get()); } else { if (! parent->getAxis(i)->isSpectra()) // WHY??? { delete child->m_axes[i]; // Call the 'different length' clone variant child->m_axes[i] = parent->m_axes[i]->clone(newAxisLength,child.get()); } } } return; }
/** * Execute the algorithm */ void ExtractMasking::exec() { MatrixWorkspace_const_sptr inputWS = getProperty("InputWorkspace"); const int nHist = static_cast<int>(inputWS->getNumberHistograms()); const int xLength(1), yLength(1); // Create a new workspace for the results, copy from the input to ensure that we copy over the instrument and current masking MatrixWorkspace_sptr outputWS = WorkspaceFactory::Instance().create(inputWS, nHist, xLength, yLength); Progress prog(this,0.0,1.0,nHist); MantidVecPtr xValues; xValues.access() = MantidVec(1, 0.0); PARALLEL_FOR2(inputWS, outputWS) for( int i = 0; i < nHist; ++i ) { PARALLEL_START_INTERUPT_REGION // Spectrum in the output workspace ISpectrum * outSpec = outputWS->getSpectrum(i); // Spectrum in the input workspace const ISpectrum * inSpec = inputWS->getSpectrum(i); // Copy X, spectrum number and detector IDs outSpec->setX(xValues); outSpec->copyInfoFrom(*inSpec); IDetector_const_sptr inputDet; bool inputIsMasked(false); try { inputDet = inputWS->getDetector(i); if( inputDet->isMasked() ) { inputIsMasked = true; } } catch(Kernel::Exception::NotFoundError &) { inputIsMasked = false; } if( inputIsMasked ) { outSpec->dataY()[0] = 0.0; outSpec->dataE()[0] = 0.0; } else { outSpec->dataY()[0] = 1.0; outSpec->dataE()[0] = 1.0; } prog.report(); PARALLEL_END_INTERUPT_REGION } PARALLEL_CHECK_INTERUPT_REGION setProperty("OutputWorkspace", outputWS); }
/** * Determine the minimum spectrum id for summing. This requires that * SumSpectra::indices has already been set. * @param localworkspace The workspace to use. * @return The minimum spectrum id for all the spectra being summed. */ specid_t SumSpectra::getOutputSpecId(MatrixWorkspace_const_sptr localworkspace) { // initial value specid_t specId = localworkspace->getSpectrum(*(this->m_indices.begin()))->getSpectrumNo(); // the total number of spectra int totalSpec = static_cast<int>(localworkspace->getNumberHistograms()); specid_t temp; for (auto index : this->m_indices) { if (index < totalSpec) { temp = localworkspace->getSpectrum(index)->getSpectrumNo(); if (temp < specId) specId = temp; } } return specId; }
void ConvertToMatrixWorkspace::exec() { MatrixWorkspace_const_sptr inputWorkspace = getProperty("InputWorkspace"); // Let's see if we have to do anything first. Basically we want to avoid the data copy if we can DataObjects::EventWorkspace_const_sptr eventW = boost::dynamic_pointer_cast<const DataObjects::EventWorkspace>(inputWorkspace); MatrixWorkspace_sptr outputWorkspace; if( eventW ) { g_log.information() << "Converting EventWorkspace to Workspace2D.\n"; const size_t numHists = inputWorkspace->getNumberHistograms(); Progress prog(this,0.0,1.0,numHists*2); // Sort the input workspace in-place by TOF. This can be faster if there are few event lists. eventW->sortAll(TOF_SORT, &prog); // Create the output workspace. This will copy many aspects fron the input one. outputWorkspace = WorkspaceFactory::Instance().create(inputWorkspace); // ...but not the data, so do that here. PARALLEL_FOR2(inputWorkspace,outputWorkspace) for (int64_t i = 0; i < (int64_t)numHists; ++i) { PARALLEL_START_INTERUPT_REGION const ISpectrum * inSpec = inputWorkspace->getSpectrum(i); ISpectrum * outSpec = outputWorkspace->getSpectrum(i); outSpec->copyInfoFrom(*inSpec); outSpec->setX(inSpec->ptrX()); outSpec->dataY() = inSpec->dataY(); outSpec->dataE() = inSpec->dataE(); prog.report("Binning"); PARALLEL_END_INTERUPT_REGION } PARALLEL_CHECK_INTERUPT_REGION outputWorkspace->generateSpectraMap(); } else {
/** Executes the algorithm * * @throw runtime_error Thrown if algorithm cannot execute */ void MaxMin::exec() { // Try and retrieve the optional properties m_MinRange = getProperty("RangeLower"); m_MaxRange = getProperty("RangeUpper"); m_MinSpec = getProperty("StartWorkspaceIndex"); m_MaxSpec = getProperty("EndWorkspaceIndex"); showMin = getProperty("ShowMin"); // Get the input workspace MatrixWorkspace_const_sptr localworkspace = getProperty("InputWorkspace"); const int numberOfSpectra = static_cast<int>(localworkspace->getNumberHistograms()); // Check 'StartSpectrum' is in range 0-numberOfSpectra if ( m_MinSpec > numberOfSpectra ) { g_log.warning("StartSpectrum out of range! Set to 0."); m_MinSpec = 0; } if ( isEmpty(m_MaxSpec) ) m_MaxSpec = numberOfSpectra-1; if ( m_MaxSpec > numberOfSpectra-1 || m_MaxSpec < m_MinSpec ) { g_log.warning("EndSpectrum out of range! Set to max detector number"); m_MaxSpec = numberOfSpectra; } if ( m_MinRange > m_MaxRange ) { g_log.warning("Range_upper is less than Range_lower. Will integrate up to frame maximum."); m_MaxRange = 0.0; } // Create the 1D workspace for the output MatrixWorkspace_sptr outputWorkspace = API::WorkspaceFactory::Instance().create(localworkspace,m_MaxSpec-m_MinSpec+1,2,1); Progress progress(this,0,1,(m_MaxSpec-m_MinSpec+1)); PARALLEL_FOR2(localworkspace,outputWorkspace) // Loop over spectra for (int i = m_MinSpec; i <= m_MaxSpec; ++i) { PARALLEL_START_INTERUPT_REGION int newindex=i-m_MinSpec; // Copy over spectrum and detector number info outputWorkspace->getSpectrum(newindex)->copyInfoFrom(*localworkspace->getSpectrum(i)); // Retrieve the spectrum into a vector const MantidVec& X = localworkspace->readX(i); const MantidVec& Y = localworkspace->readY(i); // Find the range [min,max] MantidVec::const_iterator lowit, highit; if (m_MinRange == EMPTY_DBL()) lowit=X.begin(); else lowit=std::lower_bound(X.begin(),X.end(),m_MinRange); if (m_MaxRange == EMPTY_DBL()) highit=X.end(); else highit=std::find_if(lowit,X.end(),std::bind2nd(std::greater<double>(),m_MaxRange)); // If range specified doesn't overlap with this spectrum then bail out if ( lowit == X.end() || highit == X.begin() ) continue; --highit; // Upper limit is the bin before, i.e. the last value smaller than MaxRange MantidVec::difference_type distmin=std::distance(X.begin(),lowit); MantidVec::difference_type distmax=std::distance(X.begin(),highit); MantidVec::const_iterator maxY; // Find the max/min element if (showMin==true) { maxY=std::min_element(Y.begin()+distmin,Y.begin()+distmax); } else { maxY=std::max_element(Y.begin()+distmin,Y.begin()+distmax); } MantidVec::difference_type d=std::distance(Y.begin(),maxY); // X boundaries for the max/min element outputWorkspace->dataX(newindex)[0]=*(X.begin()+d); outputWorkspace->dataX(newindex)[1]=*(X.begin()+d+1); //This is safe since X is of dimension Y+1 outputWorkspace->dataY(newindex)[0]=*maxY; progress.report(); PARALLEL_END_INTERUPT_REGION } PARALLEL_CHECK_INTERUPT_REGION // Assign it to the output workspace property setProperty("OutputWorkspace",outputWorkspace); return; }
/** * This function deals with the logic necessary for summing a Workspace2D. * @param localworkspace The input workspace for summing. * @param outSpec The spectrum for the summed output. * @param progress The progress indicator. * @param numSpectra The number of spectra contributed to the sum. * @param numMasked The spectra dropped from the summations because they are * masked. * @param numZeros The number of zero bins in histogram workspace or empty * spectra for event workspace. */ void SumSpectra::doWorkspace2D(MatrixWorkspace_const_sptr localworkspace, ISpectrum *outSpec, Progress &progress, size_t &numSpectra, size_t &numMasked, size_t &numZeros) { // Get references to the output workspaces's data vectors MantidVec &YSum = outSpec->dataY(); MantidVec &YError = outSpec->dataE(); MantidVec Weight; std::vector<size_t> nZeros; if (m_calculateWeightedSum) { Weight.assign(YSum.size(), 0); nZeros.assign(YSum.size(), 0); } numSpectra = 0; numMasked = 0; numZeros = 0; // Loop over spectra std::set<int>::iterator it; // for (int i = m_minSpec; i <= m_maxSpec; ++i) for (it = this->m_indices.begin(); it != this->m_indices.end(); ++it) { int i = *it; // Don't go outside the range. if ((i >= this->m_numberOfSpectra) || (i < 0)) { g_log.error() << "Invalid index " << i << " was specified. Sum was aborted.\n"; break; } try { // Get the detector object for this spectrum Geometry::IDetector_const_sptr det = localworkspace->getDetector(i); // Skip monitors, if the property is set to do so if (!m_keepMonitors && det->isMonitor()) continue; // Skip masked detectors if (det->isMasked()) { numMasked++; continue; } } catch (...) { // if the detector not found just carry on } numSpectra++; // Retrieve the spectrum into a vector const MantidVec &YValues = localworkspace->readY(i); const MantidVec &YErrors = localworkspace->readE(i); if (m_calculateWeightedSum) { for (int k = 0; k < this->m_yLength; ++k) { if (YErrors[k] != 0) { double errsq = YErrors[k] * YErrors[k]; YError[k] += errsq; Weight[k] += 1. / errsq; YSum[k] += YValues[k] / errsq; } else { nZeros[k]++; } } } else { for (int k = 0; k < this->m_yLength; ++k) { YSum[k] += YValues[k]; YError[k] += YErrors[k] * YErrors[k]; } } // Map all the detectors onto the spectrum of the output outSpec->addDetectorIDs(localworkspace->getSpectrum(i)->getDetectorIDs()); progress.report(); } if (m_calculateWeightedSum) { numZeros = 0; for (size_t i = 0; i < Weight.size(); i++) { if (nZeros[i] == 0) YSum[i] *= double(numSpectra) / Weight[i]; else numZeros += nZeros[i]; } } }