Changed shifted_correlation to support parallelization and easy input of selectors
This commit is contained in:
parent
9628053d26
commit
3992dd4e07
@ -81,12 +81,52 @@ def multi_subensemble_correlation(selector_function):
|
|||||||
|
|
||||||
|
|
||||||
@autosave_data(2)
|
@autosave_data(2)
|
||||||
def shifted_correlation(function, frames, selector=None, segments=100,
|
def shifted_correlation(function, frames, selector=None, segments=10,
|
||||||
skip=0.1, window=0.5, average=True, points=100,
|
skip=0.1, window=0.5, average=True, points=100,
|
||||||
nodes=8):
|
nodes=8):
|
||||||
|
"""
|
||||||
|
Calculate the time series for a correlation function.
|
||||||
|
|
||||||
|
The times at which the correlation is calculated are determined by
|
||||||
|
a logarithmic distribution.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
function: The function that should be correlated
|
||||||
|
frames: The coordinates of the simulation data
|
||||||
|
selector (opt.):
|
||||||
|
A function that returns the indices depending on
|
||||||
|
the staring frame for which particles the
|
||||||
|
correlation should be calculated
|
||||||
|
segments (int, opt.):
|
||||||
|
The number of segments the time window will be
|
||||||
|
shifted
|
||||||
|
skip (float, opt.):
|
||||||
|
The fraction of the trajectory that will be skipped
|
||||||
|
at the beginning, if this is None the start index
|
||||||
|
of the frames slice will be used, which defaults
|
||||||
|
to 0.1.
|
||||||
|
window (float, opt.):
|
||||||
|
The fraction of the simulation the time series will
|
||||||
|
cover
|
||||||
|
average (bool, opt.):
|
||||||
|
If True, returns averaged correlation function
|
||||||
|
points (int, opt.):
|
||||||
|
The number of timeshifts for which the correlation
|
||||||
|
should be calculated
|
||||||
|
nodes (int, opt.):
|
||||||
|
Number of nodes used for parallelization
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
tuple:
|
||||||
|
A list of length N that contains the timeshiftes of the frames at which
|
||||||
|
the time series was calculated and a numpy array of shape (segments, N)
|
||||||
|
that holds the (non-avaraged) correlation data
|
||||||
|
|
||||||
|
Example:
|
||||||
|
Calculating the mean square displacement of a coordinates object named ``coords``:
|
||||||
|
|
||||||
|
>>> time, data = shifted_correlation(msd, coords)
|
||||||
|
"""
|
||||||
def get_correlation(start_frame, idx, selector=None):
|
def get_correlation(start_frame, idx, selector=None):
|
||||||
shifted_idx = idx + start_frame
|
shifted_idx = idx + start_frame
|
||||||
if selector:
|
if selector:
|
||||||
@ -137,126 +177,6 @@ def shifted_correlation(function, frames, selector=None, segments=100,
|
|||||||
return t, result
|
return t, result
|
||||||
|
|
||||||
|
|
||||||
@autosave_data(nargs=2, kwargs_keys=(
|
|
||||||
'index_distribution', 'correlation', 'segments', 'window', 'skip', 'average'
|
|
||||||
), version='shifted_correlation-1')
|
|
||||||
def shifted_correlation(function, frames,
|
|
||||||
index_distribution=log_indices, correlation=correlation,
|
|
||||||
segments=10, window=0.5, skip=None,
|
|
||||||
average=False, ):
|
|
||||||
|
|
||||||
"""
|
|
||||||
Calculate the time series for a correlation function.
|
|
||||||
|
|
||||||
The times at which the correlation is calculated are determined automatically by the
|
|
||||||
function given as ``index_distribution``. The default is a logarithmic distribution.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
function: The function that should be correlated
|
|
||||||
frames: The coordinates of the simulation data
|
|
||||||
index_distribution (opt.):
|
|
||||||
A function that returns the indices for which the timeseries
|
|
||||||
will be calculated
|
|
||||||
correlation (function, opt.):
|
|
||||||
The correlation function
|
|
||||||
segments (int, opt.):
|
|
||||||
The number of segments the time window will be shifted
|
|
||||||
window (float, opt.):
|
|
||||||
The fraction of the simulation the time series will cover
|
|
||||||
skip (float, opt.):
|
|
||||||
The fraction of the trajectory that will be skipped at the beginning,
|
|
||||||
if this is None the start index of the frames slice will be used,
|
|
||||||
which defaults to 0.
|
|
||||||
counter (bool, opt.):
|
|
||||||
If True, returns length of frames (in general number of particles specified)
|
|
||||||
average (bool, opt.):
|
|
||||||
If True, returns averaged correlation function
|
|
||||||
Returns:
|
|
||||||
tuple:
|
|
||||||
A list of length N that contains the indices of the frames at which
|
|
||||||
the time series was calculated and a numpy array of shape (segments, N)
|
|
||||||
that holds the (non-avaraged) correlation data
|
|
||||||
|
|
||||||
if has_counter == True: adds number of counts to output tupel.
|
|
||||||
if average is returned it will be weighted.
|
|
||||||
|
|
||||||
Example:
|
|
||||||
Calculating the mean square displacement of a coordinates object named ``coords``:
|
|
||||||
|
|
||||||
>>> indices, data = shifted_correlation(msd, coords)
|
|
||||||
"""
|
|
||||||
if skip is None:
|
|
||||||
try:
|
|
||||||
skip = frames._slice.start / len(frames)
|
|
||||||
except (TypeError, AttributeError):
|
|
||||||
skip = 0
|
|
||||||
assert window + skip < 1
|
|
||||||
|
|
||||||
start_frames = np.unique(np.linspace(
|
|
||||||
len(frames) * skip, len(frames) * (1 - window),
|
|
||||||
num=segments, endpoint=False, dtype=int
|
|
||||||
))
|
|
||||||
num_frames = int(len(frames) * (window))
|
|
||||||
|
|
||||||
idx = index_distribution(0, num_frames)
|
|
||||||
|
|
||||||
|
|
||||||
def correlate(start_frame):
|
|
||||||
shifted_idx = idx + start_frame
|
|
||||||
return correlation(function, map(frames.__getitem__, shifted_idx))
|
|
||||||
|
|
||||||
times = np.array([frames[i].time for i in idx]) - frames[0].time
|
|
||||||
|
|
||||||
if getattr(correlation, "has_counter", False):
|
|
||||||
if average:
|
|
||||||
for i, start_frame in enumerate(start_frames):
|
|
||||||
act_result, act_count = correlate(start_frame)
|
|
||||||
act_result = np.array(list(act_result))
|
|
||||||
act_count = np.array(act_count)
|
|
||||||
if i == 0:
|
|
||||||
count = act_count
|
|
||||||
cdim = act_count.ndim
|
|
||||||
rdim = act_result.ndim
|
|
||||||
bt = np.newaxis,
|
|
||||||
for i in range(rdim - 1):
|
|
||||||
if i >= cdim:
|
|
||||||
bt += np.newaxis,
|
|
||||||
else:
|
|
||||||
bt += slice(None),
|
|
||||||
result = act_result * act_count[bt]
|
|
||||||
else:
|
|
||||||
result += act_result * act_count[bt]
|
|
||||||
count += act_count
|
|
||||||
np.divide(result, count[bt], out = result, where = count[bt] != 0)
|
|
||||||
result = np.moveaxis(result,0,cdim)
|
|
||||||
count = count / len(start_frames)
|
|
||||||
output = times, result, count
|
|
||||||
else:
|
|
||||||
count = []
|
|
||||||
result = []
|
|
||||||
for i, start_frame in enumerate(start_frames):
|
|
||||||
act_result, act_count = correlate(start_frame)
|
|
||||||
act_result = list(act_result)
|
|
||||||
result.append(act_result)
|
|
||||||
count.append(act_count)
|
|
||||||
count = np.asarray(count)
|
|
||||||
cdim = count.ndim
|
|
||||||
result = np.asarray(result)
|
|
||||||
result = np.moveaxis(result,1,cdim)
|
|
||||||
output = times, result, count
|
|
||||||
else:
|
|
||||||
result = 0 if average else []
|
|
||||||
for i, start_frame in enumerate(start_frames):
|
|
||||||
if average:
|
|
||||||
result += np.array(list(correlate(start_frame)))
|
|
||||||
else:
|
|
||||||
result.append(list(correlate(start_frame)))
|
|
||||||
result = np.array(result)
|
|
||||||
if average:
|
|
||||||
result = result / len(start_frames)
|
|
||||||
output = times, result
|
|
||||||
return output
|
|
||||||
|
|
||||||
def msd(start, frame):
|
def msd(start, frame):
|
||||||
"""
|
"""
|
||||||
Mean square displacement
|
Mean square displacement
|
||||||
|
Loading…
Reference in New Issue
Block a user