Newer
Older
// ************************************************************************************************
// BornAgain: simulate and fit reflection and scattering
//! @file GUI/Model/Beam/SourceItems.cpp
//! @brief Implements BeamItem hierarchy
//! @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/Model/Beam/SourceItems.h"
#include "Device/Beam/FootprintGauss.h"
#include "Device/Beam/FootprintSquare.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"
#include "Sim/Scan/AlphaScan.h"
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");
const QString ExpandBeamParametersGroupbox("ExpandBeamParametersGroupbox");
const QString ExpandFootprintGroupbox("ExpandFootprintGroupbox");
// ************************************************************************************************
// ************************************************************************************************
m_intensity.init("Intensity", "Beam intensity in neutrons/photons per sec.", 1e8, 3,
RealLimits::limited(0.0, 1e32), "intensity");
Pospelov, Gennady
committed
m_azimuthalAngleItem.reset(new BeamAzimuthalAngleItem());
m_footprint.init("Type", "Footprint type");
Pospelov, Gennady
committed
}
void SourceItem::writeTo(QXmlStreamWriter* w) const
XML::writeAttribute(w, XML::Attrib::version, uint(2));
// 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);
// 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);
void SourceItem::readFrom(QXmlStreamReader* r)
{
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);
double SourceItem::wavelength() const
ASSERT(m_wavelengthItem);
return m_wavelengthItem->wavelength();
Pospelov, Gennady
committed
}
void SourceItem::setWavelength(double value)
ASSERT(m_wavelengthItem);
m_wavelengthItem->resetToValue(value);
Pospelov, Gennady
committed
}
BeamWavelengthItem* SourceItem::wavelengthItem() const
ASSERT(m_wavelengthItem);
double SourceItem::azimuthalAngle() const
ASSERT(m_azimuthalAngleItem);
return m_azimuthalAngleItem->azimuthalAngle();
Pospelov, Gennady
committed
}
void SourceItem::setAzimuthalAngle(double value)
ASSERT(m_azimuthalAngleItem);
m_azimuthalAngleItem->resetToValue(value);
Pospelov, Gennady
committed
}
BeamAzimuthalAngleItem* SourceItem::azimuthalAngleItem() const
ASSERT(m_azimuthalAngleItem);
void SourceItem::setGaussianFootprint(double value)
{
m_footprint.setCurrentItem(new FootprintGaussianItem(value));
}
void SourceItem::setSquareFootprint(double value)
{
m_footprint.setCurrentItem(new FootprintSquareItem(value));
}
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
// ************************************************************************************************
{
m_wavelengthItem.reset(new BeamWavelengthItem);
m_inclinationAngleItem.reset(new BeamInclinationAngleItem);
}
void BeamItem::writeTo(QXmlStreamWriter* w) const
{
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)
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);
} 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();
}
{
double lambda = wavelength();
double inclination_angle = Units::deg2rad(getInclinationAngle());
double azimuthal_angle = Units::deg2rad(azimuthalAngle());
auto result = std::make_unique<Beam>(intensity(), lambda, inclination_angle, azimuthal_angle);
result->setFootprint(m_footprint.currentItem()->createFootprint().get());
return result;
// ************************************************************************************************
// 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());
// TODO do we need to check that axis is equidistant?
axis_item->resize(static_cast<int>(axis->size()));
axis_item->setMin(axis->min() / Units::deg);
axis_item->setMax(axis->max() / Units::deg);
void ScanItem::writeTo(QXmlStreamWriter* w) const
XML::writeAttribute(w, XML::Attrib::version, uint(2));
// parameters from base class
w->writeStartElement(Tag::BaseData);
// grazing scan
w->writeStartElement(Tag::GrazingScan);
m_grazingScanItem->writeTo(w);
w->writeEndElement();
void ScanItem::readFrom(QXmlStreamReader* r)
{
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);
// footprint (moved to base class since v21 (version == 2))
} else if (version == 1 && tag == Tag::Footprint) {
m_footprint.readFrom(r);
XML::gotoEndElementOfTag(r, tag);
// 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);
GrazingScanItem* ScanItem::grazingScanItem() const
{
BasicAxisItem* ScanItem::inclinationAxisItem() const
void ScanItem::updateToData(const Scale& axis, QString units, const Frame& frame)
grazingScanItem()->initUniformAxis(axis);
grazingScanItem()->selectUniformAxis();
grazingScanItem()->initListScan(axis, units, frame);
grazingScanItem()->selectListScan();