Skip to content
Snippets Groups Projects
SourceItems.cpp 10.9 KiB
Newer Older
  • Learn to ignore specific revisions
  • //  ************************************************************************************************
    
    Pospelov, Gennady's avatar
    Pospelov, Gennady committed
    //
    
    //  BornAgain: simulate and fit reflection and scattering
    
    Pospelov, Gennady's avatar
    Pospelov, Gennady committed
    //
    
    //! @file      GUI/Model/Beam/SourceItems.cpp
    
    //! @brief     Implements BeamItem hierarchy
    
    Pospelov, Gennady's avatar
    Pospelov, Gennady committed
    //!
    
    //! @homepage  http://www.bornagainproject.org
    
    Pospelov, Gennady's avatar
    Pospelov, Gennady committed
    //! @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)
    
    Pospelov, Gennady's avatar
    Pospelov, Gennady committed
    //
    
    //  ************************************************************************************************
    
    Pospelov, Gennady's avatar
    Pospelov, Gennady committed
    
    
    #include "GUI/Model/Beam/SourceItems.h"
    
    #include "Base/Axis/Scale.h"
    
    Wuttke, Joachim's avatar
    Wuttke, Joachim committed
    #include "Base/Const/Units.h"
    
    Mikhail Svechnikov's avatar
    Mikhail Svechnikov committed
    #include "Base/Util/Assert.h"
    
    #include "Device/Beam/Beam.h"
    
    #include "Device/Beam/FootprintGauss.h"
    #include "Device/Beam/FootprintSquare.h"
    
    #include "GUI/Model/Axis/PointwiseAxisItem.h"
    
    #include "GUI/Model/Beam/BeamAngleItems.h"
    #include "GUI/Model/Beam/BeamWavelengthItem.h"
    #include "GUI/Model/Beam/FootprintItems.h"
    #include "GUI/Model/Beam/GrazingScanItem.h"
    
    Wuttke, Joachim's avatar
    ..  
    Wuttke, Joachim committed
    
    
    namespace {
    
    Mikhail Svechnikov's avatar
    Mikhail Svechnikov committed
    namespace Tag {
    
    const QString Intensity("Intensity");
    const QString Wavelength("Wavelength");
    const QString AzimuthalAngle("AzimuthalAngle");
    const QString InclinationAngle("InclinationAngle");
    
    const QString GrazingScan("GrazingScan");
    
    const QString Footprint("Footprint");
    
    Mikhail Svechnikov's avatar
    Mikhail Svechnikov committed
    const QString BaseData("BaseData");
    
    const QString ExpandBeamParametersGroupbox("ExpandBeamParametersGroupbox");
    const QString ExpandFootprintGroupbox("ExpandFootprintGroupbox");
    
    Mikhail Svechnikov's avatar
    Mikhail Svechnikov committed
    
    
    Mikhail Svechnikov's avatar
    Mikhail Svechnikov committed
    } // namespace Tag
    
    Mikhail Svechnikov's avatar
    Mikhail Svechnikov committed
    
    
    Pospelov, Gennady's avatar
    Pospelov, Gennady committed
    } // namespace
    
    //  ************************************************************************************************
    
    //  ************************************************************************************************
    
    
    SourceItem::SourceItem()
    
        m_intensity.init("Intensity", "Beam intensity in neutrons/photons per sec.", 1e8, 3,
                         RealLimits::limited(0.0, 1e32), "intensity");
    
        m_azimuthalAngleItem.reset(new BeamAzimuthalAngleItem());
    
        m_footprint.init("Type", "Footprint type");
    
    void SourceItem::writeTo(QXmlStreamWriter* w) const
    
    Mikhail Svechnikov's avatar
    Mikhail Svechnikov committed
    {
        ASSERT(m_wavelengthItem);
    
    
        XML::writeAttribute(w, XML::Attrib::version, uint(2));
    
    Mikhail Svechnikov's avatar
    Mikhail Svechnikov committed
    
        // intensity
        w->writeStartElement(Tag::Intensity);
        m_intensity.writeTo(w);
        w->writeEndElement();
    
        // wavelength
        w->writeStartElement(Tag::Wavelength);
        m_wavelengthItem->writeTo(w);
        w->writeEndElement();
    
        // azimuthal angle
        w->writeStartElement(Tag::AzimuthalAngle);
        m_azimuthalAngleItem->writeTo(w);
        w->writeEndElement();
    
    
        // beam parameters groupbox: is expanded?
        w->writeStartElement(Tag::ExpandBeamParametersGroupbox);
    
        XML::writeAttribute(w, XML::Attrib::value, expandBeamParameters);
    
        w->writeEndElement();
    
    
        // footprint
        w->writeStartElement(Tag::Footprint);
        m_footprint.writeTo(w);
        w->writeEndElement();
    
        // footprint groupbox: is expanded?
        w->writeStartElement(Tag::ExpandFootprintGroupbox);
    
        XML::writeAttribute(w, XML::Attrib::value, expandFootprint);
    
        w->writeEndElement();
    
    void SourceItem::readFrom(QXmlStreamReader* r)
    
    Mikhail Svechnikov's avatar
    Mikhail Svechnikov committed
    {
        ASSERT(m_wavelengthItem);
    
        const uint version = XML::readUIntAttribute(r, XML::Attrib::version);
        Q_UNUSED(version)
    
        while (r->readNextStartElement()) {
            QString tag = r->name().toString();
    
            // intensity
            if (tag == Tag::Intensity) {
                m_intensity.readFrom(r);
                XML::gotoEndElementOfTag(r, tag);
    
                // wavelength
            } else if (tag == Tag::Wavelength) {
                m_wavelengthItem->readFrom(r);
                XML::gotoEndElementOfTag(r, tag);
    
                // azimuthal angle
            } else if (tag == Tag::AzimuthalAngle) {
                m_azimuthalAngleItem->readFrom(r);
                XML::gotoEndElementOfTag(r, tag);
    
    
                // beam parameters groupbox: is expanded?
            } else if (tag == Tag::ExpandBeamParametersGroupbox) {
    
                XML::readAttribute(r, XML::Attrib::value, &expandBeamParameters);
    
                XML::gotoEndElementOfTag(r, tag);
    
    
                // footprint
            } else if (tag == Tag::Footprint) {
                m_footprint.readFrom(r);
                XML::gotoEndElementOfTag(r, tag);
    
                // footprint groupbox: is expanded?
            } else if (tag == Tag::ExpandFootprintGroupbox) {
    
                XML::readAttribute(r, XML::Attrib::value, &expandFootprint);
    
                XML::gotoEndElementOfTag(r, tag);
    
    Mikhail Svechnikov's avatar
    Mikhail Svechnikov committed
            } else
                r->skipCurrentElement();
        }
    
    double SourceItem::wavelength() const
    
        ASSERT(m_wavelengthItem);
    
        return m_wavelengthItem->wavelength();
    
    void SourceItem::setWavelength(double value)
    
        ASSERT(m_wavelengthItem);
    
        m_wavelengthItem->resetToValue(value);
    
    BeamWavelengthItem* SourceItem::wavelengthItem() const
    
        ASSERT(m_wavelengthItem);
    
        return m_wavelengthItem.get();
    
    double SourceItem::azimuthalAngle() const
    
        ASSERT(m_azimuthalAngleItem);
    
        return m_azimuthalAngleItem->azimuthalAngle();
    
    void SourceItem::setAzimuthalAngle(double value)
    
        ASSERT(m_azimuthalAngleItem);
    
        m_azimuthalAngleItem->resetToValue(value);
    
    BeamAzimuthalAngleItem* SourceItem::azimuthalAngleItem() const
    
        ASSERT(m_azimuthalAngleItem);
    
        return m_azimuthalAngleItem.get();
    
    
    void SourceItem::setGaussianFootprint(double value)
    {
        m_footprint.setCurrentItem(new FootprintGaussianItem(value));
    }
    
    void SourceItem::setSquareFootprint(double value)
    {
        m_footprint.setCurrentItem(new FootprintSquareItem(value));
    }
    
    
    Mikhail Svechnikov's avatar
    Mikhail Svechnikov committed
    void SourceItem::setFootprint(const IFootprint* footprint)
    
    {
        if (!footprint)
            return;
    
        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());
    }
    
    
    //  ************************************************************************************************
    
    //  BeamItem
    //  ************************************************************************************************
    
    
    Wuttke, Joachim's avatar
    Wuttke, Joachim committed
    BeamItem::BeamItem()
    
    {
        m_wavelengthItem.reset(new BeamWavelengthItem);
        m_inclinationAngleItem.reset(new BeamInclinationAngleItem);
    }
    
    
    Wuttke, Joachim's avatar
    Wuttke, Joachim committed
    void BeamItem::writeTo(QXmlStreamWriter* w) const
    {
    
        ASSERT(m_inclinationAngleItem);
    
    Wuttke, Joachim's avatar
    Wuttke, Joachim committed
        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();
    
    Wuttke, Joachim's avatar
    Wuttke, Joachim committed
    }
    
    void BeamItem::readFrom(QXmlStreamReader* r)
    {
        const uint version = XML::readUIntAttribute(r, XML::Attrib::version);
        Q_UNUSED(version)
    
    Wuttke, Joachim's avatar
    Wuttke, Joachim committed
        ASSERT(m_inclinationAngleItem);
    
    Wuttke, Joachim's avatar
    Wuttke, Joachim committed
    
        while (r->readNextStartElement()) {
            QString tag = r->name().toString();
    
            // parameters from base class
            if (tag == Tag::BaseData) {
                SourceItem::readFrom(r);
                XML::gotoEndElementOfTag(r, tag);
    
    
                // inclination angle
            } else if (tag == Tag::InclinationAngle) {
                m_inclinationAngleItem->readFrom(r);
                XML::gotoEndElementOfTag(r, tag);
    
    
    Wuttke, Joachim's avatar
    Wuttke, Joachim committed
            } else
                r->skipCurrentElement();
        }
    }
    
    
    void BeamItem::setInclinationAngle(double value)
    {
        ASSERT(m_inclinationAngleItem);
        m_inclinationAngleItem->resetToValue(value);
    }
    
    
    Wuttke, Joachim's avatar
    Wuttke, Joachim committed
    BeamDistributionItem* BeamItem::beamDistributionItem() const
    {
        ASSERT(m_inclinationAngleItem);
        return m_inclinationAngleItem.get();
    }
    
    
    double BeamItem::getInclinationAngle() const
    {
        return dynamic_cast<BeamInclinationAngleItem*>(beamDistributionItem())->inclinationAngle();
    }
    
    
    Wuttke, Joachim's avatar
    Wuttke, Joachim committed
    std::unique_ptr<Beam> BeamItem::createBeam() const
    
    Wuttke, Joachim's avatar
    Wuttke, Joachim committed
    {
        double lambda = wavelength();
        double inclination_angle = Units::deg2rad(getInclinationAngle());
        double azimuthal_angle = Units::deg2rad(azimuthalAngle());
    
    
    Wuttke, Joachim's avatar
    Wuttke, Joachim committed
        auto result = std::make_unique<Beam>(intensity(), lambda, inclination_angle, azimuthal_angle);
    
        result->setFootprint(m_footprint.currentItem()->createFootprint().get());
        return result;
    
    //  ************************************************************************************************
    //  ScanItem
    
    //  ************************************************************************************************
    
    ScanItem::ScanItem()
    
        m_grazingScanItem.reset(new GrazingScanItem());
    
        m_wavelengthItem.reset(new BeamWavelengthItem(true));
    
    void ScanItem::setScan(const BeamScan* scan)
    
    {
        setIntensity(scan->intensity());
    
        if (const auto* s = dynamic_cast<const AlphaScan*>(scan))
            setWavelength(s->wavelength());
    
        setAzimuthalAngle(0.0);
    
    Wuttke, Joachim's avatar
    Wuttke, Joachim committed
    
        auto* axis_item = inclinationAxisItem();
    
        const Scale* axis = scan->coordinateAxis();
    
    Wuttke, Joachim's avatar
    Wuttke, Joachim committed
        ASSERT(axis);
    
        // TODO do we need to check that axis is equidistant?
    
        axis_item->resize(static_cast<int>(axis->size()));
    
    Wuttke, Joachim's avatar
    Wuttke, Joachim committed
        axis_item->setMin(axis->min() / Units::deg);
        axis_item->setMax(axis->max() / Units::deg);
    
        setFootprint(scan->footprint());
    
    void ScanItem::writeTo(QXmlStreamWriter* w) const
    
        XML::writeAttribute(w, XML::Attrib::version, uint(2));
    
    Mikhail Svechnikov's avatar
    Mikhail Svechnikov committed
    
        // parameters from base class
        w->writeStartElement(Tag::BaseData);
    
        SourceItem::writeTo(w);
    
    Mikhail Svechnikov's avatar
    Mikhail Svechnikov committed
        w->writeEndElement();
    
    
        // grazing scan
        w->writeStartElement(Tag::GrazingScan);
        m_grazingScanItem->writeTo(w);
        w->writeEndElement();
    
    void ScanItem::readFrom(QXmlStreamReader* r)
    
    Mikhail Svechnikov's avatar
    Mikhail Svechnikov committed
    {
        const uint version = XML::readUIntAttribute(r, XML::Attrib::version);
    
        while (r->readNextStartElement()) {
            QString tag = r->name().toString();
    
            // parameters from base class
            if (tag == Tag::BaseData) {
    
                SourceItem::readFrom(r);
    
    Mikhail Svechnikov's avatar
    Mikhail Svechnikov committed
                XML::gotoEndElementOfTag(r, tag);
    
    
    Mikhail Svechnikov's avatar
    Mikhail Svechnikov committed
                // footprint (moved to base class since v21 (version == 2))
    
            } else if (version == 1 && tag == Tag::Footprint) {
    
    Mikhail Svechnikov's avatar
    Mikhail Svechnikov committed
                m_footprint.readFrom(r);
                XML::gotoEndElementOfTag(r, tag);
    
    
    Mikhail Svechnikov's avatar
    Mikhail Svechnikov committed
                // footprint groupbox: is expanded? (moved to base class since v21 (version == 2))
    
            } else if (version == 1 && tag == Tag::ExpandFootprintGroupbox) {
    
                XML::readAttribute(r, XML::Attrib::value, &expandFootprint);
    
                XML::gotoEndElementOfTag(r, tag);
    
    
                // grazing scan
            } else if (tag == Tag::GrazingScan) {
                m_grazingScanItem->readFrom(r);
                XML::gotoEndElementOfTag(r, tag);
    
    
    Mikhail Svechnikov's avatar
    Mikhail Svechnikov committed
            } else
                r->skipCurrentElement();
        }
    
    GrazingScanItem* ScanItem::grazingScanItem() const
    {
    
    Wuttke, Joachim's avatar
    Wuttke, Joachim committed
        return m_grazingScanItem.get();
    
    BasicAxisItem* ScanItem::inclinationAxisItem() const
    
    Wuttke, Joachim's avatar
    Wuttke, Joachim committed
        return grazingScanItem()->alphaAxisItem();
    
    void ScanItem::updateToData(const Scale& axis, QString units, const Frame& frame)
    
        if (units == "bin") {
    
    Wuttke, Joachim's avatar
    Wuttke, Joachim committed
            grazingScanItem()->initUniformAxis(axis);
            grazingScanItem()->selectUniformAxis();
    
            grazingScanItem()->initListScan(axis, units, frame);
    
            grazingScanItem()->selectListScan();