).Fexp2)")
# convert axes in formula
metadata.setdefault("fit_slope", 1/wp.fit_slope)
metadata.setdefault("fit_y_intercept", -wp.fit_y_intercept/wp.fit_slope)
metadata.setdefault("<|E^2-1|>", wp.mean_e_sq_minus_1)
metadata.setdefault("%|E| > 2", wp.percent_e_sq_gt_2)
self.metadata = metadata
self.data.setdefault('dataset1', Dataset(wp.y,wp.x,metadata=metadata))
def make_gradient_box(self, size = (320, 35)):
boxWidth = size[0]
boxHeight = size[1]*0.4
boxTopOffset = self.imY * 0.035
colour = self.pageColour
im = Image.new('RGB', size, colour)
draw = ImageDraw.Draw(im)
#target_left = (0,0,255)
#target_right = (0,255,0)
middle = boxWidth/2
box = (0,boxTopOffset,boxWidth-1,boxTopOffset+boxHeight-1)
draw.rectangle(box, fill=self.fillColour, outline=self.outlineColour)
margin_left = int((boxWidth/4))
margin_right = int((boxWidth/4)*3)
scale = float((0.968-0.736)/(boxWidth - (margin_right - margin_left)))
metadata = self.data['dataset1'].metadata()
value = float(metadata.get("<|E^2-1|>", 0))
begin = (0.736 - margin_left * scale)
end = (0.968 + margin_left * scale)
self.wilson_grad_begin = begin
self.wilson_grad_end = end
if value < (0.736 - 0.736*0.2):
max1 = 128.0
c1 = (255.0, 0 , 0)
max2 = 128.0
c2 = (0, 0, 0)
elif (0.736 - 0.736*0.1) < value < (0.736 + 0.736*0.1):
max1 = 128.0
c1 = (0, 255.0 , 0)
max2 = 128.0
c2 = (0, 0, 0)
elif (0.736 + 0.736*0.1) <= value <= (0.968 - 0.968*0.1):
max1 = 128.0
c1 = (255.0, 0, 0)
max2 = 128.0
c2 = (255.0, 0, 0)
elif (0.968 - 0.968*0.1) < value < (0.968 + 0.968*0.1):
max1 = 128.0
c1 = (0, 0, 0)
max2 = 128.0
c2 = (0, 255.0, 0)
elif value > (0.968 + 0.968*0.1):
max1 = 128.0
c1 = (0, 0, 0)
max2 = 128.0
c2 = (255.0, 0, 0)
else:
max1 = 128.0
c1 = (255.0, 0, 0)
max2 = 128.0
c2 = (255.0, 0, 0)
for i in xrange(boxWidth-2):
i += 1
if i == margin_left:
txt = "acentric"
txt = OV.TranslatePhrase(txt)
wX, wY = IT.textsize(draw, txt, font_size=self.font_size_tiny)
top_left = (i-int(wX/2), 0)
IT.write_text_to_draw(draw, txt, top_left=top_left, font_size=self.font_size_tiny, font_colour=self.gui_html_highlight_colour)
txt = "0.736"
wX, wY = draw.textsize(txt, font=self.font_tiny)
draw.text((i-int(wX/2), boxTopOffset+boxHeight-1), "%s" %txt, font=self.font_tiny, fill=self.titleColour)
if i == (margin_right):
txt = "centric"
txt = OV.TranslatePhrase(txt)
wX, wY = draw.textsize(txt, font=self.font_tiny)
top_left = (i-int(wX/2), 0)
IT.write_text_to_draw(draw, txt, top_left=top_left, font_size=self.font_size_tiny, font_colour=self.gui_html_highlight_colour)
txt = "0.968"
wX, wY = draw.textsize(txt, font=self.font_small)
draw.text((i-int(wX/2), boxTopOffset+boxHeight-1), "%s" %txt, font=self.font_tiny, fill=self.titleColour)
top = int(boxTopOffset+1)
bottom = int(boxTopOffset+boxHeight-2)
if i < margin_left:
step = (max1)/margin_left
col = max1+step*(margin_left - i)
col = int(col)
fill = self.grad_fill(max1, c1, col)
draw.line(((i, top),(i, bottom)), fill=fill)
elif i == margin_left:
draw.line(((i, top),(i, bottom)), fill=self.outlineColour)
elif i < middle:
step = (max1)/(middle-margin_left)
col = max1+step*(i - margin_left)
col = int(col)
fill = self.grad_fill(max1, c1, col)
draw.line(((i, top),(i, bottom)), fill=fill)
elif i == middle:
draw.line(((i, top),(i, bottom)), fill=self.outlineColour)
elif i > middle and i < (margin_right):
step = (max2)/(margin_right-middle)
col = max2+step*(margin_right - i)
col = int(col)
fill = self.grad_fill(max2, c2, col)
draw.line(((i, top),(i, bottom)), fill=fill)
elif i == (margin_right):
draw.line(((i, top),(i, bottom)), fill=self.outlineColour)
else:
step = ((max2)/(boxWidth-margin_right))
col = max2+step*(i - margin_right)
col = int(col)
fill = self.grad_fill(max2, c2, col)
draw.line(((i, top),(i, bottom)), fill=fill)
val = int((value - begin) / scale)
txt = unichr(8226)
wX, wY = draw.textsize(txt, font=self.font_bold_normal)
draw.ellipse(((val-int(wX/2), boxTopOffset+3),(val+int(wX/2), boxTopOffset+boxHeight-3)), fill=(255,235,10))
draw.text((val-int(wX/2), boxTopOffset-self.imY*0.001), "%s" %txt, font=self.font_bold_normal, fill="#ff0000")
image_location = "%s.png" %("grad")
OlexVFS.save_image_to_olex(im, image_location, 1)
return im
def grad_fill(self, max, c1, col):
fill = []
for c in c1:
if not c:
c = col
fill.append(int(col))
else:
fill.append(int(c))
fill = tuple(fill)
return fill
class ChargeFlippingPlot(PrgAnalysis):
def __init__(self):
program = ExternalPrgParameters.defineExternalPrograms()[0].programs["olex2.solve"]
method = program.methods["Charge Flipping"]
self.item = "Charge Flipping"
PrgAnalysis.__init__(self, program, method)
def run_charge_flipping_graph(self, flipping, solving, previous_state):
top = self.graph_top
marker_width = 5
title = self.graphInfo.get('Title', "")
width = self.params.size_x
height = self.graph_bottom - self.graph_top
if solving.state is solving.guessing_delta:
if previous_state is not solving.guessing_delta:
txt = "%s" %self.attempt
wX, wY = IT.textsize(self.draw, txt, font_size=self.font_size_large, font_name = "Vera Bold")
x = self.counter + marker_width + 5
top_left = (x, self.graph_bottom -wY -3)
IT.write_text_to_draw(self.draw, txt, top_left=top_left, font_size=self.font_size_large, font_name = "Vera Bold", font_colour=self.light_grey)
self.attempt += 1
if self.counter != 0:
self.counter += 1
self.draw.line(((self.counter + marker_width, self.graph_top),(self.counter + marker_width, self.graphY+self.graph_top - 2)), width=1, fill=(230, 230, 230))
return
elif solving.state is solving.solving:
cc = flipping.c_tot_over_c_flip()
R1 = flipping.r1_factor()
self.counter+=marker_width
if self.counter > width - 10:
self.make_empty_graph()
self.draw = ImageDraw.Draw(self.im)
self.counter = self.bSides
txt = "...continued"
wX, wY = IT.textsize(self.draw, txt, font_size=self.font_size_normal)
x = width - wX - self.bSides - 3
top_left = (x, 20)
IT.write_text_to_draw(self.draw, txt, top_left=top_left, font_size=self.font_size_normal, font_colour=self.light_grey)
x = self.counter
## Draw CC
txt = "cc=%.3f" %cc
if cc > 1: cc = 1
ccR = int(255*cc)
ccG = int(255*(1.3-cc))
ccB = 0
cc = int(height*(1-cc) + top)
box = (x,cc,x+marker_width,cc+marker_width)
self.draw.rectangle(box, fill=(ccR, ccG, ccB), outline=(int(ccR/2), int(ccG/2), 0))
## Draw R1
txt += ", R1=%.3f" %R1
rR = int(255*R1*2)
rG = int(255*(1.3-R1*2))
rB = 0
R1 = height*(1-R1) + top
box = (x,R1,x+marker_width,R1+2)
self.draw.rectangle(box, fill=(rR, rG, rB), outline=(int(rR/2), int(rG/2), 0))
font_name = "Vera"
font_size = 10
font = IT.registerFontInstance(font_name, font_size)
legend_top = height + 20
legend_top = self.graph_bottom + 1
m_offset = 5
## Wipe the legend area
box = (0,legend_top,width,legend_top + 20)
self.draw.rectangle(box, fill=self.fillColour)
## Draw CC Legend
box = (10,legend_top +m_offset,10+marker_width, legend_top+marker_width + m_offset)
self.draw.rectangle(box, fill=(ccR, ccG, ccB), outline=(int(ccR/2), int(ccG/2), 0))
tt = "CC"
top_left = (10+marker_width+3, legend_top)
IT.write_text_to_draw(self.draw, txt, top_left=top_left, font_size=self.font_size_normal, font_colour=self.light_grey)
## Draw R1 Legend
box = (40,legend_top + m_offset + 1,40+marker_width,legend_top + m_offset + 3)
self.draw.rectangle(box, fill=(rR, rG, rB), outline=(int(rR/2), int(rG/2), 0))
tt = "R1"
self.draw.text((40+marker_width+3, legend_top), "%s" %tt, font=self.font_large, fill="#888888")
## Draw Current Numbers
wX, wY = self.draw.textsize(txt, font=self.font_large)
x = width - wX - self.bSides
self.draw.text((x, legend_top), "%s" %txt, font=self.font_large, fill="#888888")
self.update_image()
class CumulativeIntensityDistribution(Analysis):
def __init__(self):
Analysis.__init__(self)
self.item = "cumulative"
self.graphInfo["Title"] = OV.TranslatePhrase("Cumulative Intensity Distribution")
self.graphInfo["pop_html"] = self.item
self.graphInfo["pop_name"] = self.item
self.graphInfo["TopRightTitle"] = self.TopRightTitle
self.auto_axes = False
self.make_cumulative_intensity_distribution()
self.popout()
if self.params.cumulative_intensity.output_csv_file:
self.output_data_as_csv()
def make_cumulative_intensity_distribution(self):
acentric = "1-exp(-x)"
centric = "sqrt(erf(0.5*x))"
twinned_acentric = "1-(1+2*x)*exp(-2*x)" # E. Stanley, J.Appl.Cryst (1972). 5, 191
locals = {'erf':erf}
self.cctbx_cumulative_intensity_distribution()
self.make_empty_graph(axis_x = True)
self.plot_function(centric, locals=locals)
self.plot_function(acentric, locals=locals)
self.plot_function(twinned_acentric, locals=locals)
self.metadata['equations'] = [{'eq':acentric, 'name':'acentric'},
{'eq':centric, 'name':'centric'},
{'eq':twinned_acentric, 'name':"twinned acentric"},
]
key = self.draw_key(({'type': 'function',
'number': 1,
#'label': OV.TranslatePhrase('Centric')},
'label': 'Centric'},
{'type':'function',
'number': 2,
#'label': OV.TranslatePhrase('Acentric')},
'label': 'Acentric'},
{'type': 'function',
'number': 3,
#'label': OV.TranslatePhrase('Twinned Acentric')}
'label': 'Twinned Acentric'}
))
self.im.paste(key,
(int(self.graph_right-(key.size[0]+40)),
int(self.graph_bottom-(key.size[1]+40)))
)
self.draw_pairs()
def cctbx_cumulative_intensity_distribution(self, verbose=False):
from reflection_statistics import OlexCctbxGraphs
xy_plot = OlexCctbxGraphs(
'cumulative',
n_bins=self.params.cumulative_intensity.n_bins).xy_plot
metadata = {}
metadata.setdefault("y_label", xy_plot.yLegend)
metadata.setdefault("x_label", xy_plot.xLegend)
metadata.setdefault("name", 'Cumulative')
metadata['marker'] = {'size':12}
self.metadata = metadata
self.data.setdefault('dataset1', Dataset(xy_plot.x, xy_plot.y,metadata=metadata))
if verbose:
self.data['dataset1'].show_summary()
class CompletenessPlot(Analysis):
def __init__(self):
Analysis.__init__(self)
self.item = "completeness"
self.graphInfo["Title"] = OV.TranslatePhrase("Completeness Plot")
self.graphInfo["pop_html"] = self.item
self.graphInfo["pop_name"] = self.item
self.graphInfo["TopRightTitle"] = self.TopRightTitle
self.auto_axes = False
self.reverse_x = self.params.completeness.resolution_as in ('d_spacing', 'd_star_sq')
self.cctbx_completeness_statistics()
self.make_empty_graph(axis_x = True)
self.draw_pairs(reverse_x=self.reverse_x)
self.popout()
if self.params.completeness.output_csv_file:
self.output_data_as_csv()
def cctbx_completeness_statistics(self):
from reflection_statistics import OlexCctbxGraphs
params = self.params.completeness
xy_plot = OlexCctbxGraphs(
'completeness',
reflections_per_bin=params.reflections_per_bin,
bin_range_as=params.resolution_as).xy_plot
metadata = {}
metadata.setdefault("y_label", OV.TranslatePhrase("Shell Completeness"))
metadata.setdefault("x_label", params.resolution_as)
metadata.setdefault("name", 'Completeness')
self.metadata = metadata
x = [xy_plot.x[i] for i in range(len(xy_plot.y)) if xy_plot.y[i] is not None]
y = [xy_plot.y[i]*100 for i in range(len(xy_plot.y)) if xy_plot.y[i] is not None]
self.data.setdefault('dataset1', Dataset(x, y, metadata=metadata))
class SystematicAbsencesPlot(Analysis):
def __init__(self):
Analysis.__init__(self)
self.item = "sys_absences"
self.graphInfo["Title"] = OV.TranslatePhrase("Systematic Absences Intensity Distribution")
self.graphInfo["pop_html"] = self.item
self.graphInfo["pop_name"] = self.item
self.graphInfo["TopRightTitle"] = self.TopRightTitle
self.auto_axes = True
self.cctbx_systematic_absences_plot()
self.popout()
if self.have_data:
if self.params.systematic_absences.output_csv_file:
self.output_data_as_csv()
def cctbx_systematic_absences_plot(self):
from reflection_statistics import OlexCctbxGraphs
xy_plot = OlexCctbxGraphs('sys_absent').xy_plot
metadata = {}
metadata.setdefault("y_label", xy_plot.yLegend)
metadata.setdefault("x_label", xy_plot.xLegend)
metadata.setdefault("name", 'Systematic Absences')
self.metadata = metadata
if xy_plot.x is None:
self.have_data = False
self.draw_origin = True
self.make_empty_graph(axis_x = True)
print "No systematic absences present"
return None
self.have_data = True
self.data.setdefault('dataset1', Dataset(xy_plot.x, xy_plot.y, indices=xy_plot.indices, metadata=metadata))
self.draw_origin = True
self.make_empty_graph(axis_x = True)
self.draw_pairs(marker_size_factor = 1/1.5)
class bijvoet_differences_scatter_plot(Analysis):
def __init__(self):
Analysis.__init__(self)
self.item = "bijvoet_differences_scatter"
self.graphInfo["pop_html"] = self.item
self.graphInfo["pop_name"] = self.item
self.graphInfo["TopRightTitle"] = self.TopRightTitle
self.auto_axes = True
import reflection_statistics
use_students_t = self.params.bijvoet_differences_scatter_plot.use_students_t
xy_plot = reflection_statistics.bijvoet_differences_scatter_plot(
use_students_t=use_students_t).xy_plot_info()
if xy_plot is None:
self.have_data = False
return
self.graphInfo["Title"] = OV.TranslatePhrase(xy_plot.title)
metadata = {}
metadata.setdefault("fit_slope", xy_plot.fit_slope)
metadata.setdefault("fit_y_intercept", xy_plot.fit_y_intercept)
metadata.setdefault("y_label", xy_plot.yLegend)
metadata.setdefault("x_label", xy_plot.xLegend)
metadata.setdefault("name", 'Bijvoet Differences')
self.metadata = metadata
self.have_data = True
self.data.setdefault(
'dataset1', Dataset(xy_plot.x, xy_plot.y, sigmas=xy_plot.sigmas,
indices=xy_plot.indices, metadata=metadata))
self.draw_origin = True
self.make_empty_graph(axis_x = True)
self.draw_pairs(marker_size_factor = 1/1.5)
if self.have_data:
self.popout()
if self.params.bijvoet_differences_scatter_plot.output_csv_file:
self.output_data_as_csv()
class bijvoet_differences_NPP(Analysis):
def __init__(self):
Analysis.__init__(self)
self.item = "bijvoet_differences_NPP"
self.graphInfo["pop_html"] = self.item
self.graphInfo["pop_name"] = self.item
self.graphInfo["TopRightTitle"] = self.TopRightTitle
self.auto_axes = True
import reflection_statistics
params = self.params.bijvoet_differences_probability_plot
use_students_t = params.use_students_t
use_fcf = params.source == "fcf"
xy_plot = reflection_statistics.bijvoet_differences_NPP(
use_students_t=use_students_t, use_fcf=use_fcf).xy_plot_info()
if xy_plot is None:
self.have_data = False
return
self.graphInfo["Title"] = OV.TranslatePhrase(xy_plot.title)
metadata = {}
metadata.setdefault("fit_slope", xy_plot.fit_slope)
metadata.setdefault("fit_y_intercept", xy_plot.fit_y_intercept)
metadata.setdefault("y_label", xy_plot.yLegend)
metadata.setdefault("x_label", xy_plot.xLegend)
self.metadata = metadata
self.have_data = True
self.data.setdefault('dataset1', Dataset(xy_plot.x, xy_plot.y, indices=xy_plot.indices, metadata=metadata))
self.draw_origin = True
self.make_empty_graph(axis_x = True)
self.draw_pairs(marker_size_factor = 1/1.5)
if self.have_data:
self.popout()
if self.params.bijvoet_differences_probability_plot.output_csv_file:
self.output_data_as_csv()
class Normal_probability_plot(Analysis):
def __init__(self):
Analysis.__init__(self)
self.item = "Normal_probability_plot"
self.graphInfo["Title"] = OV.TranslatePhrase("Normal Probability Plot")
self.graphInfo["pop_html"] = self.item
self.graphInfo["pop_name"] = self.item
self.graphInfo["TopRightTitle"] = self.TopRightTitle
self.auto_axes = True
self.draw_origin = True
self.make_normal_probability_plot()
self.popout()
if self.params.normal_probability.output_csv_file in (True, 'true', 'True'):
self.output_data_as_csv()
def make_normal_probability_plot(self):
from reflection_statistics import normal_probability_plot
xy_plot = normal_probability_plot().xy_plot_info()
self.metadata.setdefault("y_label", xy_plot.yLegend)
self.metadata.setdefault("x_label", xy_plot.xLegend)
metadata = {}
metadata.setdefault("fit_slope", xy_plot.fit_slope)
metadata.setdefault("fit_y_intercept", xy_plot.fit_y_intercept)
amplitudes = [elem[1] for elem in list(xy_plot.amplitudes_array)]
metadata['amplitudes'] = amplitudes
data = Dataset(
xy_plot.x, xy_plot.y, indices=xy_plot.indices, metadata=metadata)
self.data.setdefault('dataset1', data)
self.make_empty_graph(axis_x = True)
self.draw_pairs()
class Fobs_Fcalc_plot(Analysis):
def __init__(self, batch_number=None):
Analysis.__init__(self)
self.item = "Fobs_Fcalc"
self.graphInfo["Title"] = OV.TranslatePhrase("Fobs vs Fcalc")
self.graphInfo["pop_html"] = self.item
self.graphInfo["pop_name"] = self.item
self.graphInfo["TopRightTitle"] = self.TopRightTitle
self.auto_axes = False
try:
batch_number = int(batch_number)
except (ValueError, TypeError):
self.batch_number = None
else:
self.batch_number = batch_number
try:
self.make_f_obs_f_calc_plot()
except AssertionError, e:
if str(e) == "model.scatterers().size() > 0":
print "You need some scatterers to do this!"
return
else:
raise
self.popout()
if self.params.fobs_fcalc.output_csv_file:
self.output_data_as_csv()
def make_f_obs_f_calc_plot(self):
from reflection_statistics import f_obs_vs_f_calc
xy_plot = f_obs_vs_f_calc(batch_number=self.batch_number).xy_plot
self.metadata['shapes'] = []
self.metadata.setdefault("y_label", xy_plot.yLegend)
self.metadata.setdefault("x_label", xy_plot.xLegend)
equal_line = {'type':'line',
'xy':('0','0','%(max_x)s','%(max_x)s'),
'line': {
'color': 'rgb(100, 100, 100)',
'width': 1,
'dash':'dashdot'
}
}
self.metadata["shapes"].append(equal_line)
## Included Data
metadata = {}
# metadata.setdefault("fit_slope", xy_plot.fit_slope)
# metadata.setdefault("fit_y_intercept", xy_plot.fit_y_intercept)
metadata["name"] = "Included Data"
data = Dataset(
xy_plot.f_calc, xy_plot.f_obs, indices=xy_plot.indices, metadata=metadata)
self.data.setdefault('dataset1', data)
## Omitted Data
metadata = {}
metadata["name"] = "Omitted Data"
if xy_plot.f_obs_omitted and xy_plot.f_obs_omitted.size():
data_omitted = Dataset(
xy_plot.f_calc_omitted, xy_plot.f_obs_omitted, indices=xy_plot.indices_omitted, metadata=metadata)
self.data.setdefault('dataset2', data_omitted)
self.make_empty_graph(axis_x = True)
self.draw_pairs()
key = self.draw_key(({'type': 'marker',
'number': 1,
'label': OV.TranslatePhrase('Filtered Data')},
{'type':'marker',
'number': 2,
'label': OV.TranslatePhrase('Omitted Data')}
))
self.im.paste(key,
(int(self.graph_right-(key.size[0]+40)),
int(self.graph_bottom-(key.size[1]+40)))
)
class Fobs_over_Fcalc_plot(Analysis):
def __init__(self):
Analysis.__init__(self)
self.item = "Fobs_over_Fcalc"
self.graphInfo["Title"] = OV.TranslatePhrase("Fobs/Fcalc vs resolution")
self.graphInfo["pop_html"] = self.item
self.graphInfo["pop_name"] = self.item
self.graphInfo["TopRightTitle"] = self.TopRightTitle
self.auto_axes = False
self.max_y = 1.05
try:
self.make_plot()
except AssertionError, e:
if str(e) == "model.scatterers().size() > 0":
print "You need some scatterers to do this!"
return
else:
raise AssertionError, e
self.popout()
if self.params.fobs_over_fcalc.output_csv_file:
self.output_data_as_csv()
def make_plot(self):
from reflection_statistics import f_obs_over_f_calc
params = self.params.fobs_over_fcalc
xy_plot = f_obs_over_f_calc(
binning=params.binning,
n_bins=params.n_bins,
resolution_as=params.resolution_as).xy_plot
self.metadata.setdefault("y_label", xy_plot.yLegend)
self.metadata.setdefault("x_label", xy_plot.xLegend)
metadata = {}
if not params.binning:
indices = xy_plot.indices
else:
indices = None
data = Dataset(
xy_plot.resolution, xy_plot.f_obs_over_f_calc,
indices=indices, metadata=metadata)
reverse_x = params.resolution_as in ('d_spacing', 'd_star_sq')
self.data.setdefault('dataset1', data)
self.make_empty_graph(axis_x=True)
#self.plot_function("1")
self.draw_fit_line(slope=0, y_intercept=1, write_equation=False)
self.draw_pairs(reverse_x=reverse_x)
class scale_factor_vs_resolution_plot(Analysis):
def __init__(self):
Analysis.__init__(self)
self.item = "scale_factor_vs_resolution"
self.graphInfo["Title"] = OV.TranslatePhrase("Scale factor vs resolution")
self.graphInfo["pop_html"] = self.item
self.graphInfo["pop_name"] = self.item
self.graphInfo["TopRightTitle"] = self.TopRightTitle
self.auto_axes = False
self.max_y = 1.05
try:
self.make_plot()
except AssertionError, e:
if str(e) == "model.scatterers().size() > 0":
print "You need some scatterers to do this!"
return
else:
raise AssertionError, e
self.popout()
if self.params.scale_factor_vs_resolution.output_csv_file:
self.output_data_as_csv()
def make_plot(self):
from reflection_statistics import scale_factor_vs_resolution
params = self.params.scale_factor_vs_resolution
xy_plot = scale_factor_vs_resolution(
params.n_bins, params.resolution_as).xy_plot_info()
self.metadata.setdefault("y_label", xy_plot.yLegend)
self.metadata.setdefault("x_label", xy_plot.xLegend)
metadata = {}
data = Dataset(
xy_plot.x, xy_plot.y, metadata=metadata)
self.data.setdefault('dataset1', data)
self.make_empty_graph(axis_x=True)
self.draw_fit_line(slope=0, y_intercept=1, write_equation=False)
reverse_x = params.resolution_as in ('d_spacing', 'd_star_sq')
self.draw_pairs(reverse_x=reverse_x)
class item_vs_resolution_plot(Analysis):
def __init__(self, item):
Analysis.__init__(self)
self.item = item
params = getattr(self.params, self.item)
self.graphInfo["Title"] = params.title
self.graphInfo["pop_html"] = self.item
self.graphInfo["pop_name"] = self.item
self.graphInfo["TopRightTitle"] = self.TopRightTitle
self.auto_axes = False
#self.max_y = 1.05
try:
res = self.make_plot()
except AssertionError, e:
if str(e) == "model.scatterers().size() > 0":
print "You need some scatterers to do this!"
return
else:
raise
if not res:
return None
self.popout()
if OV.GetParam('user.diagnostics.save_file'):
res = self.im.save(OV.ModelSrc() + "_" + self.item + ".png",'PNG')
self.output_data_as_csv()
def make_plot(self):
y_factor = 1
if "r1" in self.item:
y_factor = 100
from reflection_statistics import item_vs_resolution
params = getattr(self.params, self.item)
xy_plot = item_vs_resolution(item=self.item, n_bins=params.n_bins, resolution_as=params.resolution_as).xy_plot_info()
if not xy_plot:
return None
while None in xy_plot.y:
params.n_bins -= 1
xy_plot = item_vs_resolution(item=self.item, n_bins=params.n_bins, resolution_as=params.resolution_as).xy_plot_info()
self.metadata.setdefault("y_label", xy_plot.yLegend)
self.metadata.setdefault("x_label", xy_plot.xLegend)
self.metadata.setdefault("shapes",[])
cutoff_line = {'type':'line',
'xy':('%(min_x)s','2','%(max_x)s','2'),
'line': {
'color': 'rgb(255, 100, 100)',
'width': 1,
'dash':'dashdot'
}
}
IUCr_limit= {'type':'line',
'xy':('50', '%(min_y)s', '50', '%(max_y)s'),
'line': {
'color': 'rgb(100, 100, 100)',
'width': 1,
'dash':'dashdot'
}
}
self.metadata["shapes"].append(cutoff_line)
self.metadata["shapes"].append(IUCr_limit)
metadata = self.metadata
data = Dataset(
xy_plot.x, [y*y_factor for y in xy_plot.y], metadata=metadata)
self.data.setdefault('dataset1', data)
self.make_empty_graph(axis_x=True)
iucr = 135
if olx.xf.exptl.Radiation().startswith('0.710'):
iucr = 50
if self.item == "i_over_sigma_vs_resolution":
self.draw_fit_line(slope=0, y_intercept=3, write_equation=False, write_text="3 sigma line (noise below, data above)")
self.draw_fit_line(slope=0, y_intercept=0, x_intercept=iucr, write_equation=False, write_text="min IUCr res")
#if self.item == "cc_half_vs_resolution":
#self.draw_fit_line(slope=0, y_intercept=0.15, write_equation=False, write_text="3 sigma line (noise below, data above)")
#self.draw_fit_line(slope=0, y_intercept=0, x_intercept=iucr, write_equation=False, write_text="min IUCr res")
#if self.item == "rmerge_vs_resolution":
#self.draw_fit_line(slope=0, y_intercept=0.15, write_equation=False, write_text="3 sigma line (noise below, data above)")
#self.draw_fit_line(slope=0, y_intercept=0, x_intercept=iucr, write_equation=False, write_text="min IUCr res")
reverse_x = params.resolution_as in ('d_spacing', 'd_star_sq')
self.draw_pairs(reverse_x=reverse_x, lt=3)
return True
class X_Y_plot(Analysis):
def __init__(self):
Analysis.__init__(self)
self.item = "X_Y_plot"
self.series = []
print("Good things will come to those who wait")
def run(self):
# filepath = self.file_reader("%s/%s.csv" %(self.datadir,"ac_stats"))
# filepath = ("%s/%s.csv" %(self.datadir,"s"))
# self.get_simple_x_y_pair_data_from_file(filepath)
# meta = data['meta']
# self.graphInfo["imSize"] = meta["imSize"]
# self.graphInfo["Title"] = meta["Title"]
# self.graphInfo["pop_html"] = meta["pop_html"]
# self.graphInfo["pop_name"] = meta["pop_name"]
# self.graphInfo["TopRightTitle"] = meta["TopRightTitle"]
# self.graphInfo["FontScale"] = meta["FontScale"]
self.graphInfo.update(self.metadata)
self.make_empty_graph(axis_x = True)
i = 1
for item in self.series:
self.data.setdefault('dataset%s'%i,Dataset(x=item[0],
y=item[1],
hrefs=item[2],
targets=item[3],
metadata=item[4],
))
i += 1
self.draw_pairs()
self.graphInfo.setdefault("pop_html", 'acgraph.htm')
self.graphInfo.setdefault("pop_name", 'acgraph')
self.popout()
class HistoryGraph(Analysis):
def __init__(self, history_tree):
Analysis.__init__(self)
self.params = OV.Params().user.graphs.program_analysis
self.i_bar = 0
self.tree = history_tree
self.item = "history"
#self.params.size_x, self.params.size_y = size
#self.make_empty_graph(draw_title=False)
#self.image_location = "history.png"
self.green = OV.GetParam('gui.green').rgb[1]
self.red = OV.GetParam('gui.red').rgb[0]
self.blue = 0
self.make_graph()
#self.popout()
def make_graph(self):
global PreviousHistoryNode
bars = []
node = self.tree.active_child_node
#if node == PreviousHistoryNode:
# return
#else:
# PreviousHistoryNode = node
while node is not None:
R1 = node.R1
href = "spy.revert_history(%s)>>html.Update>>if html.IsPopup(history-tree) then spy.popout_history_tree()" %(node.name)
target = '%s (%s)' %(node.program, node.method)
if node.is_solution:
R1 = 1
else:
if R1 == 'n/a': R1 = 0.99
try:
target += ' - %.2f%%' %(node.R1 * 100)
except (ValueError, TypeError):
pass
if node is self.tree.active_node:
self.i_active_node = len(bars)
bars.append((R1,href,target))
node = node.active_child_node
n_bars = len(bars)
#width = int(olx.html.ClientWidth('self')) - OV.GetParam('gui.htmlpanelwidth_margin_adjust')
width = IT.skin_width_table - int(OV.GetParam('gui.html.table_firstcol_width')/2)
size = (width, 100)
self.params.size_x, self.params.size_y = size
self.make_empty_graph(draw_title=False)
y_scale_factor = self.params.y_scale_factor
if len(bars) > 0:
x = []
y = []
hrefs = []
targets = []
for i, bar in enumerate(bars):
x.append(i+1)
y.append(bar[0]) # R factor
hrefs.append(bar[1])
targets.append(bar[2])
data = Dataset(x, y, hrefs=hrefs, targets=targets)
self.draw_history_bars(dataset=data, y_scale_factor=y_scale_factor,
colour_function=self.get_bar_colours,
draw_bar_labels=False)
#label = '%s (%s)' %(self.tree.active_node.program, self.tree.active_node.method)
#try:
#label += ' - %.2f%%' %(self.tree.active_node.R1 * 100)
#except (ValueError, TypeError):
#pass
#self.draw_legend(label)
##self.draw_legend("%.3f" %(bars[self.i_active_node][0]))
#historyText = """\
#
#%s
#
#""" %(self.image_location, self.map_txt)
#OV.write_to_olex('history-info.htm',historyText)
def get_bar_colours(self, bar_height):
factor = self.params.y_scale_factor
#if self.i_bar == self.i_active_node:
#fill = (int(255*bar_height), int(255*(1.3-bar_height)), 0)
#self.decorated = True
##fill = OV.GetParam('gui.grey').rgb
if bar_height == factor:
fill = (139, 0, 204)
else:
fill = (int(self.red*bar_height), int(self.green*(1.3-bar_height)), self.blue)
#if self.i_bar != self.i_active_node:
#fill = IT.adjust_colour(fill, luminosity=1.5)
self.i_bar += 1
return fill
class Dataset(object):
def __init__(self, x=None, y=None, indices=None, sigmas=None,
hrefs=None, targets=None, metadata={}):
if x is None: x = []
if y is None: y = []
self.x = x
self.y = y
self.sigmas = sigmas
self.hrefs = hrefs
self.targets = targets
self.indices = indices
self._metadata = metadata
def xy_pairs(self):
return zip(self.x,self.y)
def metadata(self):
return self._metadata
def show_summary(self):
print ''.join("%f, %f\n" %(x,y) for x,y in self.xy_pairs())
def add_pair(self, x, y):
self.x.append(x)
self.y.append(y)
Analysis_instance = Analysis()
OV.registerMacro(Analysis_instance.run_Analysis,
'n_bins-Number of bins (for histograms only!)&;method-olex or cctbx')
OV.registerFunction(WilsonPlot)
OV.registerFunction(CumulativeIntensityDistribution)
OV.registerFunction(CompletenessPlot)
OV.registerFunction(SystematicAbsencesPlot)
OV.registerFunction(Fobs_Fcalc_plot)
OV.registerFunction(Fobs_over_Fcalc_plot)
OV.registerFunction(Normal_probability_plot)
OV.registerFunction(item_vs_resolution_plot)
OV.registerFunction(scale_factor_vs_resolution_plot)
OV.registerFunction(X_Y_plot)
OV.registerFunction(bijvoet_differences_scatter_plot)
OV.registerFunction(bijvoet_differences_NPP)
def array_scalar_multiplication(array, multiplier):
return [i * multiplier for i in array]
def makeReflectionGraphOptions(graph, name):
guiParams = OV.GuiParams()
### This is assuming that there are no more than FOUR option controls:
width = int(OV.GetParam('gui.htmlpanelwidth') - OV.GetParam('gui.htmlpanelwidth_margin_adjust'))/4
value = graph.short_caption
options_gui = []
i = 1
for obj in graph.active_objects():
i += 1
data_type = obj.type.phil_type
caption = obj.caption
value = obj.extract()
# obj_name = name.upper() + "_" + object.caption.upper().replace(" ","_").replace("%","").replace("-","_")
obj_name = name.upper()
if data_type == "int":
ctrl_name = 'SPIN_%s' %(obj_name)
d = {'ctrl_name':ctrl_name,
'value':value,
'max':'30',
'width':'%s' %width,
'label':'%s ' %caption,
'onchange':"spy.SetParam('user.graphs.reflections.%s.%s',html.GetValue('%s'))" %(
graph.name, obj.name,ctrl_name),
}
options_gui.append(htmlTools.make_spin_input(d))
elif data_type in ("str", "float"):
ctrl_name = 'TEXT_%s' %(obj_name)
d = {'ctrl_name':ctrl_name,
'value':value,
'width':'%s' %width,
'label':'%s ' %caption,
'onchange':"spy.SetParam('user.graphs.reflections.%s.%s',html.GetValue('%s'))" %(
graph.name, obj.name,ctrl_name),
'readonly':'readonly',
}
options_gui.append(htmlTools.make_input_text_box(d))
elif data_type == "bool":
ctrl_name = 'TICK_%s' %(obj_name)
d = {'ctrl_name':ctrl_name,
'value':'%s ' %caption,
'checked':'%s' %value,
'oncheck':"spy.SetParam('user.graphs.reflections.%s.%s','True')" %(
graph.name, obj.name),
'onuncheck':"spy.SetParam('user.graphs.reflections.%s.%s','False')" %(
graph.name, obj.name),
'width':'%s' %width,
'bgcolor':'%s' %guiParams.html.table_bg_colour,
}
options_gui.append(htmlTools.make_tick_box_input(d))
elif data_type == "choice":
items_l = []
ctrl_name = 'COMBO_%s' %(obj_name)
for thing in obj.words:
items_l.append(thing.value.lstrip('*'))
items = ";".join(items_l)
d = {'ctrl_name':ctrl_name,
'label':'%s ' %caption,
'items':items,
'value':obj.extract(),
'onchange':"spy.SetParam('user.graphs.reflections.%s.%s',html.GetValue('%s'))>>spy.make_reflection_graph(html.GetValue('SET_REFLECTION_STATISTICS'))" %(
graph.name, obj.name,ctrl_name),
'width':'%s' %width,
}
options_gui.append(htmlTools.make_combo_text_box(d))
options_gui = '\n%s | \n' %'\n'.join(options_gui)
colspan = i
return options_gui, colspan
def makeReflectionGraphGui():
global GuiGraphChooserComboExists
guiParams = OV.GuiParams()
value = False
gui_d = {}
gui_d.setdefault('colspan', '1')
gui_d.setdefault('options_gui', "")
gui_d.setdefault('make_graph_button', "")
gui_d.setdefault('graph_chooser', "")
if GuiGraphChooserComboExists:
try:
value = OV.GetValue('SET_REFLECTION_STATISTICS')
except:
value = None
if not value:
GuiGraphChooserComboExists = True
help_name = None
name = None
else:
name = value.lower().replace(" ", "_").replace("-", "_").replace("/","_over_")
graph = olx.phil_handler.get_scope_by_name('user.graphs.reflections.%s' %name)
if not graph:
value = "no phil"
help_name = None
gui_d['options_gui'], gui_d['colspan'] = makeReflectionGraphOptions(graph, name)
help_name = graph.help
onclick = 'spy.make_reflection_graph\(%s)' %name
d = {'name':'BUTTON_MAKE_REFLECTION_GRAPH',
'bgcolor':guiParams.html.input_bg_colour,
'onclick': onclick,
'width':'30',
'value':'Go',
'valign':'top',
}
#gui_d['make_graph_button'] = htmlTools.make_input_button(d)
gui_d['make_graph_button'] = "$spy.MakeHoverButton('button_small-go@MakeGraphs','%s')" %onclick
gui_d['help'] = htmlTools.make_table_first_col(
help_name=help_name, popout=False)
d = {'ctrl_name':'SET_REFLECTION_STATISTICS',
'items':"-- %Please Select% --;" +\
"Wilson Plot;" +\
"Cumulative Intensity;" +\
"Systematic Absences;" +\
"Fobs-Fcalc;" +\
"I/sigma vs resolution;" +\
"cc_half_vs_resolution;" +\
"Rmerge vs resolution;" +\
"Fobs over Fcalc;" +\
"Completeness%;" +\
"Normal Probability;" +\
"Scale factor vs resolution;" +\
"R1 factor vs resolution;" +\
"Bijvoet Differences %Probability Plot%;" +\
"Bijvoet Differences %Scatter Plot%",
'height':guiParams.html.combo_height,
'bgcolor':guiParams.html.input_bg_colour,
'value':value,
'onchange':"spy.make_reflection_graph(html.GetValue('SET_REFLECTION_STATISTICS'))>>html.Update",
'manage':'manage',
'readonly':'readonly',
'width':'$math.eval(html.clientwidth(self)-140)',
'readonly':'readonly',
}
gui_d['graph_chooser']=htmlTools.make_combo_text_box(d)
gui_d['row_table_off'] = htmlTools.include_block('gui/blocks/row_table_off.htm')
gui_d['row_table_on'] = htmlTools.include_block('gui/blocks/row_table_on.htm')
gui_d['tool-first-column'] = htmlTools.include_block('gui/blocks/tool-first-column.htm')
gui_d['bgcolor'] = guiParams.html.table_firstcol_colour
txt = '''
|
%(graph_chooser)s
|
%(make_graph_button)s
|
''' %gui_d
if gui_d['options_gui'] != '':
txt += r'''
%(row_table_off)s
%(tool-first-column)s
%(row_table_on)s
%(options_gui)s
''' %gui_d
txt = OV.Translate(txt)
return txt
OV.registerFunction(makeReflectionGraphGui)
def make_reflection_graph(name):
if not OV.HKLSrc():
print "To make the %s graph, the reflection file must be accessible." %name
print "Are you looking at a CIF file?"
print "Try typing 'export' to extract the embedded files from the CIF."
return
name = name.lower().replace(" ", "_").replace("-", "_")
run_d = {'wilson_plot': WilsonPlot,
'cumulative_intensity': CumulativeIntensityDistribution,
'systematic_absences': SystematicAbsencesPlot,
'fobs_fcalc': Fobs_Fcalc_plot,
'fobs_over_fcalc': Fobs_over_Fcalc_plot,
'completeness': CompletenessPlot,
'normal_probability': Normal_probability_plot,
'r1_factor_vs_resolution': (item_vs_resolution_plot, "r1_factor_vs_resolution"),
'i/sigma_vs_resolution': (item_vs_resolution_plot, "i_over_sigma_vs_resolution"),
'i_over_sigma_vs_resolution': (item_vs_resolution_plot, "i_over_sigma_vs_resolution"),
'cc_half_vs_resolution': (item_vs_resolution_plot, "cc_half_vs_resolution"),
'rmerge_vs_resolution': (item_vs_resolution_plot, "rmerge_vs_resolution"),
'scale_factor_vs_resolution': scale_factor_vs_resolution_plot,
'bijvoet_differences_probability_plot': bijvoet_differences_NPP,
'bijvoet_differences_scatter_plot': bijvoet_differences_scatter_plot,
}
func = run_d.get(name)
arg = None
if type(func) is tuple:
fun = func[0]
arg = func[1]
fun(arg)
else:
func()
OV.registerFunction(make_reflection_graph)
class HealthOfStructure():
def __init__(self):
self.hkl_stats = {}
self.grade_1_colour = OV.GetParam('gui.skin.diagnostics.colour_grade1').hexadecimal
self.grade_2_colour = OV.GetParam('gui.skin.diagnostics.colour_grade2').hexadecimal
self.grade_3_colour = OV.GetParam('gui.skin.diagnostics.colour_grade3').hexadecimal
self.grade_4_colour = OV.GetParam('gui.skin.diagnostics.colour_grade4').hexadecimal
self.available_width = int(OV.GetParam('gui.htmlpanelwidth'))
self.stats = None
self.scale = OV.GetParam('gui.internal_scale')
self.scope = "hkl"
self.supplied_cif = False
self.im_cache = {}
_ = ['Completeness', 'MeanIOverSigma','Rint']
_ += ['_refine_ls_shift/su_max', '_refine_diff_density_max',
'_refine_diff_density_min', '_refine_ls_goodness_of_fit_ref',
'_refine_ls_abs_structure_Flack']
for item in _:
self.im_cache.setdefault(item,{})
def get_HOS_d(self):
try:
if self.initialise_HOS():
return self.summarise_HOS()
except Exception, err:
print err
return None
def make_HOS(self, force=False, supplied_cif=False):
force = bool(force)
self.width = int(IT.skin_width*0.98)
self.supplied_cif = supplied_cif
self.scopes = OV.GetParam('user.diagnostics.scopes')
self.scope = OV.GetParam('snum.current_process_diagnostics')
if timing:
import time
t1 = time.time()
res = self.initialise_HOS(force=force)
self.hos_text = ""
if res[0]:
if OV.GetParam('user.diagnostics.pin_scopes'):
for scope in self.scopes:
self.scope = scope
self.summarise_HOS()
self.make_HOS_html()
else:
self.summarise_HOS()
self.make_HOS_html()
OV.write_to_olex("hos.htm",self.hos_text)
elif res[1]:
OV.write_to_olex("hos.htm", "")
OV.write_to_olex("reflection-stats-summary.htm" , "n/a")
self.stats = None
if timing:
print "HOS took %.4f seconds" %(time.time() - t1)
def initialise_HOS(self, force=False):
""" Returns (bool, bool) the first boolean specifies if the initialisation
was successful, and the second - if the HOS has to be reset
"""
from cctbx import uctbx
if olx.IsFileLoaded() != 'true':
return (False, True)
self.is_CIF = (olx.IsFileType('cif') == 'true')
try:
self.hkl_stats['IsCentrosymmetric'] = olex_core.SGInfo()['Centrosymmetric']
radiation = float(olx.xf.exptl.Radiation())
theta_full = math.asin(radiation*0.6)*180/math.pi
self.hkl_stats = olex_core.GetHklStat()
if self.hkl_stats['DataCount'] == 0:
self.hkl_stats = {}
resolution_type = OV.GetParam("user.diagnostics.hkl.Completeness.resolution")
if self.hkl_stats:
self.hkl_stats['MeanIOverSigma'] = 1/self.hkl_stats['Rsigma']
if resolution_type == "full":
if olx.IsFileType("ires") == 'true':
try:
acta = float(olx.Ins("ACTA"))/2
if acta < theta_full:
theta_full = acta/2
except:
pass
# adjust to the dataset theta max if needed
theta_full1 = math.asin(radiation/(2*self.hkl_stats['MinD']))*180/math.pi
if theta_full1 < theta_full:
theta_full = theta_full1
self.hkl_stats['Completeness'] = float(olx.xf.rm.Completeness(theta_full*2))
self.hkl_stats['Completeness_laue'] = float(olx.xf.rm.Completeness(theta_full*2,True))
self.hkl_stats['Completeness_point'] = float(olx.xf.rm.Completeness(theta_full*2,False))
if not self.hkl_stats and self.is_CIF:
try:
wl = float(olx.Cif('_diffrn_radiation_wavelength'))
_ = olx.Cif('_diffrn_measured_fraction_theta_%s' %resolution_type)
if _ != "n/a":
self.hkl_stats['Completeness'] = float(_)
self.hkl_stats['Completeness_laue'] = self.hkl_stats.get('Completeness_laue',float(_))
self.hkl_stats['Completeness_point'] = self.hkl_stats.get('Completeness_point',0)
twotheta = 2* (float(olx.Cif('_diffrn_reflns_theta_%s' %resolution_type)))
self.hkl_stats['MinD'] = uctbx.two_theta_as_d(twotheta ,wl, True)
else:
self.hkl_stats['MinD'] = 0
self.hkl_stats['Completeness'] = 0
##The following items can have alternate/deprecated identifiers
l = ['_diffrn_reflns_av_unetI/netI', '_diffrn_reflns_av_sigmaI/netI']
self.hkl_stats[''] = 0
for item in l:
_ = olx.Cif(item)
if _ != "n/a":
self.hkl_stats['MeanIOverSigma'] = 1/float(_)
break
else:
self.hkl_stats['MeanIOverSigma'] = 0
break
l = ['_diffrn_reflns_av_R_equivalents',]
self.hkl_stats['Rint'] = 0
for item in l:
_ = olx.Cif(item)
if _ != "n/a":
self.hkl_stats['Rint'] = float(_)
else:
self.hkl_stats['Rint'] = 1
except Exception, err:
print "Something could not be evaluated [Analysis.py]: %s" %err
l = ["- Point Group Completeness: %.2f" %self.hkl_stats['Completeness_point'],
"Laue Group Completeness: %.2f" %self.hkl_stats['Completeness_laue'],
]
target = "
- ".join(l)
OV.SetParam('user.diagnostics.hkl.Completeness.target', target)
except Exception, err:
print err
return (False, True)
if self.scope == "refinement":
return (True, True)
else:
self.scope = "hkl"
if force:
return (True, None)
try:
min_d = "%.4f" %self.hkl_stats['MinD']
if OV.GetParam('snum.hkl.d_min') == float(min_d):
if bool(olx.fs.Exists('MinD')):
return (False, False)
else:
OV.SetParam('snum.hkl.d_min',min_d)
if not self.hkl_stats:
return (False, True)
except:
return (False, True)
return (True, None)
def get_cctbx_completeness(self, dmin=None):
retVal = None
try:
from cctbx_olex_adapter import OlexCctbxAdapter
OCA = OlexCctbxAdapter()
f_sq_obs = OCA.reflections.f_sq_obs_filtered
retVal = f_sq_obs.completeness()
OV.SetParam('snum.hkl.completeness_full',retVal)
except Exception, err:
print err
pass
return retVal
def get_cctbx_reflection_statistics_html(self):
from reflection_statistics import OlexCctbxReflectionStats
self.stats = OlexCctbxReflectionStats()
value = self.stats.cctbx_stats.observations.completeness()
return value
def summarise_HOS(self):
d = {}
txt = ""
# item = "Completeness"
# value = self.get_cctbx_completeness()
# d.setdefault('Completeness', value)
# txt += "
%s | %s |
" %(item, value)
l = ['Completeness', 'MeanIOverSigma','Rint']
for item in self.hkl_stats:
value = self.hkl_stats[item]
if type(value) == tuple and len(value) > 0 and type(value[0]) == float:
value = tuple([round(x,4) for x in value])
else:
try:
fv = float(value)
iv = int(value)
if fv != iv:
value = "%.4f" %fv
except:
pass
d.setdefault(item, value)
txt += "
%s | %s |
" %(item, value)
OV.write_to_olex("reflection-stats-summary.htm" , txt)
if olx.HKLSrc():
t = time.ctime(os.path.getmtime(olx.HKLSrc()))
OV.write_to_olex("reflection-date.htm" , t)
return d
def is_in_cache(self, var, val):
global cache
if cache.has_key(var):
if cache[var]['val'] == val:
return True
else:
cache[var]['val'] = val
return False
else:
cache.setdefault(var,{'val':val, 'img':None})
return False
def make_HOS_html(self):
if self.scope == None:
self.scope = 'hkl'
# is_CIF = (olx.IsFileType('cif') == 'true')
if self.scope == "refinement":
if self.is_CIF:
l = ['_refine_ls_shift/su_max', '_refine_diff_density_max',
'_refine_diff_density_min', '_refine_ls_goodness_of_fit_ref',
'_refine_ls_abs_structure_Flack']
if olx.Cif('_refine_ls_abs_structure_Flack') == "n/a":
l.remove("_refine_ls_abs_structure_Flack")
else:
l = ['max_shift_over_esd', 'max_peak', 'max_hole', 'goof','flack_str']
if OV.GetParam('snum.refinement.flack_str')== "0" or not OV.GetParam('snum.refinement.flack_str'):
l.remove("flack_str")
else:
self.scope = "hkl"
if not self.hkl_stats:
return
l = ['MinD', 'MeanIOverSigma','Rint','Completeness']
txt = ""
counter = 0
for item in l:
counter += 1
if self.scope == "hkl":
if self.supplied_cif and item == "Rint":
value = self.supplied_cif.get('_diffrn_reflns_av_R_equivalents',0)
else:
value = self.hkl_stats[item]
if type(value) == tuple and len(value) > 0:
value = value[0]
elif self.scope == "refinement":
if self.is_CIF:
try:
value = float(olx.Cif(item))
except:
value = olx.Cif(item)
item = item.replace('/', '_over_')
else:
value = OV.GetParam('snum.refinement.%s' %item)
if item == "_refine_ls_goodness_of_fit_ref":
item = 'goof'
elif item == "_refine_diff_density_max":
item = 'max_peak'
elif item == "_refine_diff_density_min":
item = 'max_hole'
elif item == "_refine_ls_shift_over_su_max":
item = 'max_shift_over_esd'
elif item == "_refine_ls_abs_structure_Flack":
item = 'flack_str'
display = OV.GetParam('user.diagnostics.%s.%s.display' %(self.scope,item))
if item == "MinD":
_ = olx.xf.exptl.Radiation()
if _.startswith("1.54"):
_ = "Cu"
elif _.startswith("0.71"):
_ = "Mo"
display += " (%s)" %_
value_format = OV.GetParam('user.diagnostics.%s.%s.value_format' %(self.scope,item))
href = OV.GetParam('user.diagnostics.%s.%s.href' %(self.scope,item))
raw_val = value
bg_colour = None
flack_esd_f = 0
if item == "flack_str":
if "(" not in str(value):
value = str(value) + "()"
flack_val = value.split("(")[0]
flack_esd = value.split("(")[1].strip(")")
if len(flack_val.strip("-")) == 1:
if len(flack_esd) == 1:
flack_esd_f = float("%s" %flack_esd)
if len(flack_val.strip("-")) == 3:
if len(flack_esd) == 1:
flack_esd_f = float("0.%s" %flack_esd)
elif len(flack_esd) == 2:
flack_esd_f = float("%s.%s" %(flack_esd[0],flack_esd[1]))
elif len(flack_val.strip("-")) == 4:
if len(flack_esd) == 1:
flack_esd_f = float("0.0%s" %flack_esd)
elif len(flack_esd) == 2:
flack_esd_f = float("0.%s" %flack_esd)
elif len(flack_val.strip("-")) == 5:
if len(flack_esd) == 1:
flack_esd_f = float("0.00%s" %flack_esd)
elif len(flack_esd) == 2:
flack_esd_f = float("0.0%s" %flack_esd)
bg_esd = self.get_bg_colour('flack_esd', flack_esd_f)
if len(flack_esd) == 1:
_ = 0.75
else:
_ = 0.63
if len(flack_esd) == 0:
bg_val = "#000000"
bg_esd = "#000000"
else:
bg_val = self.get_bg_colour('flack_val', flack_val)
bg_colour = (bg_val,_,bg_esd)
if not bg_colour:
bg_colour = self.get_bg_colour(item, value)
if type(value) == tuple:
if len(value) > 0:
value = value[0]
else:
value = None
if value == None:
value = "n/a"
bg_colour = "#000000"
else:
try:
if "%" in value_format:
value_format = value_format.replace('%','f%%')
value = value * 100
#raw_val = value
except:
pass
if item == 'Rint':
if raw_val == 0:
value = "Merged!"
bg_colour = "#000000"
elif raw_val == -1:
value = "MERG 0"
bg_colour = "#000000"
else:
value_format = "%." + value_format
value = value_format %value
else:
try:
value_format = "%." + value_format
value = value_format %value
except:
pass
use_image = True
if use_image:
if timing:
t = time.time()
if counter == 1:
self.image_position = "first"
elif counter == len(l):
self.image_position = "last"
else:
self.image_position = "middle"
txt += self.make_hos_images(item=item, colour=bg_colour, display=display, value_raw=raw_val, value_display=value, n=len(l))
if timing:
print ".. hos image took %.3f s (%s) " %((time.time() - t),item)
else:
ref_open = ''
ref_close = ''
if href:
dollar = ""
if "()" in href:
dollar = "$"
ref_open = "" %(dollar, href)
ref_close = ""
txt += '''
%s: %s%s%s
|
'''%(bg_colour, 100/len(l), display, ref_open, value, ref_close)
txt += "
"
if self.scope == "hkl":
completeness = self.hkl_stats['Completeness']
if type(completeness) == tuple and len(completeness) > 1:
txt = """%s |
Twin component completeness (in P1): %s |
""" %(
txt, ", ".join(["%.2f%%%%" %(x*100) for x in completeness]))
txt = txt.decode('utf-8')
self.hos_text += txt
OV.SetParam('snum.hkl.hkl_stat_file', OV.HKLSrc())
def make_hos_images(self, item='test', colour='#ff0000', display='Display', value_display='10%', value_raw='0.1', n=1):
width = self.width
scale = self.scale
font_name = 'Vera'
value_display_extra = ""
completeness_box_width = 150
targetWidth = round(width/n)
targetHeight = round(OV.GetParam('gui.timage.h3.height'))
href = OV.GetParam('user.diagnostics.%s.%s.href' %(self.scope,item))
target = OV.GetParam('user.diagnostics.%s.%s.target' %(self.scope,item))
txt = ""
ref_open = ''
ref_close = ''
if href:
if href == "atom":
href = "sel %s" %OV.GetParam('snum.refinement.%s_atom' %item)
if item != 'max_hole':
ref_open = '' %(target, href)
ref_close = ""
txt += '''
%s%s | ''' %(ref_open, item, ref_close)
cache_entry = "%s_%s_%s" %(item, value_raw, targetWidth)
cache_image = self.im_cache.get(cache_entry,None)
cache_entry_large = "%s_large_%s_%s" %(item, value_raw, targetWidth)
cache_image_large = self.im_cache.get(cache_entry_large,None)
if cache_image and cache_image_large:
if debug:
print "HOS from Cache: %s" %cache_entry
im = IT.resize_image(cache_image, (targetWidth, targetHeight), name=cache_entry)
OlexVFS.save_image_to_olex(im, item, 0)
return txt
boxWidth = int(targetWidth * scale)
boxHeight = int(targetHeight * scale)
boxHalf = int(3 * scale)
bgcolour= OV.GetParam('gui.html.table_firstcol_colour').hexadecimal
im = Image.new('RGBA', (boxWidth,boxHeight), (0,0,0,0))
draw = ImageDraw.Draw(im)
try:
value_raw = float(value_raw)
except:
value_raw = 0
op = OV.GetParam('user.diagnostics.hkl.%s.op' %item)
curr_x = 0
limit_width = 0
od_value = None
theoretical_val = value_raw
if item == "Completeness":
od_value = OV.get_cif_item('_reflns_odcompleteness_completeness')
if od_value:
value_raw = float(od_value)
od_2theta = OV.get_cif_item('_reflns_odcompleteness_theta')
if od_2theta:
od_2theta = float(od_2theta) * 2
value_display_extra = "at 2Theta=%.0fdegrees" %(od_2theta)
value_display_extra = IT.get_unicode_characters(value_display_extra)
iucr_value = OV.get_cif_item('_diffrn_measured_fraction_theta_full')
if iucr_value:
value_raw = float(iucr_value)
iucr_2theta = OV.get_cif_item('_diffrn_reflns_theta_full')
iucr_2theta = "IUCr"
if iucr_2theta:
value_display_extra = "%.0f%% (IUCr)" %(value_raw *100)
if type(colour) == tuple:
fill = colour[0]
second_colour = colour[2]
second_colour_begin = colour[1]
else:
fill = colour
box = (0,0,boxWidth,boxHeight)
draw.rectangle(box, fill=fill)
font_l = IT.registerFontInstance("Vera", int(8 * scale))
if self.is_CIF:
fill = IT.adjust_colour(fill, luminosity=1.9)
draw.text((2, boxHeight - 2*8), "CIF", font=font_l, fill=fill)
top = OV.GetParam('user.diagnostics.hkl.%s.top' %item)
if item == "flack_str":
x = boxWidth * second_colour_begin
box = (x,0,boxWidth,boxHeight)
fill = second_colour
draw.rectangle(box, fill=fill)
value_display = value_display.replace("0.",".")
if item == "Completeness":
od_value = OV.get_cif_item('_reflns_odcompleteness_completeness')
if od_value:
od_2theta = OV.get_cif_item('_reflns_odcompleteness_theta')
if od_2theta:
od_2theta = float(od_2theta) * 2
## Point Group value!
_ = int(boxWidth * (1-self.hkl_stats['Completeness_point']))
if _ == 0 and theoretical_val < 0.95:
_ = 1
if _ != 0:
x = boxWidth - _
box = (x,0,boxWidth,boxHeight)
fill = OV.GetParam('gui.red').hexadecimal
draw.rectangle(box, fill=fill)
laue = float(self.hkl_stats['Completeness_laue'])
_ = int(boxWidth * (1-laue))
if _ == 0 and theoretical_val < 0.99:
_ = 1
if _ != 0:
col = self.get_bg_colour(item, laue)
right = int(laue * boxWidth)
#box = (x,int(boxHeight/2),x+right,boxHeight)
box = (0,int(boxHeight/2),right,boxHeight)
fill = col
draw.rectangle(box, fill=fill)
top = OV.GetParam('user.diagnostics.hkl.%s.top' %item)
if item == "MeanIOverSigma":
display = IT.get_unicode_characters("I/sigma")
elif item == "Rint":
display = "Rint"
display = IT.get_unicode_characters(display)
if boxWidth < 80 * scale:
font_size = 14
font_size_s = 8
x = 2
y_s = 1 * scale #top gap for the small writing
y = 1 * scale
else:
font_size = 17
font_size_s = 10
x = 2
y = int(boxHeight/45 * scale)
y_s = 0 * scale
font = IT.registerFontInstance("Vera", int(font_size * scale))
font_s = IT.registerFontInstance("Vera", int(font_size_s * scale))
## ADD THE Key
if item == "MinD":
# fill = self.get_bg_colour(item, value_raw)
# fill = '#555555'
fill = '#ffffff'
else:
fill = '#ffffff'
draw.text((x, y_s), "%s" %display, font=font_s, fill=fill)
## ADD THE ACTUAL VALUE
y += 0
if value_display_extra:
dxs,dxy = IT.getTxtWidthAndHeight(value_display, font_name=font_name, font_size=int(font_size_s * scale))
dx,dy = IT.getTxtWidthAndHeight(value_display, font_name=font_name, font_size=int(font_size * scale))
x = boxWidth - dx - 7 #right inside margin
draw.text((x, y), "%s" %value_display, font=font, fill=fill)
if value_display_extra:
draw.text((0, y - 1 + dy/2), "%s" %value_display_extra, font=font_s, fill="#ffffff")
_ = im.copy()
_ = IT.add_whitespace(im, 'right', 4*scale, "#ffffff")
_ = IT.add_whitespace(im, 'left', 4*scale, "#ffffff")
OlexVFS.save_image_to_olex(_, "%s_large" %item, 0)
#if self.image_position != "last":
#im = IT.add_whitespace(im, 'right', 4, bgcolour)
im = IT.add_whitespace(im, side='bottom', weight=2*scale, colour=bgcolour)
self.im_cache[cache_entry] = im
im = IT.resize_image(im, ((targetWidth),(targetHeight+2)), name=cache_entry)
OlexVFS.save_image_to_olex(im, item, 0)
return txt
def get_bg_colour(self, item, val):
return gui.tools.get_diagnostics_colour(self.scope, item, val)
HOS_instance = HealthOfStructure()
OV.registerFunction(HOS_instance.make_HOS)
def title_replace(title):
title = title.replace("sigma", "σ")
title = title.replace("two_theta", "2Θ / °")
title = title.replace("d_spacing", "d-spacing / Å")
title = title.replace("Fobs", "Fobs")
title = title.replace("Fobs", "Fcalc")
title = title.replace(" vs ", " vs")
title = title.replace("_", "-")
return title