Skip to content
Snippets Groups Projects
BeamItems.cpp 6.35 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/Device/BeamItems.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 "Base/Axis/IAxis.h"
    
    Wuttke, Joachim's avatar
    Wuttke, Joachim committed
    #include "Base/Const/Units.h"
    
    #include "Device/Beam/Beam.h"
    
    Wuttke, Joachim's avatar
    Wuttke, Joachim committed
    #include "GUI/Model/CatDevice/FootprintItemCatalog.h"
    
    #include "GUI/Model/Device/BeamAngleItems.h"
    
    Mikhail Svechnikov's avatar
    Mikhail Svechnikov committed
    #include "GUI/Model/Device/BeamItems.h"
    
    #include "GUI/Model/Device/BeamWavelengthItem.h"
    #include "GUI/Model/Device/FootprintItems.h"
    #include "GUI/Model/Device/PointwiseAxisItem.h"
    
    #include "GUI/Support/XML/Serialize.h"
    
    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");
    
    }
    
    
    // defines wavelength limits according to given maximum q value
    
    RealLimits getLimits(double max_q)
    
        double upper_lim = std::nextafter(4.0 * M_PI / max_q, 0.0);
        RealLimits result = RealLimits::positive();
        result.setUpperLimit(upper_lim);
        return result;
    
    Pospelov, Gennady's avatar
    Pospelov, Gennady committed
    } // namespace
    
    BeamItem::BeamItem()
    
        m_intensity.init("Intensity", "Beam intensity in neutrons (or gammas) per sec.", 1e+08,
                         Unit::unitless, 3, RealLimits::limited(0.0, 1e+32), "intensity");
    
        m_azimuthalAngleItem.reset(new BeamAzimuthalAngleItem());
    
    void BeamItem::serialize(Streamer& s)
    
        s.assertVersion(0);
    
    Mikhail Svechnikov's avatar
    Mikhail Svechnikov committed
        Serialize::rwProperty(s, Tag::Intensity, m_intensity);
        Serialize::rwClass(s, Tag::Wavelength, *m_wavelengthItem);
        Serialize::rwClass(s, Tag::AzimuthalAngle, *m_azimuthalAngleItem);
        Serialize::rwClass(s, Tag::InclinationAngle, *m_inclinationAngleItem);
    
    double BeamItem::wavelength() const
    {
    
        return m_wavelengthItem->wavelength();
    
    void BeamItem::setWavelength(double value)
    {
    
        m_wavelengthItem->resetToValue(value);
    
    BeamWavelengthItem* BeamItem::wavelengthItem() const
    {
    
        return m_wavelengthItem.get();
    
    void BeamItem::setInclinationAngle(double value)
    {
    
        m_inclinationAngleItem->resetToValue(value);
    
    BeamDistributionItem* BeamItem::inclinationAngleItem() const
    {
    
        return m_inclinationAngleItem.get();
    
    double BeamItem::getAzimuthalAngle() const
    {
    
        return m_azimuthalAngleItem->azimuthalAngle();
    
    void BeamItem::setAzimuthalAngle(double value)
    {
    
        m_azimuthalAngleItem->resetToValue(value);
    
    BeamAzimuthalAngleItem* BeamItem::azimuthalAngleItem() const
    {
    
        return m_azimuthalAngleItem.get();
    
    std::shared_ptr<Beam> BeamItem::createBeam() const
    
        double lambda = wavelength();
    
        double inclination_angle = Units::deg2rad(getInclinationAngle());
        double azimuthal_angle = Units::deg2rad(getAzimuthalAngle());
    
    Wuttke, Joachim's avatar
    Wuttke, Joachim committed
        auto result =
    
            std::make_shared<Beam>(intensity(), lambda, Direction(inclination_angle, azimuthal_angle));
    
    Pospelov, Gennady's avatar
    Pospelov, Gennady committed
        return result;
    
    Wuttke, Joachim's avatar
    Wuttke, Joachim committed
    template <typename T>
    void BeamItem::initWavelength()
    
        m_wavelengthItem.reset(new T());
    
    Wuttke, Joachim's avatar
    Wuttke, Joachim committed
    template <typename T>
    void BeamItem::initInclinationAngle()
    
        m_inclinationAngleItem.reset(new T());
    
    // Specular beam item
    /* ------------------------------------------------------------------------- */
    
    
    SpecularBeamItem::SpecularBeamItem(const InstrumentItem* owningInstrument)
    
        m_inclinationAngleItem.reset(new SpecularBeamInclinationItem(owningInstrument));
    
        initWavelength<SpecularBeamWavelengthItem>();
    
        m_footprint.init<FootprintItemCatalog>("Type", "Footprint type", "footprint");
    
    void SpecularBeamItem::serialize(Streamer& s)
    
    {
        s.assertVersion(0);
    
        Serialize::rwBaseClass<BeamItem>(s, "BeamItem", this);
    
        Serialize::rwSelected<FootprintItemCatalog>(s, m_footprint);
    
    double SpecularBeamItem::getInclinationAngle() const
    {
    
    Yurov, Dmitry's avatar
    Yurov, Dmitry committed
        return 0.0;
    }
    
    
    void SpecularBeamItem::setInclinationAngle(double value)
    {
    
        ASSERT(value == 0.0);
    
    Yurov, Dmitry's avatar
    Yurov, Dmitry committed
        value = 0.0;
        BeamItem::setInclinationAngle(value);
    }
    
    
    SpecularBeamInclinationItem* SpecularBeamItem::inclinationAngleItem() const
    {
    
        return dynamic_cast<SpecularBeamInclinationItem*>(BeamItem::inclinationAngleItem());
    
    BasicAxisItem* SpecularBeamItem::inclinationAxis() const
    
        return inclinationAngleItem()->alphaAxis();
    
    FootprintItem* SpecularBeamItem::footprint() const
    
        return m_footprint.get();
    
    Matthias Puchner's avatar
    Matthias Puchner committed
    SelectionDescriptor<FootprintItem*> SpecularBeamItem::footprintSelection() const
    {
    
        return m_footprint;
    
    Matthias Puchner's avatar
    Matthias Puchner committed
    }
    
    
    void SpecularBeamItem::setGaussianFootprint(double value)
    {
    
        m_footprint.set(new FootprintGaussianItem(value));
    
    }
    
    void SpecularBeamItem::setSquareFootprint(double value)
    {
    
        m_footprint.set(new FootprintSquareItem(value));
    
    void SpecularBeamItem::updateToData(const IAxis& axis, QString units)
    
            inclinationAngleItem()->initUniformAxis(axis);
            inclinationAngleItem()->selectUniformAxis();
        } else {
            inclinationAngleItem()->initPointwiseAxis(axis, units);
            inclinationAngleItem()->selectPointwiseAxis();
    
        updateWavelength();
    
    void SpecularBeamItem::updateWavelength()
    {
    
        auto* item = inclinationAngleItem()->alphaAxis();
        auto* wavelength = dynamic_cast<SpecularBeamWavelengthItem*>(wavelengthItem());
        if (auto* pointwiseAxis = dynamic_cast<PointwiseAxisItem*>(item)) {
            const auto* axis = pointwiseAxis->axis();
            if (axis && pointwiseAxis->getUnitsLabel() == "q-space")
    
                wavelength->setToRange(getLimits(axis->max()));
    
            wavelength->setToRange(RealLimits::positive());
    
    // GISAS beam item
    /* ------------------------------------------------------------------------- */
    
    
    GISASBeamItem::GISASBeamItem()
    
        initInclinationAngle<BeamInclinationAngleItem>();
    
        initWavelength<BeamWavelengthItem>();
    
    double GISASBeamItem::getInclinationAngle() const
    {
    
        return m_inclinationAngleGetter
                   ? m_inclinationAngleGetter()
                   : dynamic_cast<BeamInclinationAngleItem*>(inclinationAngleItem())
                         ->inclinationAngle();
    }
    
    void GISASBeamItem::setInclinationAngleGetter(std::function<double()> getter)
    {
        m_inclinationAngleGetter = getter;
    
    Yurov, Dmitry's avatar
    Yurov, Dmitry committed
    }