Skip to content

Commit

Permalink
Add probe type to the Beam model (#647)
Browse files Browse the repository at this point in the history
At the moment this just adds the additional datum and allows
serialisation etc. Old experiment files where this is not set are
interpreted as having Probe.xray. Some electron diffraction format
classes are updated here to record Probe.electron.

Co-authored-by: davidmcdonagh <davidnmcdonagh@gmail.com>
  • Loading branch information
dagewa and toastisme authored Aug 4, 2023
1 parent 5c27616 commit 4783b2c
Show file tree
Hide file tree
Showing 9 changed files with 164 additions and 25 deletions.
1 change: 1 addition & 0 deletions newsfragments/647.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
The ``Beam`` model now has a ``probe`` value to keep track of the type of radiation.
4 changes: 4 additions & 0 deletions src/dxtbx/dxtbx_model_ext.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ from scitbx.array_family import shared as flex_shared
# Attempt to use the stub typing for flex-inheritance
from scitbx.array_family.flex import FlexPlain

from dxtbx_model_ext import Probe # type: ignore

# TypeVar for the set of Experiment models that can be joint-accepted
# - profile, imageset and scalingmodel are handled as 'object'
TExperimentModel = TypeVar(
Expand Down Expand Up @@ -113,6 +115,8 @@ class Beam(BeamBase):
@staticmethod
def from_dict(data: Dict) -> Beam: ...
def to_dict(self) -> Dict: ...
@staticmethod
def get_probe_from_name(name: str) -> Probe: ...

class PolychromaticBeam(Beam):
@overload
Expand Down
2 changes: 2 additions & 0 deletions src/dxtbx/format/FormatGatanDM4.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
)
from dxtbx.format.Format import Format
from dxtbx.format.FormatMultiImage import FormatMultiImage
from dxtbx.model.beam import Probe


def read_tag(f, byteorder):
Expand Down Expand Up @@ -358,6 +359,7 @@ def _beam(self):
wavelength=wavelength,
polarization=(0, 1, 0),
polarization_fraction=0.5,
probe=Probe.electron,
)

def _scan(self):
Expand Down
2 changes: 2 additions & 0 deletions src/dxtbx/format/FormatMRC.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
from dxtbx.format.Format import Format
from dxtbx.format.FormatMultiImage import FormatMultiImage
from dxtbx.model import ScanFactory
from dxtbx.model.beam import Probe

logger = logging.getLogger("dials")

Expand Down Expand Up @@ -226,6 +227,7 @@ def _beam(self):
wavelength=wavelength,
polarization=(0, 1, 0),
polarization_fraction=0.5,
probe=Probe.electron,
)


Expand Down
2 changes: 2 additions & 0 deletions src/dxtbx/format/FormatSMVTimePix_SU.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
from scitbx import matrix

from dxtbx.format.FormatSMV import FormatSMV
from dxtbx.model.beam import Probe
from dxtbx.model.detector import Detector


Expand Down Expand Up @@ -76,6 +77,7 @@ def _beam(self):
wavelength=wavelength,
polarization=(0, 1, 0),
polarization_fraction=0.5,
probe=Probe.electron,
)

def _scan(self):
Expand Down
90 changes: 78 additions & 12 deletions src/dxtbx/model/beam.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

#include <iostream>
#include <cmath>
#include <string>
#include <scitbx/vec3.h>
#include <scitbx/array_family/shared.h>
#include <scitbx/array_family/simple_io.h>
Expand All @@ -24,6 +25,9 @@ namespace dxtbx { namespace model {

using scitbx::vec3;

// probe type enumeration
enum Probe { xray = 1, electron = 2, neutron = 3 };

/** Base class for beam objects */
class BeamBase {
public:
Expand All @@ -44,6 +48,8 @@ namespace dxtbx { namespace model {
virtual std::size_t get_num_scan_points() const = 0;
virtual scitbx::af::shared<vec3<double> > get_s0_at_scan_points() const = 0;
virtual vec3<double> get_s0_at_scan_point(std::size_t index) const = 0;
virtual Probe get_probe() const = 0;
virtual std::string get_probe_name() const = 0;

virtual void set_direction(vec3<double> direction) = 0;
virtual void set_wavelength(double wavelength) = 0;
Expand All @@ -59,6 +65,7 @@ namespace dxtbx { namespace model {
virtual void set_transmission(double transmission) = 0;
virtual void set_s0_at_scan_points(
const scitbx::af::const_ref<vec3<double> > &s0) = 0;
virtual void set_probe(Probe probe) = 0;

virtual void reset_scan_points() = 0;
virtual bool is_similar_to(const BeamBase &rhs,
Expand All @@ -82,7 +89,8 @@ namespace dxtbx { namespace model {
polarization_normal_(0.0, 1.0, 0.0),
polarization_fraction_(0.999),
flux_(0),
transmission_(1.0) {}
transmission_(1.0),
probe_(Probe::xray) {}

/**
* @param s0 The incident beam vector.
Expand All @@ -93,7 +101,8 @@ namespace dxtbx { namespace model {
polarization_normal_(0.0, 1.0, 0.0),
polarization_fraction_(0.999),
flux_(0),
transmission_(1.0) {
transmission_(1.0),
probe_(Probe::xray) {
DXTBX_ASSERT(s0.length() > 0);
wavelength_ = 1.0 / s0.length();
direction_ = -s0.normalize();
Expand All @@ -110,7 +119,8 @@ namespace dxtbx { namespace model {
polarization_normal_(0.0, 1.0, 0.0),
polarization_fraction_(0.999),
flux_(0),
transmission_(1.0) {
transmission_(1.0),
probe_(Probe::xray) {
DXTBX_ASSERT(direction.length() > 0);
direction_ = direction.normalize();
}
Expand All @@ -126,7 +136,8 @@ namespace dxtbx { namespace model {
polarization_normal_(0.0, 1.0, 0.0),
polarization_fraction_(0.999),
flux_(0),
transmission_(1.0) {
transmission_(1.0),
probe_(Probe::xray) {
DXTBX_ASSERT(s0.length() > 0);
wavelength_ = 1.0 / s0.length();
direction_ = -s0.normalize();
Expand All @@ -148,7 +159,8 @@ namespace dxtbx { namespace model {
polarization_normal_(0.0, 1.0, 0.0),
polarization_fraction_(0.999),
flux_(0),
transmission_(1.0) {
transmission_(1.0),
probe_(Probe::xray) {
DXTBX_ASSERT(direction.length() > 0);
direction_ = direction.normalize();
}
Expand All @@ -162,6 +174,7 @@ namespace dxtbx { namespace model {
* @param polarization_fraction The polarization fraction
* @param flux The beam flux
* @param transmission The beam transmission
* @param probe The probe value
*/
Beam(vec3<double> direction,
double wavelength,
Expand All @@ -170,14 +183,16 @@ namespace dxtbx { namespace model {
vec3<double> polarization_normal,
double polarization_fraction,
double flux,
double transmission)
double transmission,
Probe probe)
: wavelength_(wavelength),
divergence_(divergence),
sigma_divergence_(sigma_divergence),
polarization_normal_(polarization_normal),
polarization_fraction_(polarization_fraction),
flux_(flux),
transmission_(transmission) {
transmission_(transmission),
probe_(probe) {
DXTBX_ASSERT(direction.length() > 0);
direction_ = direction.normalize();
}
Expand Down Expand Up @@ -289,6 +304,44 @@ namespace dxtbx { namespace model {
return s0_at_scan_points_[index];
}

Probe get_probe() const {
return probe_;
}

std::string get_probe_name() const {
// Return a name that matches NeXus definitions from
// https://manual.nexusformat.org/classes/base_classes/NXsource.html
switch (probe_) {
case xray:
return std::string("x-ray");
case electron:
return std::string("electron");
case neutron:
return std::string("neutron");
default:
DXTBX_ERROR("Unknown probe type");
}
}

static Probe get_probe_from_name(const std::string probe) {
// Return a Probe matched to NeXus definitions from
// https://manual.nexusformat.org/classes/base_classes/NXsource.html

if (probe == "x-ray") {
return Probe::xray;
} else if (probe == "electron") {
return Probe::electron;
} else if (probe == "neutron") {
return Probe::neutron;
}

DXTBX_ERROR("Unknown probe " + probe);
}

void set_probe(Probe probe) {
probe_ = probe;
}

void reset_scan_points() {
s0_at_scan_points_.clear();
}
Expand Down Expand Up @@ -324,7 +377,8 @@ namespace dxtbx { namespace model {
angle_safe(polarization_normal_, rhs.get_polarization_normal()))
<= eps
&& std::abs(polarization_fraction_ - rhs.get_polarization_fraction())
<= eps;
<= eps
&& (probe_ == rhs.get_probe());
}

virtual bool is_similar_to(const BeamBase &rhs,
Expand Down Expand Up @@ -361,7 +415,8 @@ namespace dxtbx { namespace model {
angle_safe(polarization_normal_, rhs.get_polarization_normal()))
<= polarization_normal_tolerance
&& std::abs(polarization_fraction_ - rhs.get_polarization_fraction())
<= polarization_fraction_tolerance;
<= polarization_fraction_tolerance
&& (probe_ == rhs.get_probe());
}

bool operator!=(const BeamBase &rhs) const {
Expand All @@ -383,6 +438,7 @@ namespace dxtbx { namespace model {
double polarization_fraction_;
double flux_;
double transmission_;
Probe probe_;

private:
double wavelength_;
Expand All @@ -392,6 +448,7 @@ namespace dxtbx { namespace model {
/** Print beam information */
inline std::ostream &operator<<(std::ostream &os, const Beam &b) {
os << "Beam:\n";
os << " probe: " << b.get_probe_name() << "\n";
os << " wavelength: " << b.get_wavelength() << "\n";
os << " sample to source direction : "
<< b.get_sample_to_source_direction().const_ref() << "\n";
Expand All @@ -415,6 +472,7 @@ namespace dxtbx { namespace model {
set_polarization_fraction(0.5);
set_flux(0);
set_transmission(1.0);
set_probe(Probe::xray);
}

/**
Expand All @@ -429,6 +487,7 @@ namespace dxtbx { namespace model {
set_polarization_fraction(0.5);
set_flux(0);
set_transmission(1.0);
set_probe(Probe::xray);
}

/**
Expand All @@ -447,6 +506,7 @@ namespace dxtbx { namespace model {
set_polarization_fraction(0.5);
set_flux(0);
set_transmission(1.0);
set_probe(Probe::xray);
}

/**
Expand All @@ -457,14 +517,16 @@ namespace dxtbx { namespace model {
* @param polarization_fraction The polarization fraction
* @param flux The beam flux
* @param transmission The beam transmission
* @param probe The probe value
*/
PolychromaticBeam(vec3<double> direction,
double divergence,
double sigma_divergence,
vec3<double> polarization_normal,
double polarization_fraction,
double flux,
double transmission) {
double transmission,
Probe probe) {
DXTBX_ASSERT(direction.length() > 0);
direction_ = direction.normalize();
set_divergence(divergence);
Expand All @@ -473,6 +535,7 @@ namespace dxtbx { namespace model {
set_polarization_fraction(polarization_fraction);
set_flux(flux);
set_transmission(transmission);
set_probe(probe);
}

double get_wavelength() const {
Expand Down Expand Up @@ -527,7 +590,8 @@ namespace dxtbx { namespace model {
angle_safe(polarization_normal_, rhs.get_polarization_normal()))
<= eps
&& std::abs(polarization_fraction_ - rhs.get_polarization_fraction())
<= eps;
<= eps
&& (probe_ == rhs.get_probe());
}

bool is_similar_to(const BeamBase &rhs,
Expand All @@ -551,13 +615,15 @@ namespace dxtbx { namespace model {
angle_safe(polarization_normal_, rhs.get_polarization_normal()))
<= polarization_normal_tolerance
&& std::abs(polarization_fraction_ - rhs.get_polarization_fraction())
<= polarization_fraction_tolerance;
<= polarization_fraction_tolerance
&& (probe_ == rhs.get_probe());
}
};

/** Print beam information */
inline std::ostream &operator<<(std::ostream &os, const PolychromaticBeam &b) {
os << "Beam:\n";
os << " probe: " << b.get_probe_name() << "\n";
os << " sample to source direction : "
<< b.get_sample_to_source_direction().const_ref() << "\n";
os << " divergence: " << b.get_divergence() << "\n";
Expand Down
Loading

0 comments on commit 4783b2c

Please sign in to comment.