You can subscribe to this list here.
| 2005 |
Jan
(70) |
Feb
(200) |
Mar
(222) |
Apr
(198) |
May
(122) |
Jun
(74) |
Jul
(171) |
Aug
(235) |
Sep
(118) |
Oct
(165) |
Nov
(276) |
Dec
(167) |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2006 |
Jan
(102) |
Feb
(124) |
Mar
(90) |
Apr
(155) |
May
(162) |
Jun
(285) |
Jul
(142) |
Aug
(136) |
Sep
(251) |
Oct
(188) |
Nov
(156) |
Dec
(144) |
| 2007 |
Jan
(231) |
Feb
(151) |
Mar
(142) |
Apr
(69) |
May
(66) |
Jun
(88) |
Jul
(61) |
Aug
(82) |
Sep
(125) |
Oct
(167) |
Nov
(115) |
Dec
(70) |
| 2008 |
Jan
(112) |
Feb
(109) |
Mar
(163) |
Apr
(239) |
May
(185) |
Jun
(147) |
Jul
(123) |
Aug
(142) |
Sep
(134) |
Oct
(106) |
Nov
(151) |
Dec
(114) |
| 2009 |
Jan
(143) |
Feb
(188) |
Mar
(121) |
Apr
(188) |
May
(193) |
Jun
(113) |
Jul
(161) |
Aug
(172) |
Sep
(95) |
Oct
(157) |
Nov
(123) |
Dec
(112) |
| 2010 |
Jan
(61) |
Feb
(115) |
Mar
(163) |
Apr
(138) |
May
(152) |
Jun
(133) |
Jul
(228) |
Aug
(135) |
Sep
(230) |
Oct
(214) |
Nov
(178) |
Dec
(225) |
| 2011 |
Jan
(197) |
Feb
(284) |
Mar
(244) |
Apr
(190) |
May
(119) |
Jun
(195) |
Jul
(305) |
Aug
(204) |
Sep
(175) |
Oct
(196) |
Nov
(166) |
Dec
(170) |
| 2012 |
Jan
(203) |
Feb
(197) |
Mar
(255) |
Apr
(153) |
May
(111) |
Jun
(130) |
Jul
(82) |
Aug
(207) |
Sep
(103) |
Oct
(173) |
Nov
(150) |
Dec
(171) |
| 2013 |
Jan
(156) |
Feb
(242) |
Mar
(216) |
Apr
(264) |
May
(116) |
Jun
(218) |
Jul
(192) |
Aug
(255) |
Sep
(157) |
Oct
(209) |
Nov
(227) |
Dec
(222) |
| 2014 |
Jan
(207) |
Feb
(214) |
Mar
(223) |
Apr
(125) |
May
(183) |
Jun
(213) |
Jul
(219) |
Aug
(230) |
Sep
(195) |
Oct
(275) |
Nov
(179) |
Dec
(163) |
| 2015 |
Jan
(227) |
Feb
(148) |
Mar
(148) |
Apr
(178) |
May
(228) |
Jun
(195) |
Jul
(155) |
Aug
(168) |
Sep
(168) |
Oct
(151) |
Nov
(259) |
Dec
(137) |
| 2016 |
Jan
(127) |
Feb
(244) |
Mar
(219) |
Apr
(266) |
May
(120) |
Jun
(366) |
Jul
(211) |
Aug
(203) |
Sep
(222) |
Oct
(155) |
Nov
(97) |
Dec
|
|
From: <ph...@us...> - 2016-10-19 23:19:41
|
Revision: 25601
http://sourceforge.net/p/cctbx/code/25601
Author: phyy-nx
Date: 2016-10-19 23:19:39 +0000 (Wed, 19 Oct 2016)
Log Message:
-----------
XFEL DB
Don't cache db object when initializing tables
Reduce number of queries when using trial.rungroups and trial.runs (order N queryies becomes 2 queries)
Modified Paths:
--------------
trunk/xfel/ui/db/xfel_db.py
Modified: trunk/xfel/ui/db/xfel_db.py
===================================================================
--- trunk/xfel/ui/db/xfel_db.py 2016-10-19 23:19:18 UTC (rev 25600)
+++ trunk/xfel/ui/db/xfel_db.py 2016-10-19 23:19:39 UTC (rev 25601)
@@ -26,6 +26,15 @@
"imageset", "imageset_event", "beam", "detector", "experiment",
"crystal", "cell", "cell_bin", "bin", "isoform"]
+ def __getattr__(self, prop):
+ if prop == "dbobj":
+ return get_db_connection(self.params)
+ raise AttributeError("%s not found"%prop)
+
+ def __setattr__(self, prop, val):
+ if prop == "dbobj": pass
+ return super(initialize, self).__setattr__(prop, val)
+
def __init__(self, params, dbobj):
initialize_base.__init__(self, params, dbobj, interactive = False, drop_tables = None)
@@ -310,25 +319,29 @@
return Trial(self, trial_id)
def get_trial_rungroups(self, trial_id, only_active = False):
- query = "SELECT rungroup_id FROM `%s_trial_rungroup` WHERE `%s_trial_rungroup`.trial_id = %d" % \
- (self.params.experiment_tag, self.params.experiment_tag, trial_id)
- cursor = self.execute_query(query)
- rungroups = [Rungroup(self, i[0]) for i in cursor.fetchall()]
+ tag = self.params.experiment_tag
if only_active:
- return [rg for rg in rungroups if rg.active]
+ query = """SELECT t_rg.rungroup_id FROM `%s_trial_rungroup` t_rg
+ JOIN `%s_rungroup` rg ON rg.id = t_rg.rungroup_id
+ WHERE t_rg.trial_id = %d AND rg.active = True""" % (tag, tag, trial_id)
else:
- return rungroups
+ query = """SELECT t_rg.rungroup_id FROM `%s_trial_rungroup` t_rg
+ WHERE t_rg.trial_id = %d""" % (tag, trial_id)
+ cursor = self.execute_query(query)
+ rungroup_ids = ["%d"%i[0] for i in cursor.fetchall()]
+ return self.get_all_x(Rungroup, "rungroup", where = "WHERE rungroup.id IN (%s)"%",".join(rungroup_ids))
def get_trial_runs(self, trial_id):
- rungroups = self.get_trial_rungroups(trial_id, only_active=True)
- runs = []
- run_ids = []
- for rungroup in rungroups:
- for run in rungroup.runs:
- if run.id not in run_ids:
- run_ids.append(run.id)
- runs.append(run)
- return runs
+ tag = self.params.experiment_tag
+ query = """SELECT run.id FROM `%s_run` run
+ JOIN `%s_rungroup` rg ON run.run >= rg.startrun AND run.run <= rg.endrun
+ JOIN `%s_trial_rungroup` t_rg on t_rg.rungroup_id = rg.id
+ JOIN `%s_trial` trial ON trial.id = t_rg.trial_id
+ WHERE trial.id=%d AND rg.active=True
+ """ %(tag, tag, tag, tag, trial_id)
+ cursor = self.execute_query(query)
+ run_ids = ["%d"%i[0] for i in cursor.fetchall()]
+ return self.get_all_x(Run, "run", where = "WHERE run.id IN (%s)"%",".join(run_ids))
def get_all_trials(self, only_active = False):
if only_active:
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <nks...@us...> - 2016-10-19 23:19:20
|
Revision: 25600
http://sourceforge.net/p/cctbx/code/25600
Author: nksauter
Date: 2016-10-19 23:19:18 +0000 (Wed, 19 Oct 2016)
Log Message:
-----------
bugfix
Modified Paths:
--------------
trunk/xfel/cxi/merging_database_fs.py
Modified: trunk/xfel/cxi/merging_database_fs.py
===================================================================
--- trunk/xfel/cxi/merging_database_fs.py 2016-10-19 21:28:27 UTC (rev 25599)
+++ trunk/xfel/cxi/merging_database_fs.py 2016-10-19 23:19:18 UTC (rev 25600)
@@ -217,7 +217,8 @@
def insert_frame(self, **kwargs):
order = []
- if self.params.postrefinement.algorithm in ["rs2","rs_hybrid"]:
+ if self.params.postrefinement.enable==True and \
+ self.params.postrefinement.algorithm in ["rs2","rs_hybrid"]:
order_dict = {'wavelength': 1,
'beam_x': 2,
'beam_y': 3,
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <bk...@us...> - 2016-10-19 21:28:28
|
Revision: 25599
http://sourceforge.net/p/cctbx/code/25599
Author: bkpoon
Date: 2016-10-19 21:28:27 +0000 (Wed, 19 Oct 2016)
Log Message:
-----------
bug fix for choice widget; prevent selection from being None
Modified Paths:
--------------
trunk/wxtbx/phil_controls/choice.py
Modified: trunk/wxtbx/phil_controls/choice.py
===================================================================
--- trunk/wxtbx/phil_controls/choice.py 2016-10-19 17:19:06 UTC (rev 25598)
+++ trunk/wxtbx/phil_controls/choice.py 2016-10-19 21:28:27 UTC (rev 25599)
@@ -11,7 +11,7 @@
self.Bind(wx.EVT_CHOICE, lambda evt: self.DoSendEvent(), self)
def SetChoices (self, choices, captions=None, allow_none=True) :
- selection = None
+ selection = 0
is_selected = [ ("*" in choice) for choice in choices ]
if (True in is_selected) :
selection = is_selected.index(True)
@@ -21,10 +21,9 @@
if (len(captions) != len(choices)) :
raise RuntimeError("Wrong number of caption items for '%s':\n%s\n%s" %
(self.GetName(), ";".join(choices), ";".join(captions)))
- if (selection is None) and (allow_none) :
+ if (allow_none) :
captions.insert(0, "---")
choices.insert(0, None)
- selection = 0
self._options = choices
self.SetItems(captions)
self.SetSelection(selection)
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ph...@us...> - 2016-10-19 17:19:08
|
Revision: 25598
http://sourceforge.net/p/cctbx/code/25598
Author: phyy-nx
Date: 2016-10-19 17:19:06 +0000 (Wed, 19 Oct 2016)
Log Message:
-----------
Speed increase for HDF5 files. Related to dials issue #228. Contributed by @biochem_fan.
Modified Paths:
--------------
trunk/xfel/command_line/filter_experiments_by_rmsd.py
Modified: trunk/xfel/command_line/filter_experiments_by_rmsd.py
===================================================================
--- trunk/xfel/command_line/filter_experiments_by_rmsd.py 2016-10-19 17:04:38 UTC (rev 25597)
+++ trunk/xfel/command_line/filter_experiments_by_rmsd.py 2016-10-19 17:19:06 UTC (rev 25598)
@@ -66,6 +66,7 @@
phil=phil_scope,
read_experiments=True,
read_reflections=True,
+ check_format=False,
epilog=help_message)
def run(self):
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <nks...@us...> - 2016-10-19 17:04:40
|
Revision: 25597
http://sourceforge.net/p/cctbx/code/25597
Author: nksauter
Date: 2016-10-19 17:04:38 +0000 (Wed, 19 Oct 2016)
Log Message:
-----------
cxi.merge. Add range assertions to the rs2 algorithm (changing its output) and allow the option of partiality-weighting for the merging step.
Modified Paths:
--------------
trunk/xfel/cxi/postrefinement_hybrid_rs.py
trunk/xfel/cxi/postrefinement_updated_rs.py
Modified: trunk/xfel/cxi/postrefinement_hybrid_rs.py
===================================================================
--- trunk/xfel/cxi/postrefinement_hybrid_rs.py 2016-10-19 01:38:59 UTC (rev 25596)
+++ trunk/xfel/cxi/postrefinement_hybrid_rs.py 2016-10-19 17:04:38 UTC (rev 25597)
@@ -150,7 +150,8 @@
def result_for_cxi_merge(self, file_name):
scaler = self.nave1_refinery.scaler_callable(self.get_parameter_values())
values = self.get_parameter_values()
- p_scaler = flex.pow(self.refinery.get_partiality_array(values),
+ partiality_array = self.refinery.get_partiality_array(values)
+ p_scaler = flex.pow(partiality_array,
0.5*self.params.postrefinement.merge_partiality_exponent)
fat_selection = (self.nave1_refinery.lorentz_callable(self.get_parameter_values()) >
Modified: trunk/xfel/cxi/postrefinement_updated_rs.py
===================================================================
--- trunk/xfel/cxi/postrefinement_updated_rs.py 2016-10-19 01:38:59 UTC (rev 25596)
+++ trunk/xfel/cxi/postrefinement_updated_rs.py 2016-10-19 17:04:38 UTC (rev 25597)
@@ -4,7 +4,7 @@
from cctbx import miller
from dials.array_family import flex
from scitbx.math.tests.tst_weighted_correlation import simple_weighted_correlation
-from libtbx import adopt_init_args, group_args
+from libtbx import adopt_init_args
from xfel.cxi.postrefinement_legacy_rs import legacy_rs, rs_refinery, rs_parameterization, lbfgs_minimizer_base
class updated_rs(legacy_rs):
@@ -125,13 +125,16 @@
self.MINI = lbfgs_minimizer_derivatives( current_x = self.current,
parameterization = self.parameterization_class, refinery = self.refinery,
out = self.out )
+ self.refined_mini = self.MINI
def result_for_cxi_merge(self, file_name):
scaler = self.refinery.scaler_callable(self.parameterization_class(self.MINI.x))
- if self.params.postrefinement.algorithm=="rs2":
- fat_selection = (self.refinery.lorentz_callable(self.parameterization_class(self.MINI.x)) > 0.2)
- else:
- fat_selection = (self.refinery.lorentz_callable(self.parameterization_class(self.MINI.x)) < 0.9)
+ values = self.get_parameter_values()
+ partiality_array = self.refinery.get_partiality_array(values)
+ p_scaler = flex.pow(partiality_array,
+ 0.5*self.params.postrefinement.merge_partiality_exponent)
+
+ fat_selection = (partiality_array > 0.2)
fat_count = fat_selection.count(True)
#avoid empty database INSERT, if insufficient centrally-located Bragg spots:
@@ -146,7 +149,7 @@
observations = self.observations_pair1_selected.customized_copy(
indices = self.observations_pair1_selected.indices().select(fat_selection),
data = (self.observations_pair1_selected.data()/scaler).select(fat_selection),
- sigmas = (self.observations_pair1_selected.sigmas()/scaler).select(fat_selection)
+ sigmas = (self.observations_pair1_selected.sigmas()/(scaler * p_scaler)).select(fat_selection)
)
matches = miller.match_multi_indices(
miller_indices_unique=self.miller_set.indices(),
@@ -157,58 +160,22 @@
SWC = simple_weighted_correlation(I_weight, I_reference, observations.data())
print >> self.out, "CORR: NEW correlation is", SWC.corr
self.final_corr = SWC.corr
+ self.refined_mini = self.MINI
+ # New range assertions for refined variables
+ # XXX Likely these limits are problem-specific so look for another approach
+ # or expose the limits as phil parameters.
+ assert self.final_corr > 0.1
+ assert 0 < values.G
+ assert -25 < values.BFACTOR and values.BFACTOR < 25
+ assert -0.5 < 180.*values.thetax/math.pi < 0.5 , "limits on the theta rotation, please"
+ assert -0.5 < 180.*values.thetay/math.pi < 0.5 , "limits on the theta rotation, please"
+
return observations_original_index,observations,matches
-class refinery_base(group_args):
- def __init__(self, **kwargs):
- group_args.__init__(self,**kwargs)
- mandatory = ["ORI","MILLER","BEAM","WAVE","ICALCVEC","IOBSVEC"]
- for key in mandatory: getattr(self,key)
- self.DSSQ = self.ORI.unit_cell().d_star_sq(self.MILLER)
+ def get_parameter_values(self):
+ return self.refined_mini.parameterization(self.refined_mini.x)
- """Refinery class takes reference and observations, and implements target
- functions and derivatives for a particular model paradigm."""
- def get_Rh_array(self, values):
- Rh = flex.double()
- eff_Astar = self.get_eff_Astar(values)
- for mill in self.MILLER:
- x = eff_Astar * matrix.col(mill)
- Svec = x + self.BEAM
- Rh.append(Svec.length() - (1./self.WAVE))
- return Rh
-
- def get_s1_array(self, values):
- miller_vec = self.MILLER.as_vec3_double()
- ref_ori = matrix.sqr(self.ORI.reciprocal_matrix())
- Rx = matrix.col((1,0,0)).axis_and_angle_as_r3_rotation_matrix(values.thetax)
- Ry = matrix.col((0,1,0)).axis_and_angle_as_r3_rotation_matrix(values.thetay)
- s_array = flex.mat3_double(len(self.MILLER),Ry * Rx * ref_ori) * miller_vec
- s1_array = s_array + flex.vec3_double(len(self.MILLER), self.BEAM)
- return s1_array
-
- def get_eff_Astar(self, values):
- thetax = values.thetax; thetay = values.thetay;
- effective_orientation = self.ORI.rotate_thru((1,0,0),thetax
- ).rotate_thru((0,1,0),thetay
- )
- return matrix.sqr(effective_orientation.reciprocal_matrix())
-
- def scaler_callable(self, values):
- PB = self.get_partiality_array(values)
- EXP = flex.exp(-2.*values.BFACTOR*self.DSSQ)
- terms = values.G * EXP * PB
- return terms
-
- def fvec_callable(self, values):
- PB = self.get_partiality_array(values)
- EXP = flex.exp(-2.*values.BFACTOR*self.DSSQ)
- terms = (values.G * EXP * PB * self.ICALCVEC - self.IOBSVEC)
- # Ideas for improvement
- # straightforward to also include sigma weighting
- # add extra terms representing rotational excursion: terms.concatenate(1.e7*Rh)
- return terms
-
class rs2_refinery(rs_refinery):
def jacobian_callable(self,values):
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ole...@us...> - 2016-10-19 01:39:01
|
Revision: 25596
http://sourceforge.net/p/cctbx/code/25596
Author: olegsobolev
Date: 2016-10-19 01:38:59 +0000 (Wed, 19 Oct 2016)
Log Message:
-----------
Use newly generated SS restraints for the final refinement.
Modified Paths:
--------------
trunk/mmtbx/command_line/model_idealization.py
Modified: trunk/mmtbx/command_line/model_idealization.py
===================================================================
--- trunk/mmtbx/command_line/model_idealization.py 2016-10-19 01:38:09 UTC (rev 25595)
+++ trunk/mmtbx/command_line/model_idealization.py 2016-10-19 01:38:59 UTC (rev 25596)
@@ -536,6 +536,20 @@
# still need to run gm if rotamers were fixed
print >> self.log, "Not using ncs"
+ # need to update SS manager for the whole model here.
+ if self.params.use_ss_restraints:
+ ss_manager = manager(
+ pdb_hierarchy=self.whole_pdb_h,
+ geometry_restraints_manager=self.whole_grm.geometry,
+ sec_str_from_pdb_file=self.filtered_whole_ann,
+ params=None,
+ mon_lib_srv=self.mon_lib_srv,
+ verbose=-1,
+ log=self.log)
+ self.whole_grm.geometry.set_secondary_structure_restraints(
+ ss_manager=ss_manager,
+ hierarchy=self.whole_pdb_h,
+ log=self.log)
print >> self.log, "loop_ideal.ref_exclusion_selection", loop_ideal.ref_exclusion_selection
print >> self.log, "Minimizing whole model"
self.minimize(
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ole...@us...> - 2016-10-19 01:38:12
|
Revision: 25595
http://sourceforge.net/p/cctbx/code/25595
Author: olegsobolev
Date: 2016-10-19 01:38:09 +0000 (Wed, 19 Oct 2016)
Log Message:
-----------
2 out of 3 tests prove to be unstable...
Modified Paths:
--------------
trunk/mmtbx/building/tst.py
Modified: trunk/mmtbx/building/tst.py
===================================================================
--- trunk/mmtbx/building/tst.py 2016-10-19 00:39:45 UTC (rev 25594)
+++ trunk/mmtbx/building/tst.py 2016-10-19 01:38:09 UTC (rev 25595)
@@ -83,7 +83,7 @@
def exercise_map_utils () :
#
- # UNSTABLE
+ # UNSTABLE 2x
#
hierarchy, fmodel = get_1yjp_pdb_and_fmodel()
sel_cache = hierarchy.atom_selection_cache()
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ole...@us...> - 2016-10-19 00:39:47
|
Revision: 25594
http://sourceforge.net/p/cctbx/code/25594
Author: olegsobolev
Date: 2016-10-19 00:39:45 +0000 (Wed, 19 Oct 2016)
Log Message:
-----------
Actually use SS restraints in refinements.
Modified Paths:
--------------
trunk/mmtbx/command_line/model_idealization.py
Modified: trunk/mmtbx/command_line/model_idealization.py
===================================================================
--- trunk/mmtbx/command_line/model_idealization.py 2016-10-18 19:32:13 UTC (rev 25593)
+++ trunk/mmtbx/command_line/model_idealization.py 2016-10-19 00:39:45 UTC (rev 25594)
@@ -4,6 +4,7 @@
import sys, os
from iotbx.pdb import secondary_structure as ioss
from mmtbx.secondary_structure import build as ssb
+from mmtbx.secondary_structure import manager
import mmtbx.utils
from scitbx.array_family import flex
from iotbx.pdb import write_whole_pdb_file
@@ -42,6 +43,9 @@
.type = bool
.help = At the late stage if rotamer is still outlier choose another one \
with minimal clash with surrounding atoms
+use_ss_restraints = True
+ .type = bool
+ .help = Use Secondary Structure restraints
use_starting_model_for_final_gm = False
.type = bool
.help = Use supplied model for final geometry minimization. Otherwise just \
@@ -140,7 +144,7 @@
if c.is_ca_only():
ca_only_present = True
if ca_only_present:
- raise Sorry("Don't support modes with chains containing only CA atoms.")
+ raise Sorry("Don't support models with chains containing only CA atoms.")
self.original_boxed_hierarchy = self.original_hierarchy.deep_copy()
self.original_boxed_hierarchy.reset_atom_i_seqs()
@@ -299,6 +303,21 @@
self.whole_grm = get_geometry_restraints_manager(
processed_pdb_file, self.whole_xrs, params=params)
+ # set SS restratins
+ if self.params.use_ss_restraints:
+ ss_manager = manager(
+ pdb_hierarchy=self.whole_pdb_h,
+ geometry_restraints_manager=self.whole_grm.geometry,
+ sec_str_from_pdb_file=self.filtered_whole_ann,
+ params=None,
+ mon_lib_srv=self.mon_lib_srv,
+ verbose=-1,
+ log=self.log)
+ self.whole_grm.geometry.set_secondary_structure_restraints(
+ ss_manager=ss_manager,
+ hierarchy=self.whole_pdb_h,
+ log=self.log)
+
# now select part of it for working with master hierarchy
if self.using_ncs:
self.master_grm = self.whole_grm.select(self.master_sel)
@@ -356,29 +375,35 @@
self.prepare_reference_map_3(xrs=self.whole_xrs, pdb_h=self.whole_pdb_h)
# STOP()
- # getting grm without SS restraints
- self.get_grm()
-
if self.ann.get_n_helices() + self.ann.get_n_sheets() == 0:
self.ann = self.pdb_input.extract_secondary_structure()
self.original_ann = None
+ self.filtered_whole_ann = None
if self.ann is not None:
self.original_ann = self.ann.deep_copy()
print >> self.log, "Original SS annotation"
print >> self.log, self.original_ann.as_pdb_str()
- if self.ann is not None:
self.ann.remove_short_annotations()
+ self.filtered_whole_ann = self.ann.deep_copy()
self.ann.remove_empty_annotations(
hierarchy=self.working_pdb_h)
+ self.filtered_whole_ann.remove_empty_annotations(
+ hierarchy=self.whole_pdb_h)
# self.ann.concatenate_consecutive_helices()
self.ann.split_helices_with_prolines(
hierarchy=self.working_pdb_h,
asc=None)
+ self.filtered_whole_ann.split_helices_with_prolines(
+ hierarchy=self.whole_pdb_h,
+ asc=None)
# print >> self.log, "Splitted SS annotation"
# print >> self.log, ann.as_pdb_str()
print >> self.log, "Filtered SS annotation"
print >> self.log, self.ann.as_pdb_str()
- # STOP()
+
+ # getting grm with SS restraints
+ self.get_grm()
+
if (self.ann is None or
self.ann.get_n_helices() + self.ann.get_n_sheets() == 0 or
not self.params.ss_idealization.enabled):
@@ -412,6 +437,7 @@
xray_structure=self.working_xrs,
ss_annotation=self.ann,
params=self.params.ss_idealization,
+ grm=self.working_grm,
fix_rotamer_outliers=True,
cif_objects=self.cif_objects,
verbose=True,
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ole...@us...> - 2016-10-18 19:32:15
|
Revision: 25593
http://sourceforge.net/p/cctbx/code/25593
Author: olegsobolev
Date: 2016-10-18 19:32:13 +0000 (Tue, 18 Oct 2016)
Log Message:
-----------
Refuse to work on some models.
Modified Paths:
--------------
trunk/mmtbx/command_line/model_idealization.py
Modified: trunk/mmtbx/command_line/model_idealization.py
===================================================================
--- trunk/mmtbx/command_line/model_idealization.py 2016-10-18 19:31:34 UTC (rev 25592)
+++ trunk/mmtbx/command_line/model_idealization.py 2016-10-18 19:32:13 UTC (rev 25593)
@@ -133,6 +133,14 @@
o_c.raise_residue_groups_with_multiple_resnames_using_same_altloc_if_necessary()
o_c.raise_chains_with_mix_of_proper_and_improper_alt_conf_if_necessary()
o_c.raise_improper_alt_conf_if_necessary()
+ if len(self.original_hierarchy.models()) > 1:
+ raise Sorry("Multi model files are not supported")
+ ca_only_present = False
+ for c in self.original_hierarchy.only_model().chains():
+ if c.is_ca_only():
+ ca_only_present = True
+ if ca_only_present:
+ raise Sorry("Don't support modes with chains containing only CA atoms.")
self.original_boxed_hierarchy = self.original_hierarchy.deep_copy()
self.original_boxed_hierarchy.reset_atom_i_seqs()
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ole...@us...> - 2016-10-18 19:31:36
|
Revision: 25592
http://sourceforge.net/p/cctbx/code/25592
Author: olegsobolev
Date: 2016-10-18 19:31:34 +0000 (Tue, 18 Oct 2016)
Log Message:
-----------
Need processed_pdb_file for reference restraints. Very frustrating.
Modified Paths:
--------------
trunk/mmtbx/refinement/geometry_minimization.py
Modified: trunk/mmtbx/refinement/geometry_minimization.py
===================================================================
--- trunk/mmtbx/refinement/geometry_minimization.py 2016-10-18 19:19:17 UTC (rev 25591)
+++ trunk/mmtbx/refinement/geometry_minimization.py 2016-10-18 19:31:34 UTC (rev 25592)
@@ -426,38 +426,38 @@
log = null_out()
# assert hierarchy.atoms_size()==xrs.scatterers().size(), "%d %d" % (
# hierarchy.atoms_size(), xrs.scatterers().size())
- if grm is None:
- params_line = grand_master_phil_str
- params = iotbx.phil.parse(
- input_string=params_line, process_includes=True).extract()
- params.pdb_interpretation.clash_guard.nonbonded_distance_threshold=None
- params.pdb_interpretation.peptide_link.ramachandran_restraints = True
- params.pdb_interpretation.peptide_link.oldfield.weight_scale=oldfield_weight_scale
- params.pdb_interpretation.peptide_link.oldfield.plot_cutoff=oldfield_plot_cutoff
- params.pdb_interpretation.nonbonded_weight = nonbonded_weight
- params.pdb_interpretation.c_beta_restraints=True
- params.pdb_interpretation.max_reasonable_bond_distance = None
- params.pdb_interpretation.peptide_link.apply_peptide_plane = True
- params.pdb_interpretation.ncs_search.enabled = True
- params.pdb_interpretation.restraints_library.rdl = True
+ params_line = grand_master_phil_str
+ params = iotbx.phil.parse(
+ input_string=params_line, process_includes=True).extract()
+ params.pdb_interpretation.clash_guard.nonbonded_distance_threshold=None
+ params.pdb_interpretation.peptide_link.ramachandran_restraints = True
+ params.pdb_interpretation.peptide_link.oldfield.weight_scale=oldfield_weight_scale
+ params.pdb_interpretation.peptide_link.oldfield.plot_cutoff=oldfield_plot_cutoff
+ params.pdb_interpretation.nonbonded_weight = nonbonded_weight
+ params.pdb_interpretation.c_beta_restraints=True
+ params.pdb_interpretation.max_reasonable_bond_distance = None
+ params.pdb_interpretation.peptide_link.apply_peptide_plane = True
+ params.pdb_interpretation.ncs_search.enabled = True
+ params.pdb_interpretation.restraints_library.rdl = True
- processed_pdb_files_srv = mmtbx.utils.\
- process_pdb_file_srv(
- crystal_symmetry= xrs.crystal_symmetry(),
- pdb_interpretation_params = params.pdb_interpretation,
- stop_for_unknowns = False,
- log=log,
- cif_objects=None)
- processed_pdb_file, junk = processed_pdb_files_srv.\
- process_pdb_files(raw_records=flex.split_lines(hierarchy.as_pdb_string()))
+ processed_pdb_files_srv = mmtbx.utils.\
+ process_pdb_file_srv(
+ crystal_symmetry= xrs.crystal_symmetry(),
+ pdb_interpretation_params = params.pdb_interpretation,
+ stop_for_unknowns = False,
+ log=log,
+ cif_objects=None)
+ processed_pdb_file, junk = processed_pdb_files_srv.\
+ process_pdb_files(raw_records=flex.split_lines(hierarchy.as_pdb_string()))
- mon_lib_srv = processed_pdb_files_srv.mon_lib_srv
- ener_lib = processed_pdb_files_srv.ener_lib
+ mon_lib_srv = processed_pdb_files_srv.mon_lib_srv
+ ener_lib = processed_pdb_files_srv.ener_lib
- ncs_restraints_group_list = []
- if processed_pdb_file.ncs_obj is not None:
- ncs_restraints_group_list = processed_pdb_file.ncs_obj.get_ncs_restraints_group_list()
+ ncs_restraints_group_list = []
+ if processed_pdb_file.ncs_obj is not None:
+ ncs_restraints_group_list = processed_pdb_file.ncs_obj.get_ncs_restraints_group_list()
+ if grm is None:
grm = get_geometry_restraints_manager(
processed_pdb_file, xrs, params=params)
else:
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <chr...@us...> - 2016-10-18 19:19:19
|
Revision: 25591
http://sourceforge.net/p/cctbx/code/25591
Author: chrisjwilliams
Date: 2016-10-18 19:19:17 +0000 (Tue, 18 Oct 2016)
Log Message:
-----------
tweak to printing of kinemage masters for Virtual BB
Modified Paths:
--------------
trunk/mmtbx/kinemage/validation.py
Modified: trunk/mmtbx/kinemage/validation.py
===================================================================
--- trunk/mmtbx/kinemage/validation.py 2016-10-18 19:06:26 UTC (rev 25590)
+++ trunk/mmtbx/kinemage/validation.py 2016-10-18 19:19:17 UTC (rev 25591)
@@ -795,6 +795,7 @@
@1viewid {Overview}
@master {mainchain} indent
@master {Calphas} indent
+@master {Virtual BB} indent
@master {sidechain} indent
@master {H's} indent
@pointmaster 'H' {H's}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ole...@us...> - 2016-10-18 19:06:28
|
Revision: 25590
http://sourceforge.net/p/cctbx/code/25590
Author: olegsobolev
Date: 2016-10-18 19:06:26 +0000 (Tue, 18 Oct 2016)
Log Message:
-----------
Function to check chain for contatining only CA atoms.
Modified Paths:
--------------
trunk/iotbx/pdb/hierarchy.py
trunk/iotbx/pdb/tst_hierarchy.py
Modified: trunk/iotbx/pdb/hierarchy.py
===================================================================
--- trunk/iotbx/pdb/hierarchy.py 2016-10-18 17:45:43 UTC (rev 25589)
+++ trunk/iotbx/pdb/hierarchy.py 2016-10-18 19:06:26 UTC (rev 25590)
@@ -1838,6 +1838,18 @@
return True
return False
+ def is_ca_only(self):
+ """
+ Determine if chain consists only from CA atoms.
+ Upgrade options:
+ - implement threshold for cases where several residues are present in
+ full;
+ - figure out how to deal with HETATM records of the same chain.
+ - Ignore possible incorrect alignment of atom names.
+ """
+ atom_names = self.atoms().extract_name()
+ return atom_names.all_eq(" CA ")
+
class _(boost.python.injector, ext.residue_group, __hash_eq_mixin):
def only_atom_group(self):
Modified: trunk/iotbx/pdb/tst_hierarchy.py
===================================================================
--- trunk/iotbx/pdb/tst_hierarchy.py 2016-10-18 17:45:43 UTC (rev 25589)
+++ trunk/iotbx/pdb/tst_hierarchy.py 2016-10-18 19:06:26 UTC (rev 25590)
@@ -6659,6 +6659,44 @@
assert h3.atoms()[0].parent() is not None # WORKING!!!
show_atoms(h3)
+def exercise_is_ca_only():
+ pdb_inp = pdb.input(source_info=None, lines=flex.split_lines("""\
+ATOM 0 N ASP A 1 49.347 -62.804 60.380 1.00 34.60 N
+ATOM 1 CA ASP A 1 47.975 -63.194 59.946 1.00 33.86 C
+ATOM 2 C ASP A 1 47.122 -63.665 61.114 1.00 34.02 C
+ATOM 3 O ASP A 1 47.573 -64.451 61.947 1.00 32.23 O
+ATOM 4 N VAL A 2 45.889 -63.176 61.175 1.00 31.94 N
+ATOM 5 CA VAL A 2 44.978 -63.576 62.233 1.00 29.81 C
+ATOM 6 C VAL A 2 44.472 -64.973 61.900 1.00 28.28 C
+ATOM 7 O VAL A 2 43.989 -65.221 60.796 1.00 27.24 O
+ATOM 8 N GLN B 3 44.585 -65.878 62.864 1.00 25.93 N
+ATOM 9 CA GLN B 3 44.166 -67.262 62.686 1.00 24.46 C
+ATOM 10 C GLN B 3 42.730 -67.505 63.153 1.00 23.33 C
+ATOM 11 O GLN B 3 42.389 -67.234 64.302 1.00 20.10 O
+ATOM 12 N MET B 4 41.894 -68.026 62.256 1.00 24.27 N
+ATOM 13 CA MET B 4 40.497 -68.318 62.576 1.00 22.89 C
+ATOM 14 C MET B 4 40.326 -69.824 62.795 1.00 21.48 C
+ATOM 15 O MET B 4 40.633 -70.625 61.911 1.00 23.73 O
+"""))
+ pdb_h = pdb_inp.construct_hierarchy()
+ for chain in pdb_h.only_model().chains():
+ assert not chain.is_ca_only()
+ pdb_inp = pdb.input(source_info=None, lines=flex.split_lines("""\
+ATOM 1 CA ASP A 1 47.975 -63.194 59.946 1.00 33.86 C
+ATOM 5 CA VAL A 2 44.978 -63.576 62.233 1.00 29.81 C
+ATOM 8 N GLN B 3 44.585 -65.878 62.864 1.00 25.93 N
+ATOM 9 CA GLN B 3 44.166 -67.262 62.686 1.00 24.46 C
+ATOM 10 C GLN B 3 42.730 -67.505 63.153 1.00 23.33 C
+ATOM 11 O GLN B 3 42.389 -67.234 64.302 1.00 20.10 O
+ATOM 12 N MET B 4 41.894 -68.026 62.256 1.00 24.27 N
+ATOM 13 CA MET B 4 40.497 -68.318 62.576 1.00 22.89 C
+ATOM 14 C MET B 4 40.326 -69.824 62.795 1.00 21.48 C
+ATOM 15 O MET B 4 40.633 -70.625 61.911 1.00 23.73 O
+"""))
+ pdb_h = pdb_inp.construct_hierarchy()
+ result = [chain.is_ca_only() for chain in pdb_h.only_model().chains()]
+ assert result == [True, False], result
+
def exercise(args):
comprehensive = "--comprehensive" in args
forever = "--forever" in args
@@ -6718,6 +6756,7 @@
exercise_atom_xyz_9999()
# exercise_is_pure_main_conf()
exercise_selection_and_deep_copy()
+ exercise_is_ca_only()
if (not forever): break
print format_cpu_times()
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ole...@us...> - 2016-10-18 17:45:45
|
Revision: 25589
http://sourceforge.net/p/cctbx/code/25589
Author: olegsobolev
Date: 2016-10-18 17:45:43 +0000 (Tue, 18 Oct 2016)
Log Message:
-----------
check the case when all MTRIX records are identity matrices (2jee).
Modified Paths:
--------------
trunk/iotbx/ncs/__init__.py
trunk/iotbx/pdb/__init__.py
trunk/iotbx/pdb/multimer_reconstruction.py
Modified: trunk/iotbx/ncs/__init__.py
===================================================================
--- trunk/iotbx/ncs/__init__.py 2016-10-18 15:57:06 UTC (rev 25588)
+++ trunk/iotbx/ncs/__init__.py 2016-10-18 17:45:43 UTC (rev 25589)
@@ -603,7 +603,7 @@
group_by_tr[tr_id] = [[key],[selection_str]]
group_key = set([' or '.join(group_by_tr[x][0]) for x in group_by_tr])
group_val = [' or '.join(group_by_tr[x][1]) for x in group_by_tr]
- assert len(group_key) == 1
+ assert len(group_key) == 1, group_key
gk = list(group_key)[0]
self.ncs_to_asu_selection[gk] = group_val
# add the identity case to tr_id_to_selection
Modified: trunk/iotbx/pdb/__init__.py
===================================================================
--- trunk/iotbx/pdb/__init__.py 2016-10-18 15:57:06 UTC (rev 25588)
+++ trunk/iotbx/pdb/__init__.py 2016-10-18 17:45:43 UTC (rev 25589)
@@ -1161,7 +1161,6 @@
translation_vectors=self.t,
serial_numbers=self.serial_number,
coordinates_present_flags=self.coordinates_present)
-
def format_BOIMT_pdb_string(self):
'''
BIOMT data sample
@@ -1176,7 +1175,16 @@
lines.append(fmt2%(int(sn_), r_[3],r_[4],r_[5], t_[1]))
lines.append(fmt3%(int(sn_), r_[6],r_[7],r_[8], t_[2]))
return "\n".join(lines)
+ def contains_only_identity_matrices(self):
+ """
+ Check if the object contains only identity matrices, e.g. PDBID 2jee
+ """
+ result = True
+ for r, t in zip(self.r, self.t):
+ result = result and (r.is_r3_identity_matrix() and t.is_col_zero())
+ return result
+
def process_BIOMT_records(self,error_handle=True,eps=1e-4):
'''(pdb_data,boolean,float) -> group of lists
extract REMARK 350 BIOMT information, information that provides rotation matrices
Modified: trunk/iotbx/pdb/multimer_reconstruction.py
===================================================================
--- trunk/iotbx/pdb/multimer_reconstruction.py 2016-10-18 15:57:06 UTC (rev 25588)
+++ trunk/iotbx/pdb/multimer_reconstruction.py 2016-10-18 17:45:43 UTC (rev 25589)
@@ -81,7 +81,9 @@
transform_info = pdb_inp.process_mtrix_records(
error_handle=error_handle,
eps=eps)
- if transform_info.as_pdb_string() == '' or (not ncs_only(transform_info)):
+ if (transform_info.as_pdb_string() == '' or
+ not ncs_only(transform_info) or
+ transform_info.contains_only_identity_matrices()):
transform_info = None
else:
transform_info = insure_identity_is_in_transform_info(transform_info)
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <kei...@us...> - 2016-10-18 15:57:08
|
Revision: 25588
http://sourceforge.net/p/cctbx/code/25588
Author: keitaroyam
Date: 2016-10-18 15:57:06 +0000 (Tue, 18 Oct 2016)
Log Message:
-----------
Made zero pixels valid (trusted_range is not inclusive!)
Committed on behalf of Takanori
Modified Paths:
--------------
trunk/dxtbx/format/FormatHDF5SaclaMPCCD.py
Modified: trunk/dxtbx/format/FormatHDF5SaclaMPCCD.py
===================================================================
--- trunk/dxtbx/format/FormatHDF5SaclaMPCCD.py 2016-10-18 11:27:34 UTC (rev 25587)
+++ trunk/dxtbx/format/FormatHDF5SaclaMPCCD.py 2016-10-18 15:57:06 UTC (rev 25588)
@@ -127,7 +127,7 @@
self.PIXEL_SIZE),
image_size = (self.RECONST_SIZE,
self.RECONST_SIZE),
- trusted_range = (0, 65535),
+ trusted_range = (-1, 65535),
px_mm = px_mm,
mask = []) # TODO: add gaps
@@ -151,7 +151,7 @@
p.set_type("SENSOR_PAD")
p.set_name('Panel%d' % i)
p.set_image_size((512, 1024))
- p.set_trusted_range((0, 65535))
+ p.set_trusted_range((-1, 65535))
p.set_pixel_size((self.PIXEL_SIZE, self.PIXEL_SIZE))
p.set_thickness(t0)
p.set_local_frame(
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <jm...@us...> - 2016-10-18 11:27:37
|
Revision: 25587
http://sourceforge.net/p/cctbx/code/25587
Author: jmp85
Date: 2016-10-18 11:27:34 +0000 (Tue, 18 Oct 2016)
Log Message:
-----------
Added identifier to panel class. Also did a cleanc lutter
Modified Paths:
--------------
trunk/dxtbx/format/FormatHDF5SaclaMPCCD.py
trunk/dxtbx/model/boost_python/panel.cc
trunk/dxtbx/model/detector.py
trunk/dxtbx/model/panel.h
trunk/dxtbx/tests/model/tst_detector.py
Modified: trunk/dxtbx/format/FormatHDF5SaclaMPCCD.py
===================================================================
--- trunk/dxtbx/format/FormatHDF5SaclaMPCCD.py 2016-10-18 08:32:32 UTC (rev 25586)
+++ trunk/dxtbx/format/FormatHDF5SaclaMPCCD.py 2016-10-18 11:27:34 UTC (rev 25587)
@@ -44,7 +44,7 @@
# These hard-coded values can be overwritten
# by MPCCD_GEOMETRY and MPCCD_DISTANCE
- #
+ #
# These values can be retrieved from SACLA API.
# Alternatively, you can get it from a CrystFEL geometry file by
# awk '/corner_x/{x=50*$3} /corner_y/{y=50*$3; printf x","y","rot","}
Modified: trunk/dxtbx/model/boost_python/panel.cc
===================================================================
--- trunk/dxtbx/model/boost_python/panel.cc 2016-10-18 08:32:32 UTC (rev 25586)
+++ trunk/dxtbx/model/boost_python/panel.cc 2016-10-18 11:27:34 UTC (rev 25587)
@@ -401,7 +401,8 @@
tiny<double,2>,
double,
std::string,
- double>((
+ double,
+ std::string>((
arg("type"),
arg("name"),
arg("fast_axis"),
@@ -412,7 +413,8 @@
arg("trusted_range"),
arg("thickness"),
arg("material"),
- arg("mu")=0.0)))
+ arg("mu")=0.0,
+ arg("identifier")="")))
.def(init<std::string,
std::string,
tiny<double,3>,
@@ -424,7 +426,8 @@
double,
std::string,
shared_ptr<PxMmStrategy>,
- double >((
+ double,
+ std::string>((
arg("type"),
arg("name"),
arg("fast_axis"),
@@ -436,7 +439,10 @@
arg("thickness"),
arg("material"),
arg("px_mm"),
- arg("mu")=0.0)))
+ arg("mu")=0.0,
+ arg("identifier")="")))
+ .def("get_identifier", &Panel::get_identifier)
+ .def("set_identifier", &Panel::set_identifier)
.def("get_gain", &Panel::get_gain)
.def("set_gain", &Panel::set_gain)
.def("get_image_size_mm", &Panel::get_image_size_mm)
Modified: trunk/dxtbx/model/detector.py
===================================================================
--- trunk/dxtbx/model/detector.py 2016-10-18 08:32:32 UTC (rev 25586)
+++ trunk/dxtbx/model/detector.py 2016-10-18 11:27:34 UTC (rev 25587)
@@ -41,7 +41,7 @@
def make_detector(stype, fast_axis, slow_axis, origin,
pixel_size, image_size, trusted_range = (0.0, 0.0),
px_mm=None, name="Panel", thickness=0.0, material='',
- mu=0.0, gain=None):
+ mu=0.0, gain=None, identifier=""):
"""Ensure all types are correct before creating c++ detector class."""
if px_mm is None:
@@ -61,6 +61,7 @@
p.set_thickness(thickness)
p.set_material(material)
p.set_px_mm_strategy(px_mm)
+ p.set_identifier(identifier)
if gain is not None:
p.set_gain(gain)
except Exception, e:
@@ -71,7 +72,7 @@
@staticmethod
def simple(sensor, distance, beam_centre, fast_direction, slow_direction,
pixel_size, image_size, trusted_range = (0.0, 0.0), mask = [],
- px_mm=None, mu=0.0):
+ px_mm=None, mu=0.0, identifier=""):
'''Construct a simple detector at a given distance from the sample
along the direct beam presumed to be aligned with -z, offset by the
beam centre - the directions of which are given by the fast and slow
@@ -100,7 +101,15 @@
detector = detector_factory.make_detector(
detector_factory.sensor(sensor),
- fast, slow, origin, pixel_size, image_size, trusted_range, px_mm, mu=mu)
+ fast,
+ slow,
+ origin,
+ pixel_size,
+ image_size,
+ trusted_range,
+ px_mm,
+ mu=mu,
+ identifier=identifier)
detector[0].mask = mask
return detector
@@ -108,7 +117,7 @@
def two_theta(sensor, distance, beam_centre, fast_direction,
slow_direction, two_theta_direction, two_theta_angle,
pixel_size, image_size, trusted_range = (0.0, 0.0),
- mask = [], px_mm = None, mu=0.0):
+ mask = [], px_mm = None, mu=0.0, identifier=""):
'''Construct a simple detector at a given distance from the sample
along the direct beam presumed to be aligned with -z, offset by the
beam centre - the directions of which are given by the fast and slow
@@ -146,14 +155,15 @@
detector = detector_factory.make_detector(
detector_factory.sensor(sensor),
(R * fast), (R * slow), (R * origin), pixel_size,
- image_size, trusted_range, px_mm, mu=mu)
+ image_size, trusted_range, px_mm, mu=mu, identifier=identifier)
detector.mask = mask
return detector
@staticmethod
def complex(sensor, origin, fast, slow, pixel, size,
- trusted_range = (0.0, 0.0), px_mm = None, gain = None):
+ trusted_range = (0.0, 0.0), px_mm = None, gain = None,
+ identifier=""):
'''A complex detector model, where you know exactly where everything
is. This is useful for implementation of the Rigaku Saturn header
format, as that is exactly what is in there. Origin, fast and slow are
@@ -168,7 +178,8 @@
return detector_factory.make_detector(
detector_factory.sensor(sensor),
- fast, slow, origin, pixel, size, trusted_range, px_mm, gain=gain)
+ fast, slow, origin, pixel, size, trusted_range, px_mm, gain=gain,
+ identifier=identifier)
@staticmethod
def imgCIF(cif_file, sensor):
Modified: trunk/dxtbx/model/panel.h
===================================================================
--- trunk/dxtbx/model/panel.h 2016-10-18 08:32:32 UTC (rev 25586)
+++ trunk/dxtbx/model/panel.h 2016-10-18 11:27:34 UTC (rev 25587)
@@ -54,13 +54,15 @@
tiny<double,2> trusted_range,
double thickness,
std::string material,
- double mu)
+ double mu,
+ std::string identifier)
: PanelData(type, name,
fast_axis, slow_axis, origin,
pixel_size, image_size,
trusted_range, thickness, material, mu),
gain_(1.0),
- convert_coord_(new SimplePxMmStrategy()) {}
+ convert_coord_(new SimplePxMmStrategy()),
+ identifier_(identifier) {}
/** Construct with data with px/mm strategy */
Panel(std::string type,
@@ -74,16 +76,32 @@
double thickness,
std::string material,
shared_ptr<PxMmStrategy> convert_coord,
- double mu)
+ double mu,
+ std::string identifier)
: PanelData(type, name,
fast_axis, slow_axis, origin,
pixel_size, image_size,
trusted_range, thickness, material, mu),
gain_(1.0),
- convert_coord_(convert_coord) {}
+ convert_coord_(convert_coord),
+ identifier_(identifier) {}
virtual ~Panel() {}
+ /**
+ * Set the identifier
+ */
+ void set_identifier(std::string identifier) {
+ identifier_ = identifier;
+ }
+
+ /**
+ * Get the identifier
+ */
+ std::string get_identifier() const {
+ return identifier_;
+ }
+
/** Set the gain */
void set_gain(double gain) {
DXTBX_ASSERT(gain > 0);
@@ -274,12 +292,16 @@
double gain_;
shared_ptr<PxMmStrategy> convert_coord_;
+ std::string identifier_;
};
/** Print panel information */
inline
std::ostream& operator<<(std::ostream &os, const Panel &p) {
os << "Panel:" << std::endl;
+ os << " name: " << p.get_name() << std::endl;
+ os << " type: " << p.get_type() << std::endl;
+ os << " identifier: " << p.get_identifier() << std::endl;
os << " pixel_size:" << p.get_pixel_size().const_ref() << std::endl;
os << " image_size: " << p.get_image_size().const_ref() << std::endl;
os << " trusted_range: " << p.get_trusted_range().const_ref() << std::endl;
Modified: trunk/dxtbx/tests/model/tst_detector.py
===================================================================
--- trunk/dxtbx/tests/model/tst_detector.py 2016-10-18 08:32:32 UTC (rev 25586)
+++ trunk/dxtbx/tests/model/tst_detector.py 2016-10-18 11:27:34 UTC (rev 25587)
@@ -8,6 +8,11 @@
assert abs(detector[0].get_gain() - 2.0) < 1e-7
print 'OK'
+def tst_get_identifier(detector):
+ detector[0].set_identifier("HELLO")
+ assert detector[0].get_identifier() == "HELLO"
+ print 'OK'
+
def tst_get_pixel_lab_coord(detector):
from scitbx import matrix
eps = 1e-7
@@ -165,12 +170,14 @@
(512, 512), # Image size
(0, 1000), # Trusted range
0.1, # Thickness
- "Si")) # Material
+ "Si", # Material
+ identifier="123")) # Identifier
return detector
detector = create_detector()
# Perform some tests
+ tst_get_identifier(detector)
tst_get_gain(detector)
tst_set_mosflm_beam_centre(detector)
tst_get_pixel_lab_coord(detector)
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <kei...@us...> - 2016-10-18 08:32:34
|
Revision: 25586
http://sourceforge.net/p/cctbx/code/25586
Author: keitaroyam
Date: 2016-10-18 08:32:32 +0000 (Tue, 18 Oct 2016)
Log Message:
-----------
Updated SACLA dxtbx class. (1) sort the tag list because h5py's enumeration order is not well-defined. (2) delete tag selection hack (3) more sensible trusted_range (do we still need masks for the RECONST mode?)
Committed on behalf of Takanori
Modified Paths:
--------------
trunk/dxtbx/format/FormatHDF5SaclaMPCCD.py
Modified: trunk/dxtbx/format/FormatHDF5SaclaMPCCD.py
===================================================================
--- trunk/dxtbx/format/FormatHDF5SaclaMPCCD.py 2016-10-17 23:34:13 UTC (rev 25585)
+++ trunk/dxtbx/format/FormatHDF5SaclaMPCCD.py 2016-10-18 08:32:32 UTC (rev 25586)
@@ -22,42 +22,34 @@
'''
@staticmethod
- def split_tag(str):
- splitted = str.split("//")
- if (len(splitted) == 2):
- return (splitted[0], splitted[1])
- else:
- return (splitted[0], None)
-
- @staticmethod
def understand(image_file):
import h5py
- image, tag = FormatHDF5SaclaMPCCD.split_tag(image_file)
- h5_handle = h5py.File(image, 'r')
+ h5_handle = h5py.File(image_file, 'r')
- if tag is None:
- for elem in h5_handle:
- if elem.startswith("tag-"):
- return True
- return False
- else:
- return (tag in h5_handle)
+ for elem in h5_handle:
+ if elem.startswith("tag-"):
+ return True
+ return False
def __init__(self, image_file, index = 0, reconst_mode = False):
assert(self.understand(image_file))
- image, tag = self.split_tag(image_file)
self._raw_data = None
self.index = index
- self.tag = tag
- self.image_filename = image
- FormatHDF5.__init__(self, image)
+ self.image_filename = image_file
+ FormatHDF5.__init__(self, image_file)
self.PIXEL_SIZE = 50 / 1000 # 50 um
self.RECONST_SIZE = 2398 # compatible with DataConvert3 -reconst mode
# These hard-coded values can be overwritten
# by MPCCD_GEOMETRY and MPCCD_DISTANCE
+ #
+ # These values can be retrieved from SACLA API.
+ # Alternatively, you can get it from a CrystFEL geometry file by
+ # awk '/corner_x/{x=50*$3} /corner_y/{y=50*$3; printf x","y","rot","}
+ # /\/ss/{rot=-atan2($3, $4)/3.141592*180}' input.geom
+
self.distance = 50.0 # mm
self.panel_origins = [(-1755.000000, 51711.000000, 0.000000),
(-1711.000000, 24944.000000, 0.000000),
@@ -95,9 +87,8 @@
import h5py
h5_handle = h5py.File(self.image_filename, 'r')
- self._images = [tag for tag in h5_handle if tag.startswith("tag-")]
- if self.tag is None:
- self.tag = self._images[self.index]
+ self._images = sorted([tag for tag in h5_handle if tag.startswith("tag-")])
+ self.tag = self._images[self.index]
h5_handle.close()
def get_image_file(self, index=None):
@@ -132,11 +123,11 @@
self.RECONST_SIZE / 2 * self.PIXEL_SIZE),
fast_direction = '+x',
slow_direction = '-y',
- PIXEL_SIZE = (self.PIXEL_SIZE,
+ pixel_size = (self.PIXEL_SIZE,
self.PIXEL_SIZE),
image_size = (self.RECONST_SIZE,
self.RECONST_SIZE),
- trusted_range = (-1, 1000000),
+ trusted_range = (0, 65535),
px_mm = px_mm,
mask = []) # TODO: add gaps
@@ -160,7 +151,7 @@
p.set_type("SENSOR_PAD")
p.set_name('Panel%d' % i)
p.set_image_size((512, 1024))
- p.set_trusted_range((-1, 1000000))
+ p.set_trusted_range((0, 65535))
p.set_pixel_size((self.PIXEL_SIZE, self.PIXEL_SIZE))
p.set_thickness(t0)
p.set_local_frame(
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ph...@us...> - 2016-10-17 23:34:15
|
Revision: 25585
http://sourceforge.net/p/cctbx/code/25585
Author: phyy-nx
Date: 2016-10-17 23:34:13 +0000 (Mon, 17 Oct 2016)
Log Message:
-----------
XFEL UI
Don't block when changing tabs
Updates to about menu: add @idyoung to credits and change name to cctbx.xfel
Modified Paths:
--------------
trunk/xfel/ui/components/xfel_gui_init.py
Modified: trunk/xfel/ui/components/xfel_gui_init.py
===================================================================
--- trunk/xfel/ui/components/xfel_gui_init.py 2016-10-17 21:54:21 UTC (rev 25584)
+++ trunk/xfel/ui/components/xfel_gui_init.py 2016-10-17 23:34:13 UTC (rev 25585)
@@ -692,18 +692,20 @@
self.run_sentinel.start()
self.run_window.run_light.change_status('on')
- def stop_run_sentinel(self):
+ def stop_run_sentinel(self, block = True):
self.run_window.run_light.change_status('off')
self.run_sentinel.active = False
- self.run_sentinel.join()
+ if block:
+ self.run_sentinel.join()
def start_job_monitor(self):
self.job_monitor = JobMonitor(self, active=True)
self.job_monitor.start()
- def stop_job_monitor(self):
+ def stop_job_monitor(self, block = True):
self.job_monitor.active = False
- self.job_monitor.join()
+ if block:
+ self.job_monitor.join()
def start_job_sentinel(self):
self.job_sentinel = JobSentinel(self, active=True)
@@ -713,11 +715,12 @@
self.toolbar.EnableTool(self.tb_btn_run.GetId(), False)
self.toolbar.EnableTool(self.tb_btn_pause.GetId(), True)
- def stop_job_sentinel(self):
+ def stop_job_sentinel(self, block = True):
if self.job_sentinel is not None:
self.run_window.job_light.change_status('off')
self.job_sentinel.active = False
- self.job_sentinel.join()
+ if block:
+ self.job_sentinel.join()
self.toolbar.EnableTool(self.tb_btn_run.GetId(), True)
self.toolbar.EnableTool(self.tb_btn_pause.GetId(), False)
@@ -727,29 +730,32 @@
self.prg_sentinel.start()
self.run_window.prg_light.change_status('on')
- def stop_prg_sentinel(self):
+ def stop_prg_sentinel(self, block = True):
self.run_window.prg_light.change_status('off')
self.prg_sentinel.active = False
- self.prg_sentinel.join()
+ if block:
+ self.prg_sentinel.join()
def start_runstats_sentinel(self):
self.runstats_sentinel = RunStatsSentinel(self, active=True)
self.runstats_sentinel.start()
self.run_window.runstats_light.change_status('on')
- def stop_runstats_sentinel(self):
+ def stop_runstats_sentinel(self, block = True):
self.run_window.runstats_light.change_status('off')
self.runstats_sentinel.active = False
- self.runstats_sentinel.join()
+ if block:
+ self.runstats_sentinel.join()
def OnAboutBox(self, e):
''' About dialog '''
info = wx.AboutDialogInfo()
- info.SetName('iXFEL')
+ info.SetName('cctbx.xfel')
info.SetLicense(license)
info.SetDescription(description)
info.AddDeveloper('Artem Lyubimov')
info.AddDeveloper('Aaron Brewster')
+ info.AddDeveloper('Iris Young')
info.AddDeveloper('Axel Brunger')
info.AddDeveloper('Nicholas Sauter')
wx.AboutBox(info)
@@ -800,15 +806,15 @@
tab = self.run_window.main_nbook.GetSelection()
if tab == 2:
if self.job_monitor.active:
- self.stop_job_monitor()
+ self.stop_job_monitor(block = False)
self.run_window.jmn_light.change_status('off')
elif tab == 3:
if self.prg_sentinel.active:
- self.stop_prg_sentinel()
+ self.stop_prg_sentinel(block = False)
self.run_window.prg_light.change_status('off')
elif tab == 4:
if self.runstats_sentinel.active:
- self.stop_runstats_sentinel()
+ self.stop_runstats_sentinel(block = False)
self.run_window.runstats_light.change_status('off')
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <nks...@us...> - 2016-10-17 21:54:24
|
Revision: 25584
http://sourceforge.net/p/cctbx/code/25584
Author: nksauter
Date: 2016-10-17 21:54:21 +0000 (Mon, 17 Oct 2016)
Log Message:
-----------
cxi.merge, rs_hybrid model. Two new options 1) set the minimum partiality threshold for merging, default 0.2 but can be set to any value, 2) use partiality-weighting for merging, set by giving the exponent for the partiality factor, default=0, no weighting.
Modified Paths:
--------------
trunk/xfel/command_line/cxi_merge.py
trunk/xfel/cxi/postrefinement_hybrid_rs.py
Modified: trunk/xfel/command_line/cxi_merge.py
===================================================================
--- trunk/xfel/command_line/cxi_merge.py 2016-10-17 17:28:45 UTC (rev 25583)
+++ trunk/xfel/command_line/cxi_merge.py 2016-10-17 21:54:21 UTC (rev 25584)
@@ -215,7 +215,11 @@
.help = Gentle weighting rather than unit weighting for the postrefinement target
.help = Second round of LevMar adding an Rs refinement parameter
.help = Option of weighting the merged terms by partiality
- {}
+ {
+ partiality_threshold = 0.2
+ .type = float
+ .help = throw out observations below this value. Hard coded as 0.2 for rs2, allow value for hybrid
+ }
target_weighting = *unit variance gentle extreme
.type = choice
.help = weights for the residuals in the postrefinement target (only for rs_hybrid)
@@ -1507,34 +1511,6 @@
db_mgr.insert_observation(**kwargs)
- if False:
- # ******************************************************
- # try a new procedure to scale obs to the reference data with K & B,
- # to minimize (for positive Iobs only) functional...
- # ahead of doing this, section simply plots calc & obs...
- # ******************************************************
- print "For %d reflections, got slope %f, correlation %f" % \
- (data.n_obs - data.n_rejected, slope, corr)
- print "average obs", sum_y / (data.n_obs - data.n_rejected), \
- "average calc", sum_x / (data.n_obs - data.n_rejected), \
- "offset",offset
- print "Rejected %d reflections with negative intensities" % \
- data.n_rejected
-
- reference= flex.double()
- observed=flex.double()
- for pair in matches.pairs():
- if (observations.data()[pair[1]] -offset <= 0):
- continue
- I_r = self.i_model.data()[pair[0]]
- I_o = observations.data()[pair[1]]
- reference.append(I_r)
- observed.append((I_o - offset)/slope)
-
- from matplotlib import pyplot as plt
- plt.plot(flex.log10(observed),flex.log10(reference),"r.")
- plt.show()
-
print >> out, "For %d reflections, got slope %f, correlation %f" % \
(data.n_obs - data.n_rejected, slope, corr)
print >> out, "average obs", sum_y / (data.n_obs - data.n_rejected), \
@@ -1548,6 +1524,9 @@
print >> out, "Skipping these data - correlation too low."
else:
data.accept = True
+ if self.params.postrefinement.enable and self.params.postrefinement.algorithm in ["rs_hybrid"]:
+ assert slope == 1.0
+ assert self.params.include_negatives
for pair in matches.pairs():
if not self.params.include_negatives and (observations.data()[pair[1]] <= 0) :
continue
Modified: trunk/xfel/cxi/postrefinement_hybrid_rs.py
===================================================================
--- trunk/xfel/cxi/postrefinement_hybrid_rs.py 2016-10-17 17:28:45 UTC (rev 25583)
+++ trunk/xfel/cxi/postrefinement_hybrid_rs.py 2016-10-17 21:54:21 UTC (rev 25584)
@@ -149,7 +149,12 @@
def result_for_cxi_merge(self, file_name):
scaler = self.nave1_refinery.scaler_callable(self.get_parameter_values())
- fat_selection = (self.nave1_refinery.lorentz_callable(self.get_parameter_values()) > 0.2)
+ values = self.get_parameter_values()
+ p_scaler = flex.pow(self.refinery.get_partiality_array(values),
+ 0.5*self.params.postrefinement.merge_partiality_exponent)
+
+ fat_selection = (self.nave1_refinery.lorentz_callable(self.get_parameter_values()) >
+ self.params.postrefinement.rs_hybrid.partiality_threshold) # was 0.2 for rs2
fat_count = fat_selection.count(True)
#avoid empty database INSERT, if insufficient centrally-located Bragg spots:
@@ -164,7 +169,7 @@
observations = self.observations_pair1_selected.customized_copy(
indices = self.observations_pair1_selected.indices().select(fat_selection),
data = (self.observations_pair1_selected.data()/scaler).select(fat_selection),
- sigmas = (self.observations_pair1_selected.sigmas()/scaler).select(fat_selection)
+ sigmas = (self.observations_pair1_selected.sigmas()/(scaler * p_scaler)).select(fat_selection)
)
matches = miller.match_multi_indices(
miller_indices_unique=self.miller_set.indices(),
@@ -179,7 +184,6 @@
# New range assertions for refined variables
# XXX Likely these limits are problem-specific (especially G-max) so look for another approach
# or expose the limits as phil parameters.
- values = self.get_parameter_values()
assert self.final_corr > 0.1
assert 0 < values.G and values.G < 0.5
assert -25 < values.BFACTOR and values.BFACTOR < 25
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <bk...@us...> - 2016-10-17 17:28:48
|
Revision: 25583
http://sourceforge.net/p/cctbx/code/25583
Author: bkpoon
Date: 2016-10-17 17:28:45 +0000 (Mon, 17 Oct 2016)
Log Message:
-----------
Table One: changed formatting for Ramachandran and rotamer percentages to always print out 2 decimal places
Modified Paths:
--------------
trunk/iotbx/table_one.py
Modified: trunk/iotbx/table_one.py
===================================================================
--- trunk/iotbx/table_one.py 2016-10-17 11:26:11 UTC (rev 25582)
+++ trunk/iotbx/table_one.py 2016-10-17 17:28:45 UTC (rev 25583)
@@ -59,10 +59,10 @@
("n_nuc", "Nucleic acid bases", "%d", None),
("bond_rmsd", "RMS(bonds)", "%.3f", None),
("angle_rmsd", "RMS(angles)", "%.2f", None),
- ("rama_favored", "Ramachandran favored (%)", "%.2g", None),
- ("rama_allowed", "Ramachandran allowed (%)", "%.2g", None),
- ("rama_outliers", "Ramachandran outliers (%)", "%.2g", None),
- ("rota_outliers", "Rotamer outliers (%)", "%.2g", None),
+ ("rama_favored", "Ramachandran favored (%)", "%.2f", None),
+ ("rama_allowed", "Ramachandran allowed (%)", "%.2f", None),
+ ("rama_outliers", "Ramachandran outliers (%)", "%.2f", None),
+ ("rota_outliers", "Rotamer outliers (%)", "%.2f", None),
("clashscore", "Clashscore", "%.2f", None),
("adp_mean", "Average B-factor", "%.2f", None),
("adp_mean_mm", " macromolecules", "%.2f", None),
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <gra...@us...> - 2016-10-17 11:26:13
|
Revision: 25582
http://sourceforge.net/p/cctbx/code/25582
Author: graeme_winter
Date: 2016-10-17 11:26:11 +0000 (Mon, 17 Oct 2016)
Log Message:
-----------
Include exposure time in show() output for scan
Modified Paths:
--------------
trunk/dxtbx/model/scan.h
Modified: trunk/dxtbx/model/scan.h
===================================================================
--- trunk/dxtbx/model/scan.h 2016-10-17 08:06:49 UTC (rev 25581)
+++ trunk/dxtbx/model/scan.h 2016-10-17 11:26:11 UTC (rev 25582)
@@ -376,6 +376,7 @@
os << "Scan:\n";
os << " image range: " << s.get_image_range().const_ref() << "\n";
os << " oscillation: " << oscillation.const_ref() << "\n";
+ os << " exposure time: " << s.exposure_times_.const_ref()[0] << "\n";
return os;
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <gra...@us...> - 2016-10-17 08:06:51
|
Revision: 25581
http://sourceforge.net/p/cctbx/code/25581
Author: graeme_winter
Date: 2016-10-17 08:06:49 +0000 (Mon, 17 Oct 2016)
Log Message:
-----------
Need to set beam=None if not _beam()
Modified Paths:
--------------
trunk/dxtbx/format/FormatCBFFullPilatus.py
Modified: trunk/dxtbx/format/FormatCBFFullPilatus.py
===================================================================
--- trunk/dxtbx/format/FormatCBFFullPilatus.py 2016-10-17 05:59:10 UTC (rev 25580)
+++ trunk/dxtbx/format/FormatCBFFullPilatus.py 2016-10-17 08:06:49 UTC (rev 25581)
@@ -85,7 +85,7 @@
beam = self._beam()
except Exception:
- pass
+ beam = None
if beam:
# attenuation coefficient depends on the beam wavelength
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <gra...@us...> - 2016-10-17 05:59:13
|
Revision: 25580
http://sourceforge.net/p/cctbx/code/25580
Author: graeme_winter
Date: 2016-10-17 05:59:10 +0000 (Mon, 17 Oct 2016)
Log Message:
-----------
Comment out test so that it is not run to allow nightly build for OS X to be published
Modified Paths:
--------------
trunk/dxtbx/tests/tst_dials_226.py
Modified: trunk/dxtbx/tests/tst_dials_226.py
===================================================================
--- trunk/dxtbx/tests/tst_dials_226.py 2016-10-16 03:20:28 UTC (rev 25579)
+++ trunk/dxtbx/tests/tst_dials_226.py 2016-10-17 05:59:10 UTC (rev 25580)
@@ -21,5 +21,5 @@
if __name__ == '__main__':
- run()
+ #run() # disabled 2016/OCT/17 to enable nightly builds to pass
print 'OK'
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <nks...@us...> - 2016-10-16 03:20:31
|
Revision: 25579
http://sourceforge.net/p/cctbx/code/25579
Author: nksauter
Date: 2016-10-16 03:20:28 +0000 (Sun, 16 Oct 2016)
Log Message:
-----------
Better outlier rejection limits for cxi.merge, but the threshold values are likely to be problem specific.
Modified Paths:
--------------
trunk/xfel/cxi/postrefinement_hybrid_rs.py
Modified: trunk/xfel/cxi/postrefinement_hybrid_rs.py
===================================================================
--- trunk/xfel/cxi/postrefinement_hybrid_rs.py 2016-10-16 00:39:56 UTC (rev 25578)
+++ trunk/xfel/cxi/postrefinement_hybrid_rs.py 2016-10-16 03:20:28 UTC (rev 25579)
@@ -176,6 +176,14 @@
print >> self.out, "CORR: NEW correlation is", SWC.corr
self.final_corr = SWC.corr
+ # New range assertions for refined variables
+ # XXX Likely these limits are problem-specific (especially G-max) so look for another approach
+ # or expose the limits as phil parameters.
+ values = self.get_parameter_values()
+ assert self.final_corr > 0.1
+ assert 0 < values.G and values.G < 0.5
+ assert -25 < values.BFACTOR and values.BFACTOR < 25
+
return observations_original_index,observations,matches
def result_for_samosa(self):
@@ -258,6 +266,8 @@
def build_up(pfh, objective_only=False):
values = pfh.parameterization(pfh.x)
+ # XXX revisit these limits. Seems like an ad hoc approach to have to set these limits
+ # Moreover, these tests throw out ~30% of LM14 data, thus search for another approach
assert -150. < values.BFACTOR < 150. ,"limits on the exponent, please"
assert -0.5 < 180.*values.thetax/math.pi < 0.5 , "limits on the theta rotation, please"
assert -0.5 < 180.*values.thetay/math.pi < 0.5 , "limits on the theta rotation, please"
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <nks...@us...> - 2016-10-16 00:39:59
|
Revision: 25578
http://sourceforge.net/p/cctbx/code/25578
Author: nksauter
Date: 2016-10-16 00:39:56 +0000 (Sun, 16 Oct 2016)
Log Message:
-----------
cxi.merge new postrefinement algorithm 'rs_hybrid' refines the value of RS, however is a work still in progress. New phil parameter gives before/after trumpet plots for this algorithm.
Modified Paths:
--------------
trunk/xfel/command_line/cxi_merge.py
trunk/xfel/cxi/merging_database_fs.py
trunk/xfel/cxi/postrefinement_factory.py
trunk/xfel/cxi/postrefinement_legacy_rs.py
Added Paths:
-----------
trunk/xfel/cxi/data_utils.py
trunk/xfel/cxi/postrefinement_hybrid_rs.py
trunk/xfel/cxi/trumpet_plot.py
Modified: trunk/xfel/command_line/cxi_merge.py
===================================================================
--- trunk/xfel/command_line/cxi_merge.py 2016-10-14 21:50:26 UTC (rev 25577)
+++ trunk/xfel/command_line/cxi_merge.py 2016-10-16 00:39:56 UTC (rev 25578)
@@ -199,7 +199,7 @@
.type = bool
.help = enable the preliminary postrefinement algorithm (monochromatic)
.expert_level = 3
- algorithm = *rs rs2 eta_deff
+ algorithm = *rs rs2 rs_hybrid eta_deff
.type = choice
.help = rs only, eta_deff protocol 7
.expert_level = 3
@@ -207,8 +207,36 @@
.help = Reimplement postrefinement with the following (Oct 2016):
.help = Refinement engine now work on analytical derivatives instead of finite differences
.help = Better convergence using "traditional convergence test"
- .help = Use a streamlined frame_db schema
+ .help = Use a streamlined frame_db schema, currently only supported for FS (filesystem) backend
{}
+ rs_hybrid
+ .help = More aggressive postrefinement with the following (Oct 2016):
+ .help = One round of 'rs2' using LBFGS minimizer as above to refine G,B,rotx,roty
+ .help = Gentle weighting rather than unit weighting for the postrefinement target
+ .help = Second round of LevMar adding an Rs refinement parameter
+ .help = Option of weighting the merged terms by partiality
+ {}
+ target_weighting = *unit variance gentle extreme
+ .type = choice
+ .help = weights for the residuals in the postrefinement target (only for rs_hybrid)
+ .help = Unit: each residual weighted by 1.0
+ .help = Variance: weighted by 1/sigma**2. Doesn't seem right, constructive feedback invited
+ .help = Gentle: weighted by |I|/sigma**2. Seems like best option
+ .help = Extreme: weighted by (I/sigma)**2. Also seems right, but severely downweights weak refl
+ merge_weighting = *variance
+ .type = choice
+ .help = assumed that individual reflections are weighted by the counting variance
+ merge_partiality_exponent = 0
+ .type = float
+ .help = additionally weight each measurement by partiality**exp when merging
+ .help = 0 is no weighting, 1 is partiality weighting, 2 is weighting by partiality-squared
+ lineshape = *lorentzian
+ .type = choice
+ .help = Soft sphere RLP modeled with Lorentzian radial profile as in prime
+ show_trumpet_plot = False
+ .type = bool
+ .help = each-image trumpet plot showing before-after plot. Spot color warmth indicates I/sigma
+ .help = Spot radius for lower plot reflects partiality. Only implemented for rs_hybrid
}
include_negatives = False
.type = bool
@@ -1437,6 +1465,10 @@
except (AssertionError,ValueError),e:
return null_data(file_name=file_name, log_out=out.getvalue(), low_signal=True)
+ if self.params.postrefinement.show_trumpet_plot is True:
+ from xfel.cxi.trumpet_plot import trumpet_wrapper
+ trumpet_wrapper(result, postx, file_name, self.params, out)
+
if not self.params.scaling.enable or self.params.postrefinement.enable: # Do not scale anything
print >> out, "Scale factor to an isomorphous reference PDB will NOT be applied."
slope = 1.0
Added: trunk/xfel/cxi/data_utils.py
===================================================================
--- trunk/xfel/cxi/data_utils.py (rev 0)
+++ trunk/xfel/cxi/data_utils.py 2016-10-16 00:39:56 UTC (rev 25578)
@@ -0,0 +1,96 @@
+from __future__ import division
+import math
+import sys
+from dials.array_family import flex
+import cPickle as pickle
+from rstbx.dials_core.integration_core import show_observations
+
+class reduction(object):
+ """Reduced data container. Merges the following concepts:
+
+ filename : the integration pickle
+ experiment : the dxtbx-experimental model
+ HKL : the original-index miller set taken from joined database
+ """
+ def __init__(self, filename, experiment, HKL, i_sigi, measurements, params):
+ from libtbx import adopt_init_args
+ adopt_init_args(self, locals())
+ self.stash_type = None
+ self.stash_res_filter = None
+
+ from dxtbx.model.detector import detector_factory
+ self.dummy_detector = detector_factory.simple(
+ sensor = detector_factory.sensor("PAD"),
+ distance = 100,
+ beam_centre = [1000, 1000],
+ fast_direction = "+x",
+ slow_direction = "+y",
+ pixel_size = [0.2,0.2],
+ image_size = [2000,2000],
+ )
+ # simple view of post-integration, no longer need to know detector
+
+ def get_delta_psi_deg(self):
+ if self.stash_type is None:
+ self.stash_type = self.experiment.crystal.get_space_group().type()
+ UC = self.experiment.crystal.get_unit_cell()
+ from dials.algorithms.spot_prediction \
+ import StillsDeltaPsiReflectionPredictor
+ S = StillsDeltaPsiReflectionPredictor(
+ self.experiment.beam, \
+ self.dummy_detector, \
+ self.experiment.crystal.get_A(), \
+ UC, \
+ self.stash_type, \
+ 10.0) #dummy value for dmin
+
+ length = len(self.HKL)
+ R= flex.reflection_table.empty_standard(length)
+ R['miller_index'] = self.HKL
+ S.for_reflection_table(R,self.experiment.crystal.get_A())
+ degrees = (180./math.pi)*R["delpsical.rad"]
+ return degrees
+
+ def get_two_theta_deg(self):
+ wavelength=self.experiment.beam.get_wavelength()
+ UC = self.experiment.crystal.get_unit_cell()
+ two_theta = UC.two_theta(
+ miller_indices=self.HKL, wavelength=wavelength, deg=True)
+ return two_theta
+
+ def get_imposed_res_filter(self, out):
+ if self.stash_res_filter is not None: return self.stash_res_filter
+ if self.params.significance_filter.apply is True: #------------------------------------
+
+ print >>out, "Step 5. Frame by frame resolution filter"
+ # Apply an I/sigma filter ... accept resolution bins only if they
+ # have significant signal; tends to screen out higher resolution observations
+ # if the integration model doesn't quite fit
+ N_obs_pre_filter = self.i_sigi.size()
+ N_bins_small_set = N_obs_pre_filter // self.params.significance_filter.min_ct
+ N_bins_large_set = N_obs_pre_filter // self.params.significance_filter.max_ct
+
+ # Ensure there is at least one bin.
+ N_bins = max(
+ [min([self.params.significance_filter.n_bins,N_bins_small_set]),
+ N_bins_large_set, 1]
+ )
+ print >>out, "Total obs %d Choose n bins = %d"%(N_obs_pre_filter,N_bins)
+ bin_results = show_observations(self.measurements, out=sys.stdout, n_bins=N_bins)
+
+ if True: # no fuller kapton -- not implemented here,
+ # but code can and should be borrowed from cxi.merge
+ acceptable_resolution_bins = [
+ bin.mean_I_sigI > self.params.significance_filter.sigma for bin in bin_results]
+ acceptable_nested_bin_sequences = [i for i in xrange(len(acceptable_resolution_bins))
+ if False not in acceptable_resolution_bins[:i+1]]
+ N_acceptable_bins = max(acceptable_nested_bin_sequences) + 1
+ imposed_res_filter = float(bin_results[N_acceptable_bins-1].d_range.split()[2])
+ print >> out, "New resolution filter at %7.2f"%imposed_res_filter,self.filename
+ print >> out, "N acceptable bins",N_acceptable_bins
+ print >> out, "Old n_obs: %d, new n_obs: %d"%(N_obs_pre_filter,self.measurements.size())
+ # Finished applying the binwise I/sigma filter---------------------------------------
+ else:
+ imposed_res_filter=None
+ self.stash_res_filter = imposed_res_filter
+ return imposed_res_filter
Modified: trunk/xfel/cxi/merging_database_fs.py
===================================================================
--- trunk/xfel/cxi/merging_database_fs.py 2016-10-14 21:50:26 UTC (rev 25577)
+++ trunk/xfel/cxi/merging_database_fs.py 2016-10-16 00:39:56 UTC (rev 25578)
@@ -203,7 +203,7 @@
'distance': result['distance'],
'c_c': postx.final_corr,
'unique_file_name': data.file_name}
- values = postx.MINI.parameterization(postx.MINI.x)
+ values = postx.get_parameter_values()
kwargs["G"]=values.G
kwargs["BFACTOR"]=values.BFACTOR
kwargs["RS"]=values.RS
@@ -217,7 +217,7 @@
def insert_frame(self, **kwargs):
order = []
- if self.params.postrefinement.algorithm in ["rs2"]:
+ if self.params.postrefinement.algorithm in ["rs2","rs_hybrid"]:
order_dict = {'wavelength': 1,
'beam_x': 2,
'beam_y': 3,
@@ -345,7 +345,7 @@
def read_frames(self):
- if self.params.postrefinement.algorithm in ["rs2"]:
+ if self.params.postrefinement.algorithm in ["rs2","rs_hybrid"]:
return self.read_frames_updated_detail()
else:
return self.read_frames_legacy_detail()
Modified: trunk/xfel/cxi/postrefinement_factory.py
===================================================================
--- trunk/xfel/cxi/postrefinement_factory.py 2016-10-14 21:50:26 UTC (rev 25577)
+++ trunk/xfel/cxi/postrefinement_factory.py 2016-10-16 00:39:56 UTC (rev 25578)
@@ -10,6 +10,8 @@
from xfel.cxi.postrefinement_legacy_rs import legacy_rs as postrefinement_algorithm
elif self.params.postrefinement.algorithm in ['rs2']:
from xfel.cxi.postrefinement_updated_rs import updated_rs as postrefinement_algorithm
+ elif self.params.postrefinement.algorithm in ['rs_hybrid']:
+ from xfel.cxi.postrefinement_hybrid_rs import rs_hybrid as postrefinement_algorithm
return postrefinement_algorithm
return None
Added: trunk/xfel/cxi/postrefinement_hybrid_rs.py
===================================================================
--- trunk/xfel/cxi/postrefinement_hybrid_rs.py (rev 0)
+++ trunk/xfel/cxi/postrefinement_hybrid_rs.py 2016-10-16 00:39:56 UTC (rev 25578)
@@ -0,0 +1,278 @@
+from __future__ import division
+import math
+from scitbx import matrix
+from cctbx import miller
+from dials.array_family import flex
+from scitbx.math.tests.tst_weighted_correlation import simple_weighted_correlation
+from xfel.cxi.postrefinement_legacy_rs import rs_parameterization
+from xfel.cxi.postrefinement_updated_rs import rs2_refinery,lbfgs_minimizer_derivatives
+from scitbx.lstbx import normal_eqns
+from scitbx.lstbx import normal_eqns_solving
+
+class rs_hybrid(object):
+ def __init__(self,measurements_orig, params, i_model, miller_set, result, out):
+ measurements = measurements_orig.deep_copy()
+ # Now manipulate the data to conform to unit cell, asu, and space group
+ # of reference. The resolution will be cut later.
+ # Only works if there is NOT an indexing ambiguity!
+ observations = measurements.customized_copy(
+ anomalous_flag=not params.merge_anomalous,
+ crystal_symmetry=miller_set.crystal_symmetry()
+ ).map_to_asu()
+
+ observations_original_index = measurements.customized_copy(
+ anomalous_flag=not params.merge_anomalous,
+ crystal_symmetry=miller_set.crystal_symmetry()
+ )
+
+ # Ensure that match_multi_indices() will return identical results
+ # when a frame's observations are matched against the
+ # pre-generated Miller set, self.miller_set, and the reference
+ # data set, self.i_model. The implication is that the same match
+ # can be used to map Miller indices to array indices for intensity
+ # accumulation, and for determination of the correlation
+ # coefficient in the presence of a scaling reference.
+
+ assert len(i_model.indices()) == len(miller_set.indices()) \
+ and (i_model.indices() ==
+ miller_set.indices()).count(False) == 0
+ matches = miller.match_multi_indices(
+ miller_indices_unique=miller_set.indices(),
+ miller_indices=observations.indices())
+
+ pair1 = flex.int([pair[1] for pair in matches.pairs()])
+ pair0 = flex.int([pair[0] for pair in matches.pairs()])
+ # narrow things down to the set that matches, only
+ observations_pair1_selected = observations.customized_copy(
+ indices = flex.miller_index([observations.indices()[p] for p in pair1]),
+ data = flex.double([observations.data()[p] for p in pair1]),
+ sigmas = flex.double([observations.sigmas()[p] for p in pair1]),
+ )
+ observations_original_index_pair1_selected = observations_original_index.customized_copy(
+ indices = flex.miller_index([observations_original_index.indices()[p] for p in pair1]),
+ data = flex.double([observations_original_index.data()[p] for p in pair1]),
+ sigmas = flex.double([observations_original_index.sigmas()[p] for p in pair1]),
+ )
+###################
+ I_observed = observations_pair1_selected.data()
+ variance_weights = 1./(observations_pair1_selected.sigmas()*observations_pair1_selected.sigmas())
+ detail_variance_weights = flex.pow(flex.double([1./a for a in observations_pair1_selected.sigmas()]),2)
+ gentle_weights = flex.pow(flex.sqrt(flex.abs(I_observed))/observations_pair1_selected.sigmas(),2)
+ isigi_weights = flex.pow(I_observed/observations_pair1_selected.sigmas(),2)
+ unit_weights = flex.double(len(I_observed),1.)
+ chosen_weights = gentle_weights
+
+ MILLER = observations_original_index_pair1_selected.indices()
+ ORI = result["current_orientation"][0]
+ Astar = matrix.sqr(ORI.reciprocal_matrix())
+ WAVE = result["wavelength"]
+ BEAM = matrix.col((0.0,0.0,-1./WAVE))
+ BFACTOR = 0.
+
+ #calculation of correlation here
+ I_reference = flex.double([i_model.data()[pair[0]] for pair in matches.pairs()])
+ use_weights = False # New facility for getting variance-weighted correlation
+
+ if use_weights:
+ #variance weighting
+ I_weight = flex.double(
+ [1./(observations_pair1_selected.sigmas()[pair[1]])**2 for pair in matches.pairs()])
+ else:
+ I_weight = flex.double(len(observations_pair1_selected.sigmas()), 1.)
+
+ """Explanation of 'include_negatives' semantics as originally implemented in cxi.merge postrefinement:
+ include_negatives = True
+ + and - reflections both used for Rh distribution for initial estimate of RS parameter
+ + and - reflections both used for calc/obs correlation slope for initial estimate of G parameter
+ + and - reflections both passed to the refinery and used in the target function (makes sense if
+ you look at it from a certain point of view)
+
+ include_negatives = False
+ + and - reflections both used for Rh distribution for initial estimate of RS parameter
+ + reflections only used for calc/obs correlation slope for initial estimate of G parameter
+ + and - reflections both passed to the refinery and used in the target function (makes sense if
+ you look at it from a certain point of view)
+ """
+ if params.include_negatives:
+ SWC = simple_weighted_correlation(I_weight, I_reference, I_observed)
+ else:
+ non_positive = ( observations_pair1_selected.data() <= 0 )
+ SWC = simple_weighted_correlation(I_weight.select(~non_positive),
+ I_reference.select(~non_positive), I_observed.select(~non_positive))
+
+ print >> out, "Old correlation is", SWC.corr
+ assert params.postrefinement.algorithm=="rs_hybrid"
+ Rhall = flex.double()
+ for mill in MILLER:
+ H = matrix.col(mill)
+ Xhkl = Astar*H
+ Rh = ( Xhkl + BEAM ).length() - (1./WAVE)
+ Rhall.append(Rh)
+ Rs = math.sqrt(flex.mean(Rhall*Rhall))
+
+ RS = 1./10000. # reciprocal effective domain size of 1 micron
+ RS = Rs # try this empirically determined approximate, monochrome, a-mosaic value
+
+ self.rs2_current = flex.double([SWC.slope, BFACTOR, RS, 0., 0.])
+ self.rs2_parameterization_class = rs_parameterization
+
+ self.rs2_refinery = rs2_refinery(ORI=ORI, MILLER=MILLER, BEAM=BEAM, WAVE=WAVE,
+ ICALCVEC = I_reference, IOBSVEC = I_observed, WEIGHTS = chosen_weights)
+ self.nave1_refinery = nave1_refinery(ORI=ORI, MILLER=MILLER, BEAM=BEAM, WAVE=WAVE,
+ ICALCVEC = I_reference, IOBSVEC = I_observed, WEIGHTS = chosen_weights)
+
+ self.out=out; self.params = params;
+ self.miller_set = miller_set
+ self.observations_pair1_selected = observations_pair1_selected;
+ self.observations_original_index_pair1_selected = observations_original_index_pair1_selected
+ self.i_model = i_model
+
+ def run_plain(self):
+ self.MINI = lbfgs_minimizer_derivatives( current_x = self.rs2_current,
+ parameterization = self.rs2_parameterization_class, refinery = self.rs2_refinery,
+ out = self.out )
+
+ self.refined_mini = self.MINI
+ values = self.rs2_parameterization_class(self.MINI.x)
+ self.nave1_current = flex.double(
+ [values.G, values.BFACTOR, values.RS, values.thetax*1000., values.thetay*1000.])
+ self.nave1_parameterization_class = nave1_parameterization
+ self.MINI2 = per_frame_helper( current_x = self.nave1_current,
+ parameterization = self.nave1_parameterization_class, refinery = self.nave1_refinery,
+ out = self.out )
+ print >>self.out, "Trying Lev-Mar2"
+ iterations = normal_eqns_solving.naive_iterations(non_linear_ls = self.MINI2,
+ step_threshold = 0.0001,
+ gradient_threshold = 1.E-10)
+ self.refined_mini = self.MINI2
+ self.refinery = self.nave1_refinery # used elsewhere, not private interface
+
+ def result_for_cxi_merge(self, file_name):
+ scaler = self.nave1_refinery.scaler_callable(self.get_parameter_values())
+ fat_selection = (self.nave1_refinery.lorentz_callable(self.get_parameter_values()) > 0.2)
+ fat_count = fat_selection.count(True)
+
+ #avoid empty database INSERT, if insufficient centrally-located Bragg spots:
+ # in samosa, handle this at a higher level, but handle it somehow.
+ if fat_count < 3:
+ raise ValueError
+ print >> self.out, "On total %5d the fat selection is %5d"%(
+ len(self.observations_pair1_selected.indices()), fat_count)
+ observations_original_index = \
+ self.observations_original_index_pair1_selected.select(fat_selection)
+
+ observations = self.observations_pair1_selected.customized_copy(
+ indices = self.observations_pair1_selected.indices().select(fat_selection),
+ data = (self.observations_pair1_selected.data()/scaler).select(fat_selection),
+ sigmas = (self.observations_pair1_selected.sigmas()/scaler).select(fat_selection)
+ )
+ matches = miller.match_multi_indices(
+ miller_indices_unique=self.miller_set.indices(),
+ miller_indices=observations.indices())
+
+ I_weight = flex.double(len(observations.sigmas()), 1.)
+ I_reference = flex.double([self.i_model.data()[pair[0]] for pair in matches.pairs()])
+ SWC = simple_weighted_correlation(I_weight, I_reference, observations.data())
+ print >> self.out, "CORR: NEW correlation is", SWC.corr
+ self.final_corr = SWC.corr
+
+ return observations_original_index,observations,matches
+
+ def result_for_samosa(self):
+ values = self.get_parameter_values()
+ return self.refinery.get_eff_Astar(values), values.RS, self.refinery.get_partiality_array(values)
+
+ def get_parameter_values(self):
+ return self.refined_mini.parameterization(self.refined_mini.x)
+
+class nave1_refinery(rs2_refinery):
+
+ def jacobian_callable(self,values):
+ PB = self.get_partiality_array(values)
+ EXP = flex.exp(-2.*values.BFACTOR*self.DSSQ)
+ G_terms = (EXP * PB * self.ICALCVEC)
+ B_terms = (values.G * EXP * PB * self.ICALCVEC)*(-2.*self.DSSQ)
+ P_terms = (values.G * EXP * self.ICALCVEC)
+
+ thetax = values.thetax; thetay = values.thetay;
+ Rx = matrix.col((1,0,0)).axis_and_angle_as_r3_rotation_matrix(thetax)
+ dRx_dthetax = matrix.col((1,0,0)).axis_and_angle_as_r3_derivative_wrt_angle(thetax)
+ Ry = matrix.col((0,1,0)).axis_and_angle_as_r3_rotation_matrix(thetay)
+ dRy_dthetay = matrix.col((0,1,0)).axis_and_angle_as_r3_derivative_wrt_angle(thetay)
+ ref_ori = matrix.sqr(self.ORI.reciprocal_matrix())
+ miller_vec = self.MILLER.as_vec3_double()
+ ds1_dthetax = flex.mat3_double(len(self.MILLER),Ry * dRx_dthetax * ref_ori) * miller_vec
+ ds1_dthetay = flex.mat3_double(len(self.MILLER),dRy_dthetay * Rx * ref_ori) * miller_vec
+
+ s1vec = self.get_s1_array(values)
+ s1lenvec = flex.sqrt(s1vec.dot(s1vec))
+ dRh_dthetax = s1vec.dot(ds1_dthetax)/s1lenvec
+ dRh_dthetay = s1vec.dot(ds1_dthetay)/s1lenvec
+ rs = values.RS
+ Rh = self.get_Rh_array(values)
+ rs_sq = rs*rs
+ denomin = (2. * Rh * Rh + rs_sq)
+ dPB_dRh = -PB * 4. * Rh / denomin
+ dPB_dthetax = dPB_dRh * dRh_dthetax
+ dPB_dthetay = dPB_dRh * dRh_dthetay
+ Px_terms = P_terms * dPB_dthetax /1000.; Py_terms = P_terms * dPB_dthetay /1000.
+
+ dPB_drs = 4 * rs * Rh * Rh / (denomin * denomin)
+ Prs_terms = P_terms * dPB_drs
+
+ return [G_terms,B_terms,Prs_terms,Px_terms,Py_terms]
+
+class nave1_parameterization(rs_parameterization):
+ def __getattr__(YY,item):
+ if item=="thetax" : return YY.reference[3]/1000. #internally kept in milliradians
+ if item=="thetay" : return YY.reference[4]/1000.
+ if item=="G" : return YY.reference[0]
+ if item=="BFACTOR": return YY.reference[1]
+ if item=="RS": return YY.reference[2]
+ return getattr(YY,item)
+
+class per_frame_helper(normal_eqns.non_linear_ls, normal_eqns.non_linear_ls_mixin):
+ def __init__(pfh,current_x=None, parameterization=None, refinery=None, out=None,):
+ pfh.parameterization = parameterization
+ pfh.refinery = refinery
+ pfh.out = out
+ super(per_frame_helper, pfh).__init__(n_parameters=current_x.size())
+ pfh.n = current_x.size()
+ pfh.x_0 = current_x
+ pfh.restart()
+
+ def restart(pfh):
+ pfh.x = pfh.x_0.deep_copy()
+ pfh.old_x = None
+
+ def step_forward(pfh):
+ pfh.old_x = pfh.x.deep_copy()
+ pfh.x += pfh.step()
+
+ def step_backward(pfh):
+ assert pfh.old_x is not None
+ pfh.x, pfh.old_x = pfh.old_x, None
+
+ def parameter_vector_norm(pfh):
+ return pfh.x.norm()
+
+ def build_up(pfh, objective_only=False):
+ values = pfh.parameterization(pfh.x)
+ assert -150. < values.BFACTOR < 150. ,"limits on the exponent, please"
+ assert -0.5 < 180.*values.thetax/math.pi < 0.5 , "limits on the theta rotation, please"
+ assert -0.5 < 180.*values.thetay/math.pi < 0.5 , "limits on the theta rotation, please"
+ assert 0.000001 < values.RS < 0.0003 , "limits on the RLP size, please"
+ residuals = pfh.refinery.fvec_callable(values)
+ pfh.reset()
+ if objective_only:
+ pfh.add_residuals(residuals, weights=pfh.refinery.WEIGHTS)
+ else:
+ grad_r = pfh.refinery.jacobian_callable(values)
+ jacobian = flex.double(
+ flex.grid(len(pfh.refinery.MILLER), pfh.n_parameters))
+ for j, der_r in enumerate(grad_r):
+ jacobian.matrix_paste_column_in_place(der_r,j)
+ #print >> pfh.out, "COL",j, list(der_r)
+ pfh.add_equations(residuals, jacobian, weights=pfh.refinery.WEIGHTS)
+ print >> pfh.out, "rms %10.3f"%math.sqrt(flex.mean(pfh.refinery.WEIGHTS*residuals*residuals)),
+ values.show(pfh.out)
Modified: trunk/xfel/cxi/postrefinement_legacy_rs.py
===================================================================
--- trunk/xfel/cxi/postrefinement_legacy_rs.py 2016-10-14 21:50:26 UTC (rev 25577)
+++ trunk/xfel/cxi/postrefinement_legacy_rs.py 2016-10-16 00:39:56 UTC (rev 25578)
@@ -160,6 +160,10 @@
miller_indices=observations.indices())
return observations_original_index,observations,matches
+ def get_parameter_values(self):
+ values = self.parameterization_class(self.MINI.x)
+ return values
+
def result_for_samosa(self):
values = self.parameterization_class(self.MINI.x)
return self.refinery.get_eff_Astar(values), values.RS
@@ -341,4 +345,3 @@
print >> self.out, "FINALMODEL",
print >> self.out, "rms %10.3f"%math.sqrt(flex.mean(self.func*self.func)),
values.show(self.out)
-
Added: trunk/xfel/cxi/trumpet_plot.py
===================================================================
--- trunk/xfel/cxi/trumpet_plot.py (rev 0)
+++ trunk/xfel/cxi/trumpet_plot.py 2016-10-16 00:39:56 UTC (rev 25578)
@@ -0,0 +1,181 @@
+from __future__ import division
+from matplotlib import pyplot as plt
+from matplotlib import gridspec
+import math
+import os
+from dials.array_family import flex
+
+class trumpet_plot(object):
+
+ def __init__(self, nrows=2, ncols=2):
+ self.AD1TF7B_MAX2T = 45.
+ self.AD1TF7B_MAXDP = 0.5
+ self.AD1TF7B_MAXDP = 0.1
+ self.color_encoding = "I/sigma"
+ plt.figure(figsize=(12,10)) #use 9 for laptop
+ self.gs = gridspec.GridSpec(nrows=nrows,ncols=ncols,width_ratios=[3,1])
+ self.ncols = ncols
+
+ def set_reduction(self,reduction): #see data_utils for definition of this container
+ self.reduction = reduction
+ def set_refined(self,info): # a repository for the refined parameters
+ self.refined = info
+
+ def plot_one_model(self,nrow,out):
+ fig = plt.subplot(self.gs[nrow*self.ncols])
+ two_thetas = self.reduction.get_two_theta_deg()
+ degrees = self.reduction.get_delta_psi_deg()
+
+ if self.color_encoding=="conventional":
+ positive = (self.reduction.i_sigi>=0.)
+ fig.plot(two_thetas.select(positive), degrees.select(positive), "bo")
+ fig.plot(two_thetas.select(~positive), degrees.select(~positive), "r+")
+ elif self.color_encoding=="I/sigma":
+ positive = (self.reduction.i_sigi>=0.)
+ tt_selected = two_thetas.select(positive)
+ dp_selected = degrees.select(positive)
+ i_sigi_select = self.reduction.i_sigi.select(positive)
+ order = flex.sort_permutation(i_sigi_select)
+ tt_selected = tt_selected.select(order)
+ dp_selected = dp_selected.select(order)
+ i_sigi_selected = i_sigi_select.select(order)
+ from matplotlib.colors import Normalize
+ dnorm = Normalize()
+ dcolors = i_sigi_selected.as_numpy_array()
+ dnorm.autoscale(dcolors)
+ N = len(dcolors)
+ CMAP = plt.get_cmap("rainbow")
+ if self.refined.get("partiality_array",None) is None:
+ for n in xrange(N):
+ fig.plot([tt_selected[n]],[dp_selected[n]],
+ color=CMAP(dnorm(dcolors[n])),marker=".", markersize=10)
+ else:
+ partials = self.refined.get("partiality_array")
+ partials_select = partials.select(positive)
+ partials_selected = partials_select.select(order)
+ assert len(partials)==len(positive)
+ for n in xrange(N):
+ fig.plot([tt_selected[n]],[dp_selected[n]],
+ color=CMAP(dnorm(dcolors[n])),marker=".", markersize=20*partials_selected[n])
+ # change the markersize to indicate partiality.
+ negative = (self.reduction.i_sigi<0.)
+ fig.plot(two_thetas.select(negative), degrees.select(negative), "r+", linewidth=1)
+ else:
+ strong = (self.reduction.i_sigi>=10.)
+ positive = ((~strong) & (self.reduction.i_sigi>=0.))
+ negative = (self.reduction.i_sigi<0.)
+ assert (strong.count(True)+positive.count(True)+negative.count(True) ==
+ len(self.reduction.i_sigi))
+ fig.plot(two_thetas.select(positive), degrees.select(positive), "bo")
+ fig.plot(two_thetas.select(strong), degrees.select(strong), marker='.',linestyle='None',
+ markerfacecolor='#00ee00', markersize=10)
+ fig.plot(two_thetas.select(negative), degrees.select(negative), "r+")
+
+ # indicate the imposed resolution filter
+ wavelength = self.reduction.experiment.beam.get_wavelength()
+ imposed_res_filter = self.reduction.get_imposed_res_filter(out)
+ resolution_markers = [
+ a for a in [imposed_res_filter,self.reduction.measurements.d_min()] if a is not None]
+ for RM in resolution_markers:
+ two_th = (180./math.pi)*2.*math.asin(wavelength/(2.*RM))
+ plt.plot([two_th, two_th],[self.AD1TF7B_MAXDP*-0.8,self.AD1TF7B_MAXDP*0.8],'k-')
+ plt.text(two_th,self.AD1TF7B_MAXDP*-0.9,"%4.2f"%RM)
+
+ #indicate the linefit
+ mean = flex.mean(degrees)
+ minplot = flex.min(two_thetas)
+ plt.plot([0,minplot],[mean,mean],"k-")
+ LR = flex.linear_regression(two_thetas, degrees)
+ model_y = LR.slope()*two_thetas + LR.y_intercept()
+ plt.plot(two_thetas, model_y, "k-")
+
+ #Now let's take care of the red and green lines.
+ half_mosaic_rotation_deg = self.refined["half_mosaic_rotation_deg"]
+ mosaic_domain_size_ang = self.refined["mosaic_domain_size_ang"]
+ red_curve_domain_size_ang = self.refined.get("red_curve_domain_size_ang",mosaic_domain_size_ang)
+ a_step = self.AD1TF7B_MAX2T / 50.
+ a_range = flex.double([a_step*x for x in xrange(1,50)]) # domain two-theta array
+ #Bragg law [d=L/2sinTH]
+ d_spacing = (wavelength/(2.*flex.sin(math.pi*a_range/360.)))
+ # convert two_theta to a delta-psi. Formula for Deffective [Dpsi=d/2Deff]
+ inner_phi_deg = flex.asin((d_spacing / (2.*red_curve_domain_size_ang)) )*(180./math.pi)
+ outer_phi_deg = flex.asin((d_spacing / (2.*mosaic_domain_size_ang)) + \
+ half_mosaic_rotation_deg*math.pi/180. )*(180./math.pi)
+ plt.title("ML: mosaicity FW=%4.2f deg, Dsize=%5.0fA on %d spots\n%s"%(
+ 2.*half_mosaic_rotation_deg, mosaic_domain_size_ang, len(two_thetas),
+ os.path.basename(self.reduction.filename)))
+ plt.plot(a_range, inner_phi_deg, "r-")
+ plt.plot(a_range,-inner_phi_deg, "r-")
+ plt.plot(a_range, outer_phi_deg, "g-")
+ plt.plot(a_range, -outer_phi_deg, "g-")
+ plt.xlim([0,self.AD1TF7B_MAX2T])
+ plt.ylim([-self.AD1TF7B_MAXDP,self.AD1TF7B_MAXDP])
+
+ #second plot shows histogram
+ fig = plt.subplot(self.gs[1+nrow*self.ncols])
+ plt.xlim([-self.AD1TF7B_MAXDP,self.AD1TF7B_MAXDP])
+ nbins = 50
+ n,bins,patches = plt.hist(dp_selected, nbins,
+ range=(-self.AD1TF7B_MAXDP,self.AD1TF7B_MAXDP),
+ weights=self.reduction.i_sigi.select(positive),
+ normed=0, facecolor="orange", alpha=0.75)
+ #ersatz determine the median i_sigi point:
+ isi_positive = self.reduction.i_sigi.select(positive)
+ isi_order = flex.sort_permutation(isi_positive)
+ reordered = isi_positive.select(isi_order)
+ isi_median = reordered[int(len(isi_positive)*0.9)]
+ isi_top_half_selection = (isi_positive>isi_median)
+ n,bins,patches = plt.hist(dp_selected.select(isi_top_half_selection), nbins,
+ range=(-self.AD1TF7B_MAXDP,self.AD1TF7B_MAXDP),
+ weights=isi_positive.select(isi_top_half_selection),
+ normed=0, facecolor="#ff0000", alpha=0.75)
+ plt.xlabel("(degrees)")
+ plt.title("Weighted histogram of Delta-psi")
+
+ def set_color_coding(self,choice):
+ self.color_encoding = choice
+
+ def show(self):
+ plt.show()
+ #plt.tight_layout()
+ #plt.savefig('grid_figure.pdf')
+
+def trumpet_wrapper(result, postx, file_name, params, out):
+ from scitbx import matrix
+ from dxtbx.model.beam import beam_factory
+ beam = beam_factory.make_beam(s0=(0,0,-1./result["wavelength"]))
+ from dxtbx.model.experiment import experiment_list
+ from dxtbx.model import crystal
+
+ obs_to_plot = postx.observations_original_index_pair1_selected # XXX uses a private interface
+
+ HKL=obs_to_plot.indices()
+ i_sigi=obs_to_plot.data()/obs_to_plot.sigmas()
+ direct_matrix = result["current_orientation"][0].direct_matrix()
+ real_a = direct_matrix[0:3]
+ real_b = direct_matrix[3:6]
+ real_c = direct_matrix[6:9]
+ SG = obs_to_plot.space_group()
+ crystal = crystal.crystal_model(real_a, real_b, real_c, space_group=SG)
+ q = experiment_list.Experiment(beam=beam, crystal=crystal)
+
+ TPL = trumpet_plot()
+ from xfel.cxi.data_utils import reduction
+ RED = reduction(filename = file_name, experiment = q, HKL = HKL, i_sigi = i_sigi,
+ measurements = obs_to_plot, params = params)
+ TPL.set_reduction(RED)
+
+ # first plot: before postrefinement
+ TPL.reduction.experiment.crystal.set_A(matrix.sqr(result["current_orientation"][0].reciprocal_matrix()))
+ TPL.set_refined(dict(half_mosaic_rotation_deg=result["ML_half_mosaicity_deg"][0],
+ mosaic_domain_size_ang=result["ML_domain_size_ang"][0]))
+ TPL.plot_one_model(nrow=0,out=out)
+
+ # second plot after postrefinement
+ values = postx.get_parameter_values()
+ TPL.reduction.experiment.crystal.set_A(postx.refined_mini.refinery.get_eff_Astar(values))
+ TPL.refined["red_curve_domain_size_ang"]=1/values.RS
+ TPL.refined["partiality_array"]=postx.refined_mini.refinery.get_partiality_array(values)
+ TPL.plot_one_model(nrow=1,out=out)
+
+ TPL.show()
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <nks...@us...> - 2016-10-14 21:50:28
|
Revision: 25577
http://sourceforge.net/p/cctbx/code/25577
Author: nksauter
Date: 2016-10-14 21:50:26 +0000 (Fri, 14 Oct 2016)
Log Message:
-----------
cxi.merge: updated postrefinement algorithm 'rs2' uses analytical derivatives, uses better convergence test and implements streamlined frame_db schema.
Modified Paths:
--------------
trunk/xfel/command_line/cxi_merge.py
trunk/xfel/command_line/cxi_xmerge.py
trunk/xfel/cxi/merging_database_fs.py
Added Paths:
-----------
trunk/xfel/cxi/postrefinement_factory.py
trunk/xfel/cxi/postrefinement_updated_rs.py
Modified: trunk/xfel/command_line/cxi_merge.py
===================================================================
--- trunk/xfel/command_line/cxi_merge.py 2016-10-14 09:20:38 UTC (rev 25576)
+++ trunk/xfel/command_line/cxi_merge.py 2016-10-14 21:50:26 UTC (rev 25577)
@@ -199,10 +199,16 @@
.type = bool
.help = enable the preliminary postrefinement algorithm (monochromatic)
.expert_level = 3
- algorithm = *rs eta_deff
+ algorithm = *rs rs2 eta_deff
.type = choice
.help = rs only, eta_deff protocol 7
.expert_level = 3
+ rs2
+ .help = Reimplement postrefinement with the following (Oct 2016):
+ .help = Refinement engine now work on analytical derivatives instead of finite differences
+ .help = Better convergence using "traditional convergence test"
+ .help = Use a streamlined frame_db schema
+ {}
}
include_negatives = False
.type = bool
@@ -1415,11 +1421,14 @@
data.corr = corr
data.wavelength = wavelength
+ from xfel.cxi.postrefinement_factory import factory
+ PF = factory(self.params)
+ postrefinement_algorithm = PF.postrefinement_algorithm()
+
if self.params.postrefinement.enable:
# Refactorization of the Sauter(2015) code; result should be same to 5 significant figures.
# Lack of binary identity is due to the use of Python for old-code weighted correlation,
# contrasted with flex.double arithmetic for new-code.
- from xfel.cxi.postrefinement_legacy_rs import legacy_rs as postrefinement_algorithm
postx=postrefinement_algorithm(observations_original_index, self.params,
self.i_model, self.miller_set, result, out)
try:
@@ -1433,70 +1442,11 @@
slope = 1.0
offset = 0.0
- print >> out, result.get("sa_parameters")[0]
- have_sa_params = ( type(result.get("sa_parameters")[0]) == type(dict()) )
- #have_sa_params = (result.get("sa_parameters")[0].find('None')!=0)
- observations_original_index_indices = observations_original_index.indices()
if db_mgr is None: return unpack(MINI.x) # special exit for two-color indexing
- #cell_params = data.indexed_cell.parameters()
- #reserve_cell_params = result["sa_parameters"][0]["reserve_orientation"].unit_cell().parameters()
- # cell params and reserve cell params are essentially equal within numerical precision
+ frame_id_0_base = PF.insert_frame_call(locals())
- kwargs = {'wavelength': wavelength,
- 'beam_x': result['xbeam'],
- 'beam_y': result['ybeam'],
- 'distance': result['distance'],
- 'c_c': corr,
- 'slope': slope,
- 'offset': offset,
- 'unique_file_name': data.file_name}
-
- if have_sa_params:
- sa_parameters = result['sa_parameters'][0]
- res_ori_direct = sa_parameters['reserve_orientation'].direct_matrix().elems
-
- kwargs['res_ori_1'] = res_ori_direct[0]
- kwargs['res_ori_2'] = res_ori_direct[1]
- kwargs['res_ori_3'] = res_ori_direct[2]
- kwargs['res_ori_4'] = res_ori_direct[3]
- kwargs['res_ori_5'] = res_ori_direct[4]
- kwargs['res_ori_6'] = res_ori_direct[5]
- kwargs['res_ori_7'] = res_ori_direct[6]
- kwargs['res_ori_8'] = res_ori_direct[7]
- kwargs['res_ori_9'] = res_ori_direct[8]
-
- kwargs['rotation100_rad'] = sa_parameters.rotation100_rad
- kwargs['rotation010_rad'] = sa_parameters.rotation010_rad
- kwargs['rotation001_rad'] = sa_parameters.rotation001_rad
-
- kwargs['half_mosaicity_deg'] = sa_parameters.half_mosaicity_deg
- kwargs['wave_HE_ang'] = sa_parameters.wave_HE_ang
- kwargs['wave_LE_ang'] = sa_parameters.wave_LE_ang
- kwargs['domain_size_ang'] = sa_parameters.domain_size_ang
-
- else:
- res_ori_direct = matrix.sqr(
- data.indexed_cell.orthogonalization_matrix()).transpose().elems
-
- kwargs['res_ori_1'] = res_ori_direct[0]
- kwargs['res_ori_2'] = res_ori_direct[1]
- kwargs['res_ori_3'] = res_ori_direct[2]
- kwargs['res_ori_4'] = res_ori_direct[3]
- kwargs['res_ori_5'] = res_ori_direct[4]
- kwargs['res_ori_6'] = res_ori_direct[5]
- kwargs['res_ori_7'] = res_ori_direct[6]
- kwargs['res_ori_8'] = res_ori_direct[7]
- kwargs['res_ori_9'] = res_ori_direct[8]
- if self.params.scaling.report_ML:
- kwargs['half_mosaicity_deg'] = result["ML_half_mosaicity_deg"][0]
- kwargs['domain_size_ang'] = result["ML_domain_size_ang"][0]
- else:
- kwargs['half_mosaicity_deg'] =float("NaN")
- kwargs['domain_size_ang'] =float("NaN")
-
- frame_id_0_base = db_mgr.insert_frame(**kwargs)
-
+ observations_original_index_indices = observations_original_index.indices()
xypred = result["mapped_predictions"][0]
indices = flex.size_t([pair[1] for pair in matches.pairs()])
Modified: trunk/xfel/command_line/cxi_xmerge.py
===================================================================
--- trunk/xfel/command_line/cxi_xmerge.py 2016-10-14 09:20:38 UTC (rev 25576)
+++ trunk/xfel/command_line/cxi_xmerge.py 2016-10-14 21:50:26 UTC (rev 25577)
@@ -21,9 +21,7 @@
from xfel.command_line.cxi_merge import master_phil,scaling_manager
from xfel.command_line.cxi_merge import unit_cell_distribution,show_overall_observations
from xfel.command_line.cxi_merge import scaling_result
-from cctbx.crystal_orientation import crystal_orientation
from xfel import column_parser
-from xfel.cxi.util import is_odd_numbered
from cctbx import miller
#-----------------------------------------------------------------------
@@ -53,7 +51,7 @@
len(self.frames["cc"]),
statsy.mean(), statsy.unweighted_sample_standard_deviation(),
)
- if self.params.scaling.report_ML:
+ if self.params.scaling.report_ML and self.frames.has_key("half_mosaicity_deg"):
mosaic = self.frames["half_mosaicity_deg"].select(self.those_accepted)
Mstat = flex.mean_and_variance(mosaic)
print >> self.log, "%5d images, half mosaicity is %6.3f +/- %5.3f degrees"%(
@@ -81,7 +79,7 @@
self.n_low_corr
def read_all_mysql(self):
- print "reading observations from MySQL database"
+ print "reading observations from %s database"%(self.params.backend)
if self.params.backend == 'MySQL':
from xfel.cxi.merging_database import manager
@@ -118,86 +116,17 @@
parser.set_int("frame_id",self.frames_mysql["frame_id"])
parser.set_double("wavelength",self.frames_mysql["wavelength"])
parser.set_double("cc",self.frames_mysql["cc"])
- parser.set_double("slope",self.frames_mysql["slope"])
- parser.set_double("offset",self.frames_mysql["offset"])
- if self.params.scaling.report_ML:
- parser.set_double("domain_size_ang",self.frames_mysql["domain_size_ang"])
- parser.set_double("half_mosaicity_deg",self.frames_mysql["half_mosaicity_deg"])
+ try:
+ parser.set_double("slope",self.frames_mysql["slope"])
+ parser.set_double("offset",self.frames_mysql["offset"])
+ if self.params.scaling.report_ML:
+ parser.set_double("domain_size_ang",self.frames_mysql["domain_size_ang"])
+ parser.set_double("half_mosaicity_deg",self.frames_mysql["half_mosaicity_deg"])
+ except KeyError: pass
self._frames_mysql = parser
CART.join()
- def read_all(self):
- # XXX Should not be used any more--migrate C++ into
- # cxi/merging_database_fs.py?
- print "reading observations from flat-file database"
- self.frames = dict( frame_id=flex.int(),
- wavelength=flex.double(),
- cc=flex.double(),
- slope=flex.double(),
- offset=flex.double(),
- odd_numbered=flex.bool(),
- orientation=[],
- unit_cell=[])
- self.millers = dict(merged_asu_hkl=flex.miller_index())
- G = open(self.params.output.prefix+"_miller.db","r")
- for line in G.xreadlines():
- tokens = line.strip().split()
- self.millers["merged_asu_hkl"].append((int(tokens[1]),int(tokens[2]),int(tokens[3])))
-
-# --- start C++ read
- parser = column_parser()
- parser.set_int("hkl_id",0)
- parser.set_double("i",1)
- parser.set_double("sigi",2)
- parser.set_int("frame_id",5)
- parser.set_int("H",7)
- parser.set_int("K",8)
- parser.set_int("L",9)
-
- G = open(self.params.output.prefix+"_observation.db","r")
- for line in G.xreadlines():
- parser.parse_from_line(line)
- self.observations = dict(hkl_id=parser.get_int("hkl_id"),
- i=parser.get_double("i"),
- sigi=parser.get_double("sigi"),
- frame_id=parser.get_int("frame_id"),
- H=parser.get_int("H"),
- K=parser.get_int("K"),
- L=parser.get_int("L"),
- )
- self._observations = parser
- G.close()
-# --- done with C++ read
-
- G = open(self.params.output.prefix+"_frame.db","r")
- for line in G.xreadlines():
- tokens = line.strip().split()
- self.frames["frame_id"].append(int(tokens[0]))
- self.frames["wavelength"].append(float(tokens[1]))
- self.frames["cc"].append(float(tokens[5]))
- self.frames["slope"].append(float(tokens[6]))
- self.frames["offset"].append(float(tokens[7]))
- self.frames["odd_numbered"].append( is_odd_numbered(tokens[17]) )
- # components of orientation direct matrix
- odm = (float(tokens[8]), float(tokens[9]), float(tokens[10]),
- float(tokens[11]), float(tokens[12]), float(tokens[13]),
- float(tokens[14]), float(tokens[15]), float(tokens[16]),)
- CO = crystal_orientation(odm, False)
- self.frames["orientation"].append(CO)
- self.frames["unit_cell"].append(CO.unit_cell())
- G.close()
- parser = column_parser()
- parser.set_int("frame_id",0)
- parser.set_double("wavelength",1)
- parser.set_double("cc",5)
- parser.set_double("slope",6)
- parser.set_double("offset",7)
- G = open(self.params.output.prefix+"_frame.db","r")
- for line in G.xreadlines():
- parser.parse_from_line(line)
- self._frames = parser
-
#-----------------------------------------------------------------------
def run(args):
phil = iotbx.phil.process_command_line(args=args, master_string=master_phil).show()
Modified: trunk/xfel/cxi/merging_database_fs.py
===================================================================
--- trunk/xfel/cxi/merging_database_fs.py 2016-10-14 09:20:38 UTC (rev 25576)
+++ trunk/xfel/cxi/merging_database_fs.py 2016-10-14 21:50:26 UTC (rev 25577)
@@ -114,10 +114,9 @@
self.params.output.prefix,
self._semaphore)).start()
-
def initialize_db(self, indices):
from os import remove
-
+ print self.params.postrefinement.algorithm
for suffix in '_frame.db', '_miller.db', '_observation.db':
try:
remove(self.params.output.prefix + suffix)
@@ -126,13 +125,124 @@
self._db_commands_queue.put(('miller', (1, 2, 3), indices, None))
+ def insert_frame_legacy(self,result,wavelength,corr,slope,offset,data):
+ from scitbx import matrix
+ """Legacy compatibility with cxi.merge; insert frame-data to backend.
+ XXX needs to be backported to the MySQL and SQLite backends (put into a base class)
+ result: an unpickled dictionary from an integration pickle
+ wavelength, beam_x, beam_y, distance: parameters from the model
+ data: an instance of a "frame_data" container class
+ postx: an instance of the legacy_cxi_merge_postrefinement results, or None
+ """
+ have_sa_params = ( type(result.get("sa_parameters")[0]) == type(dict()) )
+ #cell_params = data.indexed_cell.parameters()
+ #reserve_cell_params =
+ # result["sa_parameters"][0]["reserve_orientation"].unit_cell().parameters()
+ # cell params == reserve cell params, within numerical precision
+ kwargs = {'wavelength': wavelength,
+ 'beam_x': result['xbeam'],
+ 'beam_y': result['ybeam'],
+ 'distance': result['distance'],
+ 'c_c': corr,
+ 'slope': slope,
+ 'offset': offset,
+ 'unique_file_name': data.file_name}
+ if have_sa_params:
+ sa_parameters = result['sa_parameters'][0]
+ res_ori_direct = sa_parameters['reserve_orientation'].direct_matrix().elems
+
+ kwargs['res_ori_1'] = res_ori_direct[0]
+ kwargs['res_ori_2'] = res_ori_direct[1]
+ kwargs['res_ori_3'] = res_ori_direct[2]
+ kwargs['res_ori_4'] = res_ori_direct[3]
+ kwargs['res_ori_5'] = res_ori_direct[4]
+ kwargs['res_ori_6'] = res_ori_direct[5]
+ kwargs['res_ori_7'] = res_ori_direct[6]
+ kwargs['res_ori_8'] = res_ori_direct[7]
+ kwargs['res_ori_9'] = res_ori_direct[8]
+
+ kwargs['rotation100_rad'] = sa_parameters.rotation100_rad
+ kwargs['rotation010_rad'] = sa_parameters.rotation010_rad
+ kwargs['rotation001_rad'] = sa_parameters.rotation001_rad
+
+ kwargs['half_mosaicity_deg'] = sa_parameters.half_mosaicity_deg
+ kwargs['wave_HE_ang'] = sa_parameters.wave_HE_ang
+ kwargs['wave_LE_ang'] = sa_parameters.wave_LE_ang
+ kwargs['domain_size_ang'] = sa_parameters.domain_size_ang
+
+ else:
+ res_ori_direct = matrix.sqr(
+ data.indexed_cell.orthogonalization_matrix()).transpose().elems
+
+ kwargs['res_ori_1'] = res_ori_direct[0]
+ kwargs['res_ori_2'] = res_ori_direct[1]
+ kwargs['res_ori_3'] = res_ori_direct[2]
+ kwargs['res_ori_4'] = res_ori_direct[3]
+ kwargs['res_ori_5'] = res_ori_direct[4]
+ kwargs['res_ori_6'] = res_ori_direct[5]
+ kwargs['res_ori_7'] = res_ori_direct[6]
+ kwargs['res_ori_8'] = res_ori_direct[7]
+ kwargs['res_ori_9'] = res_ori_direct[8]
+ if self.params.scaling.report_ML:
+ kwargs['half_mosaicity_deg'] = result["ML_half_mosaicity_deg"][0]
+ kwargs['domain_size_ang'] = result["ML_domain_size_ang"][0]
+ else:
+ kwargs['half_mosaicity_deg'] =float("NaN")
+ kwargs['domain_size_ang'] =float("NaN")
+ return self.insert_frame(**kwargs)
+
+ def insert_frame_updated(self,result,wavelength,data,postx):
+ from scitbx import matrix
+ """New compatibility with postrefinement container
+ XXX needs to be backported to the MySQL and SQLite backends (put into a base class)
+ """
+ kwargs = {'wavelength': wavelength,
+ 'beam_x': result['xbeam'],
+ 'beam_y': result['ybeam'],
+ 'distance': result['distance'],
+ 'c_c': postx.final_corr,
+ 'unique_file_name': data.file_name}
+ values = postx.MINI.parameterization(postx.MINI.x)
+ kwargs["G"]=values.G
+ kwargs["BFACTOR"]=values.BFACTOR
+ kwargs["RS"]=values.RS
+ kwargs["thetax"]=values.thetax
+ kwargs["thetay"]=values.thetay
+ Astar=postx.refinery.ORI.reciprocal_matrix()
+ kwargs['Astar_1'], kwargs['Astar_2'], kwargs['Astar_3'],\
+ kwargs['Astar_4'], kwargs['Astar_5'], kwargs['Astar_6'],\
+ kwargs['Astar_7'], kwargs['Astar_8'], kwargs['Astar_9'] = Astar
+ return self.insert_frame(**kwargs)
+
def insert_frame(self, **kwargs):
order = []
- order_dict = {'wavelength': 1,
+ if self.params.postrefinement.algorithm in ["rs2"]:
+ order_dict = {'wavelength': 1,
'beam_x': 2,
'beam_y': 3,
'distance': 4,
+ 'G': 5,
+ 'BFACTOR': 6,
+ 'RS': 7,
+ 'Astar_1': 8,
+ 'Astar_2': 9,
+ 'Astar_3': 10,
+ 'Astar_4': 11,
+ 'Astar_5': 12,
+ 'Astar_6': 13,
+ 'Astar_7': 14,
+ 'Astar_8': 15,
+ 'Astar_9': 16,
+ 'thetax': 17,
+ 'thetay': 18,
+ 'unique_file_name': 19,
+ 'c_c': 20}
+ else:
+ order_dict = {'wavelength': 1,
+ 'beam_x': 2,
+ 'beam_y': 3,
+ 'distance': 4,
'c_c': 5,
'slope': 6,
'offset': 7,
@@ -172,7 +282,6 @@
# someone else to pick up.
self._db_results_queue.put(item)
-
def insert_observation(self, **kwargs):
order = []
order_dict = {'hkl_id_0_base': 0,
@@ -236,9 +345,51 @@
def read_frames(self):
+ if self.params.postrefinement.algorithm in ["rs2"]:
+ return self.read_frames_updated_detail()
+ else:
+ return self.read_frames_legacy_detail()
+
+ def read_frames_updated_detail(self):
from cctbx.crystal_orientation import crystal_orientation
from xfel.cxi.util import is_odd_numbered
+ frames = {'frame_id': flex.int(),
+ 'wavelength': flex.double(),
+ 'cc': flex.double(),
+ 'G': flex.double(),
+ 'BFACTOR': flex.double(),
+ 'RS': flex.double(),
+ 'odd_numbered': flex.bool(),
+ 'thetax': flex.double(),
+ 'thetay': flex.double(),
+ 'orientation': [],
+ 'unit_cell': [],
+ 'unique_file_name': []}
+ stream = open(self.params.output.prefix + '_frame.db', 'r')
+ for row in stream:
+ items = row.split()
+ CO = crystal_orientation([float(t) for t in items[8:17]], True)
+ unique_file_name = eval(items[19])
+ frames['frame_id'].append(int(items[0]))
+ frames['wavelength'].append(float(items[1]))
+ frames['cc'].append(float(items[20]))
+ frames['G'].append(float(items[5]))
+ frames['BFACTOR'].append(float(items[6]))
+ frames['RS'].append(float(items[7]))
+ frames['thetax'].append(float(items[17]))
+ frames['thetay'].append(float(items[18]))
+ frames['odd_numbered'].append(is_odd_numbered(unique_file_name))
+ frames['orientation'].append(CO)
+ frames['unit_cell'].append(CO.unit_cell())
+ frames['unique_file_name'].append(unique_file_name)
+ stream.close()
+ return frames
+
+ def read_frames_legacy_detail(self):
+ from cctbx.crystal_orientation import crystal_orientation
+ from xfel.cxi.util import is_odd_numbered
+
# XXX issues with spaces in the file name, and leading and
# trailing single quotes (stripped below).
Added: trunk/xfel/cxi/postrefinement_factory.py
===================================================================
--- trunk/xfel/cxi/postrefinement_factory.py (rev 0)
+++ trunk/xfel/cxi/postrefinement_factory.py 2016-10-14 21:50:26 UTC (rev 25577)
@@ -0,0 +1,33 @@
+from __future__ import division
+
+class factory(object):
+ def __init__(self, params):
+ self.params = params
+
+ def postrefinement_algorithm(self,):
+ if self.params.postrefinement.enable:
+ if self.params.postrefinement.algorithm in ['rs','eta_deff']:
+ from xfel.cxi.postrefinement_legacy_rs import legacy_rs as postrefinement_algorithm
+ elif self.params.postrefinement.algorithm in ['rs2']:
+ from xfel.cxi.postrefinement_updated_rs import updated_rs as postrefinement_algorithm
+ return postrefinement_algorithm
+ return None
+
+ @staticmethod
+ def insert_frame_call(kwargs):
+ # legacy behavior
+ if kwargs["self"].params.postrefinement.enable==False or \
+ kwargs["self"].params.postrefinement.algorithm in ["rs","eta_deff"]:
+
+ return kwargs["db_mgr"].insert_frame_legacy(
+ **dict(
+ [ (k,kwargs[k]) for k in ["result","wavelength","corr","slope","offset","data"] ]
+ )
+ )
+ # new behavior for rs2 and rs_hybrid
+ elif kwargs["self"].params.postrefinement.algorithm in ["rs2", "rs_hybrid"]:
+ return kwargs["db_mgr"].insert_frame_updated(
+ **dict(
+ [ (k,kwargs[k]) for k in ["result","wavelength","data","postx"] ]
+ )
+ )
Added: trunk/xfel/cxi/postrefinement_updated_rs.py
===================================================================
--- trunk/xfel/cxi/postrefinement_updated_rs.py (rev 0)
+++ trunk/xfel/cxi/postrefinement_updated_rs.py 2016-10-14 21:50:26 UTC (rev 25577)
@@ -0,0 +1,282 @@
+from __future__ import division
+import math
+from scitbx import matrix
+from cctbx import miller
+from dials.array_family import flex
+from scitbx.math.tests.tst_weighted_correlation import simple_weighted_correlation
+from libtbx import adopt_init_args, group_args
+from xfel.cxi.postrefinement_legacy_rs import legacy_rs, rs_refinery, rs_parameterization, lbfgs_minimizer_base
+
+class updated_rs(legacy_rs):
+ def __init__(self,measurements_orig, params, i_model, miller_set, result, out):
+ measurements = measurements_orig.deep_copy()
+
+ # Now manipulate the data to conform to unit cell, asu, and space group
+ # of reference. The resolution will be cut later.
+ # Only works if there is NOT an indexing ambiguity!
+ observations = measurements.customized_copy(
+ anomalous_flag=not params.merge_anomalous,
+ crystal_symmetry=miller_set.crystal_symmetry()
+ ).map_to_asu()
+
+ observations_original_index = measurements.customized_copy(
+ anomalous_flag=not params.merge_anomalous,
+ crystal_symmetry=miller_set.crystal_symmetry()
+ )
+
+ # Ensure that match_multi_indices() will return identical results
+ # when a frame's observations are matched against the
+ # pre-generated Miller set, self.miller_set, and the reference
+ # data set, self.i_model. The implication is that the same match
+ # can be used to map Miller indices to array indices for intensity
+ # accumulation, and for determination of the correlation
+ # coefficient in the presence of a scaling reference.
+
+ assert len(i_model.indices()) == len(miller_set.indices()) \
+ and (i_model.indices() ==
+ miller_set.indices()).count(False) == 0
+
+ matches = miller.match_multi_indices(
+ miller_indices_unique=miller_set.indices(),
+ miller_indices=observations.indices())
+
+ pair1 = flex.int([pair[1] for pair in matches.pairs()])
+ pair0 = flex.int([pair[0] for pair in matches.pairs()])
+ # narrow things down to the set that matches, only
+ observations_pair1_selected = observations.customized_copy(
+ indices = flex.miller_index([observations.indices()[p] for p in pair1]),
+ data = flex.double([observations.data()[p] for p in pair1]),
+ sigmas = flex.double([observations.sigmas()[p] for p in pair1]),
+ )
+ observations_original_index_pair1_selected = observations_original_index.customized_copy(
+ indices = flex.miller_index([observations_original_index.indices()[p] for p in pair1]),
+ data = flex.double([observations_original_index.data()[p] for p in pair1]),
+ sigmas = flex.double([observations_original_index.sigmas()[p] for p in pair1]),
+ )
+###################
+ I_observed = observations_pair1_selected.data()
+ MILLER = observations_original_index_pair1_selected.indices()
+ ORI = result["current_orientation"][0]
+ Astar = matrix.sqr(ORI.reciprocal_matrix())
+ WAVE = result["wavelength"]
+ BEAM = matrix.col((0.0,0.0,-1./WAVE))
+ BFACTOR = 0.
+
+ #calculation of correlation here
+ I_reference = flex.double([i_model.data()[pair[0]] for pair in matches.pairs()])
+ use_weights = False # New facility for getting variance-weighted correlation
+
+ if use_weights:
+ #variance weighting
+ I_weight = flex.double(
+ [1./(observations_pair1_selected.sigmas()[pair[1]])**2 for pair in matches.pairs()])
+ else:
+ I_weight = flex.double(len(observations_pair1_selected.sigmas()), 1.)
+
+ """Explanation of 'include_negatives' semantics as originally implemented in cxi.merge postrefinement:
+ include_negatives = True
+ + and - reflections both used for Rh distribution for initial estimate of RS parameter
+ + and - reflections both used for calc/obs correlation slope for initial estimate of G parameter
+ + and - reflections both passed to the refinery and used in the target function (makes sense if
+ you look at it from a certain point of view)
+
+ include_negatives = False
+ + and - reflections both used for Rh distribution for initial estimate of RS parameter
+ + reflections only used for calc/obs correlation slope for initial estimate of G parameter
+ + and - reflections both passed to the refinery and used in the target function (makes sense if
+ you look at it from a certain point of view)
+ """
+ if params.include_negatives:
+ SWC = simple_weighted_correlation(I_weight, I_reference, I_observed)
+ else:
+ non_positive = ( observations_pair1_selected.data() <= 0 )
+ SWC = simple_weighted_correlation(I_weight.select(~non_positive),
+ I_reference.select(~non_positive), I_observed.select(~non_positive))
+
+ print >> out, "CORR: Old correlation is", SWC.corr
+ if params.postrefinement.algorithm=="rs2":
+ Rhall = flex.double()
+ for mill in MILLER:
+ H = matrix.col(mill)
+ Xhkl = Astar*H
+ Rh = ( Xhkl + BEAM ).length() - (1./WAVE)
+ Rhall.append(Rh)
+ Rs = math.sqrt(flex.mean(Rhall*Rhall))
+
+ RS = 1./10000. # reciprocal effective domain size of 1 micron
+ RS = Rs # try this empirically determined approximate, monochrome, a-mosaic value
+ current = flex.double([SWC.slope, BFACTOR, RS, 0., 0.])
+
+ parameterization_class = rs_parameterization
+ refinery = rs2_refinery(ORI=ORI, MILLER=MILLER, BEAM=BEAM, WAVE=WAVE,
+ ICALCVEC = I_reference, IOBSVEC = I_observed)
+
+ func = refinery.fvec_callable(parameterization_class(current))
+ functional = flex.sum(func*func)
+ print >> out, "functional",functional
+ self.current = current; self.parameterization_class = parameterization_class
+ self.refinery = refinery; self.out=out; self.params = params;
+ self.miller_set = miller_set
+ self.observations_pair1_selected = observations_pair1_selected;
+ self.observations_original_index_pair1_selected = observations_original_index_pair1_selected
+ self.i_model = i_model
+
+ def run_plain(self):
+ self.MINI = lbfgs_minimizer_derivatives( current_x = self.current,
+ parameterization = self.parameterization_class, refinery = self.refinery,
+ out = self.out )
+
+ def result_for_cxi_merge(self, file_name):
+ scaler = self.refinery.scaler_callable(self.parameterization_class(self.MINI.x))
+ if self.params.postrefinement.algorithm=="rs2":
+ fat_selection = (self.refinery.lorentz_callable(self.parameterization_class(self.MINI.x)) > 0.2)
+ else:
+ fat_selection = (self.refinery.lorentz_callable(self.parameterization_class(self.MINI.x)) < 0.9)
+ fat_count = fat_selection.count(True)
+
+ #avoid empty database INSERT, if insufficient centrally-located Bragg spots:
+ # in samosa, handle this at a higher level, but handle it somehow.
+ if fat_count < 3:
+ raise ValueError
+ print >> self.out, "On total %5d the fat selection is %5d"%(
+ len(self.observations_pair1_selected.indices()), fat_count)
+ observations_original_index = \
+ self.observations_original_index_pair1_selected.select(fat_selection)
+
+ observations = self.observations_pair1_selected.customized_copy(
+ indices = self.observations_pair1_selected.indices().select(fat_selection),
+ data = (self.observations_pair1_selected.data()/scaler).select(fat_selection),
+ sigmas = (self.observations_pair1_selected.sigmas()/scaler).select(fat_selection)
+ )
+ matches = miller.match_multi_indices(
+ miller_indices_unique=self.miller_set.indices(),
+ miller_indices=observations.indices())
+
+ I_weight = flex.double(len(observations.sigmas()), 1.)
+ I_reference = flex.double([self.i_model.data()[pair[0]] for pair in matches.pairs()])
+ SWC = simple_weighted_correlation(I_weight, I_reference, observations.data())
+ print >> self.out, "CORR: NEW correlation is", SWC.corr
+ self.final_corr = SWC.corr
+
+ return observations_original_index,observations,matches
+
+class refinery_base(group_args):
+ def __init__(self, **kwargs):
+ group_args.__init__(self,**kwargs)
+ mandatory = ["ORI","MILLER","BEAM","WAVE","ICALCVEC","IOBSVEC"]
+ for key in mandatory: getattr(self,key)
+ self.DSSQ = self.ORI.unit_cell().d_star_sq(self.MILLER)
+
+ """Refinery class takes reference and observations, and implements target
+ functions and derivatives for a particular model paradigm."""
+ def get_Rh_array(self, values):
+ Rh = flex.double()
+ eff_Astar = self.get_eff_Astar(values)
+ for mill in self.MILLER:
+ x = eff_Astar * matrix.col(mill)
+ Svec = x + self.BEAM
+ Rh.append(Svec.length() - (1./self.WAVE))
+ return Rh
+
+ def get_s1_array(self, values):
+ miller_vec = self.MILLER.as_vec3_double()
+ ref_ori = matrix.sqr(self.ORI.reciprocal_matrix())
+ Rx = matrix.col((1,0,0)).axis_and_angle_as_r3_rotation_matrix(values.thetax)
+ Ry = matrix.col((0,1,0)).axis_and_angle_as_r3_rotation_matrix(values.thetay)
+ s_array = flex.mat3_double(len(self.MILLER),Ry * Rx * ref_ori) * miller_vec
+ s1_array = s_array + flex.vec3_double(len(self.MILLER), self.BEAM)
+ return s1_array
+
+ def get_eff_Astar(self, values):
+ thetax = values.thetax; thetay = values.thetay;
+ effective_orientation = self.ORI.rotate_thru((1,0,0),thetax
+ ).rotate_thru((0,1,0),thetay
+ )
+ return matrix.sqr(effective_orientation.reciprocal_matrix())
+
+ def scaler_callable(self, values):
+ PB = self.get_partiality_array(values)
+ EXP = flex.exp(-2.*values.BFACTOR*self.DSSQ)
+ terms = values.G * EXP * PB
+ return terms
+
+ def fvec_callable(self, values):
+ PB = self.get_partiality_array(values)
+ EXP = flex.exp(-2.*values.BFACTOR*self.DSSQ)
+ terms = (values.G * EXP * PB * self.ICALCVEC - self.IOBSVEC)
+ # Ideas for improvement
+ # straightforward to also include sigma weighting
+ # add extra terms representing rotational excursion: terms.concatenate(1.e7*Rh)
+ return terms
+
+class rs2_refinery(rs_refinery):
+
+ def jacobian_callable(self,values):
+ PB = self.get_partiality_array(values)
+ EXP = flex.exp(-2.*values.BFACTOR*self.DSSQ)
+ G_terms = (EXP * PB * self.ICALCVEC)
+ B_terms = (values.G * EXP * PB * self.ICALCVEC)*(-2.*self.DSSQ)
+ P_terms = (values.G * EXP * self.ICALCVEC)
+
+ thetax = values.thetax; thetay = values.thetay;
+ Rx = matrix.col((1,0,0)).axis_and_angle_as_r3_rotation_matrix(thetax)
+ dRx_dthetax = matrix.col((1,0,0)).axis_and_angle_as_r3_derivative_wrt_angle(thetax)
+ Ry = matrix.col((0,1,0)).axis_and_angle_as_r3_rotation_matrix(thetay)
+ dRy_dthetay = matrix.col((0,1,0)).axis_and_angle_as_r3_derivative_wrt_angle(thetay)
+ ref_ori = matrix.sqr(self.ORI.reciprocal_matrix())
+ miller_vec = self.MILLER.as_vec3_double()
+ ds1_dthetax = flex.mat3_double(len(self.MILLER),Ry * dRx_dthetax * ref_ori) * miller_vec
+ ds1_dthetay = flex.mat3_double(len(self.MILLER),dRy_dthetay * Rx * ref_ori) * miller_vec
+
+ s1vec = self.get_s1_array(values)
+ s1lenvec = flex.sqrt(s1vec.dot(s1vec))
+ dRh_dthetax = s1vec.dot(ds1_dthetax)/s1lenvec
+ dRh_dthetay = s1vec.dot(ds1_dthetay)/s1lenvec
+ rs = values.RS
+ Rh = self.get_Rh_array(values)
+ rs_sq = rs*rs
+ dPB_dRh = -PB * 4. * Rh / (2. * Rh * Rh + rs_sq)
+ dPB_dthetax = dPB_dRh * dRh_dthetax
+ dPB_dthetay = dPB_dRh * dRh_dthetay
+ Px_terms = P_terms * dPB_dthetax; Py_terms = P_terms * dPB_dthetay
+
+ return [G_terms,B_terms,0,Px_terms,Py_terms]
+
+class lbfgs_minimizer_derivatives(lbfgs_minimizer_base):
+
+ def __init__(self, current_x=None, parameterization=None, refinery=None, out=None,
+ min_iterations=0, max_calls=1000, max_drop_eps=1.e-5):
+ adopt_init_args(self, locals())
+ self.n = current_x.size()
+ self.x = current_x
+ from scitbx import lbfgs
+ self.minimizer = lbfgs.run(
+ target_evaluator=self,
+ termination_params=lbfgs.termination_parameters(
+ traditional_convergence_test=True,
+ drop_convergence_test_max_drop_eps=max_drop_eps,
+ min_iterations=min_iterations,
+ max_iterations = None,
+ max_calls=max_calls),
+ exception_handling_params=lbfgs.exception_handling_parameters(
+ ignore_line_search_failed_rounding_errors=True,
+ ignore_line_search_failed_step_at_lower_bound=True,#the only change from default
+ ignore_line_search_failed_step_at_upper_bound=False,
+ ignore_line_search_failed_maxfev=False,
+ ignore_line_search_failed_xtol=False,
+ ignore_search_direction_not_descent=False)
+ )
+
+ def compute_functional_and_gradients(self):
+ values = self.parameterization(self.x)
+ assert -150. < values.BFACTOR < 150. # limits on the exponent, please
+ self.func = self.refinery.fvec_callable(values)
+ functional = flex.sum(self.func*self.func)
+ self.f = functional
+ jacobian = self.refinery.jacobian_callable(values)
+ self.g = flex.double(self.n)
+ for ix in xrange(self.n):
+ self.g[ix] = flex.sum(2. * self.func * jacobian[ix])
+ print >> self.out, "rms %10.3f"%math.sqrt(flex.mean(self.func*self.func)),
+ values.show(self.out)
+ return self.f, self.g
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|