aboutsummaryrefslogtreecommitdiff
path: root/scripts/plot-pr
blob: f1d8db942b5aa9f3965b9f8eecfeaebfb1d3aad8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# Plot post-refinement results
#
# Copyright © 2017-2020 Deutsches Elektronen-Synchrotron DESY,
#                       a research centre of the Helmholtz Association.
#
# Author:
#    2017-2018 Thomas White <taw@physics.org>
#

import sys
import matplotlib
import numpy as np
from matplotlib import pyplot as plt
from operator import truediv, itemgetter
from matplotlib.widgets import RadioButtons,SpanSelector,Button

crystal=0
resmin=0
resmax=100e9
inum="0"
first=True

def update_graph():

    global inum, resmin, resmax, first

    # Update pobs/pcalc scatter plot
    xlim = pgraphE.get_xlim()
    ylim = pgraphE.get_ylim()
    pgraphE.cla()
    pgraphE.scatter([x[0] for x in pgraph if x[2]==inum if x[3]<resmax if x[3]>resmin],
                 [x[1] for x in pgraph if x[2]==inum if x[3]<resmax if x[3]>resmin], marker="+")
    pgraphE.grid(b=True, which='major', color='k', linestyle='--')
    if not first:
        pgraphE.set_xlim(xlim)
        pgraphE.set_ylim(ylim)
    pgraphE.set_xlabel("pcalc")
    pgraphE.set_ylabel("pobs")
    pgraphE.set_title("Observed and calculated partialities")

    # Update spectrum plot
    pobsE.set_data([x[0] for x in specgraph if x[3]==inum if x[4]<resmax if x[4]>resmin],
                   [x[2] for x in specgraph if x[3]==inum if x[4]<resmax if x[4]>resmin])
    pcalcE.set_data([x[0] for x in specgraph if x[3]==inum if x[4]<resmax if x[4]>resmin],
                    [x[1] for x in specgraph if x[3]==inum if x[4]<resmax if x[4]>resmin])
    specgraphE.set_title("Spectrum plot for crystal %i" % crystal)

    first = False
    plt.draw()


def iteration_click(label):
    global inum
    inum = label.split(" ")[1].split("\n")[0]
    update_graph()


def resolutionchange(rmin,rmax):
    global resmin,resmax
    resmin = rmin
    resmax = rmax
    update_graph()


def read_spectrum(filename):

    specgraph = []

    try:
        fh = open(filename, 'r')
    except IOError:
        print("Failed to read "+filename)
        raise IOError

    fline = fh.readline()
    fline = fh.readline()  # Ignore header (two lines)

    while True:
        fline = fh.readline()
        if not fline:
            break
        kval = float(fline.split()[0])
        res = float(fline.split()[1])
        pcalc = float(fline.split()[2])
        pobs = float(fline.split()[3])
        inum = fline.split()[4]
        specgraph.append([kval,pcalc,pobs,inum,res])

    return sorted(specgraph, key=itemgetter(0))


def next_click(w):
    global specgraph, crystal
    crystal += 20
    specgraph = read_spectrum("%s/specgraph-crystal%i.dat" % (folder,crystal))
    update_graph()


def prev_click(w):
    global specgraph, crystal
    crystal -= 20
    specgraph = read_spectrum("%s/specgraph-crystal%i.dat" % (folder,crystal))
    update_graph()


def set_sensible_axes(w):
    pgraphE.set_xlim([-0.1,1.1])
    pgraphE.set_ylim([-0.2,2.0])
    specgraphE.set_ylim([-5.0,5.0])
    plt.draw()


# Read the pgraph file
pgraph = []

if len(sys.argv) == 2:
    folder = sys.argv[1]
else:
    folder = "pr-logs"

print("Using folder '%s'" % folder)

try:
    fh = open("%s/pgraph.dat" % folder, 'r')
except IOError:
    print("Failed to read "+filename)
    raise IOError

fline = fh.readline()  # Ignore header

while True:
    fline = fh.readline()
    if not fline:
        break
    res = float(fline.split()[4])
    Ipart = float(fline.split()[5])
    pc = float(fline.split()[6])
    po = float(fline.split()[7])
    inum = fline.split()[8]
    pgraph.append([pc,po,inum,res,Ipart])


# Read the spectrum file
specgraph = read_spectrum("%s/specgraph-crystal%i.dat" % (folder,crystal))

fig = plt.figure(figsize=(15,6))
fig.subplots_adjust(left=0.05, right=0.65)

# pobs/pcalc
pgraphE = fig.add_subplot(121)

# Spectrum
specgraphE = fig.add_subplot(122)
pobsE = specgraphE.plot([0,1],[0,1],label="pobs")[0]
pcalcE = specgraphE.plot([0,1],[0,1],label="pcalc")[0]
specgraphE.set_xlabel("khalf / m^-1")
specgraphE.set_ylabel("Partiality")
specgraphE.grid(b=True, which='major', color='k', linestyle='--')
specgraphE.legend()

# Iteration selector
ax = plt.axes([0.75, 0.50, 0.2, 0.40], facecolor="lightgoldenrodyellow")
iterations = sorted(set(["Iteration "+str(x[2]) for x in pgraph]))
if iterations[0] != "Iteration 0":
    print("Whoops, couldn't find iteration 0!")
    sys.exit(1)
iterations[0] = "Iteration 0\n(initial scaling only)"
if iterations[len(iterations)-1] != "Iteration F":
    print("Whoops, couldn't find final iteration!")
else:
    iterations[len(iterations)-1] = "Iteration F\n(after final merge)"
iteration = RadioButtons(ax, iterations)
iteration.on_clicked(iteration_click)
iteration.set_active(len(iterations)-1)

# Resolution selector
ax = plt.axes([0.75, 0.25, 0.2, 0.15], facecolor="lightgoldenrodyellow")
ax.hist([x[3] for x in pgraph],weights=[x[4] for x in pgraph],bins=100)
ax.set_xlabel("Resolution / m^-1")
ax.set_ylabel("Frequency")
ax.set_title("Resolution selector")
resolution = SpanSelector(ax, resolutionchange, 'horizontal', span_stays=True, useblit=True)

# Crystal switcher
ax = plt.axes([0.75, 0.10, 0.09, 0.05])
crystal_prev = Button(ax, "Previous crystal")
crystal_prev.on_clicked(prev_click)
ax = plt.axes([0.86, 0.10, 0.09, 0.05])
crystal_next = Button(ax, "Next crystal")
crystal_next.on_clicked(next_click)

# Set sensible axes
ax = plt.axes([0.75, 0.01, 0.09, 0.05])
sensible_axes = Button(ax, "Set sensible axes")
sensible_axes.on_clicked(set_sensible_axes)

specgraphE.relim()
specgraphE.autoscale_view(True,True,True)

plt.show()