Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
N
NIFTy
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
13
Issues
13
List
Boards
Labels
Service Desk
Milestones
Merge Requests
8
Merge Requests
8
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Incidents
Environments
Packages & Registries
Packages & Registries
Container Registry
Analytics
Analytics
CI / CD
Repository
Value Stream
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
ift
NIFTy
Commits
7107323b
Commit
7107323b
authored
Sep 03, 2017
by
Martin Reinecke
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
updates
parent
7fc8256f
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
99 additions
and
148 deletions
+99
-148
demos/critical_filtering.py
demos/critical_filtering.py
+37
-56
demos/log_normal_wiener_filter.py
demos/log_normal_wiener_filter.py
+41
-42
nifty2go/field.py
nifty2go/field.py
+10
-24
nifty2go/operators/linear_operator/linear_operator.py
nifty2go/operators/linear_operator/linear_operator.py
+2
-9
nifty2go/operators/response_operator/response_operator.py
nifty2go/operators/response_operator/response_operator.py
+9
-17
No files found.
demos/critical_filtering.py
View file @
7107323b
import
numpy
as
np
from
nifty
import
(
VL_BFGS
,
DiagonalOperator
,
FFTOperator
,
Field
,
LinearOperator
,
PowerSpace
,
RelaxedNewton
,
RGSpace
,
SteepestDescent
,
create_power_operator
,
exp
,
log
,
sqrt
)
from
nifty.library.critical_filter
import
CriticalPowerEnergy
from
nifty.library.wiener_filter
import
WienerFilterEnergy
import
nifty2go
as
ift
import
plotly.graph_objs
as
go
import
plotly.offline
as
pl
from
mpi4py
import
MPI
comm
=
MPI
.
COMM_WORLD
rank
=
comm
.
rank
np
.
random
.
seed
(
42
)
def
plot_parameters
(
m
,
t
,
p
,
p_d
):
x
=
log
(
t
.
domain
[
0
].
kindex
)
x
=
ift
.
log
(
t
.
domain
[
0
].
kindex
)
m
=
fft
.
adjoint_times
(
m
)
m
=
m
.
val
.
get_full_data
().
real
t
=
t
.
val
.
get_full_data
().
real
p
=
p
.
val
.
get_full_data
().
real
p_d
=
p_d
.
val
.
get_full_data
().
real
m
=
m
.
val
.
real
t
=
t
.
val
.
real
p
=
p
.
val
.
real
p_d
=
p_d
.
val
.
real
pl
.
plot
([
go
.
Heatmap
(
z
=
m
)],
filename
=
'map.html'
,
auto_open
=
False
)
pl
.
plot
([
go
.
Scatter
(
x
=
x
,
y
=
t
),
go
.
Scatter
(
x
=
x
,
y
=
p
),
go
.
Scatter
(
x
=
x
,
y
=
p_d
)],
filename
=
"t.html"
,
auto_open
=
False
)
class
AdjointFFTResponse
(
LinearOperator
):
class
AdjointFFTResponse
(
ift
.
LinearOperator
):
def
__init__
(
self
,
FFT
,
R
,
default_spaces
=
None
):
super
(
AdjointFFTResponse
,
self
).
__init__
(
default_spaces
)
self
.
_domain
=
FFT
.
target
...
...
@@ -56,34 +47,28 @@ class AdjointFFTResponse(LinearOperator):
if
__name__
==
"__main__"
:
distribution_strategy
=
'not'
# Set up position space
s_space
=
RGSpace
([
128
,
128
])
# s_space = HPSpace(32)
s_space
=
ift
.
RGSpace
([
128
,
128
])
# s_space =
ift.
HPSpace(32)
# Define harmonic transformation and associated harmonic space
fft
=
FFTOperator
(
s_space
)
fft
=
ift
.
FFTOperator
(
s_space
)
h_space
=
fft
.
target
[
0
]
# Set up power space
p_space
=
PowerSpace
(
h_space
,
logarithmic
=
True
,
distribution_strategy
=
distribution_strategy
)
p_space
=
ift
.
PowerSpace
(
h_space
)
# Choose the prior correlation structure and defining correlation operator
p_spec
=
(
lambda
k
:
(.
5
/
(
k
+
1
)
**
3
))
S
=
create_power_operator
(
h_space
,
power_spectrum
=
p_spec
,
distribution_strategy
=
distribution_strategy
)
S
=
ift
.
create_power_operator
(
h_space
,
power_spectrum
=
p_spec
)
# Draw a sample sh from the prior distribution in harmonic space
sp
=
Field
(
p_space
,
val
=
p_spec
,
distribution_strategy
=
distribution_strategy
)
sp
=
ift
.
Field
(
p_space
,
val
=
p_spec
(
p_space
.
kindex
))
sh
=
sp
.
power_synthesize
(
real_signal
=
True
)
# Choose the measurement instrument
# Instrument = SmoothingOperator(s_space, sigma=0.01)
Instrument
=
DiagonalOperator
(
s_space
,
diagonal
=
1.
)
Instrument
=
ift
.
DiagonalOperator
(
s_space
,
diagonal
=
1.
)
# Instrument._diagonal.val[200:400, 200:400] = 0
# Instrument._diagonal.val[64:512-64, 64:512-64] = 0
...
...
@@ -91,10 +76,10 @@ if __name__ == "__main__":
R
=
AdjointFFTResponse
(
fft
,
Instrument
)
noise
=
1.
N
=
DiagonalOperator
(
s_space
,
diagonal
=
noise
,
bare
=
True
)
n
=
Field
.
from_random
(
domain
=
s_space
,
N
=
ift
.
DiagonalOperator
(
s_space
,
diagonal
=
noise
,
bare
=
True
)
n
=
ift
.
Field
.
from_random
(
domain
=
s_space
,
random_type
=
'normal'
,
std
=
sqrt
(
noise
),
std
=
ift
.
sqrt
(
noise
),
mean
=
0
)
# Create mock data
...
...
@@ -102,47 +87,43 @@ if __name__ == "__main__":
# The information source
j
=
R
.
adjoint_times
(
N
.
inverse_times
(
d
))
realized_power
=
log
(
sh
.
power_analyze
(
binbounds
=
p_space
.
binbounds
))
data_power
=
log
(
fft
(
d
).
power_analyze
(
binbounds
=
p_space
.
binbounds
))
d_data
=
d
.
val
.
get_full_data
().
real
if
rank
==
0
:
pl
.
plot
([
go
.
Heatmap
(
z
=
d_data
)],
filename
=
'data.html'
,
auto_open
=
False
)
realized_power
=
ift
.
log
(
sh
.
power_analyze
(
binbounds
=
p_space
.
binbounds
))
data_power
=
ift
.
log
(
fft
(
d
).
power_analyze
(
binbounds
=
p_space
.
binbounds
))
d_data
=
d
.
val
.
real
pl
.
plot
([
go
.
Heatmap
(
z
=
d_data
)],
filename
=
'data.html'
,
auto_open
=
False
)
# Minimization strategy
def
convergence_measure
(
a_energy
,
iteration
):
# returns current energy
x
=
a_energy
.
value
print
(
x
,
iteration
)
minimizer1
=
RelaxedNewton
(
convergence_tolerance
=
1e-4
,
convergence_level
=
1
,
iteration_limit
=
5
,
callback
=
convergence_measure
)
minimizer2
=
VL_BFGS
(
convergence_tolerance
=
1e-10
,
convergence_level
=
1
,
iteration_limit
=
30
,
callback
=
convergence_measure
,
max_history_length
=
20
)
minimizer3
=
SteepestDescent
(
convergence_tolerance
=
1e-4
,
iteration_limit
=
100
,
callback
=
convergence_measure
)
IC1
=
ift
.
DefaultIterationController
(
verbose
=
True
,
iteration_limit
=
5
)
minimizer1
=
ift
.
RelaxedNewton
(
IC1
)
IC2
=
ift
.
DefaultIterationController
(
verbose
=
True
,
iteration_limit
=
30
)
minimizer2
=
ift
.
VL_BFGS
(
IC2
,
max_history_length
=
20
)
IC3
=
ift
.
DefaultIterationController
(
verbose
=
True
,
iteration_limit
=
100
)
minimizer3
=
ift
.
SteepestDescent
(
IC3
)
# Set starting position
flat_power
=
Field
(
p_space
,
val
=
1e-8
)
flat_power
=
ift
.
Field
(
p_space
,
val
=
1e-8
)
m0
=
flat_power
.
power_synthesize
(
real_signal
=
True
)
t0
=
Field
(
p_space
,
val
=
log
(
1.
/
(
1
+
p_space
.
kindex
)
**
2
))
def
ps0
(
k
):
return
(
1.
/
(
1.
+
k
)
**
2
)
t0
=
ift
.
Field
(
p_space
,
val
=
ift
.
log
(
1.
/
(
1
+
p_space
.
kindex
)
**
2
))
for
i
in
range
(
500
):
S0
=
create_power_operator
(
h_space
,
power_spectrum
=
exp
(
t0
),
distribution_strategy
=
distribution_strategy
)
S0
=
ift
.
create_power_operator
(
h_space
,
power_spectrum
=
ps0
)
# Initialize non-linear Wiener Filter energy
map_energy
=
WienerFilterEnergy
(
position
=
m0
,
d
=
d
,
R
=
R
,
N
=
N
,
S
=
S0
)
ICI
=
ift
.
DefaultIterationController
(
verbose
=
True
,
iteration_limit
=
60
)
inverter
=
ift
.
ConjugateGradient
(
controller
=
ICI
,
preconditioner
=
S0
.
times
)
map_energy
=
ift
.
library
.
WienerFilterEnergy
(
position
=
m0
,
d
=
d
,
R
=
R
,
N
=
N
,
S
=
S0
,
inverter
=
inverter
)
# Solve the Wiener Filter analytically
D0
=
map_energy
.
curvature
m0
=
D0
.
inverse_times
(
j
)
# Initialize power energy with updated parameters
power_energy
=
CriticalPowerEnergy
(
position
=
t0
,
m
=
m0
,
D
=
D0
,
power_energy
=
ift
.
library
.
CriticalPowerEnergy
(
position
=
t0
,
m
=
m0
,
D
=
D0
,
smoothness_prior
=
10.
,
samples
=
3
)
(
power_energy
,
convergence
)
=
minimizer2
(
power_energy
)
...
...
@@ -153,4 +134,4 @@ if __name__ == "__main__":
# Plot current estimate
print
(
i
)
if
i
%
5
==
0
:
plot_parameters
(
m0
,
t0
,
log
(
sp
),
data_power
)
plot_parameters
(
m0
,
t0
,
ift
.
log
(
sp
),
data_power
)
demos/log_normal_wiener_filter.py
View file @
7107323b
# -*- coding: utf-8 -*-
from
nifty
import
*
import
nifty
as
ift
import
nifty2go
as
ift
import
numpy
as
np
if
__name__
==
"__main__"
:
np
.
random
.
seed
(
42
)
# Setting up parameters |\label{code:wf_parameters}|
correlation_length
=
1.
# Typical distance over which the field is correlated
field_variance
=
2.
# Variance of field in position space
...
...
@@ -19,74 +19,73 @@ if __name__ == "__main__":
L
=
2.
# Total side-length of the domain
N_pixels
=
128
# Grid resolution (pixels per axis)
#signal_space = RGSpace([N_pixels, N_pixels], distances=L/N_pixels)
signal_space
=
HPSpace
(
16
)
harmonic_space
=
FFTOperator
.
get_default_codomain
(
signal_space
)
fft
=
FFTOperator
(
harmonic_space
,
target
=
signal_space
)
power_space
=
PowerSpace
(
harmonic_space
)
signal_space
=
ift
.
HPSpace
(
16
)
harmonic_space
=
signal_space
.
get_default_codomain
(
)
fft
=
ift
.
FFTOperator
(
harmonic_space
,
target
=
signal_space
)
power_space
=
ift
.
PowerSpace
(
harmonic_space
)
# Creating the mock signal |\label{code:wf_mock_signal}|
S
=
create_power_operator
(
harmonic_space
,
power_spectrum
=
power_spectrum
)
mock_power
=
Field
(
power_space
,
val
=
power_spectrum
)
S
=
ift
.
create_power_operator
(
harmonic_space
,
power_spectrum
=
power_spectrum
)
mock_power
=
ift
.
Field
(
power_space
,
val
=
power_spectrum
(
power_space
.
kindex
)
)
mock_signal
=
fft
(
mock_power
.
power_synthesize
(
real_signal
=
True
))
# Setting up an exemplary response
mask
=
Field
(
signal_space
,
val
=
1.
)
mask
=
ift
.
Field
(
signal_space
,
val
=
1.
)
N10
=
int
(
N_pixels
/
10
)
#mask.val[N10*5:N10*9, N10*5:N10*9] = 0.
R
=
ResponseOperator
(
signal_space
,
sigma
=
(
response_sigma
,),
exposure
=
(
mask
,))
#|\label{code:wf_response}|
R
=
ift
.
ResponseOperator
(
signal_space
,
sigma
=
(
response_sigma
,),
exposure
=
(
mask
,))
#|\label{code:wf_response}|
data_domain
=
R
.
target
[
0
]
R_harmonic
=
ComposedOperator
([
fft
,
R
],
default_spaces
=
[
0
,
0
])
R_harmonic
=
ift
.
ComposedOperator
([
fft
,
R
],
default_spaces
=
[
0
,
0
])
# Setting up the noise covariance and drawing a random noise realization
N
=
DiagonalOperator
(
data_domain
,
diagonal
=
mock_signal
.
var
()
/
signal_to_noise
,
bare
=
True
)
noise
=
Field
.
from_random
(
domain
=
data_domain
,
random_type
=
'normal'
,
N
=
ift
.
DiagonalOperator
(
data_domain
,
diagonal
=
mock_signal
.
var
()
/
signal_to_noise
,
bare
=
True
)
noise
=
ift
.
Field
.
from_random
(
domain
=
data_domain
,
random_type
=
'normal'
,
std
=
mock_signal
.
std
()
/
np
.
sqrt
(
signal_to_noise
),
mean
=
0
)
data
=
R
(
exp
(
mock_signal
))
+
noise
#|\label{code:wf_mock_data}|
data
=
R
(
ift
.
exp
(
mock_signal
))
+
noise
#|\label{code:wf_mock_data}|
# Wiener filter
m0
=
Field
(
harmonic_space
,
val
=
0.j
)
m0
=
ift
.
Field
(
harmonic_space
,
val
=
0.
)
ctrl
=
ift
.
DefaultIterationController
(
verbose
=
False
,
tol_abs_gradnorm
=
1
)
ctrl2
=
ift
.
DefaultIterationController
(
verbose
=
True
,
tol_abs_gradnorm
=
0.1
,
name
=
"outer"
)
inverter
=
ift
.
ConjugateGradient
(
controller
=
ctrl
,
preconditioner
=
S
.
times
)
energy
=
library
.
LogNormalWienerFilterEnergy
(
m0
,
data
,
R_harmonic
,
N
,
S
,
inverter
=
inverter
)
minimizer1
=
VL_BFGS
(
controller
=
ctrl2
,
max_history_length
=
20
)
minimizer2
=
RelaxedNewton
(
controller
=
ctrl2
)
minimizer3
=
SteepestDescent
(
controller
=
ctrl2
)
#
me1 = minimizer1(energy)
#
me2 = minimizer2(energy)
energy
=
ift
.
library
.
LogNormalWienerFilterEnergy
(
m0
,
data
,
R_harmonic
,
N
,
S
,
inverter
=
inverter
)
minimizer1
=
ift
.
VL_BFGS
(
controller
=
ctrl2
,
max_history_length
=
20
)
minimizer2
=
ift
.
RelaxedNewton
(
controller
=
ctrl2
)
minimizer3
=
ift
.
SteepestDescent
(
controller
=
ctrl2
)
print
type
(
energy
.
value
)
me1
=
minimizer1
(
energy
)
me2
=
minimizer2
(
energy
)
me3
=
minimizer3
(
energy
)
# m1 = fft(me1[0].position)
# m2 = fft(me2[0].position)
# m3 = fft(me3[0].position)
#
m1
=
fft
(
me1
[
0
].
position
)
m2
=
fft
(
me2
[
0
].
position
)
m3
=
fft
(
me3
[
0
].
position
)
#
# Probing the variance
# class Proby(DiagonalProberMixin,
Prober): pass
#
proby = Proby(signal_space, probe_count=100)
#
proby(lambda z: fft(wiener_curvature.inverse_times(fft.inverse_times(z))))
#
#
sm = SmoothingOperator(signal_space, sigma=0.02)
#
variance = sm(proby.diagonal.weight(-1))
# Probing the variance
class
Proby
(
ift
.
DiagonalProberMixin
,
ift
.
Prober
):
pass
proby
=
Proby
(
signal_space
,
probe_count
=
100
)
proby
(
lambda
z
:
fft
(
wiener_curvature
.
inverse_times
(
fft
.
inverse_times
(
z
))))
sm
=
SmoothingOperator
(
signal_space
,
sigma
=
0.02
)
variance
=
sm
(
proby
.
diagonal
.
weight
(
-
1
))
#Plotting #|\label{code:wf_plotting}|
#plotter = plotting.RG2DPlotter(color_map=plotting.colormaps.PlankCmap())
plotter
=
plotting
.
HealpixPlotter
(
color_map
=
plotting
.
colormaps
.
PlankCmap
())
plotter
=
ift
.
plotting
.
HealpixPlotter
(
color_map
=
ift
.
plotting
.
colormaps
.
PlankCmap
())
plotter
.
figure
.
xaxis
=
plotting
.
Axis
(
label
=
'Pixel Index'
)
plotter
.
figure
.
yaxis
=
plotting
.
Axis
(
label
=
'Pixel Index'
)
plotter
.
figure
.
xaxis
=
ift
.
plotting
.
Axis
(
label
=
'Pixel Index'
)
plotter
.
figure
.
yaxis
=
ift
.
plotting
.
Axis
(
label
=
'Pixel Index'
)
plotter
.
plot
.
zmax
=
5
;
plotter
.
plot
.
zmin
=
-
5
##
plotter(variance, path = 'variance.html')
plotter
(
variance
,
path
=
'variance.html'
)
# #plotter.plot.zmin = exp(mock_signal.min());
# plotter(mock_signal.real, path='mock_signal.html')
# plotter(Field(signal_space, val=np.log(data.val.get_full_data().real).reshape(signal_space.shape)),
# path = 'log_of_data.html')
#
#
plotter(m1.real, path='m_LBFGS.html')
#
plotter(m2.real, path='m_Newton.html')
#
plotter(m3.real, path='m_SteepestDescent.html')
plotter
(
m1
.
real
,
path
=
'm_LBFGS.html'
)
plotter
(
m2
.
real
,
path
=
'm_Newton.html'
)
plotter
(
m3
.
real
,
path
=
'm_SteepestDescent.html'
)
#
nifty2go/field.py
View file @
7107323b
...
...
@@ -37,7 +37,7 @@ class Field(object):
In NIFTY, Fields are used to store data arrays and carry all the needed
metainformation (i.e. the domain) for operators to be able to work on them.
In addition
Field has methods to work with power-
spectra.
In addition
, Field has methods to work with power
spectra.
Parameters
----------
...
...
@@ -52,7 +52,7 @@ class Field(object):
array's dimensions must match the domain's.
dtype : type
A numpy.type. Most common are
int,
float and complex.
A numpy.type. Most common are float and complex.
copy: boolean
...
...
@@ -265,11 +265,9 @@ class Field(object):
for
part
in
parts
]
if
keep_phase_information
:
re
sult_field
=
parts
[
0
]
+
1j
*
parts
[
1
]
re
turn
parts
[
0
]
+
1j
*
parts
[
1
]
else
:
result_field
=
parts
[
0
]
return
result_field
return
parts
[
0
]
@
classmethod
def
_single_power_analyze
(
cls
,
work_field
,
space_index
,
binbounds
):
...
...
@@ -295,21 +293,14 @@ class Field(object):
# create the result field and put power_spectrum into it
result_domain
=
list
(
work_field
.
domain
)
result_domain
[
space_index
]
=
power_domain
result_dtype
=
power_spectrum
.
dtype
result_field
=
work_field
.
copy_empty
(
domain
=
result_domain
,
dtype
=
result_dtype
)
result_field
.
set_val
(
new_val
=
power_spectrum
,
copy
=
False
)
return
result_field
return
Field
(
domain
=
result_domain
,
val
=
power_spectrum
,
dtype
=
power_spectrum
.
dtype
)
@
classmethod
def
_calculate_power_spectrum
(
cls
,
field_val
,
pdomain
,
axes
=
None
):
pindex
=
pdomain
.
pindex
# MR FIXME: how about iterating over slices, instead of replicating
# pindex? Would save memory and probably isn't slower.
if
axes
is
not
None
:
pindex
=
cls
.
_shape_up_pindex
(
pindex
=
pindex
,
...
...
@@ -711,8 +702,6 @@ class Field(object):
The weighted field.
"""
new_field
=
self
if
inplace
else
self
.
copy_empty
()
new_val
=
self
.
get_val
(
copy
=
False
)
spaces
=
utilities
.
cast_axis_to_tuple
(
spaces
,
len
(
self
.
domain
))
...
...
@@ -725,9 +714,10 @@ class Field(object):
power
=
power
,
axes
=
self
.
domain_axes
[
ind
],
inplace
=
inplace
)
# we need at most one copy, the rest can happen in place
inplace
=
True
new_field
.
set_val
(
new_val
=
new_val
,
copy
=
False
)
return
new_field
return
Field
(
self
.
domain
,
new_val
,
self
.
dtype
)
def
vdot
(
self
,
x
=
None
,
spaces
=
None
,
bare
=
False
):
""" Computes the volume-factor-aware dot product of 'self' with x.
...
...
@@ -794,7 +784,6 @@ class Field(object):
The complex conjugated field.
"""
if
inplace
:
self
.
imag
*=-
1
return
self
...
...
@@ -837,10 +826,7 @@ class Field(object):
for
i
in
range
(
len
(
self
.
domain
))
if
i
not
in
spaces
)
return_field
=
Field
(
domain
=
return_domain
,
val
=
data
,
copy
=
False
)
return
return_field
return
Field
(
domain
=
return_domain
,
val
=
data
,
copy
=
False
)
def
sum
(
self
,
spaces
=
None
):
return
self
.
_contraction_helper
(
'sum'
,
spaces
)
...
...
nifty2go/operators/linear_operator/linear_operator.py
View file @
7107323b
...
...
@@ -224,9 +224,6 @@ class LinearOperator(with_metaclass(
If the operator has an `inverse` then the inverse adjoint is identical
to the adjoint inverse. We provide both names for convenience.
See Also
--------
"""
spaces
=
self
.
_check_input_compatibility
(
x
,
spaces
)
...
...
@@ -261,8 +258,7 @@ class LinearOperator(with_metaclass(
def
_check_input_compatibility
(
self
,
x
,
spaces
,
inverse
=
False
):
if
not
isinstance
(
x
,
Field
):
raise
ValueError
(
"supplied object is not a `Field`."
)
raise
ValueError
(
"supplied object is not a `Field`."
)
if
spaces
is
None
and
self
.
default_spaces
is
not
None
:
if
not
inverse
:
...
...
@@ -281,10 +277,7 @@ class LinearOperator(with_metaclass(
# 2. Case:
# The domains of self and x match completely.
if
not
inverse
:
self_domain
=
self
.
domain
else
:
self_domain
=
self
.
target
self_domain
=
self
.
target
if
inverse
else
self
.
domain
if
spaces
is
None
:
if
self_domain
!=
x
.
domain
:
...
...
nifty2go/operators/response_operator/response_operator.py
View file @
7107323b
...
...
@@ -50,28 +50,22 @@ class ResponseOperator(LinearOperator):
default_spaces
=
None
):
super
(
ResponseOperator
,
self
).
__init__
(
default_spaces
)
self
.
_domain
=
self
.
_parse_domain
(
domain
)
kernel_smoothing
=
len
(
self
.
_domain
)
*
[
None
]
kernel_exposure
=
len
(
self
.
_domain
)
*
[
None
]
if
len
(
sigma
)
!=
len
(
exposure
):
raise
ValueError
(
"Length of smoothing kernel and length of"
"exposure do not match"
)
nsigma
=
len
(
sigma
)
for
ii
in
range
(
len
(
kernel_smoothing
)):
kernel_smoothing
[
ii
]
=
FFTSmoothingOperator
(
self
.
_domain
[
ii
],
sigma
=
sigma
[
ii
])
kernel_exposure
[
ii
]
=
DiagonalOperator
(
self
.
_domain
[
ii
],
diagonal
=
exposure
[
ii
])
self
.
_domain
=
self
.
_parse_domain
(
domain
)
kernel_smoothing
=
[
FFTSmoothingOperator
(
self
.
_domain
[
x
],
sigma
[
x
])
for
x
in
range
(
nsigma
)]
kernel_exposure
=
[
DiagonalOperator
(
self
.
_domain
[
x
],
diagonal
=
exposure
[
x
])
for
x
in
range
(
nsigma
)]
self
.
_composed_kernel
=
ComposedOperator
(
kernel_smoothing
)
self
.
_composed_exposure
=
ComposedOperator
(
kernel_exposure
)
target_list
=
[]
for
space
in
self
.
domain
:
target_list
+=
[
FieldArray
(
space
.
shape
)]
target_list
=
[
FieldArray
(
x
.
shape
)
for
x
in
self
.
domain
]
self
.
_target
=
self
.
_parse_domain
(
target_list
)
@
property
...
...
@@ -89,7 +83,6 @@ class ResponseOperator(LinearOperator):
def
_times
(
self
,
x
,
spaces
):
res
=
self
.
_composed_kernel
.
times
(
x
,
spaces
)
res
=
self
.
_composed_exposure
.
times
(
res
,
spaces
)
# res = res.weight(power=1)
# removing geometric information
return
Field
(
self
.
_target
,
val
=
res
.
val
)
...
...
@@ -98,5 +91,4 @@ class ResponseOperator(LinearOperator):
res
=
Field
(
self
.
domain
,
val
=
x
.
val
)
res
=
self
.
_composed_exposure
.
adjoint_times
(
res
,
spaces
)
res
=
res
.
weight
(
power
=-
1
)
res
=
self
.
_composed_kernel
.
adjoint_times
(
res
,
spaces
)
return
res
return
self
.
_composed_kernel
.
adjoint_times
(
res
,
spaces
)
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment