18#include <nexus/NeXusFile.hpp>
19#include <nexus/NeXusException.hpp>
42 setNumberOfDetectorGroups(0);
52 :
IPeaksWorkspace(other), m_peaks(other.m_peaks), m_columns(), m_columnNames(), m_coordSystem(other.m_coordSystem) {
63 std::vector<ColumnAndDirection> &
criteria;
74 const auto &col = name.first;
75 const bool ascending = name.second;
76 bool lessThan =
false;
77 if (col ==
"BankName") {
84 lessThan = (valA < valB);
92 lessThan = (valA < valB);
133 if (peakNum >=
static_cast<int>(
m_peaks.size()) || peakNum < 0) {
134 throw std::invalid_argument(
"PeaksWorkspace::removePeak(): peakNum is out of range.");
143 if (badPeaks.empty())
150 return std::any_of(badPeaks.cbegin(), badPeaks.cend(), [ip](int badPeak) { return badPeak == ip; });
152 m_peaks.erase(it, m_peaks.end());
160 if (
dynamic_cast<const Peak *
>(&ipeak)) {
189 if (peakNum >=
static_cast<int>(
m_peaks.size()) || peakNum < 0) {
190 throw std::invalid_argument(
"PeaksWorkspace::getPeak(): peakNum is out of range.");
201 if (peakNum >=
static_cast<int>(
m_peaks.size()) || peakNum < 0) {
202 throw std::invalid_argument(
"PeaksWorkspace::getPeak(): peakNum is out of range.");
215 boost::optional<double> detectorDistance)
const {
217 std::unique_ptr<IPeak> peak = std::make_unique<Peak>(this->
getInstrument(), QLabFrame, detectorDistance);
219 peak->setGoniometerMatrix(this->
run().getGoniometer().getR());
259 double wavelength(0);
260 if (props->hasProperty(
"wavelength")) {
261 wavelength = props->getPropertyValueAsType<
double>(
"wavelength");
262 }
else if (props->hasProperty(
"energy")) {
266 wavelength =
getInstrument()->getNumberParameter(
"wavelength").at(0);
269 if (wavelength > 0) {
272 <<
" degrees for Q sample = " <<
position <<
"\n";
299 bool labCoords)
const {
300 std::vector<std::pair<std::string, std::string>> Result;
301 std::ostringstream oss;
302 oss << std::setw(12) << std::fixed << std::setprecision(3) << (qFrame.
norm());
303 std::pair<std::string, std::string> QMag(
"|Q|", oss.str());
304 Result.emplace_back(QMag);
308 oss << std::setw(12) << std::fixed << std::setprecision(3) << (2.0 * M_PI / qFrame.
norm());
310 std::pair<std::string, std::string> dspc(
"d-spacing", oss.str());
313 Result.emplace_back(dspc);
316 bool hasOneRunNumber =
true;
320 double minDist = 10000000;
321 for (
int i = 0; i < NPeaks; i++) {
335 else if (runNum !=
run)
336 hasOneRunNumber =
false;
351 Qsamp = InvGon * Qlab;
358 if (labCoords || seqNum >= 0)
361 std::pair<std::string, std::string> QlabStr(
"Qlab", boost::lexical_cast<std::string>(Qlab));
362 Result.emplace_back(QlabStr);
365 if (!labCoords || seqNum >= 0) {
367 std::pair<std::string, std::string> QsampStr(
"QSample", boost::lexical_cast<std::string>(Qsamp));
368 Result.emplace_back(QsampStr);
375 if (
sample().hasOrientedLattice()) {
377 peak->setGoniometerMatrix(Gon);
383 V3D hkl = UB * Qsamp / 2 / M_PI;
385 std::pair<std::string, std::string>
HKL(
"HKL", boost::lexical_cast<std::string>(hkl));
386 Result.emplace_back(
HKL);
389 if (hasOneRunNumber) {
390 std::pair<std::string, std::string> runn(
"RunNumber",
" " +
std::to_string(runNum));
391 Result.emplace_back(runn);
397 Kernel::V3D PhiChiOmega(OmegaChiPhi[2], OmegaChiPhi[1], OmegaChiPhi[0]);
399 std::pair<std::string, std::string> GRead(
"Goniometer Angles", boost::lexical_cast<std::string>(PhiChiOmega));
400 Result.emplace_back(GRead);
402 std::pair<std::string, std::string> SeqNum(
"Seq Num,1st=1",
" " +
std::to_string(seqNum + 1));
403 Result.emplace_back(SeqNum);
405 oss << std::setw(12) << std::fixed << std::setprecision(3) << (peak->getWavelength());
406 std::pair<std::string, std::string> wl(
"Wavelength", oss.str());
407 Result.emplace_back(wl);
411 if (peak->findDetector()) {
412 std::pair<std::string, std::string> detpos(
"Position(x,y,z)",
413 boost::lexical_cast<std::string>(peak->getDetPos()));
414 Result.emplace_back(detpos);
416 oss << std::setw(15) << std::fixed << std::setprecision(3) << (peak->getTOF());
417 std::pair<std::string, std::string> tof(
"TOF", oss.str());
418 Result.emplace_back(tof);
422 oss << std::setw(12) << std::fixed << std::setprecision(3) << (peak->getFinalEnergy());
423 std::pair<std::string, std::string> Energy(
"Energy", oss.str());
424 Result.emplace_back(Energy);
428 std::pair<std::string, std::string> row(
"Row",
" " +
std::to_string(peak->getRow()));
429 Result.emplace_back(row);
431 std::pair<std::string, std::string> col(
"Col",
" " +
std::to_string(peak->getCol()));
432 Result.emplace_back(col);
434 std::pair<std::string, std::string> bank(
"Bank",
" " + peak->getBankName());
435 Result.emplace_back(bank);
437 oss << std::setw(12) << std::fixed << std::setprecision(3) << (peak->getScattering());
438 std::pair<std::string, std::string> scat(
"Scattering Angle", oss.str());
439 Result.emplace_back(scat);
464 const V3D qLabFrame = goniometer.getR() * lattice.getUB() *
HKL * 2 * M_PI;
468 std::unique_ptr<IPeak> peak = std::make_unique<Peak>(this->
getInstrument(), qLabFrame);
471 peak->setIntHKL(peak->getHKL());
473 peak->setGoniometerMatrix(goniometer.getR());
503 std::vector<std::pair<std::string, std::string>> Result;
504 std::ostringstream oss;
505 oss << std::setw(12) << std::fixed << std::setprecision(3) << (qFrame.
norm());
506 std::pair<std::string, std::string> QMag(
"|Q|", oss.str());
507 Result.emplace_back(QMag);
511 oss << std::setw(12) << std::fixed << std::setprecision(3) << (2.0 * M_PI / qFrame.
norm());
513 std::pair<std::string, std::string> dspc(
"d-spacing", oss.str());
516 Result.emplace_back(dspc);
519 double minDist = 10000000;
547 const std::string peaksIntegrated =
"PeaksIntegrated";
548 if (this->
run().hasProperty(peaksIntegrated)) {
549 const auto value = boost::lexical_cast<int>(this->
run().getProperty(peaksIntegrated)->
value());
569 table->addColumn(
"int",
"Index");
570 table->addColumn(
"int",
"DetectorID");
572 const auto npeaks(
static_cast<int>(this->
rowCount()));
574 for (
int i = 0; i < npeaks; ++i) {
577 auto itEnd = detIDs.end();
578 for (
auto it = detIDs.begin(); it != itEnd; ++it) {
580 table->cell<
int>(
nrows, 0) = i;
581 table->cell<
int>(
nrows, 1) = *it;
630 for (
size_t i = 0; i <
m_columns.size(); i++)
633 throw std::invalid_argument(
"Column named " + name +
" was not found in the PeaksWorkspace.");
640 throw std::invalid_argument(
"PeaksWorkspace::getColumn() called with invalid index.");
648 throw std::invalid_argument(
"PeaksWorkspace::getColumn() called with invalid index.");
655 const size_t np(
m_peaks.size());
658 std::vector<int> detectorID(np);
659 std::vector<double> H(np);
660 std::vector<double> K(np);
661 std::vector<double> L(np);
662 std::vector<double> intensity(np);
663 std::vector<double> sigmaIntensity(np);
664 std::vector<double> binCount(np);
665 std::vector<double> initialEnergy(np);
666 std::vector<double> finalEnergy(np);
667 std::vector<double> waveLength(np);
668 std::vector<double> scattering(np);
669 std::vector<double> dSpacing(np);
670 std::vector<double>
TOF(np);
671 std::vector<int> runNumber(np);
672 std::vector<int> peakNumber(np);
673 std::vector<double> tbar(np);
674 std::vector<double> goniometerMatrix(9 * np);
675 std::vector<std::string> shapes(np);
678 size_t maxShapeJSONLength = 0;
679 for (
size_t i = 0; i < np; i++) {
699 goniometerMatrix[9 * i] = gm[0][0];
700 goniometerMatrix[9 * i + 1] = gm[1][0];
701 goniometerMatrix[9 * i + 2] = gm[2][0];
702 goniometerMatrix[9 * i + 3] = gm[0][1];
703 goniometerMatrix[9 * i + 4] = gm[1][1];
704 goniometerMatrix[9 * i + 5] = gm[2][1];
705 goniometerMatrix[9 * i + 6] = gm[0][2];
706 goniometerMatrix[9 * i + 7] = gm[1][2];
707 goniometerMatrix[9 * i + 8] = gm[2][2];
710 shapes[i] = shapeJSON;
711 if (shapeJSON.size() > maxShapeJSONLength) {
712 maxShapeJSONLength = shapeJSON.size();
717 const std::string specifyInteger =
"An integer";
718 const std::string specifyDouble =
"A double";
719 const std::string specifyString =
"A string";
720 file->makeGroup(
"peaks_workspace",
"NXentry",
724 file->writeData(
"coordinate_system",
static_cast<uint32_t
>(
m_coordSystem));
729 file->putAttr(
"QConvention", m_QConvention);
732 file->writeData(
"column_1", detectorID);
733 file->openData(
"column_1");
734 file->putAttr(
"name",
"Detector ID");
735 file->putAttr(
"interpret_as", specifyInteger);
736 file->putAttr(
"units",
"Not known");
740 file->writeData(
"column_2", H);
741 file->openData(
"column_2");
742 file->putAttr(
"name",
"H");
743 file->putAttr(
"interpret_as", specifyDouble);
744 file->putAttr(
"units",
"Not known");
748 file->writeData(
"column_3", K);
749 file->openData(
"column_3");
750 file->putAttr(
"name",
"K");
751 file->putAttr(
"interpret_as", specifyDouble);
752 file->putAttr(
"units",
"Not known");
756 file->writeData(
"column_4", L);
757 file->openData(
"column_4");
758 file->putAttr(
"name",
"L");
759 file->putAttr(
"interpret_as", specifyDouble);
760 file->putAttr(
"units",
"Not known");
764 file->writeData(
"column_5", intensity);
765 file->openData(
"column_5");
766 file->putAttr(
"name",
"Intensity");
767 file->putAttr(
"interpret_as", specifyDouble);
768 file->putAttr(
"units",
"Not known");
772 file->writeData(
"column_6", sigmaIntensity);
773 file->openData(
"column_6");
774 file->putAttr(
"name",
"Sigma Intensity");
775 file->putAttr(
"interpret_as", specifyDouble);
776 file->putAttr(
"units",
"Not known");
780 file->writeData(
"column_7", binCount);
781 file->openData(
"column_7");
782 file->putAttr(
"name",
"Bin Count");
783 file->putAttr(
"interpret_as", specifyDouble);
784 file->putAttr(
"units",
"Not known");
788 file->writeData(
"column_8", initialEnergy);
789 file->openData(
"column_8");
790 file->putAttr(
"name",
"Initial Energy");
791 file->putAttr(
"interpret_as", specifyDouble);
792 file->putAttr(
"units",
"Not known");
796 file->writeData(
"column_9", finalEnergy);
797 file->openData(
"column_9");
798 file->putAttr(
"name",
"Final Energy");
799 file->putAttr(
"interpret_as", specifyDouble);
800 file->putAttr(
"units",
"Not known");
804 file->writeData(
"column_10", waveLength);
805 file->openData(
"column_10");
806 file->putAttr(
"name",
"Wave Length");
807 file->putAttr(
"interpret_as", specifyDouble);
808 file->putAttr(
"units",
"Not known");
812 file->writeData(
"column_11", scattering);
813 file->openData(
"column_11");
814 file->putAttr(
"name",
"Scattering");
815 file->putAttr(
"interpret_as", specifyDouble);
816 file->putAttr(
"units",
"Not known");
820 file->writeData(
"column_12", dSpacing);
821 file->openData(
"column_12");
822 file->putAttr(
"name",
"D Spacing");
823 file->putAttr(
"interpret_as", specifyDouble);
824 file->putAttr(
"units",
"Not known");
828 file->writeData(
"column_13",
TOF);
829 file->openData(
"column_13");
830 file->putAttr(
"name",
"TOF");
831 file->putAttr(
"interpret_as", specifyDouble);
832 file->putAttr(
"units",
"Not known");
836 file->writeData(
"column_14", runNumber);
837 file->openData(
"column_14");
838 file->putAttr(
"name",
"Run Number");
839 file->putAttr(
"interpret_as", specifyInteger);
840 file->putAttr(
"units",
"Not known");
844 file->writeData(
"column_17", peakNumber);
845 file->openData(
"column_17");
846 file->putAttr(
"name",
"Peak Number");
847 file->putAttr(
"interpret_as", specifyInteger);
848 file->putAttr(
"units",
"Not known");
852 file->writeData(
"column_18", tbar);
853 file->openData(
"column_18");
854 file->putAttr(
"name",
"TBar");
855 file->putAttr(
"interpret_as", specifyDouble);
856 file->putAttr(
"units",
"Not known");
860 std::vector<int> array_dims;
861 array_dims.emplace_back(
static_cast<int>(
m_peaks.size()));
862 array_dims.emplace_back(9);
863 file->writeData(
"column_15", goniometerMatrix, array_dims);
864 file->openData(
"column_15");
865 file->putAttr(
"name",
"Goniometer Matrix");
866 file->putAttr(
"interpret_as",
"A matrix of 3x3 doubles");
867 file->putAttr(
"units",
"Not known");
871 std::vector<int64_t> dims;
872 dims.emplace_back(np);
873 dims.emplace_back(
static_cast<int>(maxShapeJSONLength));
874 const std::string name =
"column_16";
875 file->makeData(name, NeXus::CHAR, dims,
false);
876 file->openData(name);
878 auto toNexus =
new char[maxShapeJSONLength * np];
879 for (
size_t ii = 0; ii < np; ii++) {
880 std::string rowStr = shapes[ii];
881 for (
size_t ic = 0; ic < rowStr.size(); ic++)
882 toNexus[ii * maxShapeJSONLength + ic] = rowStr[ic];
883 for (
size_t ic = rowStr.size(); ic <
static_cast<size_t>(maxShapeJSONLength); ic++)
884 toNexus[ii * maxShapeJSONLength + ic] =
' ';
887 file->putData((
void *)(toNexus));
890 file->putAttr(
"units",
"Not known");
891 file->putAttr(
"name",
"Shape");
892 file->putAttr(
"interpret_as", specifyString);
938IPropertyManager::getValue<Mantid::DataObjects::PeaksWorkspace_sptr>(
const std::string &name)
const {
943 std::string message =
944 "Attempt to assign property " + name +
" to incorrect type. Expected shared_ptr<PeaksWorkspace>.";
945 throw std::runtime_error(message);
951IPropertyManager::getValue<Mantid::DataObjects::PeaksWorkspace_const_sptr>(
const std::string &name)
const {
954 return prop->operator()();
956 std::string message =
957 "Attempt to assign property " + name +
" to incorrect type. Expected const shared_ptr<PeaksWorkspace>.";
958 throw std::runtime_error(message);
double value
The value of the point.
std::map< DeltaEMode::Type, std::string > index
#define DLLExport
Definitions of the DLLImport compiler directives for MSVC.
#define DECLARE_WORKSPACE(classname)
Run & mutableRun()
Writable version of the run object.
const Run & run() const
Run details object access.
Geometry::Instrument_const_sptr getInstrument() const
Returns the parameterized instrument.
const Sample & sample() const
Sample accessors.
int getRunNumber() const
Utility method to get the run number.
void setNumberOfDetectorGroups(const size_t count) const
Sets the number of detector groups.
Interface to the class Mantid::DataObjects::PeaksWorkspace.
ITableWorkspace is an implementation of Workspace in which the data are organised in columns of same ...
This class contains the information about the log entries.
const Geometry::Goniometer & getGoniometer() const
Return reference to the first const Goniometer object for this run.
const Geometry::OrientedLattice & getOrientedLattice() const
Get a reference to the sample's OrientedLattice.
double getL() const override
Get the L index of the peak.
double getIntensity() const override
Return the integrated peak intensity.
double getAbsorptionWeightedPathLength() const override
Gets the absorption weighted path length.
double getSigmaIntensity() const override
Return the error on the integrated peak intensity.
double getK() const override
Get the K index of the peak.
int getPeakNumber() const override
Returns the unique peak number Returns -1 if it could not find it.
int getRunNumber() const override
Return the run number this peak was measured at.
double getH() const override
Get the H index of the peak.
double getBinCount() const override
Return the # of counts in the bin at its peak.
Mantid::Kernel::Matrix< double > getGoniometerMatrix() const override
Get the goniometer rotation matrix at which this peak was measured.
const Mantid::Geometry::PeakShape & getPeakShape() const override
Get the peak shape.
PeakColumn : a Column sub-class used to display peak information as a TableWorkspace.
Comparator class for sorting peaks by one or more criteria.
bool operator()(const Peak &a, const Peak &b)
Compare two peaks using the stored criteria.
PeakComparator(std::vector< ColumnAndDirection > &criteria)
Constructor for the comparator for sorting peaks.
LeanElasticPeaksWorkspace::ColumnAndDirection ColumnAndDirection
std::vector< ColumnAndDirection > & criteria
Structure describing a single-crystal peak.
double getDSpacing() const override
Calculate the d-spacing of the peak, in 1/Angstroms
std::string getBankName() const
Find the name of the bank that is the parent of the detector.
const std::set< int > & getContributingDetIDs() const
Return the set of detector IDs that contribute to this peak.
double getInitialEnergy() const override
Get the initial (incident) neutron energy in meV.
Mantid::Kernel::V3D getQLabFrame() const override
Return the Q change (of the lattice, k_i - k_f) for this peak.
double getFinalEnergy() const override
Get the final neutron energy in meV.
double getWavelength() const override
Calculate the neutron wavelength (in angstroms) at the peak (Note for inelastic scattering - it is th...
double getTOF() const override
Calculate the time of flight (in microseconds) of the neutrons for this peak, using the geometry of t...
Mantid::Kernel::V3D getQSampleFrame() const override
Return the Q change (of the lattice, k_i - k_f) for this peak.
int getDetectorID() const
Get the ID of the detector at the center of the peak
double getScattering() const override
Calculate the scattering angle of the peak
double getValueByColName(std::string colName) const override
Helper function for displaying/sorting peaks.
The class PeaksWorkspace stores information about a set of SCD peaks.
int getNumberPeaks() const override
Kernel::SpecialCoordinateSystem getSpecialCoordinateSystem() const override
Get the special coordinate system.
API::ITableWorkspace_sptr createDetectorTable() const override
Creates a new TableWorkspace giving the IDs of the detectors that contribute to the peaks within the ...
std::vector< std::shared_ptr< Mantid::DataObjects::PeakColumn< Peak > > > m_columns
Column shared pointers.
IPeak_uptr createPeak() const override
Create a Peak using default values.
std::pair< std::string, bool > ColumnAndDirection
std::vector< Peak > m_peaks
Vector of Peak contained within.
ITableWorkspace * doCloneColumns(const std::vector< std::string > &colNames) const override
Peak & getPeak(int peakNum) override
Return a reference to the Peak.
void removePeaks(std::vector< int > badPeaks) override
Removes multiple peaks.
void removePeak(int peakNum) override
Removes the indicated peak.
std::vector< std::string > m_columnNames
Column names.
std::vector< Peak > & getPeaks()
Return a reference to the Peaks vector.
void initColumns()
Initialize the table structure.
std::shared_ptr< Mantid::API::Column > getColumn(const std::string &name) override
Gets the shared pointer to a column by name.
virtual size_t getColumnIndex(const std::string &name) const
IPeak_uptr createPeakHKL(const Kernel::V3D &HKL) const override
Create a Peak from a HKL value provided by the client.
PeaksWorkspace()
Constructor.
void addPeakColumn(const std::string &name)
Adds a new PeakColumn of the given type.
IPeak_uptr createPeakQSample(const Kernel::V3D &position) const override
Creates an instance of a Peak BUT DOES NOT ADD IT TO THE WORKSPACE.
void saveNexus(::NeXus::File *file) const override
std::vector< std::pair< std::string, std::string > > peakInfo(const Kernel::V3D &qFrame, bool labCoords) const override
Returns selected information for a "peak" at QLabFrame.
std::string getConvention() const override
bool hasIntegratedPeaks() const override
Getter for the integration status.
void sort(std::vector< ColumnAndDirection > &criteria) override
Sort the peaks by one or more criteria.
API::LogManager_sptr logs() override
Get access to shared pointer containing workspace porperties.
int peakInfoNumber(const Kernel::V3D &qFrame, bool labCoords) const override
Returns selected information for a "peak" at QLabFrame.
API::LogManager_const_sptr getLogs() const override
Get constant access to shared pointer containing workspace porperties; Copies logs into new LogManage...
size_t getMemorySize() const override
Return the memory used in bytes.
Kernel::SpecialCoordinateSystem m_coordSystem
Coordinates.
void addPeak(const Geometry::IPeak &peak) override
Add a peak to the list.
void setCoordinateSystem(const Kernel::SpecialCoordinateSystem coordinateSystem) override
Set the special coordinate system.
size_t rowCount() const override
Number of rows in the workspace.
Class to represent a particular goniometer setting, which is described by the rotation matrix.
std::vector< double > getEulerAngles(const std::string &convention="YZX")
Return Euler angles acording to a convention.
const Kernel::DblMatrix & getR() const
Return global rotation matrix.
void calcFromQSampleAndWavelength(const Mantid::Kernel::V3D &Q, double wavelength, bool flip_x=false, bool inner=false)
Calculate goniometer for rotation around y-asix for constant wavelength from Q Sample.
Structure describing a single-crystal peak.
Class to implement UB matrix.
const Kernel::DblMatrix & getUB() const
Get the UB matrix.
virtual std::string toJSON() const =0
Serialize.
Marks code as not implemented yet.
The Logger class is in charge of the publishing messages from the framework through various channels.
void information(const std::string &msg)
Logs at information level.
T Invert()
LU inversion routine.
The concrete, templated class for properties.
static T & Instance()
Return a reference to the Singleton instance, creating it if it does not already exist Creation is do...
static double run(const std::string &src, const std::string &dest, const double srcValue, const double l1, const double l2, const double theta, const DeltaEMode::Type emode, const double efixed)
Convert a single value between the given units (as strings)
double distance(const V3D &v) const noexcept
Calculates the distance between two vectors.
double norm() const noexcept
std::shared_ptr< const LogManager > LogManager_const_sptr
shared pointer to the logManager base class (const version)
std::shared_ptr< LogManager > LogManager_sptr
shared pointer to the logManager base class
std::shared_ptr< ITableWorkspace > ITableWorkspace_sptr
shared pointer to Mantid::API::ITableWorkspace
Kernel::Logger g_log("ExperimentInfo")
static logger object
std::shared_ptr< const PeaksWorkspace > PeaksWorkspace_const_sptr
Typedef for a shared pointer to a const peaks workspace.
std::shared_ptr< PeaksWorkspace > PeaksWorkspace_sptr
Typedef for a shared pointer to a peaks workspace.
std::unique_ptr< Peak > Peak_uptr
std::unique_ptr< IPeak > IPeak_uptr
SpecialCoordinateSystem
Special coordinate systems for Q3D.
Helper class which provides the Collimation Length for SANS instruments.
std::string to_string(const wide_integer< Bits, Signed > &n)