Skip to content

Commit

Permalink
Merge pull request #37 from toastisme/enable_multiple_tof_orientations
Browse files Browse the repository at this point in the history
Added goniometer rotations to ToF workflow.
  • Loading branch information
toastisme committed Dec 14, 2023
2 parents fe5884f + 4418bb7 commit 2e97283
Show file tree
Hide file tree
Showing 13 changed files with 71 additions and 57 deletions.
2 changes: 1 addition & 1 deletion src/dials/algorithms/integration/processor.py
Original file line number Diff line number Diff line change
Expand Up @@ -930,7 +930,7 @@ def summary(self):
Get a summary of the processing
"""
# Compute the task table
if self.experiments.all_stills() or self.experiments.is_single_tof_experiment():
if self.experiments.all_stills() or self.experiments.all_tof_experiments():
rows = [["#", "Group", "Frame From", "Frame To", "# Reflections"]]
for i in range(len(self)):
job = self.manager.job(i)
Expand Down
4 changes: 2 additions & 2 deletions src/dials/algorithms/refinement/parameterisation/configure.py
Original file line number Diff line number Diff line change
Expand Up @@ -395,7 +395,7 @@ def _set_n_intervals(smoother_params, analysis, scan, exp_ids):
def _parameterise_beams(options, experiments, analysis):
beam_params = []

if experiments.is_single_tof_experiment():
if experiments.all_tof_experiments():
return beam_params

sv_beam = options.scan_varying and not options.beam.force_static
Expand Down Expand Up @@ -810,7 +810,7 @@ def build_prediction_parameterisation(

# Build the prediction equation parameterisation
if do_stills: # doing stills
if experiments.is_single_tof_experiment():
if experiments.all_tof_experiments():
PredParam = TOFPredictionParameterisation
elif options.sparse:
if options.spherical_relp_model:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,7 @@ class ExperimentsPredictorFactory:
@staticmethod
def from_experiments(experiments, force_stills=False, spherical_relp=False):

if experiments.is_single_tof_experiment():
if experiments.all_tof_experiments():
return TOFExperimentsPredictor(experiments)

# Determine whether or not to use a stills predictor
Expand Down
2 changes: 1 addition & 1 deletion src/dials/algorithms/refinement/refiner.py
Original file line number Diff line number Diff line change
Expand Up @@ -373,7 +373,7 @@ def _build_components(cls, params, reflections, experiments):
obs["x_resid"] = x_calc - x_obs
obs["y_resid"] = y_calc - y_obs

if experiments.is_single_tof_experiment():
if experiments.all_tof_experiments():

obs["wavelength_resid"] = obs["wavelength_cal"] - obs["wavelength"]
obs["wavelength_resid2"] = (obs["wavelength_cal"] - obs["wavelength"]) ** 2
Expand Down
6 changes: 3 additions & 3 deletions src/dials/algorithms/refinement/reflection_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,7 @@ def from_parameters_reflections_experiments(
flex.set_random_seed(params.random_seed)
logger.debug("Random seed set to %d", params.random_seed)

if experiments.is_single_tof_experiment():
if experiments.all_tof_experiments():
refman = TOFReflectionManager

# check whether we deal with stills or scans
Expand Down Expand Up @@ -269,7 +269,7 @@ def from_parameters_reflections_experiments(
if params.outlier.algorithm in ("null", None):
outlier_detector = None
else:
if experiments.is_single_tof_experiment():
if experiments.all_tof_experiments():
colnames = ["x_resid", "y_resid", "wavelength_resid"]
elif do_stills:
colnames = ["x_resid", "y_resid"]
Expand Down Expand Up @@ -362,7 +362,7 @@ def __init__(
self._axes = [
matrix.col(g.get_rotation_axis()) if g else None for g in goniometers
]
if experiments.is_single_tof_experiment():
if experiments.all_tof_experiments():
self._s0vecs = [None]
else:
self._s0vecs = [matrix.col(e.beam.get_s0()) for e in self._experiments]
Expand Down
2 changes: 1 addition & 1 deletion src/dials/algorithms/refinement/target.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ def from_parameters_and_experiments(

# Determine whether the target is in X, Y, Phi space or just X, Y to choose
# the right Target to instantiate
if experiments.is_single_tof_experiment():
if experiments.all_tof_experiments():
targ = TOFLeastSquaresPositionalResidualWithRmsdCutoff
elif do_stills:
if do_sparse:
Expand Down
1 change: 1 addition & 0 deletions src/dials/algorithms/spot_prediction/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ def __init__(self, experiment, dmin):
self.predictor = TOFReflectionPredictor(
experiment.beam,
experiment.detector,
experiment.goniometer,
experiment.crystal.get_A(),
experiment.crystal.get_unit_cell(),
experiment.crystal.get_space_group().type(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,9 @@ namespace dials { namespace algorithms { namespace boost_python {
void export_tof_ray_predictor() {
// Create and return the wrapper for the spot predictor object
class_<TOFRayPredictor>("TOFRayPredictor", no_init)
.def(init<vec3<double> >((arg("unit_s0"))))
.def(
"__call__", &TOFRayPredictor::operator(), (arg("miller_index"), arg("UB")));
.def(init<vec3<double>, mat3<double>, mat3<double> >(
(arg("unit_s0"), arg("fixed_rotation"), arg("setting_rotation"))))
.def("__call__", &TOFRayPredictor::operator(), (arg("miller_index"), arg("UB")));
}

}}} // namespace dials::algorithms::boost_python
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,7 @@ namespace dials { namespace algorithms { namespace boost_python {
class_<Predictor>("TOFReflectionPredictor", no_init)
.def(init<const PolyBeam&,
const Detector&,
const Goniometer&,
mat3<double>,
const cctbx::uctbx::unit_cell&,
const cctbx::sgtbx::space_group_type&,
Expand Down
91 changes: 49 additions & 42 deletions src/dials/algorithms/spot_prediction/ray_predictor.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ namespace dials { namespace algorithms {
vec2<double> phi;
try {
phi = calculate_rotation_angles_(pstar0);
} catch (error const&) {
} catch (error const &) {
return rays;
}

Expand Down Expand Up @@ -124,7 +124,7 @@ namespace dials { namespace algorithms {
vec2<double> phi;
try {
phi = calculate_rotation_angles_(pstar0);
} catch (error const&) {
} catch (error const &) {
return rays;
}

Expand Down Expand Up @@ -251,52 +251,59 @@ namespace dials { namespace algorithms {
};

/**
* Class to predict s1 rays for ToF data
* Class to predict s1 rays for ToF data
*/
class TOFRayPredictor{
public:
typedef cctbx::miller::index<> miller_index;
class TOFRayPredictor {
public:
typedef cctbx::miller::index<> miller_index;

TOFRayPredictor(const vec3<double> unit_s0) : unit_s0_(unit_s0){
DIALS_ASSERT(unit_s0_.length() > 0.0);
}
TOFRayPredictor(const vec3<double> unit_s0,
mat3<double> fixed_rotation,
mat3<double> setting_rotation)
: unit_s0_(unit_s0),
fixed_rotation_(fixed_rotation),
setting_rotation_(setting_rotation)

/**
* For a given miller index and UB matrix, calculates the predicted s1 ray.
* The TOFRayPredictor wavelength and s0 variables are updated during the calculation,
* so that they can be monitored for convergence.
* @param h The miller index
* @param ub The UB matrix
* @returns Ray
*/
Ray operator()(const miller_index &h,
const mat3<double> &ub){

// Calculate the reciprocal lattice vector
vec3<double> q = ub * h;

// Calculate the wavelength required to meet the diffraction condition
wavelength_ = -2*((unit_s0_ * q)/(q *q));
s0_ = unit_s0_ / wavelength_;
DIALS_ASSERT(s0_.length() > 0);

// Calculate the Ray (default zero angle and 'entering' as false)
vec3<double> s1 = s0_ + q;
return Ray(s1, 0.0, false);
}
{
DIALS_ASSERT(unit_s0_.length() > 0.0);
}

double get_wavelength() const{
return wavelength_;
}
/**
* For a given miller index and UB matrix, calculates the predicted s1 ray.
* The TOFRayPredictor wavelength and s0 variables are updated during the
* calculation, so that they can be monitored for convergence.
* @param h The miller index
* @param ub The UB matrix
* @returns Ray
*/
Ray operator()(const miller_index &h, const mat3<double> &ub) {
// Calculate the reciprocal lattice vector
vec3<double> q = setting_rotation_ * fixed_rotation_ * ub * h;

// Calculate the wavelength required to meet the diffraction condition
wavelength_ = -2 * ((unit_s0_ * q) / (q * q));
s0_ = unit_s0_ / wavelength_;
DIALS_ASSERT(s0_.length() > 0);

// Calculate the Ray (default zero angle and 'entering' as false)
vec3<double> s1 = s0_ + q;
return Ray(s1, 0.0, false);
}

vec3<double> get_s0() const{
return s0_;
}
double get_wavelength() const {
return wavelength_;
}

vec3<double> get_s0() const {
return s0_;
}

private:
const vec3<double> unit_s0_;
double wavelength_;
vec3<double> s0_;
private:
const vec3<double> unit_s0_;
double wavelength_;
vec3<double> s0_;
mat3<double> fixed_rotation_;
mat3<double> setting_rotation_;
};

}} // namespace dials::algorithms
Expand Down
7 changes: 6 additions & 1 deletion src/dials/algorithms/spot_prediction/reflection_predictor.h
Original file line number Diff line number Diff line change
Expand Up @@ -1336,17 +1336,21 @@ namespace dials { namespace algorithms {
*/
TOFReflectionPredictor(const PolyBeam &beam,
const Detector &detector,
const Goniometer &goniometer,
mat3<double> ub,
const cctbx::uctbx::unit_cell &unit_cell,
const cctbx::sgtbx::space_group_type &space_group_type,
const double &dmin)
: beam_(beam),
detector_(detector),
goniometer_(goniometer),
ub_(ub),
unit_cell_(unit_cell),
space_group_type_(space_group_type),
dmin_(dmin),
predict_ray_(beam.get_unit_s0()) {}
predict_ray_(beam.get_unit_s0(),
goniometer.get_fixed_rotation(),
goniometer.get_setting_rotation()) {}

/**
* Predict all reflection.
Expand Down Expand Up @@ -1626,6 +1630,7 @@ namespace dials { namespace algorithms {
protected:
PolyBeam beam_;
Detector detector_;
Goniometer goniometer_;
mat3<double> ub_;
cctbx::uctbx::unit_cell unit_cell_;
cctbx::sgtbx::space_group_type space_group_type_;
Expand Down
2 changes: 1 addition & 1 deletion src/dials/command_line/integrate.py
Original file line number Diff line number Diff line change
Expand Up @@ -486,7 +486,7 @@ def run_integration(params, experiments, reference=None):
logger.info("\n".join(("", "=" * 80, "")))
logger.info(heading("Predicting reflections"))

if experiments.is_single_tof_experiment() and not params.prediction.d_min:
if experiments.all_tof_experiments() and not params.prediction.d_min:

min_s0_idx = min(
range(len(reference["wavelength"])), key=reference["wavelength"].__getitem__
Expand Down
2 changes: 1 addition & 1 deletion src/dials/command_line/symmetry.py
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,7 @@ def eliminate_sys_absent(experiments, reflections):
def get_subset_for_symmetry(experiments, reflection_tables, exclude_images=None):
"""Select an image range for symmetry analysis, or just select
the first 360 degrees of data."""
if experiments.is_single_tof_experiment():
if experiments.all_tof_experiments():
return reflection_tables
refls_for_sym = []
if exclude_images:
Expand Down

0 comments on commit 2e97283

Please sign in to comment.