Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions mxcubecore/HardwareObjects/Beamline.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,10 @@ def energy(self) -> HardwareObject | None:
def flux(self) -> HardwareObject | None:
return self.get_object_by_role("flux")

@property
def dose_rate(self) -> HardwareObject | None:
return self.get_object_by_role("dose_rate")

@property
def beam(self) -> HardwareObject | None:
return self.get_object_by_role("beam")
Expand Down
82 changes: 82 additions & 0 deletions mxcubecore/HardwareObjects/DoseRate.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
# encoding: utf-8
#
# Project name: MXCuBE
# https://github.com/mxcube
#
# This file is part of MXCuBE software.
#
# MXCuBE is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# MXCuBE is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with MXCuBE. If not, see <http://www.gnu.org/licenses/>.
"""Radiation dose for a sample as function of the flux. Uses the beamline.flux
The dose calculation routine has to be provided externally.
Example yml configuration:

.. code-block:: yaml

class: DoseRate.DoseRate
configuration:
actuator_name: doserate
username: Radiation Dose Rate
read_only: True
default_limits: (0,500) # MGy/s
objects:
dose_calculator: dose_calculator.yaml

"""

__copyright__ = """Copyright The MXCuBE Collaboration"""
__license__ = "LGPLv3+"


from mxcubecore import HardwareRepository as HWR
from mxcubecore.HardwareObjects.abstract.AbstractActuator import AbstractActuator


class DoseRate(AbstractActuator):
"""Report the dose rate"""

unit = "MGy/s"

def __init__(self, name):
super().__init__(name)
self.dose_calc = None

def init(self):
"""Initialisation"""
super().init()
self.dose_calc = self.get_object_by_role("dose_calculator")
try:
HWR.beamline.flux.connect("valueChanged", self.update_value)
except AttributeError as err:
raise RuntimeError("Flux reading is not configured") from err

def get_value(self) -> float:
"""Get the dose rate value as function of the photon flux.
Returns:
dose rate [MGy/s]
"""
self._nominal_value = self.calculate_dose(HWR.beamline.flux.get_value())
return self._nominal_value

def calculate_dose(self, flux: float | None = None) -> float:
"""Calculate the dose rate as function of the flux value.
Args:
flux: Flux value. If None, read the current beamline flux.
Returns:
The calculated dose [MGy/s]
"""
if flux is None:
flux = HWR.beamline.flux.get_value()
if flux > 0:
return self.dose_calc(flux)
return 0
45 changes: 45 additions & 0 deletions mxcubecore/HardwareObjects/mockup/DoseRateMockup.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# encoding: utf-8
#
# Project name: MXCuBE
# https://github.com/mxcube
#
# This file is part of MXCuBE software.
#
# MXCuBE is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# MXCuBE is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with MXCuBE. If not, see <http://www.gnu.org/licenses/>.
"""Radiation dose mock object"""

__copyright__ = """Copyright The MXCuBE Collaboration"""
__license__ = "LGPLv3+"

from random import uniform

from mxcubecore import HardwareRepository as HWR
from mxcubecore.HardwareObjects.DoseRate import DoseRate


class DoseRateMockup(DoseRate):
"""DoseRate mock class"""

def calculate_dose(self, flux: float | None = None) -> float:
"""Calculate the dose rate as function of the flux value.
Args:
flux: Flux value.
Returns:
The calculated dose [MGy/s]
"""
if flux is None:
flux = HWR.beamline.flux.get_value()
if flux > 0:
return flux * uniform(0, 300.0) / 1e12 # noqa S311
return 0
7 changes: 7 additions & 0 deletions mxcubecore/configuration/mockup/dose_rate_mockup.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
class: DoseRateMockup.DoseRateMockup
configuration:
actuator_name: doserate
username: Radiation Dose Rate
read_only: true
default_limits: (0,500) # MGy/s
1 change: 1 addition & 0 deletions mxcubecore/configuration/mockup/test/beamline.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ objects:
- energy: energy-mockup.xml
- beam: beam-mockup.xml
- flux: flux-mockup.xml
- dose_rate: dose_rate_mockup.yaml
- detector: detector-mockup.xml
- resolution: resolution-mockup.xml
- safety_shutter: safety-shutter-mockup.xml
Expand Down
59 changes: 59 additions & 0 deletions test/test_dose_rate.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# encoding: utf-8
#
# Project name: MXCuBE
# https://github.com/mxcube
#
# This file is part of MXCuBE software.
#
# MXCuBE is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# MXCuBE is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU General Lesser Public License
# along with MXCuBE. If not, see <http://www.gnu.org/licenses/>.

"""Test suite for AbstractFlux"""

__copyright__ = """ Copyright © 2019-2020 by the MXCuBE collaboration """
__license__ = "LGPLv3+"

import pytest

from test import TestAbstractActuatorBase


@pytest.fixture
def test_object(beamline):
"""Use the dose_rate object from beamline"""
return beamline.dose_rate


class TestDoseRate(TestAbstractActuatorBase.TestAbstractActuatorBase):
"""Test DoseRate"""

def test_initial_value(self, test_object):
assert test_object is not None, (
"DoseRate hardware objects is None (not initialized)"
)

# value should never be None
assert test_object.get_value() is not None, "initial value may not be None"

def test_attributes(self, test_object):
"""Test the attributes"""
assert test_object.read_only is True
assert test_object.get_limits() == test_object._nominal_limits

def test_methods(self, test_object):
value = test_object.get_value()
print(f"------> Dose rate is {value}")
assert isinstance(value, (int, float)), "Dose rate should be int or float"

with pytest.raises(ValueError):
test_object.set_value(value)
Loading