Commit a262f25c authored by jansen31's avatar jansen31
Browse files

partial merge from ot3d

parent bc40eb09
...@@ -6,3 +6,4 @@ build ...@@ -6,3 +6,4 @@ build
dist dist
.vscode/launch.json .vscode/launch.json
.vscode/settings.json .vscode/settings.json
tests/orb_tomog_regression_tests.py
\ No newline at end of file
...@@ -34,4 +34,4 @@ from .PHeBIE_ptychography_objective import * ...@@ -34,4 +34,4 @@ from .PHeBIE_ptychography_objective import *
from .PHeBIE_phase_objective import * from .PHeBIE_phase_objective import *
from .Wirtinger import * from .Wirtinger import *
from .Wirt_IterateMonitor import * from .Wirt_IterateMonitor import *
from .NSLS_sourceloc_objective import * from .NSLS_sourceloc_objective import *
\ No newline at end of file
...@@ -15,7 +15,7 @@ class Algorithm: ...@@ -15,7 +15,7 @@ class Algorithm:
The algorithm object is created when the Experiment object is initialized. The algorithm object is created when the Experiment object is initialized.
""" """
def __init__(self, experiment, iterateMonitor, accelerator = None): def __init__(self, experiment, iterateMonitor, accelerator=None):
# instantiate prox operators # instantiate prox operators
self.proxOperators = [] self.proxOperators = []
......
...@@ -39,7 +39,7 @@ class FeasibilityIterateMonitor(IterateMonitor): ...@@ -39,7 +39,7 @@ class FeasibilityIterateMonitor(IterateMonitor):
super(FeasibilityIterateMonitor, self).preprocess(alg) super(FeasibilityIterateMonitor, self).preprocess(alg)
nProx = len(self.proxOperators) nProx = len(self.proxOperators)
# Even if more detailed diagnostics are not run, the mathematical # Even if more detailed diagnostics are not run, the mathematical
# exit criteria will be on step-sizes, for which one needs to monitor the # exit criteria will be on step-sizes, for which one needs to monitor the
# norm of the difference between successive iterates of the blocks, in # norm of the difference between successive iterates of the blocks, in
...@@ -54,10 +54,10 @@ class FeasibilityIterateMonitor(IterateMonitor): ...@@ -54,10 +54,10 @@ class FeasibilityIterateMonitor(IterateMonitor):
# assumes that u0 is an array # assumes that u0 is an array
self.u_monitor[0] = self.u0 self.u_monitor[0] = self.u0
for j in range(1, nProx): for j in range(1, nProx):
self.u_monitor[j] = self.proxOperators[j].eval(self.u_monitor[j-1], j) self.u_monitor[j] = self.proxOperators[j].eval(self.u_monitor[j - 1], j)
else: # always creates a u_monitor, issue is whether to monitor the intermediate else: # always creates a u_monitor, issue is whether to monitor the intermediate
# steps for the gap, as the above prepares for in the case that # steps for the gap, as the above prepares for in the case that
# diagnostic ist true. # diagnostic is true.
self.u_monitor = self.u0 self.u_monitor = self.u0
# set up diagnostic arrays # set up diagnostic arrays
...@@ -105,22 +105,22 @@ class FeasibilityIterateMonitor(IterateMonitor): ...@@ -105,22 +105,22 @@ class FeasibilityIterateMonitor(IterateMonitor):
# reveals the RELEVANT convergence of the (shadow sequence of the) algorithm: # reveals the RELEVANT convergence of the (shadow sequence of the) algorithm:
if isCell(u): if isCell(u):
for j in range(len(u)): for j in range(len(u)):
self.u_monitor[0][j] = exp(-1j*angle(trace(matmul(prev_u_mon[0][j].T.conj(), u[j]))))*u[j] self.u_monitor[0][j] = exp(-1j * angle(trace(matmul(prev_u_mon[0][j].T.conj(), u[j])))) * u[j]
else: else:
# assumes that u is a ndarray # assumes that u is a ndarray
self.u_monitor[0] = exp(-1j*angle(trace(matmul(prev_u_mon[0].T.conj(), u))))*u self.u_monitor[0] = exp(-1j * angle(trace(matmul(prev_u_mon[0].T.conj(), u)))) * u
u1 = self.proxOperators[nProx-1].eval(self.u_monitor[0]) # Note: to compute u1 which prox_index should we use? u1 = self.proxOperators[nProx - 1].eval(self.u_monitor[0]) # Note: to compute u1 which prox_index should we use?
# Matlab takes whatever is defined in method_input, which corresponds # Matlab takes whatever is defined in method_input, which corresponds
# to the last prox evaluation if it was set (not always the case) # to the last prox evaluation if it was set (not always the case)
# for Douglas Rachford and DRlambda the iterates themselves do not # for Douglas Rachford and DRlambda the iterates themselves do not
# converge to the intersection, even if this is nonempty. The Shadows, however, # converge to the intersection, even if this is nonempty. The Shadows, however,
# do go to the intersection, if this is nonempty. # do go to the intersection, if this is nonempty.
if self.diagnostic: if self.diagnostic:
self.u_monitor[1] = self.proxOperators[0].eval(u1, 0) self.u_monitor[1] = self.proxOperators[0].eval(u1, 0)
for j in range(1, nProx-1): for j in range(1, nProx - 1):
self.u_monitor[j+1] = self.proxOperators[j].eval(self.u_monitor[j], j) self.u_monitor[j + 1] = self.proxOperators[j].eval(self.u_monitor[j], j)
# convert u1 to an array if necessary # convert u1 to an array if necessary
if isCell(u1): if isCell(u1):
_m, _n, p, q = size_matlab(u1[len(u1)-1]) _m, _n, p, q = size_matlab(u1[len(u1)-1])
...@@ -134,9 +134,9 @@ class FeasibilityIterateMonitor(IterateMonitor): ...@@ -134,9 +134,9 @@ class FeasibilityIterateMonitor(IterateMonitor):
if p == 1 and q == 1: if p == 1 and q == 1:
if isCell(self.u_monitor[0]): if isCell(self.u_monitor[0]):
for j in range(len(self.u_monitor[0])): for j in range(len(self.u_monitor[0])):
tmp_change = tmp_change + (norm(self.u_monitor[0][j] - prev_u_mon[0][j])/normM)**2 tmp_change = tmp_change + (norm(self.u_monitor[0][j] - prev_u_mon[0][j]) / normM) ** 2
else: else:
tmp_change = (norm(self.u_monitor[0] - prev_u_mon[0])/normM)**2 tmp_change = (norm(self.u_monitor[0] - prev_u_mon[0]) / normM) ** 2
if self.diagnostic: if self.diagnostic:
# compute shadow and gap # compute shadow and gap
tmp_shadow = tmp_change tmp_shadow = tmp_change
...@@ -146,11 +146,11 @@ class FeasibilityIterateMonitor(IterateMonitor): ...@@ -146,11 +146,11 @@ class FeasibilityIterateMonitor(IterateMonitor):
# (see Bauschke-Combettes-Luke, J. Approx. Theory, 2004) # (see Bauschke-Combettes-Luke, J. Approx. Theory, 2004)
if isCell(u1): if isCell(u1):
for jj in range(len(u1)): for jj in range(len(u1)):
tmp_shadow = tmp_shadow + (norm(self.u_monitor[1][jj] - prev_u_mon[1][jj])/normM)**2 tmp_shadow = tmp_shadow + (norm(self.u_monitor[1][jj] - prev_u_mon[1][jj]) / normM) ** 2
tmp_gap = tmp_gap + (norm(self.u_monitor[1][jj] - u1[jj])/normM)**2 tmp_gap = tmp_gap + (norm(self.u_monitor[1][jj] - u1[jj]) / normM) ** 2
else: else:
tmp_shadow = tmp_shadow + (norm(self.u_monitor[1] - prev_u_mon[1])/normM)**2 tmp_shadow = tmp_shadow + (norm(self.u_monitor[1] - prev_u_mon[1]) / normM) ** 2
tmp_gap = tmp_gap + (norm(self.u_monitor[1] - u1)/normM)**2 tmp_gap = tmp_gap + (norm(self.u_monitor[1] - u1) / normM) ** 2
for j in range(2, nProx): for j in range(2, nProx):
# For Douglas-Rachford,in general it is appropriate to monitor the # For Douglas-Rachford,in general it is appropriate to monitor the
# SHADOWS of the iterates, since in the convex case these converge # SHADOWS of the iterates, since in the convex case these converge
...@@ -158,21 +158,21 @@ class FeasibilityIterateMonitor(IterateMonitor): ...@@ -158,21 +158,21 @@ class FeasibilityIterateMonitor(IterateMonitor):
# (see Bauschke-Combettes-Luke, J. Approx. Theory, 2004) # (see Bauschke-Combettes-Luke, J. Approx. Theory, 2004)
if isCell(self.u_monitor[j]): if isCell(self.u_monitor[j]):
for jj in range(len(self.u_monitor[j])): for jj in range(len(self.u_monitor[j])):
tmp_shadow = tmp_shadow + (norm(self.u_monitor[j][jj] - prev_u_mon[j][jj])/normM)**2 tmp_shadow = tmp_shadow + (norm(self.u_monitor[j][jj] - prev_u_mon[j][jj]) / normM) ** 2
tmp_gap = tmp_gap + (norm(self.u_monitor[j][jj] - self.u_monitor[j-1][jj])/normM)**2 tmp_gap = tmp_gap + (norm(self.u_monitor[j][jj] - self.u_monitor[j - 1][jj]) / normM) ** 2
else: else:
tmp_shadow = tmp_shadow + (norm(self.u_monitor[j] - prev_u_mon[j])/normM)**2 tmp_shadow = tmp_shadow + (norm(self.u_monitor[j] - prev_u_mon[j])/normM)**2
tmp_gap = tmp_gap + (norm(self.u_monitor[j] - self.u_monitor[j-1])/normM)**2 tmp_gap = tmp_gap + (norm(self.u_monitor[j] - self.u_monitor[j-1])/normM)**2
# compute relative error # compute relative error
if self.truth is not None: if self.truth is not None:
# convert u1 to an array if necessary # convert u1 to an array if necessary
# TODO need to simplify this... # TODO need to simplify this...
if isCell(u1): if isCell(u1):
z = u1[len(u1)-1] z = u1[len(u1) - 1]
if self.truth_dim[0] == 1: if self.truth_dim[0] == 1:
z = reshape(z, (1,len(z))) # we want a true matrix not just a vector z = reshape(z, (1, len(z))) # we want a true matrix not just a vector
elif self.truth_dim[1] == 1: elif self.truth_dim[1] == 1:
z = reshape(z, (len(z),1)) # we want a true matrix not just a vector z = reshape(z, (len(z), 1)) # we want a true matrix not just a vector
else: else:
if u1.ndim == 1 or self.formulation == 'cyclic': if u1.ndim == 1 or self.formulation == 'cyclic':
z = u1 z = u1
...@@ -183,14 +183,14 @@ class FeasibilityIterateMonitor(IterateMonitor): ...@@ -183,14 +183,14 @@ class FeasibilityIterateMonitor(IterateMonitor):
z = reshape(z, (len(z),1)) # we want a true matrix not just a vector z = reshape(z, (len(z),1)) # we want a true matrix not just a vector
else: # product space else: # product space
if self.truth_dim[0] == 1: if self.truth_dim[0] == 1:
z = u1[0,:] z = u1[0, :]
z = reshape(z, (1,len(z))) # we want a true matrix not just a vector z = reshape(z, (1, len(z))) # we want a true matrix not just a vector
elif self.truth_dim[1] == 1: elif self.truth_dim[1] == 1:
z = u1[:,0] z = u1[:, 0]
z = reshape(z, (len(z),1)) # we want a true matrix not just a vector z = reshape(z, (len(z), 1)) # we want a true matrix not just a vector
else: else:
if u1.ndim == 3: if u1.ndim == 3:
z = u1[:,:,0] z = u1[:, :, 0]
else: else:
z = u1 z = u1
""" """
...@@ -224,35 +224,41 @@ class FeasibilityIterateMonitor(IterateMonitor): ...@@ -224,35 +224,41 @@ class FeasibilityIterateMonitor(IterateMonitor):
if isCell(self.u_monitor[0]): if isCell(self.u_monitor[0]):
for j in range(len(self.u_monitor[0])): for j in range(len(self.u_monitor[0])):
for jj in range(p): for jj in range(p):
tmp_change = tmp_change + (norm(self.u_monitor[0][j][:,:,jj] - prev_u_mon[0][j][:,:,jj])/normM)**2 tmp_change = tmp_change + (
norm(self.u_monitor[0][j][:, :, jj] - prev_u_mon[0][j][:, :, jj]) / normM) ** 2
if self.diagnostic: if self.diagnostic:
tmp_shadow = tmp_change tmp_shadow = tmp_change
for k in range(1, nProx): for k in range(1, nProx):
# compute (||P_SP_Mx-P_Mx||/normM)^2: # compute (||P_SP_Mx-P_Mx||/normM)^2:
for j in range(len(self.u_monitor[0])): for j in range(len(self.u_monitor[0])):
for jj in range(p): for jj in range(p):
tmp_gap = tmp_gap + (norm(self.u_monitor[k][j][:,:,jj] - self.u_monitor[k-1][:,:,jj])/normM)**2 tmp_gap = tmp_gap + (norm(
tmp_shadow = tmp_shadow + (norm(self.u_monitor[k][j][:,:,jj] - prev_u_mon[k][j][:,:,jj])/normM)**2 self.u_monitor[k][j][:, :, jj] - self.u_monitor[k - 1][:, :, jj]) / normM) ** 2
tmp_shadow = tmp_shadow + (norm(
self.u_monitor[k][j][:, :, jj] - prev_u_mon[k][j][:, :, jj]) / normM) ** 2
else: else:
for j in range(p): for j in range(p):
tmp_change = tmp_change + (norm(self.u_monitor[0][:,:,j] - prev_u_mon[0][:,:,j])/normM)**2 tmp_change = tmp_change + (norm(self.u_monitor[0][:, :, j] - prev_u_mon[0][:, :, j]) / normM) ** 2
if self.diagnostic: if self.diagnostic:
tmp_shadow = tmp_change tmp_shadow = tmp_change
for k in range(1, nProx): for k in range(1, nProx):
# compute (||P_SP_Mx-P_Mx||/normM)^2: # compute (||P_SP_Mx-P_Mx||/normM)^2:
tmp_gap = tmp_gap + (norm(self.u_monitor[k][:,:,j] - self.u_monitor[k-1][:,:,j])/normM)**2 tmp_gap = tmp_gap + (
tmp_shadow = tmp_shadow + (norm(self.u_monitor[k][:,:,j] - prev_u_mon[k][:,:,j])/normM)**2 norm(self.u_monitor[k][:, :, j] - self.u_monitor[k - 1][:, :, j]) / normM) ** 2
tmp_shadow = tmp_shadow + (
norm(self.u_monitor[k][:, :, j] - prev_u_mon[k][:, :, j]) / normM) ** 2
if self.diagnostic and self.truth is not None: if self.diagnostic and self.truth is not None:
z = u1[:,:,0] z = u1[:, :, 0]
rel_error = norm(self.truth - exp(-1j*angle(trace(matmul(self.truth.T.conj(), z)))) * z) / self.norm_truth rel_error = norm(
else: # cells of 4D arrays??? self.truth - exp(-1j * angle(trace(matmul(self.truth.T.conj(), z)))) * z) / self.norm_truth
else: # cells of 4D arrays???
pass pass
self.changes[alg.iter] = sqrt(tmp_change) self.changes[alg.iter] = sqrt(tmp_change)
if self.diagnostic: if self.diagnostic:
self.gaps[alg.iter] = sqrt(tmp_gap) self.gaps[alg.iter] = sqrt(tmp_gap)
self.shadow_changes[alg.iter] = sqrt(tmp_shadow) # this is the Euclidean norm of the gap to self.shadow_changes[alg.iter] = sqrt(tmp_shadow) # this is the Euclidean norm of the gap to
# the unregularized set. To monitor the Euclidean norm of the gap to the # the unregularized set. To monitor the Euclidean norm of the gap to the
# regularized set is expensive to calculate, so we use this surrogate. # regularized set is expensive to calculate, so we use this surrogate.
# Since the stopping criteria is on the change in the iterates, this # Since the stopping criteria is on the change in the iterates, this
...@@ -289,8 +295,8 @@ class FeasibilityIterateMonitor(IterateMonitor): ...@@ -289,8 +295,8 @@ class FeasibilityIterateMonitor(IterateMonitor):
output = super(FeasibilityIterateMonitor, self).postprocess(alg, output) output = super(FeasibilityIterateMonitor, self).postprocess(alg, output)
if self.diagnostic: if self.diagnostic:
stats = output['stats'] stats = output['stats']
stats['gaps'] = self.gaps[1:alg.iter+1] stats['gaps'] = self.gaps[1:alg.iter + 1]
stats['shadow_changes'] = self.shadow_changes[1:alg.iter+1] stats['shadow_changes'] = self.shadow_changes[1:alg.iter + 1]
if self.truth is not None: if self.truth is not None:
stats['rel_errors'] = self.rel_errors[1:alg.iter+1] stats['rel_errors'] = self.rel_errors[1:alg.iter + 1]
return output return output
\ No newline at end of file
from numpy import zeros, sqrt
from numpy.linalg import norm
from proxtoolbox import algorithms from proxtoolbox import algorithms
from proxtoolbox.utils.cell import Cell, isCell from proxtoolbox.utils.cell import isCell
from proxtoolbox.utils.size import size_matlab from proxtoolbox.utils.size import size_matlab
from numpy import zeros, angle, trace, exp, sqrt, sum, mod
from numpy.linalg import norm
class IterateMonitor: class IterateMonitor:
...@@ -14,8 +15,8 @@ class IterateMonitor: ...@@ -14,8 +15,8 @@ class IterateMonitor:
def __init__(self, experiment): def __init__(self, experiment):
self.u0 = experiment.u0 self.u0 = experiment.u0
self.u_monitor = self.u0 # the part of the sequence that is being monitored assert self.u0 is not None, 'No valid initial guess given'
# put u0 as default self.u_monitor = self.u0 # the part of the sequence that is being monitored put u0 as default
self.isCell = isCell(self.u0) self.isCell = isCell(self.u0)
self.norm_data = experiment.norm_data self.norm_data = experiment.norm_data
self.truth = experiment.truth self.truth = experiment.truth
...@@ -122,10 +123,10 @@ class IterateMonitor: ...@@ -122,10 +123,10 @@ class IterateMonitor:
u_m = self.u_monitor u_m = self.u_monitor
# Python code for [m,n,p] = size(u_m) # Python code for [m,n,p] = size(u_m)
if isCell(u_m): if isCell(u_m):
# in matlab this corresponded to a cell # in matlab this corresponded to a cell
# here we assume that such a cell is m by n where m = 1 # here we assume that such a cell is m by n where m = 1
# so far this seems to be always the case # so far this seems to be always the case
# the following tests attemp to match the ndarray case below # the following tests attempt to match the ndarray case below
m = 1 m = 1
n = len(u_m) n = len(u_m)
if n == self.n_product_Prox: if n == self.n_product_Prox:
...@@ -161,11 +162,6 @@ class IterateMonitor: ...@@ -161,11 +162,6 @@ class IterateMonitor:
output['stats']['changes'] = self.changes[1:alg.iter + 1] output['stats']['changes'] = self.changes[1:alg.iter + 1]
return output return output
@staticmethod
def phase_offset_compensated_norm(arr1, arr2, norm_factor=1, norm_type='fro'):
phase_offset = angle(sum(arr1 * arr2.conj()))
return norm(arr1 - arr2 * exp(1j * phase_offset), norm_type) / norm_factor
def getIterateSize(self, u): def getIterateSize(self, u):
""" """
Given an iterate, determine p and q parameters Given an iterate, determine p and q parameters
...@@ -207,7 +203,7 @@ class IterateMonitor: ...@@ -207,7 +203,7 @@ class IterateMonitor:
def calculateObjective(self, alg): def calculateObjective(self, alg):
""" """
Calculate objective value. The dafault implementation Calculate objective value. The default implementation
uses the optimality monitor if it exists uses the optimality monitor if it exists
Parameters Parameters
......
...@@ -101,7 +101,7 @@ class Experiment(metaclass=ExperimentMetaClass): ...@@ -101,7 +101,7 @@ class Experiment(metaclass=ExperimentMetaClass):
# (including what would have been generated with verbose mode) # (including what would have been generated with verbose mode)
graphics=0, graphics=0,
anim=False, anim=False,
anim_step = 2, # Tell how frequently the animation is updated, i.e., every `anim_step` step(s) anim_step=2, # Tell how frequently the animation is updated, i.e., every `anim_step` step(s)
anim_colorbar=False, # if True the animated image will include a colorbar (updated at each iteration) anim_colorbar=False, # if True the animated image will include a colorbar (updated at each iteration)
graphics_display=None, graphics_display=None,
figure_width=9, # figure width in inches figure_width=9, # figure width in inches
...@@ -125,6 +125,8 @@ class Experiment(metaclass=ExperimentMetaClass): ...@@ -125,6 +125,8 @@ class Experiment(metaclass=ExperimentMetaClass):
self.object = object self.object = object
self.formulation = formulation self.formulation = formulation
self.output = {}
# Those data members will define the final dimensions # Those data members will define the final dimensions
# of the dataset to be used in this experiment. # of the dataset to be used in this experiment.
# At this stage we set them to the desired values # At this stage we set them to the desired values
...@@ -135,7 +137,7 @@ class Experiment(metaclass=ExperimentMetaClass): ...@@ -135,7 +137,7 @@ class Experiment(metaclass=ExperimentMetaClass):
self.Ny = Ny self.Ny = Ny
if Nz is not None: if Nz is not None:
self.Nz = Nz self.Nz = Nz
else: else: # TODO: Bad for experiments with 3D data, where Nz may be None to simply follow the data
self.Nz = 1 self.Nz = 1
# we store here the original values specified by the user # we store here the original values specified by the user
self.desired_product_space_dimension = product_space_dimension self.desired_product_space_dimension = product_space_dimension
...@@ -176,11 +178,11 @@ class Experiment(metaclass=ExperimentMetaClass): ...@@ -176,11 +178,11 @@ class Experiment(metaclass=ExperimentMetaClass):
self.accelerator_name = accelerator_name self.accelerator_name = accelerator_name
self.rotate = rotate # tells the iterate monitor to rotate the iterates self.rotate = rotate # tells the iterate monitor to rotate the iterates
# to a fixed global reference # to a fixed global reference
self.rnd_seed = rnd_seed self.rnd_seed = rnd_seed
# additional attributes # additional attributes
self.data = None self.data = None
self.data_sq = None self.data_sq = None
self.norm_data = None self.norm_data = None
...@@ -191,9 +193,9 @@ class Experiment(metaclass=ExperimentMetaClass): ...@@ -191,9 +193,9 @@ class Experiment(metaclass=ExperimentMetaClass):
self.truth = None self.truth = None
self.truth_dim = None self.truth_dim = None
self.norm_truth = None self.norm_truth = None
self.optimality_monitor = None self.optimality_monitor = None
self.proj_iter = None # not sure what it does self.proj_iter = None # not sure what it does
self.proxOperators = [] self.proxOperators = []
...@@ -201,8 +203,8 @@ class Experiment(metaclass=ExperimentMetaClass): ...@@ -201,8 +203,8 @@ class Experiment(metaclass=ExperimentMetaClass):
self.productProxOperators = [] self.productProxOperators = []
self.n_product_Prox = None # size of the product space self.n_product_Prox = None # size of the product space
# TODO: which default: None, 0 or 1 ? # TODO: which default: None, 0 or 1 ?
# see how it is used # see how it is used
self.propagator = None self.propagator = None
self.inverse_propagator = None self.inverse_propagator = None
...@@ -213,7 +215,6 @@ class Experiment(metaclass=ExperimentMetaClass): ...@@ -213,7 +215,6 @@ class Experiment(metaclass=ExperimentMetaClass):
# for animation: # for animation:
self.anim_figure = None self.anim_figure = None
self.debug = debug self.debug = debug
def initialize(self): def initialize(self):
...@@ -231,8 +232,8 @@ class Experiment(metaclass=ExperimentMetaClass): ...@@ -231,8 +232,8 @@ class Experiment(metaclass=ExperimentMetaClass):
# load data # load data
self.loadData() self.loadData()
self.reshapeData(self.Nx, self.Ny, self.Nz) # TODO need to revisit this self.reshapeData(self.Nx, self.Ny, self.Nz) # TODO need to revisit this
# - arguments not needed in particular # - arguments not needed in particular
if self.TOL2 is None: if self.TOL2 is None:
self.TOL2 = 1e-20 self.TOL2 = 1e-20
...@@ -273,7 +274,7 @@ class Experiment(metaclass=ExperimentMetaClass): ...@@ -273,7 +274,7 @@ class Experiment(metaclass=ExperimentMetaClass):
t = time.time() t = time.time()
self.output = self.runAlgorithm(self.u0) self.output = self.runAlgorithm(self.u0) # TODO: append to dict? (in overwrite mode)
self.output['stats']['time'] = time.time() - t self.output['stats']['time'] = time.time() - t
...@@ -282,7 +283,7 @@ class Experiment(metaclass=ExperimentMetaClass): ...@@ -282,7 +283,7 @@ class Experiment(metaclass=ExperimentMetaClass):
self.output['stats']['time'], "seconds.") self.output['stats']['time'], "seconds.")
self.postprocess() self.postprocess()
if self.save_output: if self.save_output:
self.saveOutput() self.saveOutput()
...@@ -309,8 +310,8 @@ class Experiment(metaclass=ExperimentMetaClass): ...@@ -309,8 +310,8 @@ class Experiment(metaclass=ExperimentMetaClass):
dictionary containing the output of the algorithm. In dictionary containing the output of the algorithm. In
particular, it contains the last iterate and various particular, it contains the last iterate and various
statistics. statistics.
""" """
return self.algorithm.run(u) return self.algorithm.run(u)
def loadData(self): def loadData(self):
""" """
...@@ -631,15 +632,15 @@ class Experiment(metaclass=ExperimentMetaClass): ...@@ -631,15 +632,15 @@ class Experiment(metaclass=ExperimentMetaClass):
if self.anim_figure == None: if self.anim_figure == None:
# create figure # create figure
plt.ion() plt.ion()
self.anim_figure = plt.figure(figsize = (self.figure_width, self.figure_height), self.anim_figure = plt.figure(figsize=(self.figure_width, self.figure_height),
dpi = self.figure_dpi) dpi=self.figure_dpi)
self.anim_figure.canvas.mpl_connect('close_event', self.onAnimationWindowClosing) self.anim_figure.canvas.mpl_connect('close_event', self.onAnimationWindowClosing)
self.anim_ax = self.anim_figure.add_subplot(111) self.anim_ax = self.anim_figure.add_subplot(111)
self.anim_bar = None self.anim_bar = None
self.anim_im = self.anim_ax.imshow(image) self.anim_im = self.anim_ax.imshow(image)
self.anim_ax.set_title(title) self.anim_ax.set_title(title)
self.anim_figure.canvas.draw() self.anim_figure.canvas.draw()
#plt.show(block=False) # plt.show(block=False)
else: else:
self.anim_im.set_array(image) self.anim_im.set_array(image)
min_val = np.min(image) min_val = np.min(image)
......
...@@ -11,7 +11,7 @@ class DegenerateOrbital(PlanarMolecule): ...@@ -11,7 +11,7 @@ class DegenerateOrbital(PlanarMolecule):
def getDefaultParameters(): def getDefaultParameters():
defaultParams = { defaultParams = {
'experiment_name': '2D ARPES', 'experiment_name': '2D ARPES',
'data_filename': None,