diff --git a/newsfragments/622.misc b/newsfragments/622.misc new file mode 100644 index 000000000..033071027 --- /dev/null +++ b/newsfragments/622.misc @@ -0,0 +1 @@ +Add sample_to_source_distance to Beam diff --git a/src/dxtbx/dxtbx_model_ext.pyi b/src/dxtbx/dxtbx_model_ext.pyi index 8a4a85934..9ca38cffd 100644 --- a/src/dxtbx/dxtbx_model_ext.pyi +++ b/src/dxtbx/dxtbx_model_ext.pyi @@ -57,6 +57,10 @@ class BeamBase: self, points: Union[Tuple[Vec3Float], List[Vec3Float]] ) -> None: ... def get_sample_to_source_direction(self) -> Vec3Float: ... + def get_sample_to_source_distance(self) -> float: ... + def set_sample_to_source_distance( + self, sample_to_source_distance: float + ) -> None: ... def get_sigma_divergence(self) -> float: ... def set_sigma_divergence(self, sigma_divergence: float) -> None: ... def get_transmission(self) -> float: ... @@ -110,6 +114,22 @@ class Beam(BeamBase): polarization_fraction: float, flux: float, transmission: float, + probe: Probe = ..., + deg: bool = ..., + ) -> None: ... + @overload + def __init__( + self, + direction: Vec3Float, + wavelength: float, + divergence: float, + sigma_divergence: float, + polarization_normal: Vec3Float, + polarization_fraction: float, + flux: float, + transmission: float, + probe: Probe = ..., + sample_to_source_distance: float = ..., deg: bool = ..., ) -> None: ... @staticmethod @@ -141,6 +161,8 @@ class PolychromaticBeam(Beam): polarization_fraction: float, flux: float, transmission: float, + probe: Probe = ..., + sample_to_source_distance: float = ..., deg: bool = ..., ) -> None: ... @staticmethod diff --git a/src/dxtbx/model/beam.h b/src/dxtbx/model/beam.h index 7f9cefb37..42aaffe07 100644 --- a/src/dxtbx/model/beam.h +++ b/src/dxtbx/model/beam.h @@ -34,6 +34,7 @@ namespace dxtbx { namespace model { virtual ~BeamBase() {} virtual vec3 get_sample_to_source_direction() const = 0; + virtual double get_sample_to_source_distance() const = 0; virtual double get_wavelength() const = 0; virtual double get_divergence() const = 0; // Get the standard deviation of the beam divergence @@ -66,13 +67,19 @@ namespace dxtbx { namespace model { virtual void set_s0_at_scan_points( const scitbx::af::const_ref > &s0) = 0; virtual void set_probe(Probe probe) = 0; + virtual void set_sample_to_source_distance(double sample_to_source_distance) = 0; virtual void reset_scan_points() = 0; virtual bool is_similar_to(const BeamBase &rhs, double wavelength_tolerance, double direction_tolerance, double polarization_normal_tolerance, - double polarization_fraction_tolerance) const = 0; + double polarization_fraction_tolerance, + double divergence_tolerance, + double sigma_divergence_tolerance, + double flux_tolerance, + double transmission_tolerance, + double sample_to_source_distance_tolerance) const = 0; virtual void rotate_around_origin(vec3 axis, double angle) = 0; virtual bool operator!=(const BeamBase &rhs) const = 0; virtual bool operator==(const BeamBase &rhs) const = 0; @@ -90,7 +97,8 @@ namespace dxtbx { namespace model { polarization_fraction_(0.999), flux_(0), transmission_(1.0), - probe_(Probe::xray) {} + probe_(Probe::xray), + sample_to_source_distance_(0.) {} /** * @param s0 The incident beam vector. @@ -102,7 +110,8 @@ namespace dxtbx { namespace model { polarization_fraction_(0.999), flux_(0), transmission_(1.0), - probe_(Probe::xray) { + probe_(Probe::xray), + sample_to_source_distance_(0.) { DXTBX_ASSERT(s0.length() > 0); wavelength_ = 1.0 / s0.length(); direction_ = -s0.normalize(); @@ -120,7 +129,8 @@ namespace dxtbx { namespace model { polarization_fraction_(0.999), flux_(0), transmission_(1.0), - probe_(Probe::xray) { + probe_(Probe::xray), + sample_to_source_distance_(0.) { DXTBX_ASSERT(direction.length() > 0); direction_ = direction.normalize(); } @@ -137,7 +147,8 @@ namespace dxtbx { namespace model { polarization_fraction_(0.999), flux_(0), transmission_(1.0), - probe_(Probe::xray) { + probe_(Probe::xray), + sample_to_source_distance_(0.) { DXTBX_ASSERT(s0.length() > 0); wavelength_ = 1.0 / s0.length(); direction_ = -s0.normalize(); @@ -160,7 +171,8 @@ namespace dxtbx { namespace model { polarization_fraction_(0.999), flux_(0), transmission_(1.0), - probe_(Probe::xray) { + probe_(Probe::xray), + sample_to_source_distance_(0.) { DXTBX_ASSERT(direction.length() > 0); direction_ = direction.normalize(); } @@ -192,7 +204,43 @@ namespace dxtbx { namespace model { polarization_fraction_(polarization_fraction), flux_(flux), transmission_(transmission), - probe_(probe) { + probe_(probe), + sample_to_source_distance_(0.) { + DXTBX_ASSERT(direction.length() > 0); + direction_ = direction.normalize(); + } + + /** + * @param direction The beam direction vector from source to sample + * @param wavelength The wavelength of the beam + * @param divergence The beam divergence + * @param sigma_divergence The standard deviation of the beam divergence + * @param polarization_normal The polarization plane + * @param polarization_fraction The polarization fraction + * @param flux The beam flux + * @param transmission The beam transmission + * @param probe The probe value + * @param sample_to_source_distance (mm) + */ + Beam(vec3 direction, + double wavelength, + double divergence, + double sigma_divergence, + vec3 polarization_normal, + double polarization_fraction, + double flux, + double transmission, + Probe probe, + double sample_to_source_distance) + : wavelength_(wavelength), + divergence_(divergence), + sigma_divergence_(sigma_divergence), + polarization_normal_(polarization_normal), + polarization_fraction_(polarization_fraction), + flux_(flux), + transmission_(transmission), + probe_(probe), + sample_to_source_distance_(sample_to_source_distance) { DXTBX_ASSERT(direction.length() > 0); direction_ = direction.normalize(); } @@ -346,6 +394,17 @@ namespace dxtbx { namespace model { s0_at_scan_points_.clear(); } + /* Distance from sample to source in mm */ + double get_sample_to_source_distance() const { + return sample_to_source_distance_; + } + + /* Distance from sample to source in mm */ + void set_sample_to_source_distance(double sample_to_source_distance) { + DXTBX_ASSERT(sample_to_source_distance >= 0.); + sample_to_source_distance_ = sample_to_source_distance; + } + virtual bool operator==(const BeamBase &rhs) const { double eps = 1.0e-6; @@ -378,6 +437,11 @@ namespace dxtbx { namespace model { <= eps && std::abs(polarization_fraction_ - rhs.get_polarization_fraction()) <= eps + && std::abs(flux_ - rhs.get_flux()) <= eps + && std::abs(transmission_ - rhs.get_transmission()) <= eps + && std::abs(sample_to_source_distance_ + - rhs.get_sample_to_source_distance()) + <= eps && (probe_ == rhs.get_probe()); } @@ -419,6 +483,57 @@ namespace dxtbx { namespace model { && (probe_ == rhs.get_probe()); } + virtual bool is_similar_to(const BeamBase &rhs, + double wavelength_tolerance, + double direction_tolerance, + double polarization_normal_tolerance, + double polarization_fraction_tolerance, + double divergence_tolerance = 1e-6, + double sigma_divergence_tolerance = 1e-6, + double flux_tolerance = 1e-6, + double transmission_tolerance = 1e-6, + double sample_to_source_tolerance = 1e-6) const { + // scan varying model checks + if (get_num_scan_points() != rhs.get_num_scan_points()) { + return false; + } + for (std::size_t i = 0; i < get_num_scan_points(); ++i) { + vec3 s0_a = get_s0_at_scan_point(i); + vec3 s0_b = rhs.get_s0_at_scan_point(i); + + vec3 us0_a = s0_a.normalize(); + vec3 us0_b = s0_b.normalize(); + if (std::abs(angle_safe(us0_a, us0_b)) > direction_tolerance) { + return false; + } + + double wavelength_a = 1.0 / s0_a.length(); + double wavelength_b = 1.0 / s0_b.length(); + if (std::abs(wavelength_a - wavelength_b) > wavelength_tolerance) { + return false; + } + } + + // static model checks + return std::abs(angle_safe(direction_, rhs.get_sample_to_source_direction())) + <= direction_tolerance + && std::abs(wavelength_ - rhs.get_wavelength()) <= wavelength_tolerance + && std::abs( + angle_safe(polarization_normal_, rhs.get_polarization_normal())) + <= polarization_normal_tolerance + && std::abs(polarization_fraction_ - rhs.get_polarization_fraction()) + <= polarization_fraction_tolerance + && std::abs(divergence_ - rhs.get_divergence()) <= divergence_tolerance + && std::abs(sigma_divergence_ - rhs.get_sigma_divergence()) + <= sigma_divergence_tolerance + && std::abs(flux_ - rhs.get_flux()) <= flux_tolerance + && std::abs(transmission_ - rhs.get_transmission()) + <= transmission_tolerance + && std::abs(sample_to_source_distance_ + - rhs.get_sample_to_source_distance()) + <= sample_to_source_tolerance; + } + bool operator!=(const BeamBase &rhs) const { return !(*this == rhs); } @@ -439,6 +554,7 @@ namespace dxtbx { namespace model { double flux_; double transmission_; Probe probe_; + double sample_to_source_distance_; private: double wavelength_; @@ -459,9 +575,10 @@ namespace dxtbx { namespace model { os << " polarization fraction: " << b.get_polarization_fraction() << "\n"; os << " flux: " << b.get_flux() << "\n"; os << " transmission: " << b.get_transmission() << "\n"; + os << " sample to source distance: " << b.get_sample_to_source_distance() + << "\n"; return os; } - class PolychromaticBeam : public Beam { public: PolychromaticBeam() { @@ -473,6 +590,7 @@ namespace dxtbx { namespace model { set_flux(0); set_transmission(1.0); set_probe(Probe::xray); + set_sample_to_source_distance(0.0); } /** @@ -488,6 +606,24 @@ namespace dxtbx { namespace model { set_flux(0); set_transmission(1.0); set_probe(Probe::xray); + set_sample_to_source_distance(0.0); + } + + /** + * @param direction The beam direction pointing source to sample + * @param sample_to_source_distance (mm) + */ + PolychromaticBeam(vec3 direction, double sample_to_source_distance) { + DXTBX_ASSERT(direction.length() > 0); + direction_ = direction.normalize(); + set_sample_to_source_distance(sample_to_source_distance); + set_divergence(0.0); + set_sigma_divergence(0.0); + set_polarization_normal(vec3(0.0, 1.0, 0.0)); + set_polarization_fraction(0.999); + set_flux(0); + set_transmission(1.0); + set_probe(Probe::xray); } /** @@ -507,6 +643,7 @@ namespace dxtbx { namespace model { set_flux(0); set_transmission(1.0); set_probe(Probe::xray); + set_sample_to_source_distance(0.0); } /** @@ -536,6 +673,39 @@ namespace dxtbx { namespace model { set_flux(flux); set_transmission(transmission); set_probe(probe); + set_sample_to_source_distance(0.0); + } + + /** + * @param direction The beam direction pointing source to sample + * @param divergence The beam divergence + * @param sigma_divergence The standard deviation of the beam divergence + * @param polarization_normal The polarization plane + * @param polarization_fraction The polarization fraction + * @param flux The beam flux + * @param transmission The beam transmission + * @param probe The probe value + * @param sample_to_source_distance (mm) + */ + PolychromaticBeam(vec3 direction, + double divergence, + double sigma_divergence, + vec3 polarization_normal, + double polarization_fraction, + double flux, + double transmission, + Probe probe, + double sample_to_source_distance) { + DXTBX_ASSERT(direction.length() > 0); + direction_ = direction.normalize(); + set_divergence(divergence); + set_sigma_divergence(sigma_divergence); + set_polarization_normal(polarization_normal); + set_polarization_fraction(polarization_fraction); + set_flux(flux); + set_transmission(transmission); + set_probe(probe); + set_sample_to_source_distance(sample_to_source_distance); } double get_wavelength() const { @@ -591,6 +761,11 @@ namespace dxtbx { namespace model { <= eps && std::abs(polarization_fraction_ - rhs.get_polarization_fraction()) <= eps + && std::abs(flux_ - rhs.get_flux()) <= eps + && std::abs(transmission_ - rhs.get_transmission()) <= eps + && std::abs(sample_to_source_distance_ + - rhs.get_sample_to_source_distance()) + <= eps && (probe_ == rhs.get_probe()); } @@ -608,7 +783,12 @@ namespace dxtbx { namespace model { bool is_similar_to(const BeamBase &rhs, double direction_tolerance, double polarization_normal_tolerance, - double polarization_fraction_tolerance) const { + double polarization_fraction_tolerance, + double divergence_tolerance = 1e-6, + double sigma_divergence_tolerance = 1e-6, + double flux_tolerance = 1e-6, + double transmission_tolerance = 1e-6, + double sample_to_source_tolerance = 1e-6) const { return std::abs(angle_safe(direction_, rhs.get_sample_to_source_direction())) <= direction_tolerance && std::abs( @@ -616,6 +796,12 @@ namespace dxtbx { namespace model { <= polarization_normal_tolerance && std::abs(polarization_fraction_ - rhs.get_polarization_fraction()) <= polarization_fraction_tolerance + && std::abs(flux_ - rhs.get_flux()) <= flux_tolerance + && std::abs(transmission_ - rhs.get_transmission()) + <= transmission_tolerance + && std::abs(sample_to_source_distance_ + - rhs.get_sample_to_source_distance()) + <= sample_to_source_tolerance && (probe_ == rhs.get_probe()); } }; @@ -633,9 +819,10 @@ namespace dxtbx { namespace model { os << " polarization fraction: " << b.get_polarization_fraction() << "\n"; os << " flux: " << b.get_flux() << "\n"; os << " transmission: " << b.get_transmission() << "\n"; + os << " sample to source distance : " << b.get_sample_to_source_distance() + << "\n"; return os; } - }} // namespace dxtbx::model #endif // DXTBX_MODEL_BEAM_H diff --git a/src/dxtbx/model/beam.py b/src/dxtbx/model/beam.py index a7360e9e5..799d9be32 100644 --- a/src/dxtbx/model/beam.py +++ b/src/dxtbx/model/beam.py @@ -66,6 +66,10 @@ .type = float .help = "Override the flux" .short_caption = "flux" + + sample_to_source_distance = None + .type = float + .help = "Override the distance between sample and source (mm)" } """ ) @@ -116,6 +120,8 @@ def from_phil( beam.set_transmission(params.beam.transmission) if params.beam.flux is not None: beam.set_flux(params.beam.flux) + if params.beam.sample_to_source_distance is not None: + beam.set_sample_to_source_distance(params.beam.sample_to_source_distance) beam.set_probe(Beam.get_probe_from_name(params.beam.probe)) return beam @@ -186,6 +192,7 @@ def make_polychromatic_beam( flux: float = 0.0, transmission: float = 1.0, probe: Probe = Probe.xray, + sample_to_source_distance: float = 0.0, deg: bool = True, ) -> PolychromaticBeam: return PolychromaticBeam( @@ -197,6 +204,7 @@ def make_polychromatic_beam( float(flux), float(transmission), probe, + float(sample_to_source_distance), bool(deg), ) diff --git a/src/dxtbx/model/boost_python/beam.cc b/src/dxtbx/model/boost_python/beam.cc index 86cdab927..0cb9ea4c5 100644 --- a/src/dxtbx/model/boost_python/beam.cc +++ b/src/dxtbx/model/boost_python/beam.cc @@ -44,7 +44,8 @@ namespace dxtbx { namespace model { namespace boost_python { obj.get_polarization_fraction(), obj.get_flux(), obj.get_transmission(), - obj.get_probe()); + obj.get_probe(), + obj.get_sample_to_source_distance()); } static boost::python::tuple getstate(boost::python::object obj) { @@ -138,6 +139,44 @@ namespace dxtbx { namespace model { namespace boost_python { return beam; } + static Beam *make_beam_w_sample_to_source_distance(vec3 sample_to_source, + double wavelength, + double divergence, + double sigma_divergence, + vec3 polarization_normal, + double polarization_fraction, + double flux, + double transmission, + Probe probe, + double sample_to_source_distance, + bool deg) { + Beam *beam = NULL; + if (deg) { + beam = new Beam(sample_to_source, + wavelength, + deg_as_rad(divergence), + deg_as_rad(sigma_divergence), + polarization_normal, + polarization_fraction, + flux, + transmission, + probe, + sample_to_source_distance); + } else { + beam = new Beam(sample_to_source, + wavelength, + divergence, + sigma_divergence, + polarization_normal, + polarization_fraction, + flux, + transmission, + probe, + sample_to_source_distance); + } + return beam; + } + static double get_divergence(const Beam &beam, bool deg) { double divergence = beam.get_divergence(); return deg ? rad_as_deg(divergence) : divergence; @@ -197,6 +236,7 @@ namespace dxtbx { namespace model { namespace boost_python { result["flux"] = obj.get_flux(); result["transmission"] = obj.get_transmission(); result["probe"] = obj.get_probe_name(); + result["sample_to_source_distance"] = obj.get_sample_to_source_distance(); if (obj.get_num_scan_points() > 0) { boost::python::list l; scitbx::af::shared > s0_at_scan_points = obj.get_s0_at_scan_points(); @@ -229,6 +269,10 @@ namespace dxtbx { namespace model { namespace boost_python { boost::python::extract(obj["s0_at_scan_points"]); beam_detail::Beam_set_s0_at_scan_points_from_list(*b, s0_at_scan_points); } + if (obj.has_key("sample_to_source_distance")) { + double val = boost::python::extract(obj["sample_to_source_distance"]); + b->set_sample_to_source_distance(val); + } return b; } @@ -249,7 +293,8 @@ namespace dxtbx { namespace model { namespace boost_python { obj.get_polarization_fraction(), obj.get_flux(), obj.get_transmission(), - obj.get_probe()); + obj.get_probe(), + obj.get_sample_to_source_distance()); } }; @@ -271,6 +316,12 @@ namespace dxtbx { namespace model { namespace boost_python { return beam; } + static PolychromaticBeam *make_PolychromaticBeam_w_sample_to_source_distance( + vec3 direction, + double sample_to_source_distance) { + return new PolychromaticBeam(direction, sample_to_source_distance); + } + static PolychromaticBeam *make_PolychromaticBeam_w_all( vec3 direction, double divergence, @@ -280,6 +331,7 @@ namespace dxtbx { namespace model { namespace boost_python { double flux, double transmission, Probe probe, + double sample_to_source_distance, bool deg) { PolychromaticBeam *beam = NULL; if (deg) { @@ -290,7 +342,8 @@ namespace dxtbx { namespace model { namespace boost_python { polarization_fraction, flux, transmission, - probe); + probe, + sample_to_source_distance); } else { beam = new PolychromaticBeam(direction, divergence, @@ -299,7 +352,8 @@ namespace dxtbx { namespace model { namespace boost_python { polarization_fraction, flux, transmission, - probe); + probe, + sample_to_source_distance); } return beam; } @@ -316,6 +370,7 @@ namespace dxtbx { namespace model { namespace boost_python { result["flux"] = obj.get_flux(); result["transmission"] = obj.get_transmission(); result["probe"] = obj.get_probe_name(); + result["sample_to_source_distance"] = obj.get_sample_to_source_distance(); return result; } @@ -331,7 +386,8 @@ namespace dxtbx { namespace model { namespace boost_python { boost::python::extract(obj.get("flux", 0)), boost::python::extract(obj.get("transmission", 1)), Beam::get_probe_from_name( - boost::python::extract(obj.get("probe", "x-ray")))); + boost::python::extract(obj.get("probe", "x-ray"))), + boost::python::extract(obj.get("sample_to_source_distance", 0.))); return b; } @@ -380,6 +436,10 @@ namespace dxtbx { namespace model { namespace boost_python { .def("rotate_around_origin", &rotate_around_origin, (arg("axis"), arg("angle"), arg("deg") = true)) + .def("get_sample_to_source_distance", &BeamBase::get_sample_to_source_distance) + .def("set_sample_to_source_distance", + &BeamBase::set_sample_to_source_distance, + (arg("sample_to_source_distance"))) .def("__eq__", &BeamBase::operator==) .def("__ne__", &BeamBase::operator!=) .def("is_similar_to", @@ -388,7 +448,12 @@ namespace dxtbx { namespace model { namespace boost_python { arg("wavelength_tolerance") = 1e-6, arg("direction_tolerance") = 1e-6, arg("polarization_normal_tolerance") = 1e-6, - arg("polarization_fraction_tolerance") = 1e-6)); + arg("polarization_fraction_tolerance") = 1e-6, + arg("divergence") = 1e-6, + arg("sigma_divergence") = 1e-6, + arg("flux_tolerance") = 1e-6, + arg("transmission_tolerance") = 1e-6, + arg("sample_to_source_distance_tolerance") = 1e-6)); // Export Beam : BeamBase class_, bases >("Beam") @@ -422,6 +487,20 @@ namespace dxtbx { namespace model { namespace boost_python { arg("transmission"), arg("probe") = Probe::xray, arg("deg") = true))) + .def("__init__", + make_constructor(&make_beam_w_sample_to_source_distance, + default_call_policies(), + (arg("direction"), + arg("wavelength"), + arg("divergence"), + arg("sigma_divergence"), + arg("polarization_normal"), + arg("polarization_fraction"), + arg("flux"), + arg("transmission"), + arg("probe") = Probe::xray, + arg("sample_to_source_distance") = 0, + arg("deg") = true))) .def("__str__", &beam_to_string) .def("to_dict", &to_dict) .def("from_dict", &from_dict, return_value_policy()) @@ -433,6 +512,10 @@ namespace dxtbx { namespace model { namespace boost_python { class_, bases >( "PolychromaticBeam") .def(init()) + .def("__init__", + make_constructor(&make_PolychromaticBeam_w_sample_to_source_distance, + default_call_policies(), + (arg("direction"), arg("sample_to_source_distance")))) .def("__init__", make_constructor( &make_PolychromaticBeam, default_call_policies(), (arg("direction")))) @@ -454,6 +537,7 @@ namespace dxtbx { namespace model { namespace boost_python { arg("flux"), arg("transmission"), arg("probe") = Probe::xray, + arg("sample_to_source_distance") = 0, arg("deg") = true))) .def("__str__", &PolychromaticBeam_to_string) .def("to_dict", &to_dict) diff --git a/tests/model/test_beam.py b/tests/model/test_beam.py index 40659f4d4..5aea58b1b 100644 --- a/tests/model/test_beam.py +++ b/tests/model/test_beam.py @@ -107,12 +107,14 @@ def test_from_phil(): """ beam { probe = electron + sample_to_source_distance = 4000 } """ ) ).extract() b4 = BeamFactory.from_phil(params3, reference) assert b4.get_probe() == Probe.electron + assert b4.get_sample_to_source_distance() == pytest.approx(4000) def test_scan_varying(): @@ -203,6 +205,7 @@ def test_polychromatic_beam_from_phil(): polarization_fraction = .65 transmission = .5 flux = .75 + sample_to_source_distance = 5000 } """ ) @@ -218,6 +221,7 @@ def test_polychromatic_beam_from_phil(): assert beam.get_polarization_fraction() == pytest.approx(0.65) assert beam.get_transmission() == pytest.approx(0.5) assert beam.get_flux() == pytest.approx(0.75) + assert beam.get_sample_to_source_distance() == pytest.approx(5000) def test_polychromatic_beam_from_dict(): @@ -235,6 +239,7 @@ def test_make_polychromatic_beam(): transmission = 0.5 flux = 0.75 probe = Probe.neutron + sample_to_source_distance = 8500 beam = BeamFactory.make_polychromatic_beam( direction=direction, @@ -245,6 +250,7 @@ def test_make_polychromatic_beam(): transmission=transmission, flux=flux, probe=probe, + sample_to_source_distance=sample_to_source_distance, ) assert beam.get_sample_to_source_direction() == pytest.approx((0.0, 0.0, 1.0)) @@ -255,6 +261,7 @@ def test_make_polychromatic_beam(): assert beam.get_transmission() == pytest.approx(0.5) assert beam.get_flux() == pytest.approx(0.75) assert beam.get_probe() == Probe.neutron + assert beam.get_sample_to_source_distance() == pytest.approx(8500.0) def test_polychromatic_beam_wavelength_guards(): @@ -281,5 +288,5 @@ def test_polychromatic_beam_str(): beam = PolychromaticBeam() assert ( beam.__str__() - == "Beam:\n probe: x-ray\n sample to source direction : {0,0,1}\n divergence: 0\n sigma divergence: 0\n polarization normal: {0,1,0}\n polarization fraction: 0.5\n flux: 0\n transmission: 1\n" + == "Beam:\n probe: x-ray\n sample to source direction : {0,0,1}\n divergence: 0\n sigma divergence: 0\n polarization normal: {0,1,0}\n polarization fraction: 0.5\n flux: 0\n transmission: 1\n sample to source distance : 0\n" )