void ConvertEmptyToTof::setTofInWS(const std::vector<double> &tofAxis, API::MatrixWorkspace_sptr outputWS) { const size_t numberOfSpectra = m_inputWS->getNumberHistograms(); int64_t numberOfSpectraInt64 = static_cast<int64_t>(numberOfSpectra); // cast to make openmp happy g_log.debug() << "Setting the TOF X Axis for numberOfSpectra=" << numberOfSpectra << '\n'; Progress prog(this, 0.0, 0.2, numberOfSpectra); PARALLEL_FOR2(m_inputWS, outputWS) for (int64_t i = 0; i < numberOfSpectraInt64; ++i) { PARALLEL_START_INTERUPT_REGION // Just copy over outputWS->dataY(i) = m_inputWS->readY(i); outputWS->dataE(i) = m_inputWS->readE(i); // copy outputWS->setX(i, tofAxis); prog.report(); PARALLEL_END_INTERUPT_REGION } // end for i PARALLEL_CHECK_INTERUPT_REGION outputWS->getAxis(0)->unit() = UnitFactory::Instance().create("TOF"); }
/** * Converts the input workspaces to spectrum axis to ElasticQ and adds it to the * ADS to be used by PlotPeakBylogValue * @param inputWs - The MatrixWorkspace to be converted * @param wsName - The desired name of the output workspace */ void ConvolutionFitSequential::convertInputToElasticQ( API::MatrixWorkspace_sptr &inputWs, const std::string &wsName) { auto axis = inputWs->getAxis(1); if (axis->isSpectra()) { auto convSpec = createChildAlgorithm("ConvertSpectrumAxis"); // Store in ADS to allow use by PlotPeakByLogValue convSpec->setAlwaysStoreInADS(true); convSpec->setProperty("InputWorkSpace", inputWs); convSpec->setProperty("OutputWorkSpace", wsName); convSpec->setProperty("Target", "ElasticQ"); convSpec->setProperty("EMode", "Indirect"); convSpec->executeAsChildAlg(); } else if (axis->isNumeric()) { // Check that units are Momentum Transfer if (axis->unit()->unitID() != "MomentumTransfer") { throw std::runtime_error("Input must have axis values of Q"); } auto cloneWs = createChildAlgorithm("CloneWorkspace"); // Store in ADS to allow use by PlotPeakByLogValue cloneWs->setAlwaysStoreInADS(true); cloneWs->setProperty("InputWorkspace", inputWs); cloneWs->setProperty("OutputWorkspace", wsName); cloneWs->executeAsChildAlg(); } else { throw std::runtime_error( "Input workspace must have either spectra or numeric axis."); } }
/** * Loads the information contained in non-Spectra (ie, Text or Numeric) axis in the Nexus * file into the workspace. * @param local_workspace :: pointer to workspace object * @param data :: reference to the NeXuS data for the axis */ void LoadNexusProcessed::loadNonSpectraAxis(API::MatrixWorkspace_sptr local_workspace, NXData & data) { Mantid::API::Axis* axis = local_workspace->getAxis(1); if ( axis->isNumeric() ) { NXDouble axisData = data.openNXDouble("axis2"); axisData.load(); for ( int i = 0; i < static_cast<int>(axis->length()); i++ ) { axis->setValue(i, axisData[i]); } } else if ( axis->isText() ) { // We must cast the axis object to TextAxis so we may use ->setLabel Mantid::API::TextAxis* textAxis = dynamic_cast<Mantid::API::TextAxis*>(axis); NXChar axisData = data.openNXChar("axis2"); axisData.load(); std::string axisLabels = axisData(); // Use boost::tokenizer to split up the input boost::char_separator<char> sep("\n"); boost::tokenizer<boost::char_separator<char> > tokenizer(axisLabels, sep); boost::tokenizer<boost::char_separator<char> >::iterator tokIter; int i = 0; for ( tokIter = tokenizer.begin(); tokIter != tokenizer.end(); ++tokIter ) { textAxis->setLabel(i, *tokIter); ++i; } } }
/** Checks and retrieves the monitor spectrum out of the input workspace * @param inputWorkspace The input workspace. * @param wsID The workspace ID. * @returns A workspace containing the monitor spectrum only * @throw std::runtime_error If the properties are invalid */ API::MatrixWorkspace_sptr NormaliseToMonitor::getMonitorWorkspace(API::MatrixWorkspace_sptr inputWorkspace,int &wsID) { // Get the workspace from the ADS. Will throw if it's not there. MatrixWorkspace_sptr monitorWS = getProperty("MonitorWorkspace"); wsID = getProperty("MonitorWorkspaceIndex"); // Check that it's a single spectrum workspace if ( static_cast<int>(monitorWS->getNumberHistograms()) < wsID ) { throw std::runtime_error("The MonitorWorkspace must contain the MonitorWorkspaceIndex"); } // Check that the two workspace come from the same instrument if ( monitorWS->getInstrument()->getName() != inputWorkspace->getInstrument()->getName() ) { throw std::runtime_error("The Input and Monitor workspaces must come from the same instrument"); } // Check that they're in the same units if ( monitorWS->getAxis(0)->unit()->unitID() != inputWorkspace->getAxis(0)->unit()->unitID() ) { throw std::runtime_error("The Input and Monitor workspaces must have the same unit"); } // In this case we need to test whether the bins in the monitor workspace match m_commonBins = (m_commonBins && API::WorkspaceHelpers::matchingBins(inputWorkspace,monitorWS,true) ); // If the workspace passes all these tests, make a local copy because it will get changed return this->extractMonitorSpectrum(monitorWS,wsID); }
void StripVanadiumPeaks2::exec(){ // 1. Process input/output API::MatrixWorkspace_sptr inputWS = getProperty("InputWorkspace"); std::string outputWSName = getPropertyValue("OutputWorkspace"); int singleIndex = getProperty("WorkspaceIndex"); int param_fwhm = getProperty("FWHM"); int param_tolerance = getProperty("Tolerance"); bool singleSpectrum = !isEmpty(singleIndex); // 2. Call StripPeaks std::string peakpositions; std::string unit = inputWS->getAxis(0)->unit()->unitID(); if (unit == "dSpacing") { peakpositions = "0.5044,0.5191,0.5350,0.5526,0.5936,0.6178,0.6453,0.6768,0.7134,0.7566,0.8089,0.8737,0.9571,1.0701,1.2356,1.5133,2.1401"; } else if (unit == "MomentumTransfer") { g_log.error() << "Unit MomentumTransfer (Q-space) is NOT supported by StripVanadiumPeaks now.\n"; throw std::invalid_argument("Q-space is not supported"); // Comment out next line as it won't be reached. //peakpositions = "2.9359, 4.1520, 5.0851, 5.8716, 6.5648, 7.1915, 7.7676, 8.3045, 8.8074, 9.2837, 9.7368, 10.1703, 10.5849, 11.3702, 11.7443, 12.1040, 12.4568"; } else { g_log.error() << "Unit " << unit << " Is NOT supported by StripVanadiumPeaks, which only supports d-spacing" << std::endl; throw std::invalid_argument("Not supported unit"); } // Call StripPeak double pro0 = 0.0; double prof = 1.0; bool sublog = true; IAlgorithm_sptr stripPeaks = createChildAlgorithm("StripPeaks", pro0, prof, sublog); stripPeaks->setProperty("InputWorkspace", inputWS); stripPeaks->setPropertyValue("OutputWorkspace", outputWSName); stripPeaks->setProperty("FWHM", param_fwhm); stripPeaks->setProperty("Tolerance", param_tolerance); stripPeaks->setPropertyValue("PeakPositions", peakpositions); stripPeaks->setProperty<std::string>("BackgroundType", getProperty("BackgroundType")); stripPeaks->setProperty<bool>("HighBackground", getProperty("HighBackground")); if (singleSpectrum){ stripPeaks->setProperty("WorkspaceIndex", singleIndex); } stripPeaks->setProperty<double>("PeakPositionTolerance", getProperty("PeakPositionTolerance")); stripPeaks->executeAsChildAlg(); // 3. Get and set output workspace // API::MatrixWorkspace_sptr outputWS = AnalysisDataService::Instance().retrieveWS<API::MatrixWorkspace_sptr>(outputWSName); // boost::shared_ptr<API::Workspace> outputWS = AnalysisDataService::Instance().retrieve(outputWSName); API::MatrixWorkspace_sptr outputWS = stripPeaks->getProperty("OutputWorkspace"); this->setProperty("OutputWorkspace", outputWS); return; }
/** Initialization method: @param bkgWS -- shared pointer to the workspace which contains background @param sourceWS -- shared pointer to the workspace to remove background from @param emode -- energy conversion mode used during internal units conversion (0 -- elastic, 1-direct, 2 indirect, as defined in Units conversion @param pLog -- pointer to the logger class which would report errors @param nThreads -- number of threads to be used for background removal @param inPlace -- if the background removal occurs from the existing workspace or target workspace has to be cloned. */ void BackgroundHelper::initialize(const API::MatrixWorkspace_const_sptr &bkgWS, const API::MatrixWorkspace_sptr &sourceWS, int emode, Kernel::Logger *pLog, int nThreads, bool inPlace) { m_bgWs = bkgWS; m_wkWS = sourceWS; m_Emode = emode; m_pgLog = pLog; m_inPlace = inPlace; std::string bgUnits = bkgWS->getAxis(0)->unit()->unitID(); if (bgUnits != "TOF") throw std::invalid_argument(" Background Workspace: " + bkgWS->getName() + " should be in the units of TOF"); if (!(bkgWS->getNumberHistograms() == 1 || sourceWS->getNumberHistograms() == bkgWS->getNumberHistograms())) throw std::invalid_argument(" Background Workspace: " + bkgWS->getName() + " should have the same number of spectra as " "source workspace or be a single histogram " "workspace"); auto WSUnit = sourceWS->getAxis(0)->unit(); if (!WSUnit) throw std::invalid_argument(" Source Workspace: " + sourceWS->getName() + " should have units"); Geometry::IComponent_const_sptr source = sourceWS->getInstrument()->getSource(); m_Sample = sourceWS->getInstrument()->getSample(); if ((!source) || (!m_Sample)) throw std::invalid_argument( "Instrument on Source workspace:" + sourceWS->getName() + "is not sufficiently defined: failed to get source and/or sample"); m_L1 = source->getDistance(*m_Sample); // just in case. this->deleteUnitsConverters(); // allocate the array of units converters to avoid units reallocation within a // loop m_WSUnit.assign(nThreads, NULL); for (int i = 0; i < nThreads; i++) { m_WSUnit[i] = WSUnit->clone(); } m_singleValueBackground = false; if (bkgWS->getNumberHistograms() == 0) m_singleValueBackground = true; const MantidVec &dataX = bkgWS->dataX(0); const MantidVec &dataY = bkgWS->dataY(0); // const MantidVec& dataE = bkgWS->dataE(0); m_NBg = dataY[0]; m_dtBg = dataX[1] - dataX[0]; // m_ErrSq = dataE[0]*dataE[0]; // needs further clarification m_Efix = this->getEi(sourceWS); }
/** * Validation of the inputs of the RingProfile algorithm. * * Inside this method, the Workspace is considered a 2D Matrix, where each *spectrum is * the rows of the matrix and have the variation in axis0. The columns of the *matrix * is the position of dataX(0) * * The main validation are: * - the centre of the ring is inside the image it self. * - The minimum ring is smaller than the limits of the image to allow * @param inputWS: pointer to the input workspace */ void RingProfile::checkInputsForNumericWorkspace( const API::MatrixWorkspace_sptr inputWS) { g_log.notice() << "CheckingInputs For Numeric Workspace" << std::endl; // The Axis0 is defined by the values of readX inside the spectra of the // workspace. // The limits of this axis will be get by inspection of the readX vector // taking the first // and the last value. // check that centre is inside the range available for the instrument const MantidVec &refX = inputWS->readX(inputWS->getNumberHistograms() / 2); // get the limits of the axis 0 (X) double min_v_x, max_v_x; min_v_x = std::min(refX[0], refX[refX.size() - 1]); max_v_x = std::max(refX[0], refX[refX.size() - 1]); g_log.notice() << "Limits X = " << min_v_x << " " << max_v_x << std::endl; // check centre is inside the X domain if (centre_x < min_v_x || centre_x > max_v_x) { std::stringstream s; s << "The input value for centre (X=" << centre_x << ") is outside the limits of the instrument [" << min_v_x << ", " << max_v_x << "]"; throw std::invalid_argument(s.str()); } // The Axis1 is defined by the spectra inside the workspace. Its limits and // values are given by the // ws->getAxis(1) // get the limits of the axis1 (Y) API::NumericAxis *oldAxis2 = dynamic_cast<API::NumericAxis *>(inputWS->getAxis(1)); // we cannot have the positions in Y direction without a NumericAxis if (!oldAxis2) throw std::invalid_argument("Vertical axis is not a numeric axis. If it is " "a spectra axis try running " "ConvertSpectrumAxis first."); double min_v_y = std::min(oldAxis2->getMin(), oldAxis2->getMax()); double max_v_y = std::max(oldAxis2->getMin(), oldAxis2->getMax()); g_log.notice() << "Limits Y = " << min_v_y << " " << max_v_y << std::endl; // check centre is inside the Y domain if (centre_y < min_v_y || centre_y > max_v_y) { std::stringstream s; s << "The input value for centre (Y=" << centre_y << ") is outside the limits of the instrument [" << min_v_y << ", " << max_v_y << "]"; throw std::invalid_argument(s.str()); } g_log.notice() << "Centre: " << centre_x << " " << centre_y << std::endl; // check minradius is inside the limits of the region of the instrument if (centre_x - min_radius > max_v_x || centre_x + min_radius < min_v_x || centre_y - min_radius > max_v_y || centre_y + min_radius < min_v_y) throw std::invalid_argument( "The minimun radius is outside the region of the instrument"); }
double RadiusSum::getMinBinSizeForNumericImage(API::MatrixWorkspace_sptr inWS) { // The pixel dimensions: // - width: image width/ number of pixels in one row // - height: image height/ number of pixels in one column // The minimum bin size is the smallest value between this two values. std::vector<double> boundaries = getBoundariesOfNumericImage(inWS); const MantidVec &refX = inWS->readX(inputWS->getNumberHistograms() / 2); int nX = static_cast<int>(refX.size()); int nY = static_cast<int>(inWS->getAxis(1)->length()); // remembering boundaries is defined as { xMin, xMax, yMin, yMax} return std::min(((boundaries[1] - boundaries[0]) / nX), ((boundaries[3] - boundaries[2]) / nY)); }
/// Run ConvertUnits as a sub-algorithm to convert to dSpacing MatrixWorkspace_sptr DiffractionFocussing::convertUnitsToDSpacing(const API::MatrixWorkspace_sptr& workspace) { const std::string CONVERSION_UNIT = "dSpacing"; Unit_const_sptr xUnit = workspace->getAxis(0)->unit(); g_log.information() << "Converting units from "<< xUnit->label() << " to " << CONVERSION_UNIT<<".\n"; API::IAlgorithm_sptr childAlg = createSubAlgorithm("ConvertUnits", 0.34, 0.66); childAlg->setProperty("InputWorkspace", workspace); childAlg->setPropertyValue("Target",CONVERSION_UNIT); childAlg->executeAsSubAlg(); return childAlg->getProperty("OutputWorkspace"); }
/** Assuming that the input workspace is a Numeric Image where the pixel *positions depend on their * relative position inside the workspace, this function extracts the position *of the first and last * pixel of the image. * * It is important that the input workspace must be a numeric image, and not an *instrument related workspace. * The function will raise exception (std::invalid_argument) if an invalid *input is give. * * @see RadiusSum::inputWorkspaceHasInstrumentAssociated for reference. * * @param inWS reference to the workspace * @return a list of values that defines the limits of the image in this order: *Xmin, Xmax, Ymin, Ymax */ std::vector<double> RadiusSum::getBoundariesOfNumericImage(API::MatrixWorkspace_sptr inWS) { // horizontal axis // get the pixel position in the horizontal axis from the middle of the image. const MantidVec &refX = inWS->readX(inWS->getNumberHistograms() / 2); double min_x, max_x; const double &first_x(refX[0]); const double &last_x(refX[refX.size() - 1]); if (first_x < last_x) { min_x = first_x; max_x = last_x; } else { min_x = last_x; max_x = first_x; } // vertical axis API::NumericAxis *verticalAxis = dynamic_cast<API::NumericAxis *>(inWS->getAxis(1)); if (!verticalAxis) throw std::invalid_argument("Vertical axis is not a numeric axis. Can not " "find the limits of the image."); double min_y, max_y; min_y = verticalAxis->getMin(); max_y = verticalAxis->getMax(); // check the assumption made that verticalAxis will provide the correct // answer. if (min_y > max_y) { throw std::logic_error("Failure to get the boundaries of this image. " "Internal logic error. Please, inform MantidHelp"); } std::vector<double> output(4); // output = {min_x, max_x, min_y, max_y}; not // supported in all compilers output[0] = min_x; output[1] = max_x; output[2] = min_y; output[3] = max_y; return output; }
/** * Here is the main logic to perform the transformation, to calculate the bin *position in degree for each spectrum. * * The first part of the method is to check if the pixel position is inside the *ring defined as minRadio and maxRadio. * * To do this, it deducts the pixel position. This deduction follows the *followin assumption: * * - the spectrum_index == row number * - the position in the 'Y' direction is given by getAxis(1)[spectrum_index] * - the position in the 'X' direction is the central point of the bin *(dataX[column] + dataX[column+1])/2 * * Having the position of the pixel, as defined above, if the distance is *outside the ring defined by minRadio, maxRadio, * it defines the bin position as -1. * * If the pixel is inside the ring, it calculates the angle of the pixel and *calls fromAngleToBin to define the bin * position. * @param ws: pointer to the workspace * @param spectrum_index: index of the spectrum * @param bins_pos: bin positions (for each column inside the spectrum, the *correspondent bin_pos) */ void RingProfile::getBinForPixel(const API::MatrixWorkspace_sptr ws, int spectrum_index, std::vector<int> &bins_pos) { if (bins_pos.size() != ws->dataY(spectrum_index).size()) throw std::runtime_error("Invalid bin positions vector"); API::NumericAxis *oldAxis2 = dynamic_cast<API::NumericAxis *>(ws->getAxis(1)); // assumption y position is the ws->getAxis(1)(spectrum_index) if (!oldAxis2) { throw std::logic_error("Failed to cast workspace axis to NumericAxis"); } // calculate ypos, the difference of y - centre and the square of this // difference double ypos = (*oldAxis2)(spectrum_index); double diffy = ypos - centre_y; double diffy_quad = pow(diffy, 2.0); // the reference to X bins (the limits for each pixel in the horizontal // direction) auto xvec = ws->dataX(spectrum_index); // for each pixel inside this row for (size_t i = 0; i < xvec.size() - 1; i++) { double xpos = (xvec[i] + xvec[i + 1]) / 2.0; // the x position is the centre of the bins boundaries double diffx = xpos - centre_x; // calculate the distance => norm of pixel position - centre double distance = sqrt(pow(diffx, 2.0) + diffy_quad); // check if the distance is inside the ring if (distance < min_radius || distance > max_radius || distance == 0) { bins_pos[i] = -1; continue; } double angle = atan2(diffy, diffx); // call fromAngleToBin (radians) bins_pos[i] = fromAngleToBin(angle, false); } }
/** Checks and retrieves the requested spectrum out of the input workspace * @param inputWorkspace The input workspace. * @param spectra_num The spectra number. * @returns A workspace containing the monitor spectrum only. * @returns spectra number (WS ID) which is used to normalize by. * @throw std::runtime_error If the properties are invalid */ API::MatrixWorkspace_sptr NormaliseToMonitor::getInWSMonitorSpectrum( const API::MatrixWorkspace_sptr &inputWorkspace, int &spectra_num) { // this is the index of the spectra within the workspace and we need to // identify it either from DetID or from SpecID // size_t spectra_num(-1); // try monitor spectrum. If it is specified, it overrides everything int monitorSpec = getProperty("MonitorSpectrum"); if (monitorSpec < 0) { // Get hold of the monitor spectrum through detector ID int monitorID = getProperty("MonitorID"); if (monitorID < 0) { throw std::runtime_error( "Both MonitorSpectrum and MonitorID can not be negative"); } // set spectra of detector's ID of one selected monitor ID std::vector<detid_t> detID(1, monitorID); // got the index of correspondent spectra (should be only one). auto indexList = inputWorkspace->getIndicesFromDetectorIDs(detID); if (indexList.empty()) { throw std::runtime_error( "Can not find spectra, corresponding to the requested monitor ID"); } if (indexList.size() > 1) { throw std::runtime_error("More then one spectra corresponds to the " "requested monitor ID, which is unheard of"); } spectra_num = static_cast<int>(indexList[0]); } else { // monitor spectrum is specified. const SpectraAxis *axis = dynamic_cast<const SpectraAxis *>(inputWorkspace->getAxis(1)); if (!axis) { throw std::runtime_error("Cannot retrieve monitor spectrum - spectrum " "numbers not attached to workspace"); } auto specs = axis->getSpectraIndexMap(); if (!specs.count(monitorSpec)) { throw std::runtime_error("Input workspace does not contain spectrum " "number given for MonitorSpectrum"); } spectra_num = static_cast<int>(specs[monitorSpec]); } return this->extractMonitorSpectrum(inputWorkspace, spectra_num); }
void ConvertEmptyToTof::setTofInWS(const std::vector<double> &tofAxis, API::MatrixWorkspace_sptr outputWS) { const size_t numberOfSpectra = m_inputWS->getNumberHistograms(); g_log.debug() << "Setting the TOF X Axis for numberOfSpectra=" << numberOfSpectra << '\n'; auto axisPtr = Kernel::make_cow<HistogramData::HistogramX>(tofAxis); HistogramData::BinEdges edges(tofAxis); Progress prog(this, 0.0, 0.2, numberOfSpectra); for (size_t i = 0; i < numberOfSpectra; ++i) { // Replace bin edges with tof axis outputWS->setBinEdges(i, edges); prog.report(); } // end for i outputWS->getAxis(0)->unit() = UnitFactory::Instance().create("TOF"); }
void LoadDaveGrp::exec() { const std::string filename = this->getProperty("Filename"); int yLength = 0; MantidVec *xAxis = new MantidVec(); MantidVec *yAxis = new MantidVec(); std::vector<MantidVec *> data; std::vector<MantidVec *> errors; this->ifile.open(filename.c_str()); if (this->ifile.is_open()) { // Size of x axis this->getAxisLength(this->xLength); // Size of y axis this->getAxisLength(yLength); // This is also the number of groups (spectra) this->nGroups = yLength; // Read in the x axis values this->getAxisValues(xAxis, static_cast<std::size_t>(this->xLength)); // Read in the y axis values this->getAxisValues(yAxis, static_cast<std::size_t>(yLength)); // Read in the data this->getData(data, errors); } this->ifile.close(); // Scale the x-axis if it is in micro-eV to get it to meV const bool isUeV = this->getProperty("IsMicroEV"); if (isUeV) { MantidVec::iterator iter; for (iter = xAxis->begin(); iter != xAxis->end(); ++iter) { *iter /= 1000.0; } } // Create workspace API::MatrixWorkspace_sptr outputWorkspace = \ boost::dynamic_pointer_cast<API::MatrixWorkspace>\ (API::WorkspaceFactory::Instance().create("Workspace2D", this->nGroups, this->xLength, yLength)); // Force the workspace to be a distribution outputWorkspace->isDistribution(true); // Set the x-axis units outputWorkspace->getAxis(0)->unit() = Kernel::UnitFactory::Instance().create(this->getProperty("XAxisUnits")); API::Axis* const verticalAxis = new API::NumericAxis(yLength); // Set the y-axis units verticalAxis->unit() = Kernel::UnitFactory::Instance().create(this->getProperty("YAxisUnits")); outputWorkspace->replaceAxis(1, verticalAxis); for(int i = 0; i < this->nGroups; i++) { outputWorkspace->dataX(i) = *xAxis; outputWorkspace->dataY(i) = *data[i]; outputWorkspace->dataE(i) = *errors[i]; verticalAxis->setValue(i, yAxis->at(i)); delete data[i]; delete errors[i]; } delete xAxis; delete yAxis; outputWorkspace->mutableRun().addProperty("Filename",filename); this->setProperty("OutputWorkspace", outputWorkspace); }
/** * Executes the algorithm */ void ScaleX::exec() { //Get input workspace and offset const MatrixWorkspace_sptr inputW = getProperty("InputWorkspace"); m_algFactor = getProperty("Factor"); m_parname = getPropertyValue("InstrumentParameter"); m_combine = getProperty("Combine"); if(m_combine && m_parname.empty()) { throw std::invalid_argument("Combine behaviour requested but the InstrumentParameter argument is blank."); } const std::string op = getPropertyValue("Operation"); API::MatrixWorkspace_sptr outputW = createOutputWS(inputW); //Get number of histograms int histnumber = static_cast<int>(inputW->getNumberHistograms()); m_progress = new API::Progress(this, 0.0, 1.0, histnumber+1); m_progress->report("Scaling X"); m_wi_min = 0; m_wi_max = histnumber-1; //check if workspace indexes have been set int tempwi_min = getProperty("IndexMin"); int tempwi_max = getProperty("IndexMax"); if ( tempwi_max != Mantid::EMPTY_INT() ) { if ((m_wi_min <= tempwi_min) && (tempwi_min <= tempwi_max) && (tempwi_max <= m_wi_max)) { m_wi_min = tempwi_min; m_wi_max = tempwi_max; } else { g_log.error("Invalid Workspace Index min/max properties"); throw std::invalid_argument("Inconsistent properties defined"); } } // Setup appropriate binary function const bool multiply = (op=="Multiply"); if(multiply) m_binOp = std::multiplies<double>(); else m_binOp = std::plus<double>(); //Check if its an event workspace EventWorkspace_const_sptr eventWS = boost::dynamic_pointer_cast<const EventWorkspace>(inputW); if (eventWS != NULL) { this->execEvent(); return; } // do the shift in X PARALLEL_FOR2(inputW, outputW) for (int i = 0; i < histnumber; ++i) { PARALLEL_START_INTERUPT_REGION //Copy y and e data auto & outY = outputW->dataY(i); outY = inputW->dataY(i); auto & outE = outputW->dataE(i); outE = inputW->dataE(i); auto & outX = outputW->dataX(i); const auto & inX = inputW->readX(i); //Change bin value by offset if ((i >= m_wi_min) && (i <= m_wi_max)) { double factor = getScaleFactor(inputW, i); // Do the offsetting std::transform(inX.begin(), inX.end(), outX.begin(), std::bind2nd(m_binOp, factor)); // reverse the vector if multiplicative factor was negative if(multiply && factor < 0.0) { std::reverse( outX.begin(), outX.end() ); std::reverse( outY.begin(), outY.end() ); std::reverse( outE.begin(), outE.end() ); } } else { outX = inX; //copy } m_progress->report("Scaling X"); PARALLEL_END_INTERUPT_REGION } PARALLEL_CHECK_INTERUPT_REGION // Copy units if (outputW->getAxis(0)->unit().get()) outputW->getAxis(0)->unit() = inputW->getAxis(0)->unit(); try { if (inputW->getAxis(1)->unit().get()) outputW->getAxis(1)->unit() = inputW->getAxis(1)->unit(); } catch(Exception::IndexError &) { // OK, so this isn't a Workspace2D } // Assign it to the output workspace property setProperty("OutputWorkspace",outputW); }
/** * Read the instrument group * @param mtd_entry :: The node for the current workspace * @param local_workspace :: The workspace to attach the instrument */ void LoadNexusProcessed::readInstrumentGroup(NXEntry & mtd_entry, API::MatrixWorkspace_sptr local_workspace) { //Instrument information NXInstrument inst = mtd_entry.openNXInstrument("instrument"); if ( ! inst.containsGroup("detector") ) { g_log.information() << "Detector block not found. The workspace will not contain any detector information.\n"; return; } //Populate the spectra-detector map NXDetector detgroup = inst.openNXDetector("detector"); //Read necessary arrays from the file // Detector list contains a list of all of the detector numbers. If it not present then we can't update the spectra // map int ndets(-1); boost::shared_array<int> det_list(NULL); try { NXInt detlist_group = detgroup.openNXInt("detector_list"); ndets = detlist_group.dim0(); detlist_group.load(); det_list.swap(detlist_group.sharedBuffer()); } catch(std::runtime_error &) { g_log.information() << "detector_list block not found. The workspace will not contain any detector information." << std::endl; return; } //Detector count contains the number of detectors associated with each spectra NXInt det_count = detgroup.openNXInt("detector_count"); det_count.load(); //Detector index - contains the index of the detector in the workspace NXInt det_index = detgroup.openNXInt("detector_index"); det_index.load(); int nspectra = det_index.dim0(); //Spectra block - Contains spectrum numbers for each workspace index // This might not exist so wrap and check. If it doesn't exist create a default mapping bool have_spectra(true); boost::shared_array<int> spectra(NULL); try { NXInt spectra_block = detgroup.openNXInt("spectra"); spectra_block.load(); spectra.swap(spectra_block.sharedBuffer()); } catch(std::runtime_error &) { have_spectra = false; } //Now build the spectra list int *spectra_list = new int[ndets]; API::Axis *axis1 = local_workspace->getAxis(1); int index=0; for(int i = 1; i <= nspectra; ++i) { int spectrum(-1); if( have_spectra ) spectrum = spectra[i-1]; else spectrum = i+1 ; if ((i >= m_spec_min && i < m_spec_max )||(m_list && find(m_spec_list.begin(), m_spec_list.end(), i) != m_spec_list.end())) { if( m_axis1vals.empty() ) { axis1->spectraNo(index) = spectrum; } else { axis1->setValue(index, m_axis1vals[i-1]); } ++index; } int offset = det_index[i-1]; int detcount = det_count[i-1]; for(int j = 0; j < detcount; j++) { spectra_list[offset + j] = spectrum; } } local_workspace->replaceSpectraMap(new SpectraDetectorMap(spectra_list, det_list.get(), ndets)); delete[] spectra_list; }
/** Executes the algorithm * @throw Exception::FileError If the calibration file cannot be opened and read successfully * @throw Exception::InstrumentDefinitionError If unable to obtain the source-sample distance */ void AlignDetectors::exec() { // Get the input workspace MatrixWorkspace_sptr inputWS = getProperty("InputWorkspace"); // Read in the calibration data const std::string calFileName = getProperty("CalibrationFile"); OffsetsWorkspace_sptr offsetsWS = getProperty("OffsetsWorkspace"); progress(0.0,"Reading calibration file"); if (offsetsWS && !calFileName.empty()) throw std::invalid_argument("You must specify either CalibrationFile or OffsetsWorkspace but not both."); if (!offsetsWS && calFileName.empty()) throw std::invalid_argument("You must specify either CalibrationFile or OffsetsWorkspace."); if (!calFileName.empty()) { // Load the .cal file IAlgorithm_sptr alg = createChildAlgorithm("LoadCalFile"); alg->setPropertyValue("CalFilename", calFileName); alg->setProperty("InputWorkspace", inputWS); alg->setProperty<bool>("MakeGroupingWorkspace", false); alg->setProperty<bool>("MakeOffsetsWorkspace", true); alg->setProperty<bool>("MakeMaskWorkspace", false); alg->setPropertyValue("WorkspaceName", "temp"); alg->executeAsChildAlg(); offsetsWS = alg->getProperty("OutputOffsetsWorkspace"); } const int64_t numberOfSpectra = inputWS->getNumberHistograms(); // generate map of the tof->d conversion factors this->tofToDmap = calcTofToD_ConversionMap(inputWS, offsetsWS); //Check if its an event workspace EventWorkspace_const_sptr eventW = boost::dynamic_pointer_cast<const EventWorkspace>(inputWS); if (eventW != NULL) { this->execEvent(); return; } API::MatrixWorkspace_sptr outputWS = getProperty("OutputWorkspace"); // If input and output workspaces are not the same, create a new workspace for the output if (outputWS != inputWS ) { outputWS = WorkspaceFactory::Instance().create(inputWS); setProperty("OutputWorkspace",outputWS); } // Set the final unit that our output workspace will have outputWS->getAxis(0)->unit() = UnitFactory::Instance().create("dSpacing"); // Initialise the progress reporting object Progress progress(this,0.0,1.0,numberOfSpectra); // Loop over the histograms (detector spectra) PARALLEL_FOR2(inputWS,outputWS) for (int64_t i = 0; i < int64_t(numberOfSpectra); ++i) { PARALLEL_START_INTERUPT_REGION try { // Get the input spectrum number at this workspace index const ISpectrum * inSpec = inputWS->getSpectrum(size_t(i)); const double factor = calcConversionFromMap(this->tofToDmap, inSpec->getDetectorIDs()); // Get references to the x data MantidVec& xOut = outputWS->dataX(i); // Make sure reference to input X vector is obtained after output one because in the case // where the input & output workspaces are the same, it might move if the vectors were shared. const MantidVec& xIn = inSpec->readX(); //std::transform( xIn.begin(), xIn.end(), xOut.begin(), std::bind2nd(std::multiplies<double>(), factor) ); // the above transform creates wrong output in parallel in debug in Visual Studio for(size_t k = 0; k < xOut.size(); ++k) { xOut[k] = xIn[k] * factor; } // Copy the Y&E data outputWS->dataY(i) = inSpec->readY(); outputWS->dataE(i) = inSpec->readE(); } catch (Exception::NotFoundError &) { // Zero the data in this case outputWS->dataX(i).assign(outputWS->readX(i).size(),0.0); outputWS->dataY(i).assign(outputWS->readY(i).size(),0.0); outputWS->dataE(i).assign(outputWS->readE(i).size(),0.0); } progress.report(); PARALLEL_END_INTERUPT_REGION } PARALLEL_CHECK_INTERUPT_REGION }
void setXAxisUnits(API::MatrixWorkspace_sptr outputWS) { outputWS->getAxis(0)->unit() = UnitFactory::Instance().create("dSpacing"); }
/** Convert the workspace units using TOF as an intermediate step in the * conversion * @param fromUnit :: The unit of the input workspace * @param outputWS :: The output workspace */ void ConvertUnitsUsingDetectorTable::convertViaTOF( Kernel::Unit_const_sptr fromUnit, API::MatrixWorkspace_sptr outputWS) { using namespace Geometry; // Let's see if we are using a TableWorkspace to override parameters TableWorkspace_sptr paramWS = getProperty("DetectorParameters"); // See if we have supplied a DetectorParameters Workspace // TODO: Check if paramWS is NULL and if so throw an exception // const std::string l1ColumnLabel("l1"); // Let's check all the columns exist and are readable try { auto spectraColumnTmp = paramWS->getColumn("spectra"); auto l1ColumnTmp = paramWS->getColumn("l1"); auto l2ColumnTmp = paramWS->getColumn("l2"); auto twoThetaColumnTmp = paramWS->getColumn("twotheta"); auto efixedColumnTmp = paramWS->getColumn("efixed"); auto emodeColumnTmp = paramWS->getColumn("emode"); } catch (...) { throw Exception::InstrumentDefinitionError( "DetectorParameter TableWorkspace is not defined correctly."); } // Now let's read them into some vectors. auto l1Column = paramWS->getColVector<double>("l1"); auto l2Column = paramWS->getColVector<double>("l2"); auto twoThetaColumn = paramWS->getColVector<double>("twotheta"); auto efixedColumn = paramWS->getColVector<double>("efixed"); auto emodeColumn = paramWS->getColVector<int>("emode"); auto spectraColumn = paramWS->getColVector<int>("spectra"); EventWorkspace_sptr eventWS = boost::dynamic_pointer_cast<EventWorkspace>(outputWS); assert(static_cast<bool>(eventWS) == m_inputEvents); // Sanity check Progress prog(this, 0.2, 1.0, m_numberOfSpectra); int64_t numberOfSpectra_i = static_cast<int64_t>(m_numberOfSpectra); // cast to make openmp happy // Get the unit object for each workspace Kernel::Unit_const_sptr outputUnit = outputWS->getAxis(0)->unit(); std::vector<double> emptyVec; int failedDetectorCount = 0; // ConstColumnVector<int> spectraNumber = paramWS->getVector("spectra"); // TODO: Check why this parallel stuff breaks // Loop over the histograms (detector spectra) // PARALLEL_FOR1(outputWS) for (int64_t i = 0; i < numberOfSpectra_i; ++i) { // Lets find what row this spectrum ID appears in our detector table. // PARALLEL_START_INTERUPT_REGION std::size_t wsid = i; try { double deg2rad = M_PI / 180.; auto det = outputWS->getDetector(i); int specid = det->getID(); // int spectraNumber = static_cast<int>(spectraColumn->toDouble(i)); // wsid = outputWS->getIndexFromSpectrumNumber(spectraNumber); g_log.debug() << "###### Spectra #" << specid << " ==> Workspace ID:" << wsid << std::endl; // Now we need to find the row that contains this spectrum std::vector<int>::iterator specIter; specIter = std::find(spectraColumn.begin(), spectraColumn.end(), specid); if (specIter != spectraColumn.end()) { size_t detectorRow = std::distance(spectraColumn.begin(), specIter); double l1 = l1Column[detectorRow]; double l2 = l2Column[detectorRow]; double twoTheta = twoThetaColumn[detectorRow] * deg2rad; double efixed = efixedColumn[detectorRow]; int emode = emodeColumn[detectorRow]; g_log.debug() << "specId from detector table = " << spectraColumn[detectorRow] << std::endl; // l1 = l1Column->toDouble(detectorRow); // l2 = l2Column->toDouble(detectorRow); // twoTheta = deg2rad * twoThetaColumn->toDouble(detectorRow); // efixed = efixedColumn->toDouble(detectorRow); // emode = static_cast<int>(emodeColumn->toDouble(detectorRow)); g_log.debug() << "###### Spectra #" << specid << " ==> Det Table Row:" << detectorRow << std::endl; g_log.debug() << "\tL1=" << l1 << ",L2=" << l2 << ",TT=" << twoTheta << ",EF=" << efixed << ",EM=" << emode << std::endl; // Make local copies of the units. This allows running the loop in // parallel Unit *localFromUnit = fromUnit->clone(); Unit *localOutputUnit = outputUnit->clone(); /// @todo Don't yet consider hold-off (delta) const double delta = 0.0; // Convert the input unit to time-of-flight localFromUnit->toTOF(outputWS->dataX(wsid), emptyVec, l1, l2, twoTheta, emode, efixed, delta); // Convert from time-of-flight to the desired unit localOutputUnit->fromTOF(outputWS->dataX(wsid), emptyVec, l1, l2, twoTheta, emode, efixed, delta); // EventWorkspace part, modifying the EventLists. if (m_inputEvents) { eventWS->getEventList(wsid) .convertUnitsViaTof(localFromUnit, localOutputUnit); } // Clear unit memory delete localFromUnit; delete localOutputUnit; } else { // Not found g_log.debug() << "Spectrum " << specid << " not found!" << std::endl; failedDetectorCount++; outputWS->maskWorkspaceIndex(wsid); } } catch (Exception::NotFoundError &) { // Get to here if exception thrown when calculating distance to detector failedDetectorCount++; // Since you usually (always?) get to here when there's no attached // detectors, this call is // the same as just zeroing out the data (calling clearData on the // spectrum) outputWS->maskWorkspaceIndex(i); } prog.report("Convert to " + m_outputUnit->unitID()); // PARALLEL_END_INTERUPT_REGION } // loop over spectra // PARALLEL_CHECK_INTERUPT_REGION if (failedDetectorCount != 0) { g_log.information() << "Something went wrong for " << failedDetectorCount << " spectra. Masking spectrum." << std::endl; } if (m_inputEvents) eventWS->clearMRU(); }
/** Executes the algorithm * */ void SplineBackground::exec() { API::MatrixWorkspace_sptr inWS = getProperty("InputWorkspace"); int spec = getProperty("WorkspaceIndex"); if (spec > static_cast<int>(inWS->getNumberHistograms())) throw std::out_of_range("WorkspaceIndex is out of range."); const MantidVec& X = inWS->readX(spec); const MantidVec& Y = inWS->readY(spec); const MantidVec& E = inWS->readE(spec); const bool isHistogram = inWS->isHistogramData(); const int ncoeffs = getProperty("NCoeff"); const int k = 4; // order of the spline + 1 (cubic) const int nbreak = ncoeffs - (k - 2); if (nbreak <= 0) throw std::out_of_range("Too low NCoeff"); gsl_bspline_workspace *bw; gsl_vector *B; gsl_vector *c, *w, *x, *y; gsl_matrix *Z, *cov; gsl_multifit_linear_workspace *mw; double chisq; int n = static_cast<int>(Y.size()); bool isMasked = inWS->hasMaskedBins(spec); std::vector<int> masked(Y.size()); if (isMasked) { for(API::MatrixWorkspace::MaskList::const_iterator it=inWS->maskedBins(spec).begin();it!=inWS->maskedBins(spec).end();++it) masked[it->first] = 1; n -= static_cast<int>(inWS->maskedBins(spec).size()); } if (n < ncoeffs) { g_log.error("Too many basis functions (NCoeff)"); throw std::out_of_range("Too many basis functions (NCoeff)"); } /* allocate a cubic bspline workspace (k = 4) */ bw = gsl_bspline_alloc(k, nbreak); B = gsl_vector_alloc(ncoeffs); x = gsl_vector_alloc(n); y = gsl_vector_alloc(n); Z = gsl_matrix_alloc(n, ncoeffs); c = gsl_vector_alloc(ncoeffs); w = gsl_vector_alloc(n); cov = gsl_matrix_alloc(ncoeffs, ncoeffs); mw = gsl_multifit_linear_alloc(n, ncoeffs); /* this is the data to be fitted */ int j = 0; for (MantidVec::size_type i = 0; i < Y.size(); ++i) { if (isMasked && masked[i]) continue; gsl_vector_set(x, j, (isHistogram ? (0.5*(X[i]+X[i+1])) : X[i])); // Middle of the bins, if a histogram gsl_vector_set(y, j, Y[i]); gsl_vector_set(w, j, E[i]>0.?1./(E[i]*E[i]):0.); ++j; } if (n != j) { gsl_bspline_free(bw); gsl_vector_free(B); gsl_vector_free(x); gsl_vector_free(y); gsl_matrix_free(Z); gsl_vector_free(c); gsl_vector_free(w); gsl_matrix_free(cov); gsl_multifit_linear_free(mw); throw std::runtime_error("Assertion failed: n != j"); } double xStart = X.front(); double xEnd = X.back(); /* use uniform breakpoints */ gsl_bspline_knots_uniform(xStart, xEnd, bw); /* construct the fit matrix X */ for (int i = 0; i < n; ++i) { double xi=gsl_vector_get(x, i); /* compute B_j(xi) for all j */ gsl_bspline_eval(xi, B, bw); /* fill in row i of X */ for (j = 0; j < ncoeffs; ++j) { double Bj = gsl_vector_get(B, j); gsl_matrix_set(Z, i, j, Bj); } } /* do the fit */ gsl_multifit_wlinear(Z, w, y, c, cov, &chisq, mw); /* output the smoothed curve */ API::MatrixWorkspace_sptr outWS = WorkspaceFactory::Instance().create(inWS,1,X.size(),Y.size()); { outWS->getAxis(1)->setValue(0, inWS->getAxis(1)->spectraNo(spec)); double xi, yi, yerr; for (MantidVec::size_type i=0;i<Y.size();i++) { xi = X[i]; gsl_bspline_eval(xi, B, bw); gsl_multifit_linear_est(B, c, cov, &yi, &yerr); outWS->dataY(0)[i] = yi; outWS->dataE(0)[i] = yerr; } outWS->dataX(0) = X; } gsl_bspline_free(bw); gsl_vector_free(B); gsl_vector_free(x); gsl_vector_free(y); gsl_matrix_free(Z); gsl_vector_free(c); gsl_vector_free(w); gsl_matrix_free(cov); gsl_multifit_linear_free(mw); setProperty("OutputWorkspace",outWS); }
/** Executes the rebin algorithm * * @throw runtime_error Thrown if */ void Rebunch::exec() { // retrieve the properties int n_bunch=getProperty("NBunch"); // Get the input workspace MatrixWorkspace_const_sptr inputW = getProperty("InputWorkspace"); bool dist = inputW->isDistribution(); // workspace independent determination of length int histnumber = static_cast<int>(inputW->size()/inputW->blocksize()); /* const std::vector<double>& Xold = inputW->readX(0); const std::vector<double>& Yold = inputW->readY(0); int size_x=Xold.size(); int size_y=Yold.size(); */ int size_x = static_cast<int>(inputW->readX(0).size()); int size_y = static_cast<int>(inputW->readY(0).size()); //signal is the same length for histogram and point data int ny=(size_y/n_bunch); if(size_y%n_bunch >0)ny+=1; // default is for hist int nx=ny+1; bool point=false; if (size_x==size_y) { point=true; nx=ny; } // make output Workspace the same type is the input, but with new length of signal array API::MatrixWorkspace_sptr outputW = API::WorkspaceFactory::Instance().create(inputW,histnumber,nx,ny); int progress_step = histnumber / 100; if (progress_step == 0) progress_step = 1; PARALLEL_FOR2(inputW,outputW) for (int hist=0; hist < histnumber;hist++) { PARALLEL_START_INTERUPT_REGION // Ensure that axis information are copied to the output workspace if the axis exists try { outputW->getAxis(1)->spectraNo(hist)=inputW->getAxis(1)->spectraNo(hist); } catch( Exception::IndexError& ) { // Not a Workspace2D } // get const references to input Workspace arrays (no copying) const MantidVec& XValues = inputW->readX(hist); const MantidVec& YValues = inputW->readY(hist); const MantidVec& YErrors = inputW->readE(hist); //get references to output workspace data (no copying) MantidVec& XValues_new=outputW->dataX(hist); MantidVec& YValues_new=outputW->dataY(hist); MantidVec& YErrors_new=outputW->dataE(hist); // output data arrays are implicitly filled by function if(point) { rebunch_point(XValues,YValues,YErrors,XValues_new,YValues_new,YErrors_new,n_bunch); } else { rebunch_hist(XValues,YValues,YErrors,XValues_new,YValues_new,YErrors_new,n_bunch, dist); } if (hist % progress_step == 0) { progress(double(hist)/histnumber); interruption_point(); } PARALLEL_END_INTERUPT_REGION } PARALLEL_CHECK_INTERUPT_REGION outputW->isDistribution(dist); // Copy units if (outputW->getAxis(0)->unit().get()) outputW->getAxis(0)->unit() = inputW->getAxis(0)->unit(); try { if (inputW->getAxis(1)->unit().get()) outputW->getAxis(1)->unit() = inputW->getAxis(1)->unit(); } catch(Exception::IndexError&) { // OK, so this isn't a Workspace2D } // Assign it to the output workspace property setProperty("OutputWorkspace",outputW); return; }
/** Differentiate between Instrument related image (where the position of the *pixels depend on the instrument * attached to the workspace) and Numeric image (where the position of the *pixels depend on the relative position * in the workspace). * * An instrument related image has the axis 1 defined as spectra (collection of *spectrum numbers each one associated to * one or more detectors in the instrument). * * @param inWS the input workspace * @return True if it is an instrument related workspace. */ bool RadiusSum::inputWorkspaceHasInstrumentAssociated( API::MatrixWorkspace_sptr inWS) { return inWS->getAxis(1)->isSpectra(); }
/** Executes the algorithm * * @throw Exception::FileError If the grouping file cannot be opened or read successfully * @throw runtime_error If unable to run one of the sub-algorithms successfully */ void DiffractionFocussing::exec() { // retrieve the properties std::string groupingFileName=getProperty("GroupingFileName"); // Get the input workspace MatrixWorkspace_sptr inputW = getProperty("InputWorkspace"); bool dist = inputW->isDistribution(); //do this first to check that a valid file is available before doing any work std::multimap<int64_t,int64_t> detectorGroups;// <group, UDET> if (!readGroupingFile(groupingFileName, detectorGroups)) { throw Exception::FileError("Error reading .cal file",groupingFileName); } //Convert to d-spacing units API::MatrixWorkspace_sptr tmpW = convertUnitsToDSpacing(inputW); //Rebin to a common set of bins RebinWorkspace(tmpW); std::set<int64_t> groupNumbers; for(std::multimap<int64_t,int64_t>::const_iterator d = detectorGroups.begin();d!=detectorGroups.end();d++) { if (groupNumbers.find(d->first) == groupNumbers.end()) { groupNumbers.insert(d->first); } } int iprogress = 0; int iprogress_count = static_cast<int>(groupNumbers.size()); int iprogress_step = iprogress_count / 100; if (iprogress_step == 0) iprogress_step = 1; std::vector<int64_t> resultIndeces; for(std::set<int64_t>::const_iterator g = groupNumbers.begin();g!=groupNumbers.end();g++) { if (iprogress++ % iprogress_step == 0) { progress(0.68 + double(iprogress)/iprogress_count/3); } std::multimap<int64_t,int64_t>::const_iterator from = detectorGroups.lower_bound(*g); std::multimap<int64_t,int64_t>::const_iterator to = detectorGroups.upper_bound(*g); std::vector<detid_t> detectorList; for(std::multimap<int64_t,int64_t>::const_iterator d = from;d!=to;d++) detectorList.push_back(static_cast<detid_t>(d->second)); // Want version 1 of GroupDetectors here API::IAlgorithm_sptr childAlg = createSubAlgorithm("GroupDetectors",-1.0,-1.0,true,1); childAlg->setProperty("Workspace", tmpW); childAlg->setProperty< std::vector<detid_t> >("DetectorList",detectorList); childAlg->executeAsSubAlg(); try { // get the index of the combined spectrum int ri = childAlg->getProperty("ResultIndex"); if (ri >= 0) { resultIndeces.push_back(ri); } } catch(...) { throw std::runtime_error("Unable to get Properties from GroupDetectors sub-algorithm"); } } // Discard left-over spectra, but print warning message giving number discarded int discarded = 0; const int64_t oldHistNumber = tmpW->getNumberHistograms(); API::Axis *spectraAxis = tmpW->getAxis(1); for(int64_t i=0; i < oldHistNumber; i++) if ( spectraAxis->spectraNo(i) >= 0 && find(resultIndeces.begin(),resultIndeces.end(),i) == resultIndeces.end()) { ++discarded; } g_log.warning() << "Discarded " << discarded << " spectra that were not assigned to any group" << std::endl; // Running GroupDetectors leads to a load of redundant spectra // Create a new workspace that's the right size for the meaningful spectra and copy them in int64_t newSize = tmpW->blocksize(); API::MatrixWorkspace_sptr outputW = API::WorkspaceFactory::Instance().create(tmpW,resultIndeces.size(),newSize+1,newSize); // Copy units outputW->getAxis(0)->unit() = tmpW->getAxis(0)->unit(); outputW->getAxis(1)->unit() = tmpW->getAxis(1)->unit(); API::Axis *spectraAxisNew = outputW->getAxis(1); for(int64_t hist=0; hist < static_cast<int64_t>(resultIndeces.size()); hist++) { int64_t i = resultIndeces[hist]; double spNo = static_cast<double>(spectraAxis->spectraNo(i)); MantidVec &tmpE = tmpW->dataE(i); MantidVec &outE = outputW->dataE(hist); MantidVec &tmpY = tmpW->dataY(i); MantidVec &outY = outputW->dataY(hist); MantidVec &tmpX = tmpW->dataX(i); MantidVec &outX = outputW->dataX(hist); outE.assign(tmpE.begin(),tmpE.end()); outY.assign(tmpY.begin(),tmpY.end()); outX.assign(tmpX.begin(),tmpX.end()); spectraAxisNew->setValue(hist,spNo); spectraAxis->setValue(i,-1); } progress(1.); outputW->isDistribution(dist); // Assign it to the output workspace property setProperty("OutputWorkspace",outputW); return; }
/** Executes the regroup algorithm * * @throw runtime_error Thrown if */ void Regroup::exec() { // retrieve the properties std::vector<double> rb_params=getProperty("Params"); // Get the input workspace MatrixWorkspace_const_sptr inputW = getProperty("InputWorkspace"); // can work only if all histograms have the same boundaries if (!API::WorkspaceHelpers::commonBoundaries(inputW)) { g_log.error("Histograms with different boundaries"); throw std::runtime_error("Histograms with different boundaries"); } bool dist = inputW->isDistribution(); int histnumber = static_cast<int>(inputW->getNumberHistograms()); MantidVecPtr XValues_new; const MantidVec & XValues_old = inputW->readX(0); std::vector<int> xoldIndex;// indeces of new x in XValues_old // create new output X axis int ntcnew = newAxis(rb_params,XValues_old,XValues_new.access(),xoldIndex); // make output Workspace the same type is the input, but with new length of signal array API::MatrixWorkspace_sptr outputW = API::WorkspaceFactory::Instance().create(inputW,histnumber,ntcnew,ntcnew-1); int progress_step = histnumber / 100; if (progress_step == 0) progress_step = 1; for (int hist=0; hist < histnumber;hist++) { // get const references to input Workspace arrays (no copying) const MantidVec& XValues = inputW->readX(hist); const MantidVec& YValues = inputW->readY(hist); const MantidVec& YErrors = inputW->readE(hist); //get references to output workspace data (no copying) MantidVec& YValues_new=outputW->dataY(hist); MantidVec& YErrors_new=outputW->dataE(hist); // output data arrays are implicitly filled by function rebin(XValues,YValues,YErrors,xoldIndex,YValues_new,YErrors_new, dist); outputW->setX(hist,XValues_new); if (hist % progress_step == 0) { progress(double(hist)/histnumber); interruption_point(); } } outputW->isDistribution(dist); // Copy units if (outputW->getAxis(0)->unit().get()) outputW->getAxis(0)->unit() = inputW->getAxis(0)->unit(); try { if (inputW->getAxis(1)->unit().get()) outputW->getAxis(1)->unit() = inputW->getAxis(1)->unit(); } catch(Exception::IndexError) { // OK, so this isn't a Workspace2D } // Assign it to the output workspace property setProperty("OutputWorkspace",outputW); return; }
/** * Executes the algorithm */ void ScaleX::exec() { //Get input workspace and offset const MatrixWorkspace_sptr inputW = getProperty("InputWorkspace"); factor = getProperty("Factor"); API::MatrixWorkspace_sptr outputW = createOutputWS(inputW); //Get number of histograms int histnumber = static_cast<int>(inputW->getNumberHistograms()); m_progress = new API::Progress(this, 0.0, 1.0, histnumber+1); m_progress->report("Scaling X"); wi_min = 0; wi_max = histnumber-1; //check if workspace indexes have been set int tempwi_min = getProperty("IndexMin"); int tempwi_max = getProperty("IndexMax"); if ( tempwi_max != Mantid::EMPTY_INT() ) { if ((wi_min <= tempwi_min) && (tempwi_min <= tempwi_max) && (tempwi_max <= wi_max)) { wi_min = tempwi_min; wi_max = tempwi_max; } else { g_log.error("Invalid Workspace Index min/max properties"); throw std::invalid_argument("Inconsistent properties defined"); } } //Check if its an event workspace EventWorkspace_const_sptr eventWS = boost::dynamic_pointer_cast<const EventWorkspace>(inputW); if (eventWS != NULL) { this->execEvent(); return; } // do the shift in X PARALLEL_FOR2(inputW, outputW) for (int i=0; i < histnumber; ++i) { PARALLEL_START_INTERUPT_REGION //Do the offsetting for (int j=0; j < static_cast<int>(inputW->readX(i).size()); ++j) { //Change bin value by offset if ((i >= wi_min) && (i <= wi_max)) outputW->dataX(i)[j] = inputW->readX(i)[j] * factor; else outputW->dataX(i)[j] = inputW->readX(i)[j]; } //Copy y and e data outputW->dataY(i) = inputW->dataY(i); outputW->dataE(i) = inputW->dataE(i); if( (i >= wi_min) && (i <= wi_max) && factor<0 ) { std::reverse( outputW->dataX(i).begin(), outputW->dataX(i).end() ); std::reverse( outputW->dataY(i).begin(), outputW->dataY(i).end() ); std::reverse( outputW->dataE(i).begin(), outputW->dataE(i).end() ); } m_progress->report("Scaling X"); PARALLEL_END_INTERUPT_REGION } PARALLEL_CHECK_INTERUPT_REGION // Copy units if (outputW->getAxis(0)->unit().get()) outputW->getAxis(0)->unit() = inputW->getAxis(0)->unit(); try { if (inputW->getAxis(1)->unit().get()) outputW->getAxis(1)->unit() = inputW->getAxis(1)->unit(); } catch(Exception::IndexError &) { // OK, so this isn't a Workspace2D } // Assign it to the output workspace property setProperty("OutputWorkspace",outputW); }