Newer
Older
// ************************************************************************************************
// BornAgain: simulate and fit reflection and scattering
//! @file GUI/Model/Beam/SourceItems.cpp
//! @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 AzimuthalAngle("AzimuthalAngle");
const QString ExpandBeamParametersGroupbox("ExpandBeamParametersGroupbox");
const QString ExpandFootprintGroupbox("ExpandFootprintGroupbox");
const QString Footprint("Footprint");
const QString GrazingScan("GrazingScan");
const QString InclinationAngle("InclinationAngle");
const QString Intensity("Intensity");
const QString Wavelength("Wavelength");
// ************************************************************************************************
// ************************************************************************************************
m_intensity.init("Intensity", "Beam intensity in neutrons/photons per sec.", 1e8, 3,
RealLimits::limited(0.0, 1e32), "intensity");
Pospelov, Gennady
committed
m_azimuthal_angle_item = std::make_unique<BeamAzimuthalAngleItem>();
m_footprint.initWithArgs("Type", "Footprint type", FootprintItemCatalog::Type::Gaussian);
Pospelov, Gennady
committed
}
void SourceItem::writeTo(QXmlStreamWriter* w) const
XML::writeAttribute(w, XML::Attrib::version, uint(2));
XML::writeTaggedElement(w, Tag::Wavelength, *m_wavelength_item);
XML::writeTaggedElement(w, Tag::AzimuthalAngle, *m_azimuthal_angle_item);
XML::writeTaggedValue(w, Tag::ExpandBeamParametersGroupbox, expandBeamParameters);
XML::writeTaggedElement(w, Tag::Footprint, m_footprint);
XML::writeTaggedValue(w, Tag::ExpandFootprintGroupbox, expandFootprint);
void SourceItem::readFrom(QXmlStreamReader* r)
const uint version = XML::readUInt(r, XML::Attrib::version);
Q_UNUSED(version)
while (r->readNextStartElement()) {
QString tag = r->name().toString();
if (tag == Tag::Intensity) {
} else if (tag == Tag::Wavelength)
XML::readTaggedElement(r, tag, *m_wavelength_item);
else if (tag == Tag::AzimuthalAngle)
XML::readTaggedElement(r, tag, *m_azimuthal_angle_item);
else if (tag == Tag::ExpandBeamParametersGroupbox)
else if (tag == Tag::Footprint)
XML::readTaggedElement(r, tag, m_footprint);
else if (tag == Tag::ExpandFootprintGroupbox)
expandFootprint = XML::readTaggedBool(r, tag);
else
double SourceItem::wavelength() const
ASSERT(m_wavelength_item);
return m_wavelength_item->wavelength();
Pospelov, Gennady
committed
}
void SourceItem::setWavelength(double value)
ASSERT(m_wavelength_item);
m_wavelength_item->resetToValue(value);
Pospelov, Gennady
committed
}
BeamWavelengthItem* SourceItem::wavelengthItem() const
ASSERT(m_wavelength_item);
return m_wavelength_item.get();
double SourceItem::azimuthalAngle() const
ASSERT(m_azimuthal_angle_item);
return m_azimuthal_angle_item->azimuthalAngle();
Pospelov, Gennady
committed
}
void SourceItem::setAzimuthalAngle(double value)
ASSERT(m_azimuthal_angle_item);
m_azimuthal_angle_item->resetToValue(value);
Pospelov, Gennady
committed
}
BeamAzimuthalAngleItem* SourceItem::azimuthalAngleItem() const
ASSERT(m_azimuthal_angle_item);
return m_azimuthal_angle_item.get();
void SourceItem::setGaussianFootprint(double value)
{
m_footprint.setCertainItem(new FootprintGaussianItem(value));
}
void SourceItem::setSquareFootprint(double value)
{
m_footprint.setCertainItem(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_wavelength_item = std::make_unique<BeamWavelengthItem>();
m_inclination_angle_item = std::make_unique<BeamInclinationAngleItem>();
void BeamItem::writeTo(QXmlStreamWriter* w) const
{
XML::writeAttribute(w, XML::Attrib::version, uint(1));
XML::writeTaggedElement(w, Tag::InclinationAngle, *m_inclination_angle_item);
}
void BeamItem::readFrom(QXmlStreamReader* r)
{
const uint version = XML::readUInt(r, XML::Attrib::version);
while (r->readNextStartElement()) {
QString tag = r->name().toString();
if (tag == Tag::BaseData)
XML::readBaseElement<SourceItem>(r, this);
else if (tag == Tag::InclinationAngle)
XML::readTaggedElement(r, tag, *m_inclination_angle_item);
void BeamItem::setInclinationAngle(double value)
{
ASSERT(m_inclination_angle_item);
m_inclination_angle_item->resetToValue(value);
BeamDistributionItem* BeamItem::beamDistributionItem() const
{
ASSERT(m_inclination_angle_item);
return m_inclination_angle_item.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().dVal(), lambda, inclination_angle, azimuthal_angle);
result->setFootprint(m_footprint.certainItem()->createFootprint().get());
// ************************************************************************************************
// ScanItem
// ************************************************************************************************
m_grazing_scan_item = std::make_unique<GrazingScanItem>();
m_wavelength_item = std::make_unique<BeamWavelengthItem>(true);
void ScanItem::setScan(const BeamScan* scan)
if (const auto* s = dynamic_cast<const AlphaScan*>(scan))
// 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));
XML::writeTaggedElement(w, Tag::GrazingScan, *m_grazing_scan_item);
void ScanItem::readFrom(QXmlStreamReader* r)
const uint version = XML::readUInt(r, XML::Attrib::version);
while (r->readNextStartElement()) {
QString tag = r->name().toString();
if (tag == Tag::BaseData)
XML::readBaseElement<SourceItem>(r, this);
else if (version == 1 && tag == Tag::Footprint)
XML::readTaggedElement(r, tag, m_footprint);
else if (version == 1 && tag == Tag::ExpandFootprintGroupbox)
else if (tag == Tag::GrazingScan)
XML::readTaggedElement(r, tag, *m_grazing_scan_item);
else
GrazingScanItem* ScanItem::grazingScanItem() const
{
BasicAxisItem* ScanItem::inclinationAxisItem() const
grazingScanItem()->initUniformAxis(axis);
grazingScanItem()->selectUniformAxis();
grazingScanItem()->selectListScan();