Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • c.trageser/bornagain
  • mlz/bornagain
2 results
Show changes
Commits on Source (19)
Showing
with 149 additions and 46 deletions
......@@ -13,6 +13,7 @@
// ************************************************************************************************
#include "Base/Axis/Scale.h"
#include "Base/Const/Units.h"
#include "Base/Util/Assert.h"
#include "Base/Util/StringUtil.h"
#include <iomanip>
......@@ -63,6 +64,11 @@ std::string Scale::axisLabel() const
return m_coord->label();
}
std::string Scale::coordName() const
{
return Coordinate(axisLabel()).name();
}
std::string Scale::unit() const
{
return Coordinate(axisLabel()).unit();
......@@ -222,8 +228,7 @@ Scale Scale::plottableScale() const
{
ASSERT(m_coord);
if (m_coord->unit() == "rad")
return transformedScale(Coordinate(m_coord->name(), "deg").label(),
[](double x) { return x * 180 / pi; });
return transformedScale(Coordinate(m_coord->name(), "deg").label(), Units::rad2deg);
return {m_coord->label(), m_bins};
}
......
......@@ -80,6 +80,7 @@ public:
friend std::ostream& operator<<(std::ostream& ostr, const Scale& ax);
std::string coordName() const;
std::string unit() const;
Scale plottableScale() const;
......
// ************************************************************************************************
//
// BornAgain: simulate and fit reflection and scattering
//
//! @file Base/Util/ConversionUtil.cpp
//! @brief Implements namespace Conversion.
//!
//! @homepage http://www.bornagainproject.org
//! @license GNU General Public License v3 or higher (see COPYING)
//! @copyright Forschungszentrum Jülich GmbH 2023
//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS)
//
// ************************************************************************************************
#include "Base/Util/ConversionUtil.h"
#include <cmath>
#include <numbers>
using std::numbers::pi;
double Convert::Refl::qz2alpha(double lambda, double qz)
{
return std::asin(qz * lambda / 4 / pi);
}
double Convert::Refl::qz2lambda(double alpha, double qz)
{
return 4 * pi * std::sin(alpha) / qz;
}
double Convert::Refl::qz(double alpha, double lambda)
{
return qz2lambda(alpha, lambda);
}
// ************************************************************************************************
//
// BornAgain: simulate and fit reflection and scattering
//
//! @file Base/Util/ConversionUtil.h
//! @brief Implements namespace Conversion.
//!
//! @homepage http://www.bornagainproject.org
//! @license GNU General Public License v3 or higher (see COPYING)
//! @copyright Forschungszentrum Jülich GmbH 2023
//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS)
//
// ************************************************************************************************
#ifndef BORNAGAIN_BASE_UTIL_CONVERSIONUTIL_H
#define BORNAGAIN_BASE_UTIL_CONVERSIONUTIL_H
namespace Convert::Refl {
double qz2alpha(double lambda, double qz);
double qz2lambda(double alpha, double qz);
double qz(double alpha, double lambda);
} // namespace Convert::Refl
#endif // BORNAGAIN_BASE_UTIL_CONVERSIONUTIL_H
......@@ -16,6 +16,7 @@
#include "Base/Axis/Frame.h"
#include "Base/Axis/MakeScale.h"
#include "Base/Axis/Scale.h"
#include "Base/Const/Units.h"
#include "Device/Data/Datafield.h"
#include "Device/IO/ReadWriteINT.h"
#include "GUI/Support/XML/UtilXML.h"
......@@ -39,10 +40,10 @@ PointwiseAxisItem::PointwiseAxisItem(QObject* parent)
PointwiseAxisItem::~PointwiseAxisItem() = default;
void PointwiseAxisItem::setAxisAndUnit(const Scale& axis, const QString& units_label)
void PointwiseAxisItem::setAxis(const Scale& axis)
{
m_axis = std::unique_ptr<Scale>(axis.clone());
m_nativeAxisUnits = units_label;
m_nativeAxisUnits = QString::fromStdString(axis.unit());
}
const Scale* PointwiseAxisItem::axis() const
......@@ -134,7 +135,12 @@ void PointwiseAxisItem::updateAxIndicators(const Frame& cs)
if (!m_axis || nativeAxisUnits() == "bin")
return;
setMin(cs.axis(0).min());
setMax(cs.axis(0).max());
if (cs.axis(0).unit() == "rad") {
setMin(Units::rad2deg(cs.axis(0).min()));
setMax(Units::rad2deg(cs.axis(0).max()));
} else {
setMin(cs.axis(0).min());
setMax(cs.axis(0).max());
}
resize(static_cast<int>(m_axis->size()));
}
......@@ -27,9 +27,9 @@ public:
~PointwiseAxisItem() override;
// setters, getters
void setAxisAndUnit(const Scale& axis, const QString& units_label);
void setAxis(const Scale& axis);
const Scale* axis() const;
QString nativeAxisUnits() const;
void updateAxIndicators(const Frame& cs);
......
......@@ -184,13 +184,18 @@ void GrazingScanItem::initUniformAxis(const Scale& axis)
m_uniformAlphaAxis->resize(static_cast<int>(axis.size()));
}
void GrazingScanItem::initListScan(const Scale& axis, QString units, const Frame& frame)
void GrazingScanItem::initListScan(const Scale& axis)
{
if (!m_pointwiseAlphaAxis) {
m_pointwiseAlphaAxis.reset(new PointwiseAxisItem());
setAxisPresentationDefaults(m_pointwiseAlphaAxis.get());
}
m_pointwiseAlphaAxis->setAxis(axis);
}
m_pointwiseAlphaAxis->setAxisAndUnit(axis, units);
void GrazingScanItem::updateAxIndicators(const Frame& frame)
{
if (!m_pointwiseAlphaAxis)
return;
m_pointwiseAlphaAxis->updateAxIndicators(frame);
}
......@@ -59,7 +59,8 @@ public:
void selectListScan();
void initUniformAxis(const Scale& axis);
void initListScan(const Scale& axis, QString units, const Frame& frame);
void initListScan(const Scale& axis);
void updateAxIndicators(const Frame& frame);
private:
std::unique_ptr<BasicAxisItem> m_uniformAlphaAxis;
......
......@@ -16,6 +16,7 @@
#include "Base/Axis/Scale.h"
#include "Base/Const/Units.h"
#include "Base/Util/Assert.h"
#include "Base/Util/ConversionUtil.h"
#include "Device/Beam/Beam.h"
#include "Device/Beam/FootprintGauss.h"
#include "Device/Beam/FootprintSquare.h"
......@@ -359,13 +360,13 @@ BasicAxisItem* ScanItem::inclinationAxisItem() const
return grazingScanItem()->alphaAxisItem();
}
void ScanItem::updateToData(const Scale& axis, QString units, const Frame& frame)
void ScanItem::updateToData(const Scale& axis)
{
if (units == "bin") {
if (axis.unit() == "bin") {
grazingScanItem()->initUniformAxis(axis);
grazingScanItem()->selectUniformAxis();
} else {
grazingScanItem()->initListScan(axis, units, frame);
grazingScanItem()->initListScan(axis);
grazingScanItem()->selectListScan();
}
}
......@@ -100,7 +100,7 @@ public:
GrazingScanItem* grazingScanItem() const;
BasicAxisItem* inclinationAxisItem() const;
void updateToData(const Scale& axis, QString units, const Frame& frame);
void updateToData(const Scale& axis);
private:
std::unique_ptr<GrazingScanItem> m_grazingScanItem;
......
......@@ -47,14 +47,19 @@ DataItem::DataItem(const QString& modelType)
DataItem::~DataItem() = default;
void DataItem::setDatafield(const Datafield& data)
void DataItem::setOriginalDatafield(const Datafield& data)
{
std::unique_lock<std::mutex> lock(m_update_data_mutex);
m_datafield = std::make_unique<Datafield>(data.plottableField());
m_datafield = std::make_unique<Datafield>(data);
setLastModified(QDateTime::currentDateTime());
emit datafieldChanged();
}
void DataItem::setDatafield(const Datafield& data)
{
setOriginalDatafield(data.plottableField());
}
void DataItem::setRawDataVector(const std::vector<double>& data)
{
ASSERT(m_datafield->size() == data.size());
......
......@@ -45,6 +45,7 @@ public:
Datafield* p_field() { return m_datafield.get(); }
const Datafield* c_field() const { return m_datafield.get(); }
void setOriginalDatafield(const Datafield& data);
virtual void setDatafield(const Datafield& data);
//! Sets the raw data vector from external source.
......
......@@ -13,6 +13,7 @@
// ************************************************************************************************
#include "GUI/Model/Device/DatafileItem.h"
#include "Base/Axis/Frame.h"
#include "Base/Axis/Scale.h"
#include "Device/Data/DataUtil.h"
#include "Device/Data/Datafield.h"
......@@ -132,14 +133,14 @@ DataItem* DatafileItem::initNativeData()
return m_nativeDataItem.get();
}
QString DatafileItem::nativeDataUnits() const
{
return m_nativeDataUnits;
}
bool DatafileItem::holdsDimensionalData() const
{
return nativeDataUnits() != "bin";
const Frame& frame = dataItem()->c_field()->frame();
for (size_t k = 0; k < frame.rank(); k++)
if (frame.axis(k).unit() != "bin")
return true;
return false;
}
const Datafield* DatafileItem::nativeDatafield() const
......@@ -397,5 +398,4 @@ void DatafileItem::updateToInstrument(const InstrumentItem* instrument)
auto* data_source = native_data_item ? native_data_item : data_item;
std::unique_ptr<Datafield> native_data(data_source->c_field()->clone());
const QString units_label = nativeDataUnits();
}
......@@ -58,7 +58,6 @@ public:
DataItem* initNativeData();
QString nativeDataUnits() const;
bool holdsDimensionalData() const;
const Datafield* nativeDatafield() const;
......
......@@ -17,6 +17,7 @@
#include "Base/Axis/Scale.h"
#include "Base/Const/Units.h"
#include "Base/Util/Assert.h"
#include "Base/Util/ConversionUtil.h"
#include "Device/Beam/Beam.h"
#include "Device/Beam/IFootprint.h"
#include "Device/Data/Datafield.h"
......@@ -371,14 +372,14 @@ void SpecularInstrumentItem::updateToRealData(const DatafileItem* item)
if (shape().size() != item->shape().size())
throw std::runtime_error("Specular instrument type is incompatible with passed data shape");
const auto& data = item->nativeDatafield()->axis(0);
scanItem()->updateToData(data, item->nativeDataUnits(), makeFrame());
const auto& dataAxis = item->nativeDatafield()->axis(0);
scanItem()->updateToData(dataAxis);
scanItem()->grazingScanItem()->updateAxIndicators(makeFrame());
}
bool SpecularInstrumentItem::alignedWith(const DatafileItem* item) const
{
const QString native_units = item->nativeDataUnits();
if (native_units == "bin")
if (!item->holdsDimensionalData())
return scanItem()->grazingScanItem()->uniformAlphaAxisSelected()
&& shape() == item->shape();
......@@ -389,9 +390,6 @@ bool SpecularInstrumentItem::alignedWith(const DatafileItem* item) const
dynamic_cast<const PointwiseAxisItem*>(scanItem()->grazingScanItem()->alphaAxisItem());
ASSERT(axisItem);
if (axisItem->nativeAxisUnits() != native_units)
return false;
const auto* instrumentAxis = axisItem->axis();
if (!instrumentAxis)
return false;
......@@ -410,15 +408,23 @@ Frame SpecularInstrumentItem::makeFrame() const
auto* axis_item = scanItem()->inclinationAxisItem();
if (auto* pointwise_axis = dynamic_cast<PointwiseAxisItem*>(axis_item)) {
if (!pointwise_axis->axis()) // workaround for loading project
const Scale* pAxis = pointwise_axis->axis();
if (!pAxis) // workaround for loading project
return Frame({});
Scale* ax0 = pointwise_axis->axis()->clone();
if (pAxis->unit() == "1/nm") {
double l = scanItem()->wavelength();
Scale ax = pAxis->transformedScale(Coordinate("alpha_i", "rad").label(), [l](double x) {
return Convert::Refl::qz2alpha(l, x);
});
return Frame(std::move(ax.clone()));
}
Scale* ax0 = pAxis->clone();
std::vector<const Scale*> f{ax0};
return Frame(f);
}
Scale axis = axis_item->makeScale("alpha_i (rad)");
std::vector<const Scale*> f{axis.clone()};
return Frame(f);
}
......
......@@ -14,6 +14,7 @@
#include "GUI/Model/Job/JobItem.h"
#include "Base/Axis/Frame.h"
#include "Base/Axis/Scale.h"
#include "Device/Data/Datafield.h"
#include "Device/Detector/IDetector.h"
#include "GUI/Model/Axis/AmplitudeAxisItem.h"
......@@ -329,12 +330,15 @@ void JobItem::copyDatafileItemIntoJob(const DatafileItem* srcDatafileItem)
createDatafileItem();
srcDatafileItem->copyTo(realItem());
// override axes units of simulated data
ASSERT(m_simulatedDataItem);
// m_simulatedDataItem->setCurrentCoord(m_realItem->dataItem()->currentCoord());
if (rank() == 1)
if (rank() == 1) {
m_realItem->data1DItem()->setRealPlotStyle();
// coords of loaded data --> instrumental --> representation coords
const Datafield* old = m_realItem->data1DItem()->c_field();
Frame frame = instrumentItem()->makeFrame();
m_realItem->data1DItem()->setDatafield(
{frame.clone(), old->flatVector(), old->errorSigmas()});
}
}
DatafileItem* JobItem::realItem()
......
......@@ -65,6 +65,13 @@ InstrumentView::InstrumentView(QWidget* parent, ProjectDocument* document)
// Initial state
createWidgetsForCurrentInstrument();
subscribeOnExternalUpdates();
}
void InstrumentView::subscribeOnExternalUpdates()
{
connect(m_document->multiNotifier(), &MultiInstrumentNotifier::instrumentChanged, this,
&InstrumentView::onInstrumentChangedFromExternal, Qt::UniqueConnection);
}
void InstrumentView::showEvent(QShowEvent*)
......@@ -80,8 +87,7 @@ void InstrumentView::hideEvent(QHideEvent*)
{
// when the instrument view gets hidden (meaning another view is shown), it's necessary to
// listen to changes (e.g. performed by the LinkInstrumentManager).
connect(m_document->multiNotifier(), &MultiInstrumentNotifier::instrumentChanged, this,
&InstrumentView::onInstrumentChangedFromExternal);
subscribeOnExternalUpdates();
}
void InstrumentView::createWidgetsForCurrentInstrument()
......
......@@ -34,6 +34,7 @@ private:
void showEvent(QShowEvent*) override;
void hideEvent(QHideEvent*) override;
void subscribeOnExternalUpdates();
void createWidgetsForCurrentInstrument();
void onInstrumentNameEdited(const QString& newName);
void onInstrumentdescriptionEdited(const QString& t);
......
......@@ -16,6 +16,7 @@
#include "Base/Axis/MakeScale.h"
#include "Base/Axis/Scale.h"
#include "Base/Util/Assert.h"
#include "Base/Util/ConversionUtil.h"
#include "Device/Pol/PolFilter.h"
#include "Param/Distrib/Distributions.h"
#include "Param/Distrib/ParameterSample.h"
......@@ -141,9 +142,7 @@ void QzScan::createBeams()
m_beams.clear();
for (size_t i = 0; i < nScan(); i++) {
// Qz scan is internally understood as wavelength scan
// TODO use some shared function "qz2lambda"
double lambda =
4.0 * std::numbers::pi * std::sin(defaultInclination) / m_axis->binCenter(i);
double lambda = Convert::Refl::qz2lambda(defaultInclination, m_axis->binCenter(i));
Beam* beam = new Beam(defaultIntensity, lambda, defaultInclination);
// Since the grazing geometry is not clear in q-space, the footprint should not be used
beam->setFootprint(nullptr);
......
......@@ -16,6 +16,7 @@
#include "Base/Axis/MakeScale.h"
#include "Base/Axis/Scale.h"
#include "Base/Const/Units.h"
#include "Base/Util/ConversionUtil.h"
#include "Device/Beam/Beam.h"
#include "Device/Beam/FootprintGauss.h"
#include "Device/Beam/FootprintSquare.h"
......@@ -288,7 +289,7 @@ BeamScan* test::makeSimulation::BasicSpecularScan(bool vsQ)
auto angles = angle_axis.binCenters();
std::vector<double> qs(angle_axis.size(), 0.0);
for (size_t i = 0, size = qs.size(); i < size; ++i)
qs[i] = 4.0 * pi * std::sin(angles[i]) / wavelength;
qs[i] = Convert::Refl::qz(angles[i], wavelength);
return new QzScan(qs);
}
auto* result = new AlphaScan(EquiScan("alpha_i (rad)", n, max_angle / n, max_angle));
......