/** Execute the algorithm. */ void SaveIsawUB::exec() { try { Workspace_sptr ws1 = getProperty("InputWorkspace"); ExperimentInfo_sptr ws; MultipleExperimentInfos_sptr MDWS = boost::dynamic_pointer_cast<MultipleExperimentInfos>(ws1); if (MDWS != nullptr) { ws = MDWS->getExperimentInfo(0); } else { ws = boost::dynamic_pointer_cast<ExperimentInfo>(ws1); } if (!ws) throw std::invalid_argument("Must specify either a MatrixWorkspace or a " "PeaksWorkspace or a MDWorkspace."); if (!ws->sample().hasOrientedLattice()) throw std::invalid_argument( "Workspace must have an oriented lattice to save"); std::string Filename = getProperty("Filename"); ofstream out; out.open(Filename.c_str()); OrientedLattice lattice = ws->sample().getOrientedLattice(); Kernel::DblMatrix ub = lattice.getUB(); Kernel::DblMatrix modub = lattice.getModUB(); // Write the ISAW UB matrix const int beam = 2; const int up = 1; const int back = 0; out << fixed; for (size_t basis = 0; basis < 3; basis++) { out << setw(11) << setprecision(8) << ub[beam][basis] << setw(12) << setprecision(8) << ub[back][basis] << setw(12) << setprecision(8) << ub[up][basis] << " \n"; } int ModDim = 0; for (int i = 0; i < 3; i++) { if (lattice.getModVec(i) == V3D(0, 0, 0)) continue; else ModDim++; } if (ModDim > 0) { out << "ModUB: \n"; for (size_t basis = 0; basis < 3; basis++) { out << setw(11) << setprecision(8) << modub[beam][basis] << setw(12) << setprecision(8) << modub[back][basis] << setw(12) << setprecision(8) << modub[up][basis] << " \n"; } } // out << "Lattice Parameters: \n"; out << setw(11) << setprecision(4) << lattice.a() << setw(12) << setprecision(4) << lattice.b() << setw(12) << setprecision(4) << lattice.c() << setw(12) << setprecision(4) << lattice.alpha() << setw(12) << setprecision(4) << lattice.beta() << setw(12) << setprecision(4) << lattice.gamma() << setw(12) << setprecision(4) << lattice.volume() << " \n"; double ErrorVolume = getErrorVolume(lattice); out << setw(11) << setprecision(4) << lattice.errora() << setw(12) << setprecision(4) << lattice.errorb() << setw(12) << setprecision(4) << lattice.errorc() << setw(12) << setprecision(4) << lattice.erroralpha() << setw(12) << setprecision(4) << lattice.errorbeta() << setw(12) << setprecision(4) << lattice.errorgamma() << setw(12) << setprecision(4) << ErrorVolume << " \n"; out << "\n"; if (ModDim >= 1) { out << "Modulation Vector 1: " << setw(12) << setprecision(4) << lattice.getdh(0) << setw(12) << setprecision(4) << lattice.getdk(0) << setw(12) << setprecision(4) << lattice.getdl(0) << " \n"; out << "Modulation Vector 1 error: " << setw(6) << setprecision(4) << lattice.getdherr(0) << setw(12) << setprecision(4) << lattice.getdkerr(0) << setw(12) << setprecision(4) << lattice.getdlerr(0) << " \n\n"; } if (ModDim >= 2) { out << "Modulation Vector 2: " << setw(12) << setprecision(4) << lattice.getdh(1) << setw(12) << setprecision(4) << lattice.getdk(1) << setw(12) << setprecision(4) << lattice.getdl(1) << " \n"; out << "Modulation Vector 2 error: " << setw(6) << setprecision(4) << lattice.getdherr(1) << setw(12) << setprecision(4) << lattice.getdkerr(1) << setw(12) << setprecision(4) << lattice.getdlerr(1) << " \n\n"; } if (ModDim == 3) { out << "Modulation Vector 3: " << setw(12) << setprecision(4) << lattice.getdh(2) << setw(12) << setprecision(4) << lattice.getdk(2) << setw(12) << setprecision(4) << lattice.getdl(2) << " \n"; out << "Modulation Vector 3 error: " << setw(6) << setprecision(4) << lattice.getdherr(2) << setw(12) << setprecision(4) << lattice.getdkerr(2) << setw(12) << setprecision(4) << lattice.getdlerr(2) << " \n\n"; } if (ModDim >= 1) { out << "Max Order: " << lattice.getMaxOrder() << " \n"; out << "Cross Terms: " << lattice.getCrossTerm() << " \n"; } out << "\n"; if (ModDim == 0) { out << "The above matrix is the Transpose of the UB Matrix. "; out << "The UB matrix maps the column\n"; out << "vector (h,k,l ) to the column vector "; out << "(q'x,q'y,q'z).\n"; out << "|Q'|=1/dspacing and its coordinates are a "; out << "right-hand coordinate system where\n"; out << " x is the beam direction and z is vertically "; out << "upward.(IPNS convention)\n"; } else { out << "The above matrix is the Transpose of the UB Matrix and the " "Transpose of ModUB. "; out << "The UB matrix together with ModUB maps the column vector " "(h,k,l,m,n,p) \n"; out << "to the column vector (q'x,q'y,q'z).\n"; out << "The columns of ModUB are the coordinates of modulation vectors " "in Qlab. \n"; out << "|Q'|=1/dspacing and its coordinates are a "; out << "right-hand coordinate system where"; out << " x is the beam direction and z is vertically "; out << "upward.(IPNS convention)\n"; } out.close(); } catch (exception &s) { throw std::invalid_argument(s.what()); } }
/** Execute the algorithm. */ void IntegrateEllipsoids::exec() { // get the input workspace MatrixWorkspace_sptr wksp = getProperty("InputWorkspace"); EventWorkspace_sptr eventWS = boost::dynamic_pointer_cast<EventWorkspace>(wksp); Workspace2D_sptr histoWS = boost::dynamic_pointer_cast<Workspace2D>(wksp); if (!eventWS && !histoWS) { throw std::runtime_error("IntegrateEllipsoids needs either a " "EventWorkspace or Workspace2D as input."); } // error out if there are not events if (eventWS && eventWS->getNumberEvents() <= 0) { throw std::runtime_error( "IntegrateEllipsoids does not work for empty event lists"); } PeaksWorkspace_sptr in_peak_ws = getProperty("PeaksWorkspace"); if (!in_peak_ws) { throw std::runtime_error("Could not read the peaks workspace"); } double radius_m = getProperty("RegionRadius"); double radius_s = getProperty("SatelliteRegionRadius"); int numSigmas = getProperty("NumSigmas"); double cutoffIsigI = getProperty("CutoffIsigI"); bool specify_size = getProperty("SpecifySize"); double peak_radius = getProperty("PeakSize"); double sate_peak_radius = getProperty("SatellitePeakSize"); double back_inner_radius = getProperty("BackgroundInnerSize"); double sate_back_inner_radius = getProperty("SatelliteBackgroundInnerSize"); double back_outer_radius = getProperty("BackgroundOuterSize"); double sate_back_outer_radius = getProperty("SatelliteBackgroundOuterSize"); bool hkl_integ = getProperty("IntegrateInHKL"); bool integrateEdge = getProperty("IntegrateIfOnEdge"); bool adaptiveQBackground = getProperty("AdaptiveQBackground"); double adaptiveQMultiplier = getProperty("AdaptiveQMultiplier"); double adaptiveQBackgroundMultiplier = 0.0; bool useOnePercentBackgroundCorrection = getProperty("UseOnePercentBackgroundCorrection"); if (adaptiveQBackground) adaptiveQBackgroundMultiplier = adaptiveQMultiplier; if (!integrateEdge) { // This only fails in the unit tests which say that MaskBTP is not // registered try { runMaskDetectors(in_peak_ws, "Tube", "edges"); runMaskDetectors(in_peak_ws, "Pixel", "edges"); } catch (...) { g_log.error("Can't execute MaskBTP algorithm for this instrument to set " "edge for IntegrateIfOnEdge option"); } calculateE1(in_peak_ws->detectorInfo()); // fill E1Vec for use in detectorQ } Mantid::DataObjects::PeaksWorkspace_sptr peak_ws = getProperty("OutputWorkspace"); if (peak_ws != in_peak_ws) peak_ws = in_peak_ws->clone(); // get UBinv and the list of // peak Q's for the integrator std::vector<Peak> &peaks = peak_ws->getPeaks(); size_t n_peaks = peak_ws->getNumberPeaks(); size_t indexed_count = 0; std::vector<V3D> peak_q_list; std::vector<std::pair<double, V3D>> qList; std::vector<V3D> hkl_vectors; std::vector<V3D> mnp_vectors; int ModDim = 0; for (size_t i = 0; i < n_peaks; i++) // Note: we skip un-indexed peaks { V3D hkl(peaks[i].getIntHKL()); V3D mnp(peaks[i].getIntMNP()); if (mnp[0] != 0 && ModDim == 0) ModDim = 1; if (mnp[1] != 0 && ModDim == 1) ModDim = 2; if (mnp[2] != 0 && ModDim == 2) ModDim = 3; // use tolerance == 1 to just check for (0,0,0,0,0,0) if (Geometry::IndexingUtils::ValidIndex(hkl, 1.0)) { peak_q_list.emplace_back(peaks[i].getQLabFrame()); qList.emplace_back(1., V3D(peaks[i].getQLabFrame())); hkl_vectors.push_back(hkl); mnp_vectors.push_back(mnp); indexed_count++; } } if (indexed_count < 3) throw std::runtime_error( "At least three linearly independent indexed peaks are needed."); // Get UB using indexed peaks and // lab-Q vectors Matrix<double> UB(3, 3, false); Matrix<double> modUB(3, 3, false); Matrix<double> modHKL(3, 3, false); Geometry::IndexingUtils::Optimize_6dUB(UB, modUB, hkl_vectors, mnp_vectors, ModDim, peak_q_list); int maxOrder = 0; bool CT = false; if (peak_ws->sample().hasOrientedLattice()) { OrientedLattice lattice = peak_ws->mutableSample().getOrientedLattice(); lattice.setUB(UB); lattice.setModUB(modUB); modHKL = lattice.getModHKL(); maxOrder = lattice.getMaxOrder(); CT = lattice.getCrossTerm(); } Matrix<double> UBinv(UB); UBinv.Invert(); UBinv *= (1.0 / (2.0 * M_PI)); std::vector<double> PeakRadiusVector(n_peaks, peak_radius); std::vector<double> BackgroundInnerRadiusVector(n_peaks, back_inner_radius); std::vector<double> BackgroundOuterRadiusVector(n_peaks, back_outer_radius); if (specify_size) { if (back_outer_radius > radius_m) throw std::runtime_error( "BackgroundOuterSize must be less than or equal to the RegionRadius"); if (back_inner_radius >= back_outer_radius) throw std::runtime_error( "BackgroundInnerSize must be less BackgroundOuterSize"); if (peak_radius > back_inner_radius) throw std::runtime_error( "PeakSize must be less than or equal to the BackgroundInnerSize"); } // make the integrator Integrate3DEvents integrator(qList, hkl_vectors, mnp_vectors, UBinv, modHKL, radius_m, radius_s, maxOrder, CT, useOnePercentBackgroundCorrection); // get the events and add // them to the inegrator // set up a descripter of where we are going this->initTargetWSDescr(wksp); // set up the progress bar const size_t numSpectra = wksp->getNumberHistograms(); Progress prog(this, 0.5, 1.0, numSpectra); if (eventWS) { // process as EventWorkspace qListFromEventWS(integrator, prog, eventWS, UBinv, hkl_integ); } else { // process as Workspace2D qListFromHistoWS(integrator, prog, histoWS, UBinv, hkl_integ); } double inti; double sigi; std::vector<double> principalaxis1, principalaxis2, principalaxis3; std::vector<double> sateprincipalaxis1, sateprincipalaxis2, sateprincipalaxis3; for (size_t i = 0; i < n_peaks; i++) { const V3D hkl(peaks[i].getIntHKL()); const V3D mnp(peaks[i].getIntMNP()); if (Geometry::IndexingUtils::ValidIndex(hkl, 1.0) || Geometry::IndexingUtils::ValidIndex(mnp, 1.0)) { const V3D peak_q = peaks[i].getQLabFrame(); // modulus of Q const double lenQpeak = adaptiveQMultiplier != 0.0 ? peak_q.norm() : 0.0; double adaptiveRadius = adaptiveQMultiplier * lenQpeak + peak_radius; if (mnp != V3D(0, 0, 0)) adaptiveRadius = adaptiveQMultiplier * lenQpeak + sate_peak_radius; if (adaptiveRadius <= 0.0) { g_log.error() << "Error: Radius for integration sphere of peak " << i << " is negative = " << adaptiveRadius << '\n'; peaks[i].setIntensity(0.0); peaks[i].setSigmaIntensity(0.0); PeakRadiusVector[i] = 0.0; BackgroundInnerRadiusVector[i] = 0.0; BackgroundOuterRadiusVector[i] = 0.0; continue; } double adaptiveBack_inner_radius; double adaptiveBack_outer_radius; if (mnp == V3D(0, 0, 0)) { adaptiveBack_inner_radius = adaptiveQBackgroundMultiplier * lenQpeak + back_inner_radius; adaptiveBack_outer_radius = adaptiveQBackgroundMultiplier * lenQpeak + back_outer_radius; } else { adaptiveBack_inner_radius = adaptiveQBackgroundMultiplier * lenQpeak + sate_back_inner_radius; adaptiveBack_outer_radius = adaptiveQBackgroundMultiplier * lenQpeak + sate_back_outer_radius; } PeakRadiusVector[i] = adaptiveRadius; BackgroundInnerRadiusVector[i] = adaptiveBack_inner_radius; BackgroundOuterRadiusVector[i] = adaptiveBack_outer_radius; std::vector<double> axes_radii; Mantid::Geometry::PeakShape_const_sptr shape = integrator.ellipseIntegrateModEvents( E1Vec, peak_q, hkl, mnp, specify_size, adaptiveRadius, adaptiveBack_inner_radius, adaptiveBack_outer_radius, axes_radii, inti, sigi); peaks[i].setIntensity(inti); peaks[i].setSigmaIntensity(sigi); peaks[i].setPeakShape(shape); if (axes_radii.size() == 3) { if (inti / sigi > cutoffIsigI || cutoffIsigI == EMPTY_DBL()) { if (mnp == V3D(0, 0, 0)) { principalaxis1.push_back(axes_radii[0]); principalaxis2.push_back(axes_radii[1]); principalaxis3.push_back(axes_radii[2]); } else { sateprincipalaxis1.push_back(axes_radii[0]); sateprincipalaxis2.push_back(axes_radii[1]); sateprincipalaxis3.push_back(axes_radii[2]); } } } } else { peaks[i].setIntensity(0.0); peaks[i].setSigmaIntensity(0.0); } } if (principalaxis1.size() > 1) { Statistics stats1 = getStatistics(principalaxis1); g_log.notice() << "principalaxis1: " << " mean " << stats1.mean << " standard_deviation " << stats1.standard_deviation << " minimum " << stats1.minimum << " maximum " << stats1.maximum << " median " << stats1.median << "\n"; Statistics stats2 = getStatistics(principalaxis2); g_log.notice() << "principalaxis2: " << " mean " << stats2.mean << " standard_deviation " << stats2.standard_deviation << " minimum " << stats2.minimum << " maximum " << stats2.maximum << " median " << stats2.median << "\n"; Statistics stats3 = getStatistics(principalaxis3); g_log.notice() << "principalaxis3: " << " mean " << stats3.mean << " standard_deviation " << stats3.standard_deviation << " minimum " << stats3.minimum << " maximum " << stats3.maximum << " median " << stats3.median << "\n"; if (sateprincipalaxis1.size() > 1) { Statistics satestats1 = getStatistics(sateprincipalaxis1); g_log.notice() << "sateprincipalaxis1: " << " mean " << satestats1.mean << " standard_deviation " << satestats1.standard_deviation << " minimum " << satestats1.minimum << " maximum " << satestats1.maximum << " median " << satestats1.median << "\n"; Statistics satestats2 = getStatistics(sateprincipalaxis2); g_log.notice() << "sateprincipalaxis2: " << " mean " << satestats2.mean << " standard_deviation " << satestats2.standard_deviation << " minimum " << satestats2.minimum << " maximum " << satestats2.maximum << " median " << satestats2.median << "\n"; Statistics satestats3 = getStatistics(sateprincipalaxis3); g_log.notice() << "sateprincipalaxis3: " << " mean " << satestats3.mean << " standard_deviation " << satestats3.standard_deviation << " minimum " << satestats3.minimum << " maximum " << satestats3.maximum << " median " << satestats3.median << "\n"; } constexpr size_t histogramNumber = 3; Workspace_sptr wsProfile = WorkspaceFactory::Instance().create( "Workspace2D", histogramNumber, principalaxis1.size(), principalaxis1.size()); Workspace2D_sptr wsProfile2D = boost::dynamic_pointer_cast<Workspace2D>(wsProfile); AnalysisDataService::Instance().addOrReplace("EllipsoidAxes", wsProfile2D); // set output workspace Points points(principalaxis1.size(), LinearGenerator(0, 1)); wsProfile2D->setHistogram(0, points, Counts(std::move(principalaxis1))); wsProfile2D->setHistogram(1, points, Counts(std::move(principalaxis2))); wsProfile2D->setHistogram(2, points, Counts(std::move(principalaxis3))); if (cutoffIsigI != EMPTY_DBL()) { principalaxis1.clear(); principalaxis2.clear(); principalaxis3.clear(); sateprincipalaxis1.clear(); sateprincipalaxis2.clear(); sateprincipalaxis3.clear(); specify_size = true; peak_radius = std::max(std::max(stats1.mean, stats2.mean), stats3.mean) + numSigmas * std::max(std::max(stats1.standard_deviation, stats2.standard_deviation), stats3.standard_deviation); back_inner_radius = peak_radius; back_outer_radius = peak_radius * 1.25992105; // A factor of 2 ^ (1/3) // will make the background // shell volume equal to the peak region volume. for (size_t i = 0; i < n_peaks; i++) { V3D hkl(peaks[i].getIntHKL()); V3D mnp(peaks[i].getIntMNP()); if (Geometry::IndexingUtils::ValidIndex(hkl, 1.0) || Geometry::IndexingUtils::ValidIndex(mnp, 1.0)) { const V3D peak_q = peaks[i].getQLabFrame(); std::vector<double> axes_radii; integrator.ellipseIntegrateModEvents( E1Vec, peak_q, hkl, mnp, specify_size, peak_radius, back_inner_radius, back_outer_radius, axes_radii, inti, sigi); peaks[i].setIntensity(inti); peaks[i].setSigmaIntensity(sigi); if (axes_radii.size() == 3) { if (mnp == V3D(0, 0, 0)) { principalaxis1.push_back(axes_radii[0]); principalaxis2.push_back(axes_radii[1]); principalaxis3.push_back(axes_radii[2]); } else { sateprincipalaxis1.push_back(axes_radii[0]); sateprincipalaxis2.push_back(axes_radii[1]); sateprincipalaxis3.push_back(axes_radii[2]); } } } else { peaks[i].setIntensity(0.0); peaks[i].setSigmaIntensity(0.0); } } if (principalaxis1.size() > 1) { Workspace_sptr wsProfile2 = WorkspaceFactory::Instance().create( "Workspace2D", histogramNumber, principalaxis1.size(), principalaxis1.size()); Workspace2D_sptr wsProfile2D2 = boost::dynamic_pointer_cast<Workspace2D>(wsProfile2); AnalysisDataService::Instance().addOrReplace("EllipsoidAxes_2ndPass", wsProfile2D2); Points profilePoints(principalaxis1.size(), LinearGenerator(0, 1)); wsProfile2D->setHistogram(0, profilePoints, Counts(std::move(principalaxis1))); wsProfile2D->setHistogram(1, profilePoints, Counts(std::move(principalaxis2))); wsProfile2D->setHistogram(2, profilePoints, Counts(std::move(principalaxis3))); } } } // This flag is used by the PeaksWorkspace to evaluate whether it has been // integrated. peak_ws->mutableRun().addProperty("PeaksIntegrated", 1, true); // These flags are specific to the algorithm. peak_ws->mutableRun().addProperty("PeakRadius", PeakRadiusVector, true); peak_ws->mutableRun().addProperty("BackgroundInnerRadius", BackgroundInnerRadiusVector, true); peak_ws->mutableRun().addProperty("BackgroundOuterRadius", BackgroundOuterRadiusVector, true); setProperty("OutputWorkspace", peak_ws); }