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));
w->writeEndElement();
w->writeStartElement(Tag::AzimuthalAngle);
w->writeStartElement(Tag::ExpandBeamParametersGroupbox);
XML::writeAttribute(w, XML::Attrib::value, expandBeamParameters);
w->writeStartElement(Tag::Footprint);
m_footprint.writeTo(w);
w->writeEndElement();
w->writeStartElement(Tag::ExpandFootprintGroupbox);
XML::writeAttribute(w, XML::Attrib::value, 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) {
XML::gotoEndElementOfTag(r, tag);
} else if (tag == Tag::AzimuthalAngle) {
m_azimuthal_angle_item->readFrom(r);
} else if (tag == Tag::ExpandBeamParametersGroupbox) {
expandBeamParameters = XML::readBool(r, XML::Attrib::value);
XML::gotoEndElementOfTag(r, tag);
} else if (tag == Tag::Footprint) {
m_footprint.readFrom(r);
XML::gotoEndElementOfTag(r, tag);
} else if (tag == Tag::ExpandFootprintGroupbox) {
expandFootprint = XML::readBool(r, XML::Attrib::value);
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));
w->writeStartElement(Tag::BaseData);
SourceItem::writeTo(w);
w->writeEndElement();
w->writeStartElement(Tag::InclinationAngle);
m_inclination_angle_item->writeTo(w);
}
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) {
SourceItem::readFrom(r);
XML::gotoEndElementOfTag(r, tag);
} else if (tag == Tag::InclinationAngle) {
m_inclination_angle_item->readFrom(r);
XML::gotoEndElementOfTag(r, tag);
} else
r->skipCurrentElement();
}
}
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));
w->writeStartElement(Tag::GrazingScan);
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) {
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) {
expandFootprint = XML::readBool(r, XML::Attrib::value);
XML::gotoEndElementOfTag(r, tag);
} else if (tag == Tag::GrazingScan) {
XML::gotoEndElementOfTag(r, tag);
GrazingScanItem* ScanItem::grazingScanItem() const
{
BasicAxisItem* ScanItem::inclinationAxisItem() const
grazingScanItem()->initUniformAxis(axis);
grazingScanItem()->selectUniformAxis();
grazingScanItem()->selectListScan();