diff --git a/GUI/Model/Device/InstrumentItems.cpp b/GUI/Model/Device/InstrumentItems.cpp index d9d77778c363a396a1b4e1b05c0f2ec44730b93a..8e34bb8c8bf17bb70e289ed814c9fd10b877bd3f 100644 --- a/GUI/Model/Device/InstrumentItems.cpp +++ b/GUI/Model/Device/InstrumentItems.cpp @@ -52,6 +52,7 @@ const QString WithPolarizerAnalyzer("WithPolarizerAnalyzer"); const QString AnalyzerEfficiency("AnalyzerEfficiency"); const QString AnalyzerTotalTransmission("AnalyzerTotalTransmission"); const QString Beam("Beam"); +const QString Scan("Scan"); const QString Polarization("Polarization"); const QString AnalyzerDirection("AnalyzerDirection"); const QString Background("Background"); @@ -272,18 +273,22 @@ void InstrumentItem::readFrom(QXmlStreamReader* r) } // ************************************************************************************************ -// class SpecularInstrumentItem +// class ScanningItem // ************************************************************************************************ -SpecularInstrumentItem::SpecularInstrumentItem() +ScanningItem::ScanningItem(InstrumentItem* instrument, double intensity) + : m_scanItem(new ScanItem(instrument)) { - m_scanItem.reset(new ScanItem(this)); - m_scanItem->intensity().setValue(1); // overwrite default value set by BeamItem c'tor + m_scanItem->intensity().setValue(intensity); // overwrite default value set by BeamItem c'tor } -ScanItem* SpecularInstrumentItem::scanItem() const +// ************************************************************************************************ +// class SpecularInstrumentItem +// ************************************************************************************************ + +SpecularInstrumentItem::SpecularInstrumentItem() + : ScanningItem(this, 1) { - return dynamic_cast<ScanItem*>(m_scanItem.get()); } std::vector<int> SpecularInstrumentItem::shape() const @@ -404,9 +409,8 @@ ISimulation* SpecularInstrumentItem::createSimulation(const MultiLayer& sample) // ************************************************************************************************ DepthprobeInstrumentItem::DepthprobeInstrumentItem() + : ScanningItem(this, 1e8) { - m_scanItem.reset(new ScanItem(this)); - auto* axisItem = scanItem()->inclinationAxisItem(); axisItem->setMin(0.0); axisItem->setMax(1.0); @@ -428,8 +432,8 @@ void DepthprobeInstrumentItem::writeTo(QXmlStreamWriter* w) const w->writeEndElement(); // beam - w->writeStartElement(Tag::Beam); - m_scanItem->writeTo(w); + w->writeStartElement(Tag::Scan); + scanItem()->writeTo(w); w->writeEndElement(); // z axis @@ -452,8 +456,8 @@ void DepthprobeInstrumentItem::readFrom(QXmlStreamReader* r) XML::gotoEndElementOfTag(r, tag); // scan - } else if (tag == Tag::Beam) { - m_scanItem->readFrom(r); + } else if (tag == Tag::Scan) { + scanItem()->readFrom(r); XML::gotoEndElementOfTag(r, tag); // z axis @@ -466,11 +470,6 @@ void DepthprobeInstrumentItem::readFrom(QXmlStreamReader* r) } } -ScanItem* DepthprobeInstrumentItem::scanItem() const -{ - return dynamic_cast<ScanItem*>(m_scanItem.get()); -} - std::vector<int> DepthprobeInstrumentItem::shape() const { return {}; // no certain shape to avoid linking to real data @@ -536,12 +535,11 @@ const ICoordSystem* DepthprobeInstrumentItem::createCoordSystem() const // ************************************************************************************************ OffspecInstrumentItem::OffspecInstrumentItem() - : m_detector(new OffspecDetectorItem) + : ScanningItem(this, 1e8) + , m_detector(new OffspecDetectorItem) { m_alphaAxis.initMin("Min", "Starting value", 0.0, Unit::degree, RealLimits::limited(-90, 90)); m_alphaAxis.initMax("Max", "Ending value", 10.0, Unit::degree, RealLimits::limited(-90, 90)); - - m_scanItem.reset(new ScanItem(this)); } void OffspecInstrumentItem::writeTo(QXmlStreamWriter* w) const @@ -554,19 +552,14 @@ void OffspecInstrumentItem::writeTo(QXmlStreamWriter* w) const w->writeEndElement(); // beam - w->writeStartElement(Tag::Beam); - m_scanItem->writeTo(w); + w->writeStartElement(Tag::Scan); + scanItem()->writeTo(w); w->writeEndElement(); // alpha axis w->writeStartElement(Tag::AlphaAxis); m_alphaAxis.writeTo(w); w->writeEndElement(); - - // beam parameters groupbox: is expanded? - w->writeStartElement(Tag::ExpandBeamParametersGroupbox); - XML::writeAttribute(w, XML::Attrib::value, m_expandBeamParameters); - w->writeEndElement(); } void OffspecInstrumentItem::readFrom(QXmlStreamReader* r) @@ -583,8 +576,8 @@ void OffspecInstrumentItem::readFrom(QXmlStreamReader* r) XML::gotoEndElementOfTag(r, tag); // scan - } else if (tag == Tag::Beam) { - m_scanItem->readFrom(r); + } else if (tag == Tag::Scan) { + scanItem()->readFrom(r); XML::gotoEndElementOfTag(r, tag); // alpha axis @@ -592,21 +585,11 @@ void OffspecInstrumentItem::readFrom(QXmlStreamReader* r) m_alphaAxis.readFrom(r); XML::gotoEndElementOfTag(r, tag); - // beam parameters groupbox: is expanded? - } else if (tag == Tag::ExpandBeamParametersGroupbox) { - XML::readAttribute(r, XML::Attrib::value, &m_expandBeamParameters); - XML::gotoEndElementOfTag(r, tag); - } else r->skipCurrentElement(); } } -ScanItem* OffspecInstrumentItem::scanItem() const -{ - return dynamic_cast<ScanItem*>(m_scanItem.get()); -} - std::vector<int> OffspecInstrumentItem::shape() const { return {(int)m_alphaAxis.nbins(), detectorItem()->ySize()}; @@ -645,15 +628,15 @@ const ICoordSystem* OffspecInstrumentItem::createCoordSystem() const ISimulation* OffspecInstrumentItem::createSimulation(const MultiLayer& sample) const { - auto beam = scanItem()->createBeam(); + const auto beam = scanItem()->createBeam(); beam->setPolarization(m_polarization); - auto detector = detectorItem()->createOffspecDetector(); + const auto detector = detectorItem()->createOffspecDetector(); detector->setAnalyzer(m_analyzerDirection, m_analyzerEfficiency, m_analyzerTotalTransmission); const auto* det = dynamic_cast<const OffspecDetector*>(detector.get()); auto* result = new OffspecSimulation(*beam, sample, *det); - const auto axis = alphaAxis().createAxis(Units::deg); + const auto axis = alphaScanAxis().createAxis(Units::deg); result->setBeamParameters(scanItem()->wavelength(), *axis, scanItem()->azimuthalAngle()); if (const auto background = backgroundItem()->createBackground()) @@ -768,9 +751,9 @@ std::unique_ptr<IDetector> GISASInstrumentItem::createDetector() const ISimulation* GISASInstrumentItem::createSimulation(const MultiLayer& sample) const { - auto beam = beamItem()->createBeam(); + const auto beam = beamItem()->createBeam(); beam->setPolarization(m_polarization); - auto detector = detectorItem()->createDetector(); + const auto detector = detectorItem()->createDetector(); detector->setAnalyzer(m_analyzerDirection, m_analyzerEfficiency, m_analyzerTotalTransmission); detector->setDetectorNormal(beam->ki()); diff --git a/GUI/Model/Device/InstrumentItems.h b/GUI/Model/Device/InstrumentItems.h index c369310e0c2eac7fce02ccd4506fb6abb4843c31..cd0190a180120857eac85d83c32e4ba9a97c3cfe 100644 --- a/GUI/Model/Device/InstrumentItems.h +++ b/GUI/Model/Device/InstrumentItems.h @@ -22,14 +22,15 @@ #include "GUI/Model/Descriptor/SelectionProperty.h" #include "GUI/Model/Descriptor/VectorProperty.h" #include "GUI/Model/Device/BackgroundItems.h" -#include "GUI/Model/Device/BeamItems.h" #include "GUI/Model/Device/DetectorItem.h" +#include "GUI/Model/Device/SourceItems.h" #include <functional> #include <memory> class BackgroundItem; class DataItem; class DepthprobeSimulation; +class IBeamScan; class ISimulation; class MaskContainerItem; class MultiLayer; @@ -138,11 +139,21 @@ protected: }; -class SpecularInstrumentItem : public InstrumentItem { +//! Mix-in class, to equip an instrument class with a scan item + +class ScanningItem { public: - SpecularInstrumentItem(); + ScanningItem(InstrumentItem* instrument, double intensity); + ScanItem* scanItem() const { return m_scanItem.get(); } + +private: + std::unique_ptr<ScanItem> m_scanItem; +}; - ScanItem* scanItem() const; + +class SpecularInstrumentItem : public InstrumentItem, public ScanningItem { +public: + SpecularInstrumentItem(); std::vector<int> shape() const override; void updateToRealData(const RealItem* item) override; @@ -152,21 +163,16 @@ public: const ICoordSystem* createCoordSystem() const override; ISimulation* createSimulation(const MultiLayer& sample) const override; - -private: - std::unique_ptr<ScanItem> m_scanItem; }; -class DepthprobeInstrumentItem : public InstrumentItem { +class DepthprobeInstrumentItem : public InstrumentItem, public ScanningItem { public: DepthprobeInstrumentItem(); void writeTo(QXmlStreamWriter* w) const override; void readFrom(QXmlStreamReader* r) override; - ScanItem* scanItem() const; - std::vector<int> shape() const override; void updateToRealData(const RealItem* item) override; QString instrumentType() const override; @@ -174,55 +180,42 @@ public: const ICoordSystem* createCoordSystem() const override; AxisProperty& zAxis() { return m_zAxis; } - const AxisProperty& zAxis() const { return m_zAxis; } bool isExpandParameters() const { return m_expandParameters; } void setExpandParameters(bool b) { m_expandParameters = b; } ISimulation* createSimulation(const MultiLayer& sample) const override; -protected: +private: mutable std::unique_ptr<const ICoordSystem> m_coosys; AxisProperty m_zAxis; bool m_expandParameters = true; - -private: - std::unique_ptr<ScanItem> m_scanItem; }; -class OffspecInstrumentItem : public InstrumentItem { +class OffspecInstrumentItem : public InstrumentItem, public ScanningItem { public: OffspecInstrumentItem(); void writeTo(QXmlStreamWriter* w) const override; void readFrom(QXmlStreamReader* r) override; - ScanItem* scanItem() const; - std::vector<int> shape() const override; void updateToRealData(const RealItem* item) override; QString instrumentType() const override; const ICoordSystem* createCoordSystem() const override; - AxisProperty& alphaAxis() { return m_alphaAxis; } - const AxisProperty& alphaAxis() const { return m_alphaAxis; } - - bool isExpandBeamParameters() const { return m_expandBeamParameters; } - void setExpandBeamParameters(bool b) { m_expandBeamParameters = b; } + AxisProperty& alphaScanAxis() { return m_alphaAxis; } + const AxisProperty& alphaScanAxis() const { return m_alphaAxis; } ISimulation* createSimulation(const MultiLayer& sample) const override; OffspecDetectorItem* detectorItem() const { return m_detector.get(); } -protected: +private: AxisProperty m_alphaAxis; - bool m_expandBeamParameters = true; std::unique_ptr<OffspecDetectorItem> m_detector; - -private: - std::unique_ptr<ScanItem> m_scanItem; }; diff --git a/GUI/Model/Device/PointwiseAxisItem.cpp b/GUI/Model/Device/PointwiseAxisItem.cpp index c322e09dd001c3f7d35295bc5fb04bbefb1c74db..27b6eef5c86635f80541801708c1c0809d0bdfa1 100644 --- a/GUI/Model/Device/PointwiseAxisItem.cpp +++ b/GUI/Model/Device/PointwiseAxisItem.cpp @@ -17,6 +17,7 @@ #include "Device/Data/Datafield.h" #include "Device/IO/ReadWriteINT.h" #include "GUI/Model/Device/InstrumentItems.h" + namespace { namespace Tag { diff --git a/GUI/Model/Device/BeamItems.cpp b/GUI/Model/Device/SourceItems.cpp similarity index 82% rename from GUI/Model/Device/BeamItems.cpp rename to GUI/Model/Device/SourceItems.cpp index 33268beba4d656fe8972212b28f3e442000af4af..403ef3882cbabb88e7bbf6142bc248b0a81e0747 100644 --- a/GUI/Model/Device/BeamItems.cpp +++ b/GUI/Model/Device/SourceItems.cpp @@ -2,7 +2,7 @@ // // BornAgain: simulate and fit reflection and scattering // -//! @file GUI/Model/Device/BeamItems.cpp +//! @file GUI/Model/Device/SourceItems.cpp //! @brief Implements BeamItem hierarchy //! //! @homepage http://www.bornagainproject.org @@ -12,14 +12,19 @@ // // ************************************************************************************************ -#include "GUI/Model/Device/BeamItems.h" +#include "GUI/Model/Device/SourceItems.h" +#include "Base/Axis/FixedBinAxis.h" #include "Base/Const/Units.h" #include "Base/Util/Assert.h" #include "Device/Beam/Beam.h" +#include "Device/Beam/FootprintGauss.h" +#include "Device/Beam/FootprintSquare.h" #include "GUI/Model/Device/BeamAngleItems.h" #include "GUI/Model/Device/BeamWavelengthItem.h" #include "GUI/Model/Device/FootprintItems.h" #include "GUI/Model/Device/GrazingScanItem.h" +#include "GUI/Model/Device/PointwiseAxisItem.h" +#include "Sim/Scan/IBeamScan.h" namespace { @@ -53,7 +58,6 @@ SourceItem::SourceItem() void SourceItem::writeTo(QXmlStreamWriter* w) const { ASSERT(m_wavelengthItem); - ASSERT(m_inclinationAngleItem); XML::writeAttribute(w, XML::Attrib::version, uint(1)); @@ -72,11 +76,6 @@ void SourceItem::writeTo(QXmlStreamWriter* w) const m_azimuthalAngleItem->writeTo(w); w->writeEndElement(); - // inclination angle - w->writeStartElement(Tag::InclinationAngle); - m_inclinationAngleItem->writeTo(w); - w->writeEndElement(); - // beam parameters groupbox: is expanded? w->writeStartElement(Tag::ExpandBeamParametersGroupbox); XML::writeAttribute(w, XML::Attrib::value, m_expandBeamParameters); @@ -86,7 +85,6 @@ void SourceItem::writeTo(QXmlStreamWriter* w) const void SourceItem::readFrom(QXmlStreamReader* r) { ASSERT(m_wavelengthItem); - ASSERT(m_inclinationAngleItem); const uint version = XML::readUIntAttribute(r, XML::Attrib::version); Q_UNUSED(version) @@ -109,11 +107,6 @@ void SourceItem::readFrom(QXmlStreamReader* r) m_azimuthalAngleItem->readFrom(r); XML::gotoEndElementOfTag(r, tag); - // inclination angle - } else if (tag == Tag::InclinationAngle) { - m_inclinationAngleItem->readFrom(r); - XML::gotoEndElementOfTag(r, tag); - // beam parameters groupbox: is expanded? } else if (tag == Tag::ExpandBeamParametersGroupbox) { XML::readAttribute(r, XML::Attrib::value, &m_expandBeamParameters); @@ -142,18 +135,6 @@ BeamWavelengthItem* SourceItem::wavelengthItem() const return m_wavelengthItem.get(); } -void SourceItem::setInclinationAngle(double value) -{ - ASSERT(m_inclinationAngleItem); - m_inclinationAngleItem->resetToValue(value); -} - -BeamDistributionItem* SourceItem::beamDistributionItem() const -{ - ASSERT(m_inclinationAngleItem); - return m_inclinationAngleItem.get(); -} - double SourceItem::azimuthalAngle() const { ASSERT(m_azimuthalAngleItem); @@ -172,18 +153,6 @@ BeamAzimuthalAngleItem* SourceItem::azimuthalAngleItem() const return m_azimuthalAngleItem.get(); } -std::shared_ptr<Beam> SourceItem::createBeam() const -{ - double lambda = wavelength(); - double inclination_angle = Units::deg2rad(getInclinationAngle()); - double azimuthal_angle = Units::deg2rad(azimuthalAngle()); - - auto result = - std::make_shared<Beam>(InBeam(intensity(), lambda, inclination_angle, azimuthal_angle)); - - return result; -} - // ************************************************************************************************ // BeamItem // ************************************************************************************************ @@ -196,18 +165,25 @@ BeamItem::BeamItem() void BeamItem::writeTo(QXmlStreamWriter* w) const { + ASSERT(m_inclinationAngleItem); XML::writeAttribute(w, XML::Attrib::version, uint(1)); // parameters from base class w->writeStartElement(Tag::BaseData); SourceItem::writeTo(w); w->writeEndElement(); + + // inclination angle + w->writeStartElement(Tag::InclinationAngle); + m_inclinationAngleItem->writeTo(w); + w->writeEndElement(); } void BeamItem::readFrom(QXmlStreamReader* r) { const uint version = XML::readUIntAttribute(r, XML::Attrib::version); Q_UNUSED(version) + ASSERT(m_inclinationAngleItem); while (r->readNextStartElement()) { QString tag = r->name().toString(); @@ -217,27 +193,75 @@ void BeamItem::readFrom(QXmlStreamReader* r) SourceItem::readFrom(r); XML::gotoEndElementOfTag(r, tag); + // inclination angle + } else if (tag == Tag::InclinationAngle) { + m_inclinationAngleItem->readFrom(r); + XML::gotoEndElementOfTag(r, tag); + } else r->skipCurrentElement(); } } +void BeamItem::setInclinationAngle(double value) +{ + ASSERT(m_inclinationAngleItem); + m_inclinationAngleItem->resetToValue(value); +} + +BeamDistributionItem* BeamItem::beamDistributionItem() const +{ + ASSERT(m_inclinationAngleItem); + return m_inclinationAngleItem.get(); +} + double BeamItem::getInclinationAngle() const { return dynamic_cast<BeamInclinationAngleItem*>(beamDistributionItem())->inclinationAngle(); } +std::unique_ptr<Beam> BeamItem::createBeam() const +{ + double lambda = wavelength(); + double inclination_angle = Units::deg2rad(getInclinationAngle()); + double azimuthal_angle = Units::deg2rad(azimuthalAngle()); + + return std::make_unique<Beam>(InBeam(intensity(), lambda, inclination_angle, azimuthal_angle)); +} + // ************************************************************************************************ // ScanItem // ************************************************************************************************ ScanItem::ScanItem(const InstrumentItem* owningInstrument) { - m_inclinationAngleItem.reset(new GrazingScanItem(owningInstrument)); + m_grazingScanItem.reset(new GrazingScanItem(owningInstrument)); m_wavelengthItem.reset(new BeamWavelengthItem); m_footprint.init("Type", "Footprint type"); } +void ScanItem::setScan(const IBeamScan* scan) +{ + setIntensity(scan->intensity()); + setWavelength(scan->wavelength()); + setAzimuthalAngle(0.0); + + auto* axis_item = inclinationAxisItem(); + const IAxis* axis = dynamic_cast<const FixedBinAxis*>(scan->coordinateAxis()); + ASSERT(axis); + axis_item->setBinCount(static_cast<int>(axis->size())); + axis_item->setMin(axis->min() / Units::deg); + axis_item->setMax(axis->max() / Units::deg); + axis_item->setTitle(QString::fromStdString(axis->axisName())); + + if (const IFootprintFactor* footprint = scan->footprintFactor()) { + if (const auto* const fp = dynamic_cast<const FootprintGauss*>(footprint)) + setGaussianFootprint(fp->widthRatio()); + else if (const auto* const fp = dynamic_cast<const FootprintSquare*>(footprint)) + setSquareFootprint(fp->widthRatio()); + } +} + void ScanItem::writeTo(QXmlStreamWriter* w) const { XML::writeAttribute(w, XML::Attrib::version, uint(1)); @@ -291,16 +315,9 @@ double ScanItem::getInclinationAngle() const return 0.0; } -void ScanItem::setInclinationAngle(double value) -{ - ASSERT(value == 0.0); - SourceItem::setInclinationAngle(0.); -} - GrazingScanItem* ScanItem::grazingScanItem() const { - ASSERT(m_inclinationAngleItem); - return dynamic_cast<GrazingScanItem*>(m_inclinationAngleItem.get()); + return m_grazingScanItem.get(); } BasicAxisItem* ScanItem::inclinationAxisItem() const @@ -329,6 +346,15 @@ void ScanItem::updateToData(const IAxis& axis, QString units) } } +std::unique_ptr<Beam> ScanItem::createBeam() const +{ + double lambda = wavelength(); + double inclination_angle = Units::deg2rad(getInclinationAngle()); + double azimuthal_angle = Units::deg2rad(azimuthalAngle()); + + return std::make_unique<Beam>(InBeam(intensity(), lambda, inclination_angle, azimuthal_angle)); +} + /* std::shared_ptr<AlphaScan> ScanItem::createAlphaScan() const { diff --git a/GUI/Model/Device/BeamItems.h b/GUI/Model/Device/SourceItems.h similarity index 84% rename from GUI/Model/Device/BeamItems.h rename to GUI/Model/Device/SourceItems.h index fd42c9952973bb48e93524380bfd3c0c67b52abb..fa8550fdf133639ad8cd2e68f482a4f49f9503ff 100644 --- a/GUI/Model/Device/BeamItems.h +++ b/GUI/Model/Device/SourceItems.h @@ -2,7 +2,7 @@ // // BornAgain: simulate and fit reflection and scattering // -//! @file GUI/Model/Device/BeamItems.h +//! @file GUI/Model/Device/SourceItems.h //! @brief Defines BeamItem hierarchy //! //! @homepage http://www.bornagainproject.org @@ -12,8 +12,8 @@ // // ************************************************************************************************ -#ifndef BORNAGAIN_GUI_MODEL_DEVICE_BEAMITEMS_H -#define BORNAGAIN_GUI_MODEL_DEVICE_BEAMITEMS_H +#ifndef BORNAGAIN_GUI_MODEL_DEVICE_SOURCEITEMS_H +#define BORNAGAIN_GUI_MODEL_DEVICE_SOURCEITEMS_H #include "GUI/Model/CatDevice/FootprintItemCatalog.h" #include "GUI/Model/Descriptor/DoubleProperty.h" @@ -29,6 +29,7 @@ class BeamWavelengthItem; class FootprintItem; class GrazingScanItem; class IAxis; +class IBeamScan; class InstrumentItem; //! Base class for BeamItem and ScanItem. Name refers to radiation source. @@ -42,17 +43,10 @@ public: void setWavelength(double value); BeamWavelengthItem* wavelengthItem() const; - virtual double getInclinationAngle() const = 0; - virtual void setInclinationAngle(double value); - - BeamDistributionItem* beamDistributionItem() const; - double azimuthalAngle() const; void setAzimuthalAngle(double value); BeamAzimuthalAngleItem* azimuthalAngleItem() const; - std::shared_ptr<Beam> createBeam() const; - bool isExpandBeamParameters() const { return m_expandBeamParameters; } void setExpandBeamParameters(bool b) { m_expandBeamParameters = b; } @@ -63,7 +57,6 @@ protected: std::unique_ptr<BeamWavelengthItem> m_wavelengthItem; std::unique_ptr<BeamAzimuthalAngleItem> m_azimuthalAngleItem; - std::unique_ptr<BeamDistributionItem> m_inclinationAngleItem; DoubleProperty m_intensity; bool m_expandBeamParameters = true; @@ -76,18 +69,26 @@ public: void writeTo(QXmlStreamWriter* w) const; void readFrom(QXmlStreamReader* r); - double getInclinationAngle() const override; + BeamDistributionItem* beamDistributionItem() const; + void setInclinationAngle(double value); + double getInclinationAngle() const; + + std::unique_ptr<Beam> createBeam() const; + +private: + std::unique_ptr<BeamDistributionItem> m_inclinationAngleItem; }; class ScanItem : public SourceItem { public: explicit ScanItem(const InstrumentItem* owningInstrument); + void setScan(const IBeamScan* scan); + void writeTo(QXmlStreamWriter* w) const; void readFrom(QXmlStreamReader* r); - double getInclinationAngle() const override; - void setInclinationAngle(double value) override; + double getInclinationAngle() const; GrazingScanItem* grazingScanItem() const; BasicAxisItem* inclinationAxisItem() const; @@ -102,9 +103,12 @@ public: bool isExpandFootprint() const { return m_expandFootprint; } void setExpandFootprint(bool b) { m_expandFootprint = b; } + std::unique_ptr<Beam> createBeam() const; + private: SelectionProperty<FootprintItemCatalog> m_footprint; bool m_expandFootprint = true; + std::unique_ptr<GrazingScanItem> m_grazingScanItem; }; -#endif // BORNAGAIN_GUI_MODEL_DEVICE_BEAMITEMS_H +#endif // BORNAGAIN_GUI_MODEL_DEVICE_SOURCEITEMS_H diff --git a/GUI/Model/FromCore/ItemizeSimulation.cpp b/GUI/Model/FromCore/ItemizeSimulation.cpp index d3aa4ec88630f98d2dfce5ccc3c083e4776a4c19..a7aa6700af2bb05355cba03e800669edca146ce1 100644 --- a/GUI/Model/FromCore/ItemizeSimulation.cpp +++ b/GUI/Model/FromCore/ItemizeSimulation.cpp @@ -15,8 +15,6 @@ #include "GUI/Model/FromCore/ItemizeSimulation.h" #include "Base/Const/Units.h" #include "Device/Beam/Beam.h" -#include "Device/Beam/FootprintGauss.h" -#include "Device/Beam/FootprintSquare.h" #include "Device/Detector/OffspecDetector.h" #include "Device/Detector/SphericalDetector.h" #include "Device/Mask/DetectorMask.h" @@ -143,16 +141,6 @@ void setDetectorMasks(DetectorItem* detector_item, const IDetector& detector) } } -void setFootprintFactor(const IFootprintFactor* footprint, ScanItem* beam_item) -{ - if (!footprint) - return; - if (const auto* const gaussian_fp = dynamic_cast<const FootprintGauss*>(footprint)) - beam_item->setGaussianFootprint(gaussian_fp->widthRatio()); - else if (const auto* const square_fp = dynamic_cast<const FootprintSquare*>(footprint)) - beam_item->setSquareFootprint(square_fp->widthRatio()); -} - void setDistributionTypeAndPars(BeamDistributionItem* pdi, const IDistribution1D* d) { const double factor = 1 / pdi->scaleFactor(); @@ -238,22 +226,10 @@ void setOffspecBeamItem(ScanItem* scan_item, const OffspecSimulation& simulation scan_item->setIntensity(beam.intensity()); scan_item->setWavelength(beam.wavelength()); - scan_item->setInclinationAngle(Units::rad2deg(beam.alpha_i())); scan_item->setAzimuthalAngle(Units::rad2deg(beam.phi_i())); // TODO implement beam divergence } -void setAxisItem(BasicAxisItem* item, const IAxis& axis, double factor) -{ - if (!dynamic_cast<const FixedBinAxis*>(&axis)) - throw Error("setAxisItem() -> Error. Unexpected axis"); - - item->setBinCount(static_cast<int>(axis.size())); - item->setMin(factor * axis.min()); - item->setMax(factor * axis.max()); - item->setTitle(QString::fromStdString(axis.axisName())); -} - void setSphericalDetector(SphericalDetectorItem* detectorItem, const SphericalDetector& detector) { // Axes @@ -416,9 +392,9 @@ OffspecInstrumentItem* createOffspecInstrumentItem(const OffspecSimulation& simu setPolarizer2(result, detector.analyzer()); const double factor = 1. / Units::deg; - result->alphaAxis().setNbins(simulation.beamAxis()->size()); - result->alphaAxis().setMin(factor * simulation.beamAxis()->min()); - result->alphaAxis().setMax(factor * simulation.beamAxis()->max()); + result->alphaScanAxis().setNbins(simulation.beamAxis()->size()); + result->alphaScanAxis().setMin(factor * simulation.beamAxis()->min()); + result->alphaScanAxis().setMax(factor * simulation.beamAxis()->max()); return result; } @@ -430,15 +406,7 @@ SpecularInstrumentItem* createSpecularInstrumentItem(const SpecularSimulation& s const IBeamScan* scan = simulation.scan(); - scan_item->setIntensity(scan->intensity()); - scan_item->setWavelength(scan->wavelength()); - scan_item->setInclinationAngle(0.0); // inclination angle is hardcoded - scan_item->setAzimuthalAngle(0.0); // azimuthal angle is hardcoded - - auto* axis_item = scan_item->inclinationAxisItem(); - setAxisItem(axis_item, *scan->coordinateAxis(), 1. / Units::deg); - - setFootprintFactor(scan->footprintFactor(), scan_item); + scan_item->setScan(scan); if (const auto* s2 = dynamic_cast<const AlphaScan*>(scan)) { if (const IDistribution1D* distribution = s2->wavelengthDistribution()) diff --git a/GUI/Model/Project/LinkInstrumentManager.cpp b/GUI/Model/Project/LinkInstrumentManager.cpp index 720b8b2e041e31b93093ee808d12b164e7095780..de50ebf90dafc4bb8d28968c7a70c523829f2cd9 100644 --- a/GUI/Model/Project/LinkInstrumentManager.cpp +++ b/GUI/Model/Project/LinkInstrumentManager.cpp @@ -68,12 +68,11 @@ QString printShapeMessage(const std::vector<int>& instrument_shape, LinkInstrumentManager::LinkInstrumentManager(ProjectDocument* document) : m_document(document) { - connect(m_document->instrumentsEditController(), - &MultiInstrumentNotifier::instrumentAddedOrRemoved, this, + connect(m_document->multiNotifier(), &MultiInstrumentNotifier::instrumentAddedOrRemoved, this, &LinkInstrumentManager::onInstrumentAddedOrRemoved); - connect(m_document->instrumentsEditController(), &MultiInstrumentNotifier::instrumentChanged, - this, &LinkInstrumentManager::onInstrumentChanged); + connect(m_document->multiNotifier(), &MultiInstrumentNotifier::instrumentChanged, this, + &LinkInstrumentManager::onInstrumentChanged); } bool LinkInstrumentManager::canLinkDataToInstrument(const RealItem* realItem, @@ -109,8 +108,7 @@ bool LinkInstrumentManager::canLinkDataToInstrument(const RealItem* realItem, if (!QuestionOnInstrumentReshaping(message)) return false; - m_document->instrumentsEditController()->updateInstrumentToRealDataItem(instrumentItem, - realItem); + m_document->multiNotifier()->updateInstrumentToRealDataItem(instrumentItem, realItem); return true; } diff --git a/GUI/Model/Project/ProjectDocument.cpp b/GUI/Model/Project/ProjectDocument.cpp index 02f8050f2d17227020430d7f526087c20cf87218..2c564dc90bf3e50f23046bd54d4bd838b0c50f23 100644 --- a/GUI/Model/Project/ProjectDocument.cpp +++ b/GUI/Model/Project/ProjectDocument.cpp @@ -147,7 +147,7 @@ LinkInstrumentManager* ProjectDocument::linkInstrumentManager() return m_linkManager.get(); } -MultiInstrumentNotifier* ProjectDocument::instrumentsEditController() +MultiInstrumentNotifier* ProjectDocument::multiNotifier() { return &m_instrumentEditController; } diff --git a/GUI/Model/Project/ProjectDocument.h b/GUI/Model/Project/ProjectDocument.h index 44a71e9d110c938ed81ba32e3ec4b4da2aebbcb3..bd475e3d227cbf55b066d032a82108cc11f6cf7b 100644 --- a/GUI/Model/Project/ProjectDocument.h +++ b/GUI/Model/Project/ProjectDocument.h @@ -80,7 +80,7 @@ public: //! Use this to modify instrument list or instrument data. //! Listen to its signals to get notification about any changes. //! \sa MultiInstrumentNotifier for more information - MultiInstrumentNotifier* instrumentsEditController(); + MultiInstrumentNotifier* multiNotifier(); void saveProjectFileWithData(const QString& projectPullPath); diff --git a/GUI/View/Import/RealDataPropertiesWidget.cpp b/GUI/View/Import/RealDataPropertiesWidget.cpp index 181a40d4f773efbcc28e0c7e6b772cff4d7ceea8..34c8ea419a6116d8bf22eafb5b6dd24dc3e5ae76 100644 --- a/GUI/View/Import/RealDataPropertiesWidget.cpp +++ b/GUI/View/Import/RealDataPropertiesWidget.cpp @@ -49,12 +49,10 @@ RealDataPropertiesWidget::RealDataPropertiesWidget(QWidget* parent, ProjectDocum static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, &RealDataPropertiesWidget::onInstrumentComboIndexChanged); - connect(m_document->instrumentsEditController(), - &MultiInstrumentNotifier::instrumentAddedOrRemoved, this, + connect(m_document->multiNotifier(), &MultiInstrumentNotifier::instrumentAddedOrRemoved, this, &RealDataPropertiesWidget::updateInstrumentComboEntries); - connect(m_document->instrumentsEditController(), - &MultiInstrumentNotifier::instrumentNameChanged, this, + connect(m_document->multiNotifier(), &MultiInstrumentNotifier::instrumentNameChanged, this, &RealDataPropertiesWidget::updateInstrumentComboEntries); connect(m_document->linkInstrumentManager(), &LinkInstrumentManager::linkToInstrumentChanged, diff --git a/GUI/View/Instrument/DepthprobeInstrumentEditor.cpp b/GUI/View/Instrument/DepthprobeInstrumentEditor.cpp index 403cb57ba88d28e177a9c1ad0a6c374249c658be..14b0af052169ee08dc46e786c31ac57512b72507 100644 --- a/GUI/View/Instrument/DepthprobeInstrumentEditor.cpp +++ b/GUI/View/Instrument/DepthprobeInstrumentEditor.cpp @@ -15,7 +15,7 @@ #include "GUI/View/Instrument/DepthprobeInstrumentEditor.h" #include "GUI/Model/Device/InstrumentItems.h" #include "GUI/View/Device/AxisPropertyForm.h" -#include "GUI/View/Instrument/SpecularBeamEditor.h" +#include "GUI/View/Instrument/ScanEditor.h" #include <QVBoxLayout> DepthprobeInstrumentEditor::DepthprobeInstrumentEditor(QWidget* parent, @@ -28,8 +28,8 @@ DepthprobeInstrumentEditor::DepthprobeInstrumentEditor(QWidget* parent, auto* layout = new QVBoxLayout(this); layout->setContentsMargins(0, 0, 0, 0); - auto* beamEditor = new SpecularBeamEditor(this, instrument->scanItem(), &m_ec); - layout->addWidget(beamEditor); + auto* scanEditor = new ScanEditor(this, instrument->scanItem(), &m_ec); + layout->addWidget(scanEditor); auto* depthAxisEditor = new AxisPropertyForm(this, "Depth axis", &instrument->zAxis(), "Number of points in scan across sample bulk"); @@ -37,8 +37,7 @@ DepthprobeInstrumentEditor::DepthprobeInstrumentEditor(QWidget* parent, layout->addStretch(); - connect(beamEditor, &SpecularBeamEditor::dataChanged, this, - &DepthprobeInstrumentEditor::dataChanged); + connect(scanEditor, &ScanEditor::dataChanged, this, &DepthprobeInstrumentEditor::dataChanged); connect(depthAxisEditor, &AxisPropertyForm::dataChanged, this, &DepthprobeInstrumentEditor::dataChanged); } diff --git a/GUI/View/Instrument/GISASBeamEditor.cpp b/GUI/View/Instrument/GISASBeamEditor.cpp index 1964867f340bd29a1e919853ba05b5f51169c4b2..b22e79b2ca7842c7ccd01e90600f7f5d420203e8 100644 --- a/GUI/View/Instrument/GISASBeamEditor.cpp +++ b/GUI/View/Instrument/GISASBeamEditor.cpp @@ -15,9 +15,9 @@ #include "GUI/View/Instrument/GISASBeamEditor.h" #include "Base/Util/Assert.h" #include "GUI/Model/Device/BeamAngleItems.h" -#include "GUI/Model/Device/BeamItems.h" #include "GUI/Model/Device/BeamWavelengthItem.h" #include "GUI/Model/Device/GrazingScanItem.h" +#include "GUI/Model/Device/SourceItems.h" #include "GUI/View/Instrument/DistributionEditor.h" #include "GUI/View/Numeric/FixupDoubleValidator.h" #include "GUI/View/Tool/GroupBoxCollapser.h" diff --git a/GUI/View/Instrument/InstrumentLibraryEditor.cpp b/GUI/View/Instrument/InstrumentLibraryEditor.cpp index 9854fd28793014d0d70e4027276c4032ccf4e070..abda0e01b990d0095e4dd0401a4cc005269c49e6 100644 --- a/GUI/View/Instrument/InstrumentLibraryEditor.cpp +++ b/GUI/View/Instrument/InstrumentLibraryEditor.cpp @@ -221,7 +221,7 @@ void InstrumentLibraryEditor::createWidgetsForCurrentInstrument() &InstrumentLibraryEditor::onInstrumentChangedByEditor); layout->addWidget(editor); } else if (auto* os = dynamic_cast<OffspecInstrumentItem*>(currentInstrument)) { - auto* editor = new OffspecInstrumentEditor(m_ui->scrollArea, os); + auto* editor = new OffspecInstrumentEditor(m_ui->scrollArea, os, ec); connect(editor, &OffspecInstrumentEditor::dataChanged, this, &InstrumentLibraryEditor::onInstrumentChangedByEditor); layout->addWidget(editor); diff --git a/GUI/View/Instrument/InstrumentListView.cpp b/GUI/View/Instrument/InstrumentListView.cpp index 51d2276f887ff877a359f681611fed079b5bb08c..4222dddedff2e4a79c734eb7a809f45cd7024f7a 100644 --- a/GUI/View/Instrument/InstrumentListView.cpp +++ b/GUI/View/Instrument/InstrumentListView.cpp @@ -51,7 +51,7 @@ InstrumentListView::InstrumentListView(ProjectDocument* document, QWidget* paren "}\n")); layout->addWidget(m_listView); - m_model = new InstrumentListModel(this, m_document->instrumentsEditController()); + m_model = new InstrumentListModel(this, m_document->multiNotifier()); m_listView->setModel(m_model); m_newGisasAction = new QAction("New GISAS", this); diff --git a/GUI/View/Instrument/InstrumentView.cpp b/GUI/View/Instrument/InstrumentView.cpp index dead4a27ec579e7fcc672040982856afcabe0bf3..48cb7ca49354655acbd53ecff962d7b1f02d9d71 100644 --- a/GUI/View/Instrument/InstrumentView.cpp +++ b/GUI/View/Instrument/InstrumentView.cpp @@ -71,16 +71,16 @@ void InstrumentView::showEvent(QShowEvent*) // disconnect because when this view is visible, no other instance is modifying instruments. By // disconnecting, no additional logic is necessary to avoid recursive calls (recursive since // this view also causes instrumentChanged to be emitted). - disconnect(m_document->instrumentsEditController(), &MultiInstrumentNotifier::instrumentChanged, - this, &InstrumentView::onInstrumentChangedFromExternal); + disconnect(m_document->multiNotifier(), &MultiInstrumentNotifier::instrumentChanged, this, + &InstrumentView::onInstrumentChangedFromExternal); } void InstrumentView::hideEvent(QHideEvent*) { // when the instrument view gets hidden (meaning another view is shown), it's necessary to // listen to changes (e.g. performed by the LinkInstrumentManager). - connect(m_document->instrumentsEditController(), &MultiInstrumentNotifier::instrumentChanged, - this, &InstrumentView::onInstrumentChangedFromExternal); + connect(m_document->multiNotifier(), &MultiInstrumentNotifier::instrumentChanged, this, + &InstrumentView::onInstrumentChangedFromExternal); } void InstrumentView::createWidgetsForCurrentInstrument() @@ -123,14 +123,14 @@ void InstrumentView::createWidgetsForCurrentInstrument() connect(collapser, &GroupBoxCollapser::toggled, this, [currentInstrument](bool b) { currentInstrument->setExpandInfo(b); }); - auto* ec = m_document->instrumentsEditController(); + auto* ec = m_document->multiNotifier(); if (auto* sp = dynamic_cast<SpecularInstrumentItem*>(currentInstrument)) { auto* editor = new SpecularInstrumentEditor(m_scrollArea, sp, ec); connect(editor, &SpecularInstrumentEditor::dataChanged, this, &InstrumentView::onInstrumentChangedByEditor); layout->addWidget(editor); } else if (auto* os = dynamic_cast<OffspecInstrumentItem*>(currentInstrument)) { - auto* editor = new OffspecInstrumentEditor(m_scrollArea, os); + auto* editor = new OffspecInstrumentEditor(m_scrollArea, os, ec); connect(editor, &OffspecInstrumentEditor::dataChanged, this, &InstrumentView::onInstrumentChangedByEditor); layout->addWidget(editor); @@ -154,7 +154,7 @@ void InstrumentView::onInstrumentNameEdited(const QString& newName) { auto* currentInstrument = m_instrumentListView->currentInstrumentItem(); if (currentInstrument && currentInstrument->instrumentName() != newName) - m_document->instrumentsEditController()->setInstrumentName(currentInstrument, newName); + m_document->multiNotifier()->setInstrumentName(currentInstrument, newName); } void InstrumentView::onInstrumentdescriptionEdited(const QString& t) @@ -168,7 +168,7 @@ void InstrumentView::onInstrumentdescriptionEdited(const QString& t) void InstrumentView::onInstrumentChangedByEditor() { - m_document->instrumentsEditController()->notifyInstrumentChanged( + m_document->multiNotifier()->notifyInstrumentChanged( m_instrumentListView->currentInstrumentItem()); } diff --git a/GUI/View/Instrument/OffspecBeamEditor.cpp b/GUI/View/Instrument/OffspecBeamEditor.cpp deleted file mode 100644 index 5e28e1b21c750692ed39a4af424dc7d889884d82..0000000000000000000000000000000000000000 --- a/GUI/View/Instrument/OffspecBeamEditor.cpp +++ /dev/null @@ -1,88 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file GUI/View/Instrument/OffspecBeamEditor.cpp -//! @brief Implements class OffspecBeamEditor -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2018 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "GUI/View/Instrument/OffspecBeamEditor.h" -#include "GUI/Model/Device/BeamAngleItems.h" -#include "GUI/Model/Device/BeamWavelengthItem.h" -#include "GUI/Model/Device/InstrumentItems.h" -#include "GUI/View/Device/AxisPropertyForm.h" -#include "GUI/View/Instrument/DistributionEditor.h" -#include "GUI/View/Numeric/FixupDoubleValidator.h" -#include "GUI/View/Tool/GroupBoxCollapser.h" -#include <QFormLayout> -#include <QLineEdit> - -OffspecBeamEditor::OffspecBeamEditor(QWidget* parent, OffspecInstrumentItem* item) - : QGroupBox("Beam and scan parameters", parent) -{ - ASSERT(item); - - auto* vLayout = new QVBoxLayout(this); - vLayout->setContentsMargins(30, 8, 0, 0); - auto* form = new QFormLayout(); - form->setFieldGrowthPolicy(QFormLayout::FieldsStayAtSizeHint); - vLayout->addLayout(form); - auto* intensityEditor = new QLineEdit(this); - intensityEditor->setToolTip("Beam intensity in neutrons/photons per second."); - auto* validator = new FixupDoubleValidator(intensityEditor); - validator->setNotation(QDoubleValidator::ScientificNotation); - validator->setRange(0.0, 1e32, 1000); - intensityEditor->setValidator(validator); - form->addRow("Intensity:", intensityEditor); - - ScanItem* scanI = item->scanItem(); - - auto* wavelengthEditor = new DistributionEditor( - "Wavelength", MeanConfig{true}, GUI::ID::Distributions::All, this, scanI->wavelengthItem()); - vLayout->addWidget(wavelengthEditor); - - auto* inclinationEditor = new AxisPropertyForm(this, "Grazing angles", &item->alphaAxis(), - "Number of points in scan"); - vLayout->addWidget(inclinationEditor); - - auto* azimuthalEditor = - new DistributionEditor("Azimuthal angle", MeanConfig{false}, GUI::ID::Distributions::All, - this, scanI->azimuthalAngleItem()); - vLayout->addWidget(azimuthalEditor); - - intensityEditor->setText(QString::number(scanI->intensity())); - - auto* collapser = GroupBoxCollapser::installIntoGroupBox(this); - collapser->setExpanded(item->isExpandBeamParameters()); - connect(collapser, &GroupBoxCollapser::toggled, this, - [item](bool b) { item->setExpandBeamParameters(b); }); - - connect(wavelengthEditor, &DistributionEditor::distributionChanged, this, - &OffspecBeamEditor::dataChanged); - connect(inclinationEditor, &AxisPropertyForm::dataChanged, this, - &OffspecBeamEditor::dataChanged); - connect(azimuthalEditor, &DistributionEditor::distributionChanged, this, - &OffspecBeamEditor::dataChanged); - - // validate value while typing - connect(intensityEditor, &QLineEdit::textEdited, [=]() { - QString str = intensityEditor->text(); - int pos; - if (intensityEditor->validator()->validate(str, pos) == QValidator::Acceptable) { - scanI->setIntensity(intensityEditor->text().toDouble()); - emit dataChanged(); - } - }); - // if validator does not assert the input value, it says about that, - // and here we return to the last correct value - connect(validator, &FixupDoubleValidator::fixupSignal, [=]() { - auto* editor = qobject_cast<QLineEdit*>(validator->parent()); - editor->setText(QString::number(scanI->intensity(), 'g')); - }); -} diff --git a/GUI/View/Instrument/OffspecBeamEditor.h b/GUI/View/Instrument/OffspecBeamEditor.h deleted file mode 100644 index ee4d8c447186cbcd7227c72797ef9658118766c7..0000000000000000000000000000000000000000 --- a/GUI/View/Instrument/OffspecBeamEditor.h +++ /dev/null @@ -1,34 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file GUI/View/Instrument/OffspecBeamEditor.h -//! @brief Defines class OffspecBeamEditor -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2018 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_GUI_VIEW_INSTRUMENT_OFFSPECBEAMEDITOR_H -#define BORNAGAIN_GUI_VIEW_INSTRUMENT_OFFSPECBEAMEDITOR_H - -#include <QGroupBox> - -class OffspecInstrumentItem; - -//! Off-specular beam editor. Operates on OffspecInstrumentItem - -class OffspecBeamEditor : public QGroupBox { - Q_OBJECT - -public: - OffspecBeamEditor(QWidget* parent, OffspecInstrumentItem* item); - -signals: - void dataChanged(); -}; - -#endif // BORNAGAIN_GUI_VIEW_INSTRUMENT_OFFSPECBEAMEDITOR_H diff --git a/GUI/View/Instrument/OffspecInstrumentEditor.cpp b/GUI/View/Instrument/OffspecInstrumentEditor.cpp index 9ffb526a28670dbd6b3ab08245bca43039156801..70cb2f73c2c53772fd640eba4f4a2b7975beee21 100644 --- a/GUI/View/Instrument/OffspecInstrumentEditor.cpp +++ b/GUI/View/Instrument/OffspecInstrumentEditor.cpp @@ -14,20 +14,22 @@ #include "GUI/View/Instrument/OffspecInstrumentEditor.h" #include "GUI/Model/Device/InstrumentItems.h" -#include "GUI/View/Instrument/OffspecBeamEditor.h" #include "GUI/View/Instrument/OffspecDetectorEditor.h" #include "GUI/View/Instrument/PolarizationAnalysisEditor.h" +#include "GUI/View/Instrument/ScanEditor.h" +OffspecInstrumentEditor::OffspecInstrumentEditor(QWidget* parent, OffspecInstrumentItem* instrument, + MultiInstrumentNotifier* ec) -OffspecInstrumentEditor::OffspecInstrumentEditor(QWidget* parent, OffspecInstrumentItem* instrument) : QWidget(parent) + , m_ec(ec, instrument) { ASSERT(instrument); auto* layout = new QVBoxLayout(this); layout->setContentsMargins(0, 0, 0, 0); - auto* beamEditor = new OffspecBeamEditor(this, instrument); - layout->addWidget(beamEditor); + auto* scanEditor = new ScanEditor(this, instrument->scanItem(), &m_ec); + layout->addWidget(scanEditor); auto* detectorEditor = new OffspecDetectorEditor(this, instrument); layout->addWidget(detectorEditor); @@ -37,8 +39,7 @@ OffspecInstrumentEditor::OffspecInstrumentEditor(QWidget* parent, OffspecInstrum layout->addStretch(); - connect(beamEditor, &OffspecBeamEditor::dataChanged, this, - &OffspecInstrumentEditor::dataChanged); + connect(scanEditor, &ScanEditor::dataChanged, this, &OffspecInstrumentEditor::dataChanged); connect(detectorEditor, &OffspecDetectorEditor::dataChanged, this, &OffspecInstrumentEditor::dataChanged); connect(polMatricesAnalysisEditor, &PolarizationAnalysisEditor::dataChanged, this, diff --git a/GUI/View/Instrument/OffspecInstrumentEditor.h b/GUI/View/Instrument/OffspecInstrumentEditor.h index dda3efdcdbf83ec3b8e54752df37eddbc4335929..394aefa58d7d4aaa124a8faa3ffcb66eb7d08346 100644 --- a/GUI/View/Instrument/OffspecInstrumentEditor.h +++ b/GUI/View/Instrument/OffspecInstrumentEditor.h @@ -15,18 +15,24 @@ #ifndef BORNAGAIN_GUI_VIEW_INSTRUMENT_OFFSPECINSTRUMENTEDITOR_H #define BORNAGAIN_GUI_VIEW_INSTRUMENT_OFFSPECINSTRUMENTEDITOR_H +#include "GUI/Model/Device/InstrumentNotifier.h" #include <QWidget> +class MultiInstrumentNotifier; class OffspecInstrumentItem; class OffspecInstrumentEditor : public QWidget { Q_OBJECT public: - OffspecInstrumentEditor(QWidget* parent, OffspecInstrumentItem* instrument); + OffspecInstrumentEditor(QWidget* parent, OffspecInstrumentItem* instrument, + MultiInstrumentNotifier* ec); signals: void dataChanged(); + +private: + InstrumentNotifier m_ec; }; #endif // BORNAGAIN_GUI_VIEW_INSTRUMENT_OFFSPECINSTRUMENTEDITOR_H diff --git a/GUI/View/Instrument/SpecularBeamEditor.cpp b/GUI/View/Instrument/ScanEditor.cpp similarity index 92% rename from GUI/View/Instrument/SpecularBeamEditor.cpp rename to GUI/View/Instrument/ScanEditor.cpp index 4e60b3cf4a6fcb998c6183c593478072e768d1ef..27d4dfcdbac35a4fefca33b945dc2e414634c84c 100644 --- a/GUI/View/Instrument/SpecularBeamEditor.cpp +++ b/GUI/View/Instrument/ScanEditor.cpp @@ -2,8 +2,8 @@ // // BornAgain: simulate and fit reflection and scattering // -//! @file GUI/View/Instrument/SpecularBeamEditor.cpp -//! @brief Defines class SpecularBeamEditor +//! @file GUI/View/Instrument/ScanEditor.cpp +//! @brief Defines class ScanEditor //! //! @homepage http://www.bornagainproject.org //! @license GNU General Public License v3 or higher (see COPYING) @@ -12,11 +12,11 @@ // // ************************************************************************************************ -#include "GUI/View/Instrument/SpecularBeamEditor.h" +#include "GUI/View/Instrument/ScanEditor.h" #include "Base/Util/Assert.h" -#include "GUI/Model/Device/BeamItems.h" #include "GUI/Model/Device/BeamWavelengthItem.h" #include "GUI/Model/Device/InstrumentNotifier.h" +#include "GUI/Model/Device/SourceItems.h" #include "GUI/View/Device/FootprintForm.h" #include "GUI/View/Instrument/AlphaScanEditor.h" #include "GUI/View/Instrument/DistributionEditor.h" @@ -25,7 +25,7 @@ #include <QFormLayout> #include <QLineEdit> -SpecularBeamEditor::SpecularBeamEditor(QWidget* parent, ScanItem* item, InstrumentNotifier* ec) +ScanEditor::ScanEditor(QWidget* parent, ScanItem* item, InstrumentNotifier* ec) : QGroupBox("Beam and scan parameters", parent) { ASSERT(item); @@ -75,7 +75,7 @@ SpecularBeamEditor::SpecularBeamEditor(QWidget* parent, ScanItem* item, Instrume connect(inclinationEditor, &AlphaScanEditor::dataChanged, wavelengthEditor, &DistributionEditor::updateData); - connect(footprintEditor, &FootprintForm::dataChanged, this, &SpecularBeamEditor::dataChanged); + connect(footprintEditor, &FootprintForm::dataChanged, this, &ScanEditor::dataChanged); // validate value while typing connect(intensityLineEdit, &QLineEdit::textEdited, [=]() { diff --git a/GUI/View/Instrument/SpecularBeamEditor.h b/GUI/View/Instrument/ScanEditor.h similarity index 62% rename from GUI/View/Instrument/SpecularBeamEditor.h rename to GUI/View/Instrument/ScanEditor.h index 33c137960b2ab5bf4d7c49bdab4e6d29a04ef3c7..d542a467c0d38fc5bbe9365ba74d6f10bc37ca26 100644 --- a/GUI/View/Instrument/SpecularBeamEditor.h +++ b/GUI/View/Instrument/ScanEditor.h @@ -2,8 +2,8 @@ // // BornAgain: simulate and fit reflection and scattering // -//! @file GUI/View/Instrument/SpecularBeamEditor.h -//! @brief Defines class SpecularBeamEditor +//! @file GUI/View/Instrument/ScanEditor.h +//! @brief Defines class ScanEditor //! //! @homepage http://www.bornagainproject.org //! @license GNU General Public License v3 or higher (see COPYING) @@ -12,8 +12,8 @@ // // ************************************************************************************************ -#ifndef BORNAGAIN_GUI_VIEW_INSTRUMENT_SPECULARBEAMEDITOR_H -#define BORNAGAIN_GUI_VIEW_INSTRUMENT_SPECULARBEAMEDITOR_H +#ifndef BORNAGAIN_GUI_VIEW_INSTRUMENT_SCANEDITOR_H +#define BORNAGAIN_GUI_VIEW_INSTRUMENT_SCANEDITOR_H #include <QGroupBox> @@ -22,14 +22,14 @@ class InstrumentNotifier; //! Specular beam editor. Operates on ScanItem. -class SpecularBeamEditor : public QGroupBox { +class ScanEditor : public QGroupBox { Q_OBJECT public: - SpecularBeamEditor(QWidget* parent, ScanItem* item, InstrumentNotifier* ec); + ScanEditor(QWidget* parent, ScanItem* item, InstrumentNotifier* ec); signals: void dataChanged(); }; -#endif // BORNAGAIN_GUI_VIEW_INSTRUMENT_SPECULARBEAMEDITOR_H +#endif // BORNAGAIN_GUI_VIEW_INSTRUMENT_SCANEDITOR_H diff --git a/GUI/View/Instrument/SpecularInstrumentEditor.cpp b/GUI/View/Instrument/SpecularInstrumentEditor.cpp index 8efc66fcf4c58288757644cd541fb1ce528de8dd..5b8d9cce1948c80ae59a430b9d6ec8ac4c4a0fad 100644 --- a/GUI/View/Instrument/SpecularInstrumentEditor.cpp +++ b/GUI/View/Instrument/SpecularInstrumentEditor.cpp @@ -16,7 +16,7 @@ #include "GUI/Model/Device/InstrumentItems.h" #include "GUI/View/Device/BackgroundForm.h" #include "GUI/View/Instrument/PolarizationAnalysisEditor.h" -#include "GUI/View/Instrument/SpecularBeamEditor.h" +#include "GUI/View/Instrument/ScanEditor.h" SpecularInstrumentEditor::SpecularInstrumentEditor(QWidget* parent, SpecularInstrumentItem* instrument, @@ -28,8 +28,8 @@ SpecularInstrumentEditor::SpecularInstrumentEditor(QWidget* parent, auto* layout = new QVBoxLayout(this); layout->setContentsMargins(0, 0, 0, 0); - auto* beamEditor = new SpecularBeamEditor(this, instrument->scanItem(), &m_ec); - layout->addWidget(beamEditor); + auto* scanEditor = new ScanEditor(this, instrument->scanItem(), &m_ec); + layout->addWidget(scanEditor); auto* polMatricesAnalysisEditor = new PolarizationAnalysisEditor(this, instrument); layout->addWidget(polMatricesAnalysisEditor); @@ -39,8 +39,7 @@ SpecularInstrumentEditor::SpecularInstrumentEditor(QWidget* parent, layout->addStretch(); - connect(beamEditor, &SpecularBeamEditor::dataChanged, this, - &SpecularInstrumentEditor::dataChanged); + connect(scanEditor, &ScanEditor::dataChanged, this, &SpecularInstrumentEditor::dataChanged); connect(polMatricesAnalysisEditor, &PolarizationAnalysisEditor::dataChanged, this, &SpecularInstrumentEditor::dataChanged); connect(backgroundForm, &BackgroundForm::dataChanged, this, diff --git a/Tests/Unit/GUI/TestAutosaveController.cpp b/Tests/Unit/GUI/TestAutosaveController.cpp index d9ee8fdc09edd929378de4abcafb4f4a0bb1fa3f..1934ae9b4bb03753200fa33e715e3a1a6aa5667b 100644 --- a/Tests/Unit/GUI/TestAutosaveController.cpp +++ b/Tests/Unit/GUI/TestAutosaveController.cpp @@ -17,8 +17,7 @@ protected: void modify_models(ProjectDocument& doc) { auto* instrument = doc.instrumentModel()->instrumentItems().front(); - doc.instrumentsEditController()->setInstrumentName(instrument, - QUuid::createUuid().toString()); + doc.multiNotifier()->setInstrumentName(instrument, QUuid::createUuid().toString()); } const int m_save_wait = 10000; }; diff --git a/Tests/Unit/GUI/TestInstrumentItems.cpp b/Tests/Unit/GUI/TestInstrumentItems.cpp index 008761f4b6256f86906142401034a3fa4944f51a..5bbc0b4ec568164482f6b6785d192b682b40256c 100644 --- a/Tests/Unit/GUI/TestInstrumentItems.cpp +++ b/Tests/Unit/GUI/TestInstrumentItems.cpp @@ -11,17 +11,17 @@ TEST(TestInstrumentCollection, instrumentAddedRemoved) { ProjectDocument document; - QSignalSpy spy(document.instrumentsEditController(), SIGNAL(instrumentAddedOrRemoved())); + QSignalSpy spy(document.multiNotifier(), SIGNAL(instrumentAddedOrRemoved())); EXPECT_TRUE(spy.isValid()); // populating instrument model - auto* p = document.instrumentsEditController()->addInstrumentItem<GISASInstrumentItem>(); + auto* p = document.multiNotifier()->addInstrumentItem<GISASInstrumentItem>(); // checking that a signal was emitted about the new instrument EXPECT_EQ(spy.count(), 1); // removing instrument - document.instrumentsEditController()->removeInstrument(p); + document.multiNotifier()->removeInstrument(p); EXPECT_EQ(spy.count(), 2); } @@ -32,44 +32,40 @@ TEST(TestInstrumentCollection, instrumentChanged) ProjectDocument document; // populating instrument model - auto* instrument1 = - document.instrumentsEditController()->addInstrumentItem<GISASInstrumentItem>(); - auto* instrument2 = - document.instrumentsEditController()->addInstrumentItem<SpecularInstrumentItem>(); + auto* instrument1 = document.multiNotifier()->addInstrumentItem<GISASInstrumentItem>(); + auto* instrument2 = document.multiNotifier()->addInstrumentItem<SpecularInstrumentItem>(); - QSignalSpy spy(document.instrumentsEditController(), - SIGNAL(instrumentChanged(const InstrumentItem*))); + QSignalSpy spy(document.multiNotifier(), SIGNAL(instrumentChanged(const InstrumentItem*))); EXPECT_TRUE(spy.isValid()); // change name of instrument 1 - document.instrumentsEditController()->setInstrumentName(instrument1, "A"); + document.multiNotifier()->setInstrumentName(instrument1, "A"); EXPECT_EQ(spy.count(), 1); const auto* instr = qvariant_cast<const InstrumentItem*>(spy.at(0).at(0)); EXPECT_EQ(instr, instrument1); // change other properties, e.g. id instrument1->setId("xxxxx"); - document.instrumentsEditController()->notifyInstrumentChanged(instrument1); + document.multiNotifier()->notifyInstrumentChanged(instrument1); EXPECT_EQ(spy.count(), 2); // change name of instrument 2 - document.instrumentsEditController()->setInstrumentName(instrument2, "B"); + document.multiNotifier()->setInstrumentName(instrument2, "B"); EXPECT_EQ(spy.count(), 3); instr = qvariant_cast<const InstrumentItem*>(spy.at(2).at(0)); EXPECT_EQ(instr, instrument2); // Add another instrument - auto* instrument3 = - document.instrumentsEditController()->addInstrumentItem<OffspecInstrumentItem>(); + auto* instrument3 = document.multiNotifier()->addInstrumentItem<OffspecInstrumentItem>(); // Change instrument2 - document.instrumentsEditController()->setInstrumentName(instrument2, "BB"); + document.multiNotifier()->setInstrumentName(instrument2, "BB"); EXPECT_EQ(spy.count(), 4); instr = qvariant_cast<const InstrumentItem*>(spy.at(3).at(0)); EXPECT_EQ(instr, instrument2); // Change instrument3 - document.instrumentsEditController()->setInstrumentName(instrument3, "C"); + document.multiNotifier()->setInstrumentName(instrument3, "C"); EXPECT_EQ(spy.count(), 5); instr = qvariant_cast<const InstrumentItem*>(spy.at(4).at(0)); EXPECT_EQ(instr, instrument3); diff --git a/Tests/Unit/GUI/TestLinkInstrument.cpp b/Tests/Unit/GUI/TestLinkInstrument.cpp index 99bb0e121bd62aaa0806d08bb1e62ef3492c80d3..3a0a6894fb88c7bb7424d0edb67baa32040259b2 100644 --- a/Tests/Unit/GUI/TestLinkInstrument.cpp +++ b/Tests/Unit/GUI/TestLinkInstrument.cpp @@ -55,7 +55,7 @@ TEST(TestLinkInstrument, canLinkToInstrument) // changing detector binning and checking that link is destroyed auto* detectorItem = dynamic_cast<RectangularDetectorItem*>(instrument->detectorItem()); detectorItem->setXSize(10); - document.instrumentsEditController()->notifyInstrumentChanged(instrument); + document.multiNotifier()->notifyInstrumentChanged(instrument); EXPECT_EQ(linkedRealDataItems(*document.realModel(), instrument), QList<RealItem*>()); EXPECT_EQ(realData->instrumentId(), QString()); diff --git a/Tests/Unit/GUI/TestProjectDocument.cpp b/Tests/Unit/GUI/TestProjectDocument.cpp index 91cc0a6c739094b3c8c2685b2ccad40b3954bd51..043dbe4a5cdce763d0471013df95d811a948b6ab 100644 --- a/Tests/Unit/GUI/TestProjectDocument.cpp +++ b/Tests/Unit/GUI/TestProjectDocument.cpp @@ -19,8 +19,7 @@ protected: void modify_models(ProjectDocument& doc) { auto* instrument = doc.instrumentModel()->instrumentItems().front(); - doc.instrumentsEditController()->setInstrumentName(instrument, - QUuid::createUuid().toString()); + doc.multiNotifier()->setInstrumentName(instrument, QUuid::createUuid().toString()); } };