void EQSANSSensitivityCorrection::exec() { MatrixWorkspace_sptr inputWS = getProperty("InputWorkspace"); MatrixWorkspace_sptr effWS = getProperty("EfficiencyWorkspace"); const double factor = getProperty("Factor"); const double error = getProperty("Error"); Progress progress(this,0.0,1.0,5); // Now create a workspace to put in the wavelength-dependence MatrixWorkspace_sptr lambdaWS = WorkspaceFactory::Instance().create(inputWS); // Number of X bins const int xLength = static_cast<int>(inputWS->readY(0).size()); // Number of detector pixels const int numHists = static_cast<int>(inputWS->getNumberHistograms()); const MantidVec& XIn = inputWS->dataX(0); MantidVec& YOut = lambdaWS->dataY(0); MantidVec& EOut = lambdaWS->dataE(0); progress.report("Computing detector efficiency"); for (int i = 0; i < xLength; i++) { double wl = (XIn[i]+XIn[i+1])/2.0; YOut[i] = 1.0-std::exp(-factor*wl); EOut[i] = std::fabs(factor)*std::exp(-factor*wl)*error; } progress.report("Computing detector efficiency"); for (int i = 0; i < numHists; i++) { MantidVec& YOut_i = lambdaWS->dataY(i); MantidVec& EOut_i = lambdaWS->dataE(i); MantidVec& XOut_i = lambdaWS->dataX(i); YOut_i = YOut; EOut_i = EOut; XOut_i = XIn; } lambdaWS = lambdaWS * effWS; MatrixWorkspace_sptr outputWS = inputWS / lambdaWS; setProperty("OutputWorkspace", outputWS); setProperty("OutputEfficiencyWorkspace", lambdaWS); setProperty("OutputMessage", "Applied wavelength-dependent sensitivity correction"); }
void ImggFormatsConvertViewQtWidget::writeImg( MatrixWorkspace_sptr inWks, const std::string &outputName, const std::string &outFormat) const { if (!inWks) return; auto width = inWks->getNumberHistograms(); if (0 == width) return; auto height = inWks->blocksize(); QImage img(QSize(static_cast<int>(width), static_cast<int>(height)), QImage::Format_Indexed8); int tableSize = 256; QVector<QRgb> grayscale(tableSize); for (int i = 0; i < grayscale.size(); i++) { int level = i; // would be equivalent: qGray(i, i, i); grayscale[i] = qRgb(level, level, level); } img.setColorTable(grayscale); // only 16 to 8 bits color map supported with current libraries const double scaleFactor = std::numeric_limits<unsigned short int>::max() / std::numeric_limits<unsigned char>::max(); for (int yi = 0; yi < static_cast<int>(width); ++yi) { const auto &row = inWks->readY(yi); for (int xi = 0; xi < static_cast<int>(width); ++xi) { int scaled = static_cast<int>(row[xi] / scaleFactor); // Images not from IMAT, just crop. This needs much improvement when // we have proper Load/SaveImage algorithms if (scaled > 255) scaled = 255; if (scaled < 0) scaled = 0; img.setPixel(xi, yi, scaled); } } writeImgFile(img, outputName, outFormat); }
/** * Groups the workspace according to grouping provided. * * @param ws :: Workspace to group * @param g :: The grouping information * @return Sptr to created grouped workspace */ MatrixWorkspace_sptr groupWorkspace(MatrixWorkspace_const_sptr ws, const Grouping& g) { // As I couldn't specify multiple groups for GroupDetectors, I am going down quite a complicated // route - for every group distinct grouped workspace is created using GroupDetectors. These // workspaces are then merged into the output workspace. // Create output workspace MatrixWorkspace_sptr outWs = WorkspaceFactory::Instance().create(ws, g.groups.size(), ws->readX(0).size(), ws->blocksize()); for(size_t gi = 0; gi < g.groups.size(); gi++) { Mantid::API::IAlgorithm_sptr alg = AlgorithmManager::Instance().create("GroupDetectors"); alg->setChild(true); // So Output workspace is not added to the ADS alg->initialize(); alg->setProperty("InputWorkspace", boost::const_pointer_cast<MatrixWorkspace>(ws)); alg->setPropertyValue("SpectraList", g.groups[gi]); alg->setPropertyValue("OutputWorkspace", "grouped"); // Is not actually used, just to make validators happy alg->execute(); MatrixWorkspace_sptr grouped = alg->getProperty("OutputWorkspace"); // Copy the spectrum *(outWs->getSpectrum(gi)) = *(grouped->getSpectrum(0)); // Update spectrum number outWs->getSpectrum(gi)->setSpectrumNo(static_cast<specid_t>(gi)); // Copy to the output workspace outWs->dataY(gi) = grouped->readY(0); outWs->dataX(gi) = grouped->readX(0); outWs->dataE(gi) = grouped->readE(0); } return outWs; }
/** * This function handles the logic for summing RebinnedOutput workspaces. * @param outputWorkspace the workspace to hold the summed input * @param progress the progress indicator * @param numSpectra * @param numMasked * @param numZeros */ void SumSpectra::doRebinnedOutput(MatrixWorkspace_sptr outputWorkspace, Progress &progress, size_t &numSpectra, size_t &numMasked, size_t &numZeros) { // Get a copy of the input workspace MatrixWorkspace_sptr temp = getProperty("InputWorkspace"); // First, we need to clean the input workspace for nan's and inf's in order // to treat the data correctly later. This will create a new private // workspace that will be retrieved as mutable. IAlgorithm_sptr alg = this->createChildAlgorithm("ReplaceSpecialValues"); alg->setProperty<MatrixWorkspace_sptr>("InputWorkspace", temp); std::string outName = "_" + temp->getName() + "_clean"; alg->setProperty("OutputWorkspace", outName); alg->setProperty("NaNValue", 0.0); alg->setProperty("NaNError", 0.0); alg->setProperty("InfinityValue", 0.0); alg->setProperty("InfinityError", 0.0); alg->executeAsChildAlg(); MatrixWorkspace_sptr localworkspace = alg->getProperty("OutputWorkspace"); // Transform to real workspace types RebinnedOutput_sptr inWS = boost::dynamic_pointer_cast<RebinnedOutput>(localworkspace); RebinnedOutput_sptr outWS = boost::dynamic_pointer_cast<RebinnedOutput>(outputWorkspace); // Get references to the output workspaces's data vectors ISpectrum *outSpec = outputWorkspace->getSpectrum(0); MantidVec &YSum = outSpec->dataY(); MantidVec &YError = outSpec->dataE(); MantidVec &FracSum = outWS->dataF(0); 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 = m_indices.begin(); it != m_indices.end(); ++it) { int i = *it; // Don't go outside the range. if ((i >= 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); const MantidVec &FracArea = inWS->readF(i); if (m_calculateWeightedSum) { for (int k = 0; k < this->m_yLength; ++k) { if (YErrors[k] != 0) { double errsq = YErrors[k] * YErrors[k] * FracArea[k] * FracArea[k]; YError[k] += errsq; Weight[k] += 1. / errsq; YSum[k] += YValues[k] * FracArea[k] / errsq; FracSum[k] += FracArea[k]; } else { nZeros[k]++; FracSum[k] += FracArea[k]; } } } else { for (int k = 0; k < this->m_yLength; ++k) { YSum[k] += YValues[k] * FracArea[k]; YError[k] += YErrors[k] * YErrors[k] * FracArea[k] * FracArea[k]; FracSum[k] += FracArea[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]; } } // Create the correct representation outWS->finalize(); }
double DiffractionEventCalibrateDetectors::intensity( double x, double y, double z, double rotx, double roty, double rotz, std::string detname, std::string inname, std::string outname, std::string peakOpt, std::string rb_param, std::string groupWSName) { EventWorkspace_sptr inputW = boost::dynamic_pointer_cast<EventWorkspace>( AnalysisDataService::Instance().retrieve(inname)); bool debug = true; CPUTimer tim; movedetector(x, y, z, rotx, roty, rotz, detname, inputW); if (debug) std::cout << tim << " to movedetector()\n"; IAlgorithm_sptr alg3 = createChildAlgorithm("ConvertUnits"); alg3->setProperty<EventWorkspace_sptr>("InputWorkspace", inputW); alg3->setPropertyValue("OutputWorkspace", outname); alg3->setPropertyValue("Target", "dSpacing"); alg3->executeAsChildAlg(); MatrixWorkspace_sptr outputW = alg3->getProperty("OutputWorkspace"); if (debug) std::cout << tim << " to ConvertUnits\n"; IAlgorithm_sptr alg4 = createChildAlgorithm("DiffractionFocussing"); alg4->setProperty<MatrixWorkspace_sptr>("InputWorkspace", outputW); alg4->setProperty<MatrixWorkspace_sptr>("OutputWorkspace", outputW); alg4->setPropertyValue("GroupingFileName", ""); alg4->setPropertyValue("GroupingWorkspace", groupWSName); alg4->executeAsChildAlg(); outputW = alg4->getProperty("OutputWorkspace"); // Remove file if (debug) std::cout << tim << " to DiffractionFocussing\n"; IAlgorithm_sptr alg5 = createChildAlgorithm("Rebin"); alg5->setProperty<MatrixWorkspace_sptr>("InputWorkspace", outputW); alg5->setProperty<MatrixWorkspace_sptr>("OutputWorkspace", outputW); alg5->setPropertyValue("Params", rb_param); alg5->executeAsChildAlg(); outputW = alg5->getProperty("OutputWorkspace"); if (debug) std::cout << tim << " to Rebin\n"; // Find point of peak centre const MantidVec &yValues = outputW->readY(0); auto it = std::max_element(yValues.begin(), yValues.end()); double peakHeight = *it; if (peakHeight == 0) return -0.000; double peakLoc = outputW->readX(0)[it - yValues.begin()]; IAlgorithm_sptr fit_alg; try { // set the ChildAlgorithm no to log as this will be run once per spectra fit_alg = createChildAlgorithm("Fit", -1, -1, false); } catch (Exception::NotFoundError &) { g_log.error("Can't locate Fit algorithm"); throw; } std::ostringstream fun_str; fun_str << "name=Gaussian,Height=" << peakHeight << ",Sigma=0.01,PeakCentre=" << peakLoc; fit_alg->setProperty("Function", fun_str.str()); fit_alg->setProperty("InputWorkspace", outputW); fit_alg->setProperty("WorkspaceIndex", 0); fit_alg->setProperty("StartX", outputW->readX(0)[0]); fit_alg->setProperty("EndX", outputW->readX(0)[outputW->blocksize()]); fit_alg->setProperty("MaxIterations", 200); fit_alg->setProperty("Output", "fit"); fit_alg->executeAsChildAlg(); if (debug) std::cout << tim << " to Fit\n"; std::vector<double> params; // = fit_alg->getProperty("Parameters"); Mantid::API::IFunction_sptr fun_res = fit_alg->getProperty("Function"); for (size_t i = 0; i < fun_res->nParams(); ++i) { params.push_back(fun_res->getParameter(i)); } peakHeight = params[0]; peakLoc = params[1]; movedetector(-x, -y, -z, -rotx, -roty, -rotz, detname, inputW); if (debug) std::cout << tim << " to movedetector()\n"; // Optimize C/peakheight + |peakLoc-peakOpt| where C is scaled by number of // events EventWorkspace_const_sptr inputE = boost::dynamic_pointer_cast<const EventWorkspace>(inputW); return (static_cast<int>(inputE->getNumberEvents()) / 1.e6) / peakHeight + std::fabs(peakLoc - boost::lexical_cast<double>(peakOpt)); }
void CalculateEfficiency::normalizeDetectors(MatrixWorkspace_sptr rebinnedWS, MatrixWorkspace_sptr outputWS, double sum, double error, int nPixels, double min_eff, double max_eff) { // Number of spectra const size_t numberOfSpectra = rebinnedWS->getNumberHistograms(); // Empty vector to store the pixels that outside the acceptable efficiency range std::vector<size_t> dets_to_mask; for (size_t i = 0; i < numberOfSpectra; i++) { const double currProgress = 0.4+0.2*((double)i/(double)numberOfSpectra); progress(currProgress, "Computing sensitivity"); // Get the detector object for this spectrum IDetector_const_sptr det = rebinnedWS->getDetector(i); // If this detector is masked, skip to the next one if ( det->isMasked() ) continue; // Retrieve the spectrum into a vector const MantidVec& YIn = rebinnedWS->readY(i); const MantidVec& EIn = rebinnedWS->readE(i); MantidVec& YOut = outputWS->dataY(i); MantidVec& EOut = outputWS->dataE(i); // If this detector is a monitor, skip to the next one if ( det->isMonitor() ) { YOut[0] = 1.0; EOut[0] = 0.0; continue; } // Normalize counts to get relative efficiency YOut[0] = nPixels/sum * YIn[0]; const double err_sum = YIn[0]/sum*error; EOut[0] = nPixels/std::abs(sum) * std::sqrt(EIn[0]*EIn[0] + err_sum*err_sum); // Mask this detector if the signal is outside the acceptable band if ( !isEmpty(min_eff) && YOut[0] < min_eff ) dets_to_mask.push_back(i); if ( !isEmpty(max_eff) && YOut[0] > max_eff ) dets_to_mask.push_back(i); } // If we identified pixels to be masked, mask them now if ( !dets_to_mask.empty() ) { // Mask detectors that were found to be outside the acceptable efficiency band try { IAlgorithm_sptr mask = createChildAlgorithm("MaskDetectors", 0.8, 0.9); // First we mask detectors in the output workspace mask->setProperty<MatrixWorkspace_sptr>("Workspace", outputWS); mask->setProperty< std::vector<size_t> >("WorkspaceIndexList", dets_to_mask); mask->execute(); mask = createChildAlgorithm("MaskDetectors", 0.9, 1.0); // Then we mask the same detectors in the input workspace mask->setProperty<MatrixWorkspace_sptr>("Workspace", rebinnedWS); mask->setProperty< std::vector<size_t> >("WorkspaceIndexList", dets_to_mask); mask->execute(); } catch (std::invalid_argument& err) { std::stringstream e; e << "Invalid argument to MaskDetectors Child Algorithm: " << err.what(); g_log.error(e.str()); } catch (std::runtime_error& err) { std::stringstream e; e << "Unable to successfully run MaskDetectors Child Algorithm: " << err.what(); g_log.error(e.str()); } } }
/** Execute the algorithm. */ void MaxEnt::exec() { // MaxEnt parameters // Complex data? bool complex = getProperty("ComplexData"); // Image must be positive? bool positiveImage = getProperty("PositiveImage"); // Autoshift bool autoShift = getProperty("AutoShift"); // Increase the number of points in the image by this factor size_t densityFactor = getProperty("DensityFactor"); // Background (default level, sky background, etc) double background = getProperty("A"); // Chi target double chiTarget = getProperty("ChiTarget"); // Required precision for Chi arget double chiEps = getProperty("ChiEps"); // Maximum degree of non-parallelism between S and C double angle = getProperty("MaxAngle"); // Distance penalty for current image double distEps = getProperty("DistancePenalty"); // Maximum number of iterations size_t niter = getProperty("MaxIterations"); // Maximum number of iterations in alpha chop size_t alphaIter = getProperty("AlphaChopIterations"); // Number of spectra and datapoints // Read input workspace MatrixWorkspace_sptr inWS = getProperty("InputWorkspace"); // Number of spectra size_t nspec = inWS->getNumberHistograms(); // Number of data points size_t npoints = inWS->blocksize() * densityFactor; // Number of X bins size_t npointsX = inWS->isHistogramData() ? npoints + 1 : npoints; // The type of entropy we are going to use (depends on the type of image, // positive only, or positive and/or negative) MaxentData_sptr maxentData; if (positiveImage) { maxentData = boost::make_shared<MaxentData>( boost::make_shared<MaxentEntropyPositiveValues>()); } else { maxentData = boost::make_shared<MaxentData>( boost::make_shared<MaxentEntropyNegativeValues>()); } // Output workspaces MatrixWorkspace_sptr outImageWS; MatrixWorkspace_sptr outDataWS; MatrixWorkspace_sptr outEvolChi; MatrixWorkspace_sptr outEvolTest; nspec = complex ? nspec / 2 : nspec; outImageWS = WorkspaceFactory::Instance().create(inWS, 2 * nspec, npointsX, npoints); outDataWS = WorkspaceFactory::Instance().create(inWS, 2 * nspec, npointsX, npoints); outEvolChi = WorkspaceFactory::Instance().create(inWS, nspec, niter, niter); outEvolTest = WorkspaceFactory::Instance().create(inWS, nspec, niter, niter); npoints *= 2; for (size_t s = 0; s < nspec; s++) { // Start distribution (flat background) std::vector<double> image(npoints, background); if (complex) { auto dataRe = inWS->readY(s); auto dataIm = inWS->readY(s + nspec); auto errorsRe = inWS->readE(s); auto errorsIm = inWS->readE(s + nspec); maxentData->loadComplex(dataRe, dataIm, errorsRe, errorsIm, image, background); } else { auto data = inWS->readY(s); auto error = inWS->readE(s); maxentData->loadReal(data, error, image, background); } // To record the algorithm's progress std::vector<double> evolChi(niter, 0.); std::vector<double> evolTest(niter, 0.); // Progress Progress progress(this, 0, 1, niter); // Run maxent algorithm for (size_t it = 0; it < niter; it++) { // Calculate quadratic model coefficients // (SB eq. 21 and 24) maxentData->calculateQuadraticCoefficients(); double currAngle = maxentData->getAngle(); double currChisq = maxentData->getChisq(); auto coeffs = maxentData->getQuadraticCoefficients(); // Calculate delta to construct new image (SB eq. 25) auto delta = move(coeffs, chiTarget / currChisq, chiEps, alphaIter); // Apply distance penalty (SB eq. 33) image = maxentData->getImage(); delta = applyDistancePenalty(delta, coeffs, image, background, distEps); // Update image according to 'delta' and calculate the new Chi-square maxentData->updateImage(delta); currChisq = maxentData->getChisq(); // Record the evolution of Chi-square and angle(S,C) evolChi[it] = currChisq; evolTest[it] = currAngle; // Stop condition, solution found if ((std::abs(currChisq / chiTarget - 1.) < chiEps) && (currAngle < angle)) { break; } // Check for canceling the algorithm if (!(it % 1000)) { interruption_point(); } progress.report(); } // iterations // Get calculated data auto solData = maxentData->getReconstructedData(); auto solImage = maxentData->getImage(); // Populate the output workspaces populateDataWS(inWS, s, nspec, solData, outDataWS); populateImageWS(inWS, s, nspec, solImage, outImageWS, autoShift); // Populate workspaces recording the evolution of Chi and Test // X values for (size_t it = 0; it < niter; it++) { outEvolChi->dataX(s)[it] = static_cast<double>(it); outEvolTest->dataX(s)[it] = static_cast<double>(it); } // Y values outEvolChi->dataY(s).assign(evolChi.begin(), evolChi.end()); outEvolTest->dataY(s).assign(evolTest.begin(), evolTest.end()); // No errors } // Next spectrum setProperty("EvolChi", outEvolChi); setProperty("EvolAngle", outEvolTest); setProperty("ReconstructedImage", outImageWS); setProperty("ReconstructedData", outDataWS); }
void ImageROIViewQtWidget::showProjectionImage( const Mantid::API::WorkspaceGroup_sptr &wsg, size_t idx) { MatrixWorkspace_sptr ws; try { ws = boost::dynamic_pointer_cast<MatrixWorkspace>(wsg->getItem(idx)); if (!ws) return; } catch (std::exception &e) { QMessageBox::warning( this, "Cannot load image", "There was a problem while trying to find the image data: " + QString::fromStdString(e.what())); } const size_t MAXDIM = 2048 * 16; size_t width; try { width = boost::lexical_cast<size_t>(ws->run().getLogData("Axis1")->value()); // TODO: add a settings option for this (like max mem allocation for // images)? if (width >= MAXDIM) width = MAXDIM; } catch (std::exception &e) { QMessageBox::critical(this, "Cannot load image", "There was a problem while trying to " "find the width of the image: " + QString::fromStdString(e.what())); return; } size_t height; try { height = boost::lexical_cast<size_t>(ws->run().getLogData("Axis2")->value()); if (height >= MAXDIM) height = MAXDIM; } catch (std::exception &e) { QMessageBox::critical(this, "Cannot load image", "There was a problem while trying to " "find the height of the image: " + QString::fromStdString(e.what())); return; } // images are loaded as 1 histogram == 1 pixel (1 bin per histogram): if (height != ws->getNumberHistograms() || width != ws->blocksize()) { QMessageBox::critical( this, "Image dimensions do not match in the input image workspace", "Could not load the expected " "number of rows and columns."); return; } // find min and max to scale pixel values double min = std::numeric_limits<double>::max(), max = std::numeric_limits<double>::min(); for (size_t i = 0; i < ws->getNumberHistograms(); ++i) { for (size_t j = 0; j < ws->blocksize(); ++j) { const double &v = ws->readY(i)[j]; if (v < min) min = v; if (v > max) max = v; } } if (min >= max) { QMessageBox::warning( this, "Empty image!", "The image could be loaded but it contains " "effectively no information, all pixels have the same value."); // black picture QPixmap pix(static_cast<int>(width), static_cast<int>(height)); pix.fill(QColor(0, 0, 0)); m_ui.label_img->setPixmap(pix); m_ui.label_img->show(); m_basePixmap.reset(new QPixmap(pix)); return; } // load / transfer image into a QImage QImage rawImg(QSize(static_cast<int>(width), static_cast<int>(height)), QImage::Format_RGB32); const double max_min = max - min; const double scaleFactor = 255.0 / max_min; for (size_t yi = 0; yi < width; ++yi) { for (size_t xi = 0; xi < width; ++xi) { const double &v = ws->readY(yi)[xi]; // color the range min-max in gray scale. To apply different color // maps you'd need to use rawImg.setColorTable() or similar. const int scaled = static_cast<int>(scaleFactor * (v - min)); QRgb vRgb = qRgb(scaled, scaled, scaled); rawImg.setPixel(static_cast<int>(xi), static_cast<int>(yi), vRgb); } } // paint and show image // direct from image QPixmap pix = QPixmap::fromImage(rawImg); m_ui.label_img->setPixmap(pix); m_ui.label_img->show(); m_basePixmap.reset(new QPixmap(pix)); // Alternative, drawing with a painter: // QPixmap pix(static_cast<int>(width), static_cast<int>(height)); // QPainter painter; // painter.begin(&pix); // painter.drawImage(0, 0, rawImg); // painter.end(); // m_ui.label_img->setPixmap(pix); // m_ui.label_img->show(); // m_basePixmap.reset(new QPixmap(pix)); }
/** Checks input properties and compares them to previous values * @param is :: [output] Number of the first run * @param ie :: [output] Number of the last run */ void PlotAsymmetryByLogValue::checkProperties(size_t &is, size_t &ie) { // Log Value m_logName = getPropertyValue("LogValue"); // Get function to apply to logValue m_logFunc = getPropertyValue("Function"); // Get type of computation m_int = (getPropertyValue("Type") == "Integral"); // Get grouping properties m_forward_list = getProperty("ForwardSpectra"); m_backward_list = getProperty("BackwardSpectra"); // Get green and red periods m_red = getProperty("Red"); m_green = getProperty("Green"); // Get time min and time max m_minTime = getProperty("TimeMin"); m_maxTime = getProperty("TimeMax"); // Get type of dead-time corrections m_dtcType = getPropertyValue("DeadTimeCorrType"); m_dtcFile = getPropertyValue("DeadTimeCorrFile"); // Get runs std::string firstFN = getProperty("FirstRun"); std::string lastFN = getProperty("LastRun"); // Parse run names and get the number of runs parseRunNames(firstFN, lastFN, m_filenameBase, m_filenameExt, m_filenameZeros); is = atoi(firstFN.c_str()); // starting run number ie = atoi(lastFN.c_str()); // last run number if (ie < is) { throw std::runtime_error( "First run number is greater than last run number"); } // Create a string holding all the properties std::ostringstream ss; ss << m_filenameBase << "," << m_filenameExt << "," << m_filenameZeros << ","; ss << m_dtcType << "," << m_dtcFile << ","; ss << getPropertyValue("ForwardSpectra") << "," << getPropertyValue("BackwardSpectra") << ","; ss << m_int << "," << m_minTime << "," << m_maxTime << ","; ss << m_red << "," << m_green << ","; ss << m_logName << ", " << m_logFunc; m_allProperties = ss.str(); // Check if we can re-use results from previous run // We can reuse results if: // 1. There is a ws in the ADS with name m_currResName // 2. It is a MatrixWorkspace // 3. It has a title equatl to m_allProperties // This ws stores previous results as described below if (AnalysisDataService::Instance().doesExist(m_currResName)) { MatrixWorkspace_sptr prevResults = AnalysisDataService::Instance().retrieveWS<MatrixWorkspace>( m_currResName); if (prevResults) { if (m_allProperties == prevResults->getTitle()) { // We can re-use results size_t nPoints = prevResults->blocksize(); size_t nHisto = prevResults->getNumberHistograms(); if (nHisto == 2) { // Only 'red' data for (size_t i = 0; i < nPoints; i++) { // The first spectrum contains: X -> run number, Y -> log value // The second spectrum contains: Y -> redY, E -> redE size_t run = static_cast<size_t>(prevResults->readX(0)[i]); if ((run >= is) && (run <= ie)) { m_logValue[run] = prevResults->readY(0)[i]; m_redY[run] = prevResults->readY(1)[i]; m_redE[run] = prevResults->readE(1)[i]; } } } else { // 'Red' and 'Green' data for (size_t i = 0; i < nPoints; i++) { // The first spectrum contains: X -> run number, Y -> log value // The second spectrum contains: Y -> diffY, E -> diffE // The third spectrum contains: Y -> redY, E -> redE // The fourth spectrum contains: Y -> greenY, E -> greeE // The fifth spectrum contains: Y -> sumY, E -> sumE size_t run = static_cast<size_t>(prevResults->readX(0)[i]); if ((run >= is) && (run <= ie)) { m_logValue[run] = prevResults->readY(0)[i]; m_diffY[run] = prevResults->readY(1)[i]; m_diffE[run] = prevResults->readE(1)[i]; m_redY[run] = prevResults->readY(2)[i]; m_redE[run] = prevResults->readE(2)[i]; m_greenY[run] = prevResults->readY(3)[i]; m_greenE[run] = prevResults->readE(3)[i]; m_sumY[run] = prevResults->readY(4)[i]; m_sumE[run] = prevResults->readE(4)[i]; } } } } } } }
/** Calculate the integral asymmetry for a workspace (red & green). * The calculation is done by MuonAsymmetryCalc and SimpleIntegration algorithms. * @param ws_red :: The red workspace * @param ws_green :: The green workspace * @param Y :: Reference to a variable receiving the value of asymmetry * @param E :: Reference to a variable receiving the value of the error */ void PlotAsymmetryByLogValue::calcIntAsymmetry(API::MatrixWorkspace_sptr ws_red, API::MatrixWorkspace_sptr ws_green,double& Y, double& E) { if ( !m_autogroup ) { groupDetectors(ws_red,m_backward_list); groupDetectors(ws_red,m_forward_list); groupDetectors(ws_green,m_backward_list); groupDetectors(ws_green,m_forward_list); } Property* startXprop = getProperty("TimeMin"); Property* endXprop = getProperty("TimeMax"); bool setX = !startXprop->isDefault() && !endXprop->isDefault(); double startX(0.0),endX(0.0); if (setX) { startX = getProperty("TimeMin"); endX = getProperty("TimeMax"); } if (!m_int) { // "Differential asymmetry" API::MatrixWorkspace_sptr tmpWS = API::WorkspaceFactory::Instance().create( ws_red,1,ws_red->readX(0).size(),ws_red->readY(0).size()); for(size_t i=0; i<tmpWS->dataY(0).size(); i++) { double FNORM = ws_green->readY(0)[i] + ws_red->readY(0)[i]; FNORM = FNORM != 0.0 ? 1.0 / FNORM : 1.0; double BNORM = ws_green->readY(1)[i] + ws_red->readY(1)[i]; BNORM = BNORM != 0.0 ? 1.0 / BNORM : 1.0; double ZF = ( ws_green->readY(0)[i] - ws_red->readY(0)[i] ) * FNORM; double ZB = ( ws_green->readY(1)[i] - ws_red->readY(1)[i] ) * BNORM; tmpWS->dataY(0)[i] = ZB - ZF; tmpWS->dataE(0)[i] = (1.0+ZF*ZF)*FNORM+(1.0+ZB*ZB)*BNORM; } IAlgorithm_sptr integr = createChildAlgorithm("Integration"); integr->setProperty("InputWorkspace",tmpWS); integr->setPropertyValue("OutputWorkspace","tmp"); if (setX) { integr->setProperty("RangeLower",startX); integr->setProperty("RangeUpper",endX); } integr->execute(); MatrixWorkspace_sptr out = integr->getProperty("OutputWorkspace"); Y = out->readY(0)[0] / static_cast<double>(tmpWS->dataY(0).size()); E = out->readE(0)[0] / static_cast<double>(tmpWS->dataY(0).size()); } else { // "Integral asymmetry" IAlgorithm_sptr integr = createChildAlgorithm("Integration"); integr->setProperty("InputWorkspace", ws_red); integr->setPropertyValue("OutputWorkspace","tmp"); if (setX) { integr->setProperty("RangeLower",startX); integr->setProperty("RangeUpper",endX); } integr->execute(); API::MatrixWorkspace_sptr intWS_red = integr->getProperty("OutputWorkspace"); integr = createChildAlgorithm("Integration"); integr->setProperty("InputWorkspace", ws_green); integr->setPropertyValue("OutputWorkspace","tmp"); if (setX) { integr->setProperty("RangeLower",startX); integr->setProperty("RangeUpper",endX); } integr->execute(); API::MatrixWorkspace_sptr intWS_green = integr->getProperty("OutputWorkspace"); double YIF = ( intWS_green->readY(0)[0] - intWS_red->readY(0)[0] ) / ( intWS_green->readY(0)[0] + intWS_red->readY(0)[0] ); double YIB = ( intWS_green->readY(1)[0] - intWS_red->readY(1)[0] ) / ( intWS_green->readY(1)[0] + intWS_red->readY(1)[0] ); Y = YIB - YIF; double VARIF = (1.0 + YIF*YIF) / ( intWS_green->readY(0)[0] + intWS_red->readY(0)[0] ); double VARIB = (1.0 + YIB*YIB) / ( intWS_green->readY(1)[0] + intWS_red->readY(1)[0] ); E = sqrt( VARIF + VARIB ); } }
/** Calculate the integral asymmetry for a workspace. * The calculation is done by MuonAsymmetryCalc and SimpleIntegration algorithms. * @param ws :: The workspace * @param Y :: Reference to a variable receiving the value of asymmetry * @param E :: Reference to a variable receiving the value of the error */ void PlotAsymmetryByLogValue::calcIntAsymmetry(API::MatrixWorkspace_sptr ws, double& Y, double& E) { Property* startXprop = getProperty("TimeMin"); Property* endXprop = getProperty("TimeMax"); bool setX = !startXprop->isDefault() && !endXprop->isDefault(); double startX(0.0),endX(0.0); if (setX) { startX = getProperty("TimeMin"); endX = getProperty("TimeMax"); } if (!m_int) { // "Differential asymmetry" IAlgorithm_sptr asym = createChildAlgorithm("AsymmetryCalc"); asym->initialize(); asym->setProperty("InputWorkspace",ws); asym->setPropertyValue("OutputWorkspace","tmp"); if ( !m_autogroup ) { asym->setProperty("ForwardSpectra",m_forward_list); asym->setProperty("BackwardSpectra",m_backward_list); } asym->execute(); MatrixWorkspace_sptr asymWS = asym->getProperty("OutputWorkspace"); IAlgorithm_sptr integr = createChildAlgorithm("Integration"); integr->setProperty("InputWorkspace",asymWS); integr->setPropertyValue("OutputWorkspace","tmp"); if (setX) { integr->setProperty("RangeLower",startX); integr->setProperty("RangeUpper",endX); } integr->execute(); API::MatrixWorkspace_sptr out = integr->getProperty("OutputWorkspace"); Y = out->readY(0)[0]; E = out->readE(0)[0]; } else { // "Integral asymmetry" IAlgorithm_sptr integr = createChildAlgorithm("Integration"); integr->setProperty("InputWorkspace", ws); integr->setPropertyValue("OutputWorkspace","tmp"); if (setX) { integr->setProperty("RangeLower",startX); integr->setProperty("RangeUpper",endX); } integr->execute(); API::MatrixWorkspace_sptr intWS = integr->getProperty("OutputWorkspace"); IAlgorithm_sptr asym = createChildAlgorithm("AsymmetryCalc"); asym->initialize(); asym->setProperty("InputWorkspace",intWS); asym->setPropertyValue("OutputWorkspace","tmp"); if ( !m_autogroup ) { asym->setProperty("ForwardSpectra",m_forward_list); asym->setProperty("BackwardSpectra",m_backward_list); } asym->execute(); MatrixWorkspace_sptr out = asym->getProperty("OutputWorkspace"); Y = out->readY(0)[0]; E = out->readE(0)[0]; } }
/** Convert a SPICE 2D Det MatrixWorkspace to MDEvents and append to an * MDEventWorkspace * It is optional to use a virtual instrument or copy from input data workspace * @brief ConvertCWSDExpToMomentum::convertSpiceMatrixToMomentumMDEvents * @param dataws :: data matrix workspace * @param usevirtual :: boolean flag to use virtual instrument * @param startdetid :: starting detid for detectors from this workspace mapping * to virtual instrument in MDEventWorkspace * @param runnumber :: run number for all MDEvents created from this matrix * workspace */ void ConvertCWSDExpToMomentum::convertSpiceMatrixToMomentumMDEvents( MatrixWorkspace_sptr dataws, bool usevirtual, const detid_t &startdetid, const int runnumber) { // Create transformation matrix from which the transformation is Kernel::DblMatrix rotationMatrix; setupTransferMatrix(dataws, rotationMatrix); g_log.information() << "Before insert new event, output workspace has " << m_outputWS->getNEvents() << "Events.\n"; // Creates a new instance of the MDEventInserte to output workspace MDEventWorkspace<MDEvent<3>, 3>::sptr mdws_mdevt_3 = boost::dynamic_pointer_cast<MDEventWorkspace<MDEvent<3>, 3>>(m_outputWS); MDEventInserter<MDEventWorkspace<MDEvent<3>, 3>::sptr> inserter(mdws_mdevt_3); // Calcualte k_i: it is assumed that all k_i are same for one Pt. // number, i.e., one 2D XML file Kernel::V3D sourcePos = dataws->getInstrument()->getSource()->getPos(); Kernel::V3D samplePos = dataws->getInstrument()->getSample()->getPos(); if (dataws->readX(0).size() != 2) throw std::runtime_error( "Input matrix workspace has wrong dimension in X-axis."); double momentum = 0.5 * (dataws->readX(0)[0] + dataws->readX(0)[1]); Kernel::V3D ki = (samplePos - sourcePos) * (momentum / sourcePos.norm()); g_log.debug() << "Source at " << sourcePos.toString() << ", Norm = " << sourcePos.norm() << ", momentum = " << momentum << "\n" << "k_i = " << ki.toString() << "\n"; // Go though each spectrum to conver to MDEvent size_t numspec = dataws->getNumberHistograms(); double maxsignal = 0; size_t nummdevents = 0; for (size_t iws = 0; iws < numspec; ++iws) { // Get detector positions and signal double signal = dataws->readY(iws)[0]; // Skip event with 0 signal if (signal < 0.001) continue; double error = dataws->readE(iws)[0]; Kernel::V3D detpos = dataws->getDetector(iws)->getPos(); std::vector<Mantid::coord_t> q_sample(3); // Calculate Q-sample and new detector ID in virtual instrument. Kernel::V3D qlab = convertToQSample(samplePos, ki, detpos, momentum, q_sample, rotationMatrix); detid_t native_detid = dataws->getDetector(iws)->getID(); detid_t detid = native_detid + startdetid; // Insert inserter.insertMDEvent( static_cast<float>(signal), static_cast<float>(error * error), static_cast<uint16_t>(runnumber), detid, q_sample.data()); updateQRange(q_sample); g_log.debug() << "Q-lab = " << qlab.toString() << "\n"; g_log.debug() << "Insert DetID " << detid << ", signal = " << signal << ", with q_sample = " << q_sample[0] << ", " << q_sample[1] << ", " << q_sample[2] << "\n"; // Update some statistical inforamtion if (signal > maxsignal) maxsignal = signal; ++nummdevents; } g_log.information() << "Imported Matrixworkspace: Max. Signal = " << maxsignal << ", Add " << nummdevents << " MDEvents " << "\n"; // Add experiment info including instrument, goniometer and run number ExperimentInfo_sptr expinfo = boost::make_shared<ExperimentInfo>(); if (usevirtual) expinfo->setInstrument(m_virtualInstrument); else { Geometry::Instrument_const_sptr tmp_inst = dataws->getInstrument(); expinfo->setInstrument(tmp_inst); } expinfo->mutableRun().setGoniometer(dataws->run().getGoniometer(), false); expinfo->mutableRun().addProperty("run_number", runnumber); // Add all the other propertys from original data workspace const std::vector<Kernel::Property *> vec_property = dataws->run().getProperties(); for (auto property : vec_property) { expinfo->mutableRun().addProperty(property->clone()); } m_outputWS->addExperimentInfo(expinfo); return; }
//---------------------------------------------------------------------------------------------- /// @copydoc Mantid::API::Algorithm::exec() void ResetNegatives::exec() { MatrixWorkspace_sptr inputWS = this->getProperty("InputWorkspace"); MatrixWorkspace_sptr outputWS = this->getProperty("OutputWorkspace"); // get the minimum for each spectrum IAlgorithm_sptr alg = this->createChildAlgorithm("Min", 0., .1); alg->setProperty<MatrixWorkspace_sptr>("InputWorkspace", inputWS); alg->executeAsChildAlg(); MatrixWorkspace_const_sptr minWS = alg->getProperty("OutputWorkspace"); // determine if there is anything to do int64_t nHist = static_cast<int64_t>(minWS->getNumberHistograms()); bool hasNegative = false; for (int64_t i = 0; i < nHist; i++) { if (minWS->readY(i)[0] < 0) { hasNegative = true; } break; } // get out early if there is nothing to do if (!hasNegative) { g_log.information() << "No values are negative. Copying InputWorkspace to OutputWorkspace\n"; if (inputWS != outputWS) { IAlgorithm_sptr alg = this->createChildAlgorithm("CloneWorkspace", .1, 1.); alg->setProperty<Workspace_sptr>("InputWorkspace", inputWS); alg->executeAsChildAlg(); Workspace_sptr temp = alg->getProperty("OutputWorkspace"); setProperty("OutputWorkspace", boost::dynamic_pointer_cast<MatrixWorkspace>(temp)); } return; } // sort the event list to make it fast and thread safe DataObjects::EventWorkspace_const_sptr eventWS = boost::dynamic_pointer_cast<const DataObjects::EventWorkspace>( inputWS ); if (eventWS) eventWS->sortAll(DataObjects::TOF_SORT, NULL); Progress prog(this, .1, 1., 2*nHist); // generate output workspace - copy X and dY outputWS = API::WorkspaceFactory::Instance().create(inputWS); PARALLEL_FOR2(inputWS,outputWS) for (int64_t i = 0; i < nHist; i++) { PARALLEL_START_INTERUPT_REGION outputWS->dataY(i) = inputWS->readY(i); outputWS->dataE(i) = inputWS->readE(i); outputWS->setX(i, inputWS->refX(i)); // share the pointer more prog.report(); PARALLEL_END_INTERUPT_REGION } PARALLEL_CHECK_INTERUPT_REGION // do the actual work if (this->getProperty("AddMinimum")) { this->pushMinimum(minWS, outputWS, prog); } else { this->changeNegatives(minWS, this->getProperty("ResetValue"), outputWS, prog); } setProperty("OutputWorkspace",outputWS); }
void TOFSANSResolutionByPixel::exec() { MatrixWorkspace_sptr inWS = getProperty("InputWorkspace"); double deltaR = getProperty("DeltaR"); double R1 = getProperty("SourceApertureRadius"); double R2 = getProperty("SampleApertureRadius"); const bool doGravity = getProperty("AccountForGravity"); // Check the input checkInput(inWS); // Setup outputworkspace auto outWS = setupOutputWorkspace(inWS); // Convert to meters deltaR /= 1000.0; R1 /= 1000.0; R2 /= 1000.0; // The moderator workspace needs to match the data workspace // in terms of wavelength binning const MatrixWorkspace_sptr sigmaModeratorVSwavelength = getModeratorWorkspace(inWS); // create interpolation table from sigmaModeratorVSwavelength Kernel::Interpolation lookUpTable; const MantidVec xInterpolate = sigmaModeratorVSwavelength->readX(0); const MantidVec yInterpolate = sigmaModeratorVSwavelength->readY(0); // prefer the input to be a pointworkspace and create interpolation function if (sigmaModeratorVSwavelength->isHistogramData()) { g_log.notice() << "mid-points of SigmaModerator histogram bins will be " "used for interpolation."; for (size_t i = 0; i < xInterpolate.size() - 1; ++i) { const double midpoint = (xInterpolate[i + 1] + xInterpolate[i]) / 2.0; lookUpTable.addPoint(midpoint, yInterpolate[i]); } } else { for (size_t i = 0; i < xInterpolate.size(); ++i) { lookUpTable.addPoint(xInterpolate[i], yInterpolate[i]); } } // Calculate the L1 distance const V3D samplePos = inWS->getInstrument()->getSample()->getPos(); const V3D sourcePos = inWS->getInstrument()->getSource()->getPos(); const V3D SSD = samplePos - sourcePos; const double L1 = SSD.norm(); // Get the collimation length double LCollim = getProperty("CollimationLength"); if (LCollim == 0.0) { auto collimationLengthEstimator = SANSCollimationLengthEstimator(); LCollim = collimationLengthEstimator.provideCollimationLength(inWS); g_log.information() << "No collimation length was specified. A default " "collimation length was estimated to be " << LCollim << std::endl; } else { g_log.information() << "The collimation length is " << LCollim << std::endl; } const int numberOfSpectra = static_cast<int>(inWS->getNumberHistograms()); Progress progress(this, 0.0, 1.0, numberOfSpectra); for (int i = 0; i < numberOfSpectra; i++) { IDetector_const_sptr det; try { det = inWS->getDetector(i); } catch (Exception::NotFoundError &) { g_log.information() << "Spectrum index " << i << " has no detector assigned to it - discarding" << std::endl; } // If no detector found or if it's masked or a monitor, skip onto the next // spectrum if (!det || det->isMonitor() || det->isMasked()) continue; // Get the flight path from the sample to the detector pixel const V3D samplePos = inWS->getInstrument()->getSample()->getPos(); const V3D scatteredFlightPathV3D = det->getPos() - samplePos; const double L2 = scatteredFlightPathV3D.norm(); TOFSANSResolutionByPixelCalculator calculator; const double waveLengthIndependentFactor = calculator.getWavelengthIndependentFactor(R1, R2, deltaR, LCollim, L2); // Multiplicative factor to go from lambda to Q // Don't get fooled by the function name... const double theta = inWS->detectorTwoTheta(det); double sinTheta = sin(theta / 2.0); double factor = 4.0 * M_PI * sinTheta; const MantidVec &xIn = inWS->readX(i); const size_t xLength = xIn.size(); // Gravity correction boost::shared_ptr<GravitySANSHelper> grav; if (doGravity) { grav = boost::make_shared<GravitySANSHelper>(inWS, det, getProperty("ExtraLength")); } // Get handles on the outputWorkspace MantidVec &yOut = outWS->dataY(i); // for each wavelenght bin of each pixel calculate a q-resolution for (size_t j = 0; j < xLength - 1; j++) { // use the midpoint of each bin const double wl = (xIn[j + 1] + xIn[j]) / 2.0; // Calculate q. Alternatively q could be calculated using ConvertUnit // If we include a gravity correction we need to adjust sinTheta // for each wavelength (in Angstrom) if (doGravity) { double sinThetaGrav = grav->calcSinTheta(wl); factor = 4.0 * M_PI * sinThetaGrav; } const double q = factor / wl; // wavelenght spread from bin assumed to be const double sigmaSpreadFromBin = xIn[j + 1] - xIn[j]; // Get the uncertainty in Q auto sigmaQ = calculator.getSigmaQValue(lookUpTable.value(wl), waveLengthIndependentFactor, q, wl, sigmaSpreadFromBin, L1, L2); // Insert the Q value and the Q resolution into the outputworkspace yOut[j] = sigmaQ; } progress.report("Computing Q resolution"); } // Set the y axis label outWS->setYUnitLabel("QResolution"); setProperty("OutputWorkspace", outWS); }
void TOFSANSResolutionByPixel::exec() { MatrixWorkspace_sptr inOutWS = getProperty("Workspace"); double deltaR = getProperty("DeltaR"); double R1 = getProperty("SourceApertureRadius"); double R2 = getProperty("SampleApertureRadius"); // Convert to meters deltaR /= 1000.0; R1 /= 1000.0; R2 /= 1000.0; const MatrixWorkspace_sptr sigmaModeratorVSwavelength = getProperty("SigmaModerator"); // create interpolation table from sigmaModeratorVSwavelength Kernel::Interpolation lookUpTable; const MantidVec xInterpolate = sigmaModeratorVSwavelength->readX(0); const MantidVec yInterpolate = sigmaModeratorVSwavelength->readY(0); // prefer the input to be a pointworkspace and create interpolation function if (sigmaModeratorVSwavelength->isHistogramData()) { g_log.notice() << "mid-points of SigmaModerator histogram bins will be " "used for interpolation."; for (size_t i = 0; i < xInterpolate.size() - 1; ++i) { const double midpoint = xInterpolate[i + 1] - xInterpolate[i]; lookUpTable.addPoint(midpoint, yInterpolate[i]); } } else { for (size_t i = 0; i < xInterpolate.size(); ++i) { lookUpTable.addPoint(xInterpolate[i], yInterpolate[i]); } } const V3D samplePos = inOutWS->getInstrument()->getSample()->getPos(); const V3D sourcePos = inOutWS->getInstrument()->getSource()->getPos(); const V3D SSD = samplePos - sourcePos; const double L1 = SSD.norm(); const int numberOfSpectra = static_cast<int>(inOutWS->getNumberHistograms()); Progress progress(this, 0.0, 1.0, numberOfSpectra); for (int i = 0; i < numberOfSpectra; i++) { IDetector_const_sptr det; try { det = inOutWS->getDetector(i); } catch (Exception::NotFoundError &) { g_log.information() << "Spectrum index " << i << " has no detector assigned to it - discarding" << std::endl; } // If no detector found or if it's masked or a monitor, skip onto the next // spectrum if (!det || det->isMonitor() || det->isMasked()) continue; // Get the flight path from the sample to the detector pixel const V3D scatteredFlightPathV3D = det->getPos() - samplePos; const double L2 = scatteredFlightPathV3D.norm(); const double Lsum = L1 + L2; // calculate part that is wavelenght independent const double dTheta2 = (4.0 * M_PI * M_PI / 12.0) * (3.0 * R1 * R1 / (L1 * L1) + 3.0 * R2 * R2 * Lsum * Lsum / (L1 * L1 * L2 * L2) + (deltaR * deltaR) / (L2 * L2)); // Multiplicative factor to go from lambda to Q // Don't get fooled by the function name... const double theta = inOutWS->detectorTwoTheta(det); const double factor = 4.0 * M_PI * sin(theta / 2.0); const MantidVec &xIn = inOutWS->readX(i); MantidVec &yIn = inOutWS->dataY(i); const size_t xLength = xIn.size(); // for each wavelenght bin of each pixel calculate a q-resolution for (size_t j = 0; j < xLength - 1; j++) { // use the midpoint of each bin const double wl = (xIn[j + 1] + xIn[j]) / 2.0; // Calculate q. Alternatively q could be calculated using ConvertUnit const double q = factor / wl; // wavelenght spread from bin assumed to be const double sigmaSpreadFromBin = xIn[j + 1] - xIn[j]; // wavelenght spread from moderatorm, converted from microseconds to // wavelengths const double sigmaModerator = lookUpTable.value(wl) * 3.9560 / (1000.0 * Lsum); // calculate wavelenght resolution from moderator and histogram time bin const double sigmaLambda = std::sqrt(sigmaSpreadFromBin * sigmaSpreadFromBin / 12.0 + sigmaModerator * sigmaModerator); // calculate sigmaQ for a given lambda and pixel const double sigmaOverLambdaTimesQ = q * sigmaLambda / wl; const double sigmaQ = std::sqrt( dTheta2 / (wl * wl) + sigmaOverLambdaTimesQ * sigmaOverLambdaTimesQ); // update inout workspace with this sigmaQ yIn[j] = sigmaQ; } progress.report("Computing Q resolution"); } }
/** Calls Gaussian1D as a child algorithm to fit the offset peak in a spectrum * * @param wi :: The Workspace Index to fit. * @param inputW :: Input workspace. * @param peakPositions :: Peak positions. * @param fitWindows :: Fit windows. * @param nparams :: Number of parameters. * @param minD :: Min distance. * @param maxD :: Max distance. * @param peakPosToFit :: Actual peak positions to fit (output). * @param peakPosFitted :: Actual peak positions fitted (output). * @param chisq :: chisq. * @param peakHeights :: vector for fitted heights of peaks * @param i_highestpeak:: index of the highest peak among all peaks * @param resolution :: spectrum's resolution delta(d)/d * @param dev_resolution :: standard deviation resolution * @return The number of peaks in range */ int GetDetOffsetsMultiPeaks::fitSpectra( const int64_t wi, MatrixWorkspace_sptr inputW, const std::vector<double> &peakPositions, const std::vector<double> &fitWindows, size_t &nparams, double &minD, double &maxD, std::vector<double> &peakPosToFit, std::vector<double> &peakPosFitted, std::vector<double> &chisq, std::vector<double> &peakHeights, int &i_highestpeak, double &resolution, double &dev_resolution) { // Default overall fit range is the whole spectrum const MantidVec &X = inputW->readX(wi); minD = X.front(); maxD = X.back(); // Trim in the edges based on where the data turns off of zero const MantidVec &Y = inputW->readY(wi); size_t minDindex = 0; for (; minDindex < Y.size(); ++minDindex) { if (Y[minDindex] > 0.) { minD = X[minDindex]; break; } } if (minD >= maxD) { // throw if minD >= maxD std::stringstream ess; ess << "Stuff went wrong with wkspIndex=" << wi << " specIndex=" << inputW->getSpectrum(wi)->getSpectrumNo(); throw std::runtime_error(ess.str()); } size_t maxDindex = Y.size() - 1; for (; maxDindex > minDindex; --maxDindex) { if (Y[maxDindex] > 0.) { maxD = X[maxDindex]; break; } } std::stringstream dbss; dbss << "D-RANGE[" << inputW->getSpectrum(wi)->getSpectrumNo() << "]: " << minD << " -> " << maxD; g_log.debug(dbss.str()); // Setup the fit windows bool useFitWindows = (!fitWindows.empty()); std::vector<double> fitWindowsToUse; for (int i = 0; i < static_cast<int>(peakPositions.size()); ++i) { if ((peakPositions[i] > minD) && (peakPositions[i] < maxD)) { if (m_useFitWindowTable) { fitWindowsToUse.push_back(std::max(m_vecFitWindow[wi][2 * i], minD)); fitWindowsToUse.push_back( std::min(m_vecFitWindow[wi][2 * i + 1], maxD)); } else if (useFitWindows) { fitWindowsToUse.push_back(std::max(fitWindows[2 * i], minD)); fitWindowsToUse.push_back(std::min(fitWindows[2 * i + 1], maxD)); } peakPosToFit.push_back(peakPositions[i]); } } int numPeaksInRange = static_cast<int>(peakPosToFit.size()); if (numPeaksInRange == 0) { std::stringstream outss; outss << "Spectrum " << wi << " has no peak in range (" << minD << ", " << maxD << ")"; g_log.information(outss.str()); return 0; } // Fit peaks API::IAlgorithm_sptr findpeaks = createChildAlgorithm("FindPeaks", -1, -1, false); findpeaks->setProperty("InputWorkspace", inputW); findpeaks->setProperty<int>("FWHM", 7); findpeaks->setProperty<int>("Tolerance", 4); // FindPeaks will do the checking on the validity of WorkspaceIndex findpeaks->setProperty("WorkspaceIndex", static_cast<int>(wi)); // Get the specified peak positions, which is optional findpeaks->setProperty("PeakPositions", peakPosToFit); if (useFitWindows) findpeaks->setProperty("FitWindows", fitWindowsToUse); findpeaks->setProperty<std::string>("PeakFunction", m_peakType); findpeaks->setProperty<std::string>("BackgroundType", m_backType); findpeaks->setProperty<bool>("HighBackground", this->getProperty("HighBackground")); findpeaks->setProperty<int>("MinGuessedPeakWidth", 4); findpeaks->setProperty<int>("MaxGuessedPeakWidth", 4); findpeaks->setProperty<double>("MinimumPeakHeight", m_minPeakHeight); findpeaks->setProperty("StartFromObservedPeakCentre", true); findpeaks->executeAsChildAlg(); // Collect fitting resutl of all peaks ITableWorkspace_sptr peakslist = findpeaks->getProperty("PeaksList"); // use tmpPeakPosToFit to shuffle the vectors std::vector<double> tmpPeakPosToFit; generatePeaksList(peakslist, static_cast<int>(wi), peakPosToFit, tmpPeakPosToFit, peakPosFitted, peakHeights, chisq, (useFitWindows || m_useFitWindowTable), fitWindowsToUse, minD, maxD, resolution, dev_resolution); peakPosToFit = tmpPeakPosToFit; nparams = peakPosFitted.size(); // Find the highest peak i_highestpeak = -1; double maxheight = 0; for (int i = 0; i < static_cast<int>(peakPosFitted.size()); ++i) { double tmpheight = peakHeights[i]; if (tmpheight > maxheight) { maxheight = tmpheight; i_highestpeak = i; } } return numPeaksInRange; }
void FFTDerivative::execRealFFT() { MatrixWorkspace_sptr inWS = getProperty("InputWorkspace"); MatrixWorkspace_sptr outWS; size_t n = inWS->getNumberHistograms(); API::Progress progress(this,0,1,n); size_t ny = inWS->readY(0).size(); size_t nx = inWS->readX(0).size(); // Workspace for holding a copy of a spectrum. Each spectrum is symmetrized to minimize // possible edge effects. MatrixWorkspace_sptr copyWS = boost::dynamic_pointer_cast<Mantid::API::MatrixWorkspace> (Mantid::API::WorkspaceFactory::Instance().create(inWS,1,nx+ny,ny+ny)); bool isHist = (nx != ny); for(size_t spec = 0; spec < n; ++spec) { const Mantid::MantidVec& x0 = inWS->readX(spec); const Mantid::MantidVec& y0 = inWS->readY(spec); Mantid::MantidVec& x1 = copyWS->dataX(0); Mantid::MantidVec& y1 = copyWS->dataY(0); double xx = 2*x0[0]; x1[ny] = x0[0]; y1[ny] = y0[0]; for(size_t i = 1; i < ny; ++i) { size_t j1 = ny - i; size_t j2 = ny + i; x1[j1] = xx - x0[i]; x1[j2] = x0[i]; y1[j1] = y1[j2] = y0[i]; } x1[0] = 2*x1[1] - x1[2]; y1[0] = y0.back(); if (isHist) { x1[y1.size()] = x0[ny]; } // Transform symmetrized spectrum IAlgorithm_sptr fft = createChildAlgorithm("RealFFT"); fft->setProperty("InputWorkspace",copyWS); fft->setProperty("WorkspaceIndex",0); fft->setProperty("Transform","Forward"); fft->execute(); MatrixWorkspace_sptr transWS = fft->getProperty("OutputWorkspace"); Mantid::MantidVec& nu = transWS->dataX(0); Mantid::MantidVec& re = transWS->dataY(0); Mantid::MantidVec& im = transWS->dataY(1); int dn = getProperty("Order"); bool swap_re_im = dn % 2 != 0; int sign_re = 1; int sign_im = -1; switch(dn % 4) { case 1: sign_re = 1; sign_im = -1; break; case 2: sign_re = -1; sign_im = -1; break; case 3: sign_re = -1; sign_im = 1; break; } // Multiply the transform by (2*pi*i*w)**dn for(size_t j=0; j < re.size(); ++j) { double w = 2 * M_PI * nu[j]; double ww = w; for(int k = dn; k > 1; --k) { ww *= w; } double a = sign_re * re[j]*ww; double b = sign_im * im[j]*ww; if (swap_re_im) { re[j] = b; im[j] = a; } else { re[j] = a; im[j] = b; } } // Inverse transform fft = createChildAlgorithm("RealFFT"); fft->setProperty("InputWorkspace",transWS); fft->setProperty("Transform","Backward"); fft->execute(); transWS = fft->getProperty("OutputWorkspace"); size_t m2 = transWS->readY(0).size() / 2; size_t my = m2 + ((transWS->readY(0).size() % 2) ? 1 : 0); size_t mx = my + (transWS->isHistogramData() ? 1 : 0); if (!outWS) { outWS = boost::dynamic_pointer_cast<Mantid::API::MatrixWorkspace> (Mantid::API::WorkspaceFactory::Instance().create(inWS,n,mx,my)); } // Save the upper half of the inverse transform for output Mantid::MantidVec& x = outWS->dataX(spec); Mantid::MantidVec& y = outWS->dataY(spec); double dx = x1[0]; std::copy(transWS->dataX(0).begin() + m2,transWS->dataX(0).end(),x.begin()); std::transform(x.begin(),x.end(),x.begin(),std::bind2nd(std::plus<double>(),dx)); std::copy(transWS->dataY(0).begin() + m2,transWS->dataY(0).end(),y.begin()); // shift the data to make x and x0 match. using linear interpolation. if (x.size() != x0.size() && false)// TODO: doesn't work at the moment. needs to be working { std::cerr << "(my != x0.size()) " << x0[0] << "!=" << x[0] << std::endl; dx = x0[0] - x[0]; assert(dx > 0.0); double f = (x0[0] - x[0]) / (x0[1] - x0[0]); for(size_t i = 0; i < my - 1; ++i) { y[i] += (y[i+1] - y[i]) * f; x[i] = x0[i]; } x.back() += dx; } progress.report(); } setProperty("OutputWorkspace",outWS); }
/** Filter non-background data points out and create a background workspace */ Workspace2D_sptr ProcessBackground::filterForBackground(BackgroundFunction_sptr bkgdfunction) { double posnoisetolerance = getProperty("NoiseTolerance"); double negnoisetolerance = getProperty("NegativeNoiseTolerance"); if (isEmpty(negnoisetolerance)) negnoisetolerance = posnoisetolerance; // Calcualte theoretical values const std::vector<double> x = m_dataWS->readX(m_wsIndex); API::FunctionDomain1DVector domain(x); API::FunctionValues values(domain); bkgdfunction->function(domain, values); g_log.information() << "Function used to select background points : " << bkgdfunction->asString() << "\n"; // Optional output string userbkgdwsname = getPropertyValue("UserBackgroundWorkspace"); if (userbkgdwsname.size() == 0) throw runtime_error("In mode SelectBackgroundPoints, " "UserBackgroundWorkspace must be given!"); size_t sizex = domain.size(); size_t sizey = values.size(); MatrixWorkspace_sptr visualws = boost::dynamic_pointer_cast<MatrixWorkspace>( WorkspaceFactory::Instance().create("Workspace2D", 4, sizex, sizey)); for (size_t i = 0; i < sizex; ++i) { for (size_t j = 0; j < 4; ++j) { visualws->dataX(j)[i] = domain[i]; } } for (size_t i = 0; i < sizey; ++i) { visualws->dataY(0)[i] = values[i]; visualws->dataY(1)[i] = m_dataWS->readY(m_wsIndex)[i] - values[i]; visualws->dataY(2)[i] = posnoisetolerance; visualws->dataY(3)[i] = -negnoisetolerance; } setProperty("UserBackgroundWorkspace", visualws); // Filter for background std::vector<double> vecx, vecy, vece; for (size_t i = 0; i < domain.size(); ++i) { // double y = m_dataWS->readY(m_wsIndex)[i]; // double theoryy = values[i]; y-theoryy double purey = visualws->readY(1)[i]; if (purey < posnoisetolerance && purey > -negnoisetolerance) { // Selected double x = domain[i]; double y = m_dataWS->readY(m_wsIndex)[i]; double e = m_dataWS->readE(m_wsIndex)[i]; vecx.push_back(x); vecy.push_back(y); vece.push_back(e); } } g_log.information() << "Found " << vecx.size() << " background points out of " << m_dataWS->readX(m_wsIndex).size() << " total data points. " << "\n"; // Build new workspace for OutputWorkspace size_t nspec = 3; Workspace2D_sptr outws = boost::dynamic_pointer_cast<DataObjects::Workspace2D>( API::WorkspaceFactory::Instance().create("Workspace2D", nspec, vecx.size(), vecy.size())); for (size_t i = 0; i < vecx.size(); ++i) { for (size_t j = 0; j < nspec; ++j) outws->dataX(j)[i] = vecx[i]; outws->dataY(0)[i] = vecy[i]; outws->dataE(0)[i] = vece[i]; } return outws; }
void FFTDerivative::execComplexFFT() { MatrixWorkspace_sptr inWS = getProperty("InputWorkspace"); MatrixWorkspace_sptr outWS; size_t n = inWS->getNumberHistograms(); API::Progress progress(this,0,1,n); size_t ny = inWS->readY(0).size(); size_t nx = inWS->readX(0).size(); // Workspace for holding a copy of a spectrum. Each spectrum is symmetrized to minimize // possible edge effects. MatrixWorkspace_sptr copyWS = boost::dynamic_pointer_cast<Mantid::API::MatrixWorkspace> (Mantid::API::WorkspaceFactory::Instance().create(inWS,1,nx+ny,ny+ny)); bool isHist = (nx != ny); for(size_t spec = 0; spec < n; ++spec) { const Mantid::MantidVec& x0 = inWS->readX(spec); const Mantid::MantidVec& y0 = inWS->readY(spec); Mantid::MantidVec& x1 = copyWS->dataX(0); Mantid::MantidVec& y1 = copyWS->dataY(0); double xx = 2*x0[0]; x1[ny] = x0[0]; y1[ny] = y0[0]; for(size_t i = 1; i < ny; ++i) { size_t j1 = ny - i; size_t j2 = ny + i; x1[j1] = xx - x0[i]; x1[j2] = x0[i]; y1[j1] = y1[j2] = y0[i]; } x1[0] = 2*x1[1] - x1[2]; y1[0] = y0.back(); if (isHist) { x1[y1.size()] = x0[ny]; } // Transform symmetrized spectrum IAlgorithm_sptr fft = createChildAlgorithm("FFT"); fft->setProperty("InputWorkspace",copyWS); fft->setProperty("Real",0); fft->setProperty("Transform","Forward"); fft->execute(); MatrixWorkspace_sptr transWS = fft->getProperty("OutputWorkspace"); Mantid::MantidVec& nu = transWS->dataX(3); Mantid::MantidVec& re = transWS->dataY(3); Mantid::MantidVec& im = transWS->dataY(4); int dn = getProperty("Order"); bool swap_re_im = dn % 2 != 0; int sign_re = 1; int sign_im = -1; switch(dn % 4) { case 1: sign_re = 1; sign_im = -1; break; case 2: sign_re = -1; sign_im = -1; break; case 3: sign_re = -1; sign_im = 1; break; } // Multiply the transform by (2*pi*i*w)**dn for(size_t j=0; j < re.size(); ++j) { double w = 2 * M_PI * nu[j]; double ww = w; for(int k = dn; k > 1; --k) { ww *= w; } double a = sign_re * re[j]*ww; double b = sign_im * im[j]*ww; if (swap_re_im) { re[j] = b; im[j] = a; } else { re[j] = a; im[j] = b; } } // Inverse transform fft = createChildAlgorithm("FFT"); fft->setProperty("InputWorkspace",transWS); fft->setProperty("Real",3); fft->setProperty("Imaginary",4); fft->setProperty("Transform","Backward"); fft->execute(); transWS = fft->getProperty("OutputWorkspace"); size_t m2 = transWS->readY(0).size() / 2; //size_t my = m2 + (transWS->readY(0).size() % 2 ? 1 : 0); //size_t mx = my + (transWS->isHistogramData() ? 1 : 0); if (!outWS) { outWS = boost::dynamic_pointer_cast<Mantid::API::MatrixWorkspace> //(Mantid::API::WorkspaceFactory::Instance().create(inWS,n,mx,my)); (Mantid::API::WorkspaceFactory::Instance().create(inWS)); } // Save the upper half of the inverse transform for output Mantid::MantidVec& x = outWS->dataX(spec); Mantid::MantidVec& y = outWS->dataY(spec); double dx = x1[m2]; std::copy(transWS->dataX(0).begin() + m2,transWS->dataX(0).end(),x.begin()); std::transform(x.begin(),x.end(),x.begin(),std::bind2nd(std::plus<double>(),dx)); std::copy(transWS->dataY(0).begin() + m2,transWS->dataY(0).end(),y.begin()); progress.report(); } setProperty("OutputWorkspace",outWS); }