Compare commits
	
		
			19 Commits
		
	
	
		
			00043637e9
			...
			feature/co
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | 6b7641f152 | ||
|  | cd7097ad46 | ||
|  | a0ca2d8657 | ||
|  | 9ff3badab1 | ||
|  | 0f47475f22 | ||
|  | f6ff7606ad | ||
|  | 96c624efee | ||
|  | 492098fe01 | ||
|  | accb43d7e6 | ||
|  | 07b14a6cd6 | ||
|  | e124506d10 | ||
|  | 8169e76964 | ||
| 65ac6e9143 | |||
|  | 9f6af2af11 | ||
|  | 0ffce2f17a | ||
|  | 0eff84910b | ||
|  | dae2d6ed95 | ||
|  | ec4094cd92 | ||
|  | 4047db209c | 
| @@ -166,8 +166,10 @@ def autosave_data( | |||||||
|         @functools.wraps(function) |         @functools.wraps(function) | ||||||
|         def autosave(*args, **kwargs): |         def autosave(*args, **kwargs): | ||||||
|             description = kwargs.pop("description", "") |             description = kwargs.pop("description", "") | ||||||
|  |             autosave_dir_overwrite = kwargs.pop("autosave_dir_overwrite", None) | ||||||
|  |             autosave_dir = autosave_dir_overwrite if autosave_dir_overwrite is not None else autosave_directory | ||||||
|             autoload = kwargs.pop("autoload", True) and load_autosave_data |             autoload = kwargs.pop("autoload", True) and load_autosave_data | ||||||
|             if autosave_directory is not None: |             if autosave_dir is not None: | ||||||
|                 relevant_args = list(args[:nargs]) |                 relevant_args = list(args[:nargs]) | ||||||
|                 if kwargs_keys is not None: |                 if kwargs_keys is not None: | ||||||
|                     for key in [*posargs_keys, *kwargs_keys]: |                     for key in [*posargs_keys, *kwargs_keys]: | ||||||
|   | |||||||
| @@ -434,6 +434,34 @@ def center_of_masses( | |||||||
|         ] |         ] | ||||||
|     ).T[mask] |     ).T[mask] | ||||||
|     return np.array(positions) |     return np.array(positions) | ||||||
|  |      | ||||||
|  |      | ||||||
|  | @map_coordinates | ||||||
|  | def center_of_atoms( | ||||||
|  |     frame: CoordinateFrame, atom_indices=None, shear: bool = False | ||||||
|  | ) -> NDArray: | ||||||
|  |     if atom_indices is None: | ||||||
|  |         atom_indices = list(range(len(frame))) | ||||||
|  |     res_ids = frame.residue_ids[atom_indices] | ||||||
|  |     if shear: | ||||||
|  |         coords = frame[atom_indices] | ||||||
|  |         box = frame.box | ||||||
|  |         sort_ind = res_ids.argsort(kind="stable") | ||||||
|  |         i = np.concatenate([[0], np.where(np.diff(res_ids[sort_ind]) > 0)[0] + 1]) | ||||||
|  |         coms = coords[sort_ind[i]][res_ids - min(res_ids)] | ||||||
|  |         cor = pbc_diff(coords, coms, box) | ||||||
|  |         coords = coms + cor | ||||||
|  |     else: | ||||||
|  |         coords = frame.whole[atom_indices] | ||||||
|  |     mask = np.bincount(res_ids)[1:] != 0 | ||||||
|  |     positions = np.array( | ||||||
|  |         [ | ||||||
|  |             np.bincount(res_ids, weights=c)[1:] | ||||||
|  |             / np.bincount(res_ids)[1:] | ||||||
|  |             for c in coords.T | ||||||
|  |         ] | ||||||
|  |     ).T[mask] | ||||||
|  |     return np.array(positions) | ||||||
|  |  | ||||||
|  |  | ||||||
| @map_coordinates | @map_coordinates | ||||||
|   | |||||||
| @@ -18,7 +18,7 @@ def log_indices(first: int, last: int, num: int = 100) -> np.ndarray: | |||||||
|     return np.unique(np.int_(ls) - 1 + first) |     return np.unique(np.int_(ls) - 1 + first) | ||||||
|  |  | ||||||
|  |  | ||||||
| @autosave_data(2) | @autosave_data(nargs=2, kwargs_keys=('selector', 'segments', 'skip', 'window', 'average', 'points',), version=1.0) | ||||||
| def shifted_correlation( | def shifted_correlation( | ||||||
|     function: Callable, |     function: Callable, | ||||||
|     frames: Coordinates, |     frames: Coordinates, | ||||||
| @@ -147,7 +147,8 @@ def shifted_correlation( | |||||||
|     num_frames = int(len(frames) * window) |     num_frames = int(len(frames) * window) | ||||||
|     ls = np.logspace(0, np.log10(num_frames + 1), num=points) |     ls = np.logspace(0, np.log10(num_frames + 1), num=points) | ||||||
|     idx = np.unique(np.int_(ls) - 1) |     idx = np.unique(np.int_(ls) - 1) | ||||||
|     t = np.array([frames[i].time for i in idx]) - frames[0].time |     dt = round(frames[1].time - frames[0].time, 6) # round to avoid bad floats | ||||||
|  |     t = idx * dt | ||||||
|  |  | ||||||
|     result = np.array( |     result = np.array( | ||||||
|         [ |         [ | ||||||
| @@ -199,7 +200,7 @@ def msd( | |||||||
|         raise ValueError('Parameter axis has to be ether "all", "x", "y", or "z"!') |         raise ValueError('Parameter axis has to be ether "all", "x", "y", or "z"!') | ||||||
|  |  | ||||||
|  |  | ||||||
| def isf( | def isf_raw( | ||||||
|     start_frame: CoordinateFrame, |     start_frame: CoordinateFrame, | ||||||
|     end_frame: CoordinateFrame, |     end_frame: CoordinateFrame, | ||||||
|     q: float = 22.7, |     q: float = 22.7, | ||||||
| @@ -216,29 +217,59 @@ def isf( | |||||||
|         displacements = displacements_without_drift(start_frame, end_frame, trajectory) |         displacements = displacements_without_drift(start_frame, end_frame, trajectory) | ||||||
|     if axis == "all": |     if axis == "all": | ||||||
|         distance = (displacements**2).sum(axis=1) ** 0.5 |         distance = (displacements**2).sum(axis=1) ** 0.5 | ||||||
|         return np.sinc(distance * q / np.pi).mean() |         return np.sinc(distance * q / np.pi) | ||||||
|     elif axis == "xy" or axis == "yx": |     elif axis == "xy" or axis == "yx": | ||||||
|         distance = (displacements[:, [0, 1]]**2).sum(axis=1) ** 0.5 |         distance = (displacements[:, [0, 1]]**2).sum(axis=1) ** 0.5 | ||||||
|         return np.real(jn(0, distance * q)).mean() |         return np.real(jn(0, distance * q)) | ||||||
|     elif axis == "xz" or axis == "zx": |     elif axis == "xz" or axis == "zx": | ||||||
|         distance = (displacements[:, [0, 2]]**2).sum(axis=1) ** 0.5 |         distance = (displacements[:, [0, 2]]**2).sum(axis=1) ** 0.5 | ||||||
|         return np.real(jn(0, distance * q)).mean() |         return np.real(jn(0, distance * q)) | ||||||
|     elif axis == "yz" or axis == "zy": |     elif axis == "yz" or axis == "zy": | ||||||
|         distance = (displacements[:, [1, 2]]**2).sum(axis=1) ** 0.5 |         distance = (displacements[:, [1, 2]]**2).sum(axis=1) ** 0.5 | ||||||
|         return np.real(jn(0, distance * q)).mean() |         return np.real(jn(0, distance * q)) | ||||||
|     elif axis == "x": |     elif axis == "x": | ||||||
|         distance = np.abs(displacements[:, 0]) |         distance = np.abs(displacements[:, 0]) | ||||||
|         return np.mean(np.cos(np.abs(q * distance))) |         return np.cos(np.abs(q * distance)) | ||||||
|     elif axis == "y": |     elif axis == "y": | ||||||
|         distance = np.abs(displacements[:, 1]) |         distance = np.abs(displacements[:, 1]) | ||||||
|         return np.mean(np.cos(np.abs(q * distance))) |         return np.cos(np.abs(q * distance)) | ||||||
|     elif axis == "z": |     elif axis == "z": | ||||||
|         distance = np.abs(displacements[:, 2]) |         distance = np.abs(displacements[:, 2]) | ||||||
|         return np.mean(np.cos(np.abs(q * distance))) |         return np.cos(np.abs(q * distance)) | ||||||
|     else: |     else: | ||||||
|         raise ValueError('Parameter axis has to be ether "all", "x", "y", or "z"!') |         raise ValueError('Parameter axis has to be ether "all", "x", "y", or "z"!') | ||||||
|  |  | ||||||
|  |  | ||||||
|  | def isf( | ||||||
|  |     start_frame: CoordinateFrame, | ||||||
|  |     end_frame: CoordinateFrame, | ||||||
|  |     q: float = 22.7, | ||||||
|  |     trajectory: Coordinates = None, | ||||||
|  |     axis: str = "all", | ||||||
|  | ) -> float: | ||||||
|  |     """ | ||||||
|  |     Incoherent intermediate scattering function averaged over all particles. | ||||||
|  |     See isf_raw for details. | ||||||
|  |     """ | ||||||
|  |     return isf_raw(start_frame, end_frame, q=q, trajectory=trajectory, axis=axis).mean() | ||||||
|  |  | ||||||
|  |  | ||||||
|  | def isf_mean_var( | ||||||
|  |     start_frame: CoordinateFrame, | ||||||
|  |     end_frame: CoordinateFrame, | ||||||
|  |     q: float = 22.7, | ||||||
|  |     trajectory: Coordinates = None, | ||||||
|  |     axis: str = "all", | ||||||
|  | ) -> float: | ||||||
|  |     """ | ||||||
|  |     Incoherent intermediate scattering function averaged over all particles and the | ||||||
|  |     variance. | ||||||
|  |     See isf_raw for details. | ||||||
|  |     """ | ||||||
|  |     values = isf_raw(start_frame, end_frame, q=q, trajectory=trajectory, axis=axis) | ||||||
|  |     return values.mean(), values.var() | ||||||
|  |  | ||||||
|  |  | ||||||
| def rotational_autocorrelation( | def rotational_autocorrelation( | ||||||
|     start_frame: CoordinateFrame, end_frame: CoordinateFrame, order: int = 2 |     start_frame: CoordinateFrame, end_frame: CoordinateFrame, order: int = 2 | ||||||
| ) -> float: | ) -> float: | ||||||
| @@ -430,6 +461,7 @@ def non_gaussian_parameter( | |||||||
|     end_frame: CoordinateFrame, |     end_frame: CoordinateFrame, | ||||||
|     trajectory: Coordinates = None, |     trajectory: Coordinates = None, | ||||||
|     axis: str = "all", |     axis: str = "all", | ||||||
|  |     full_output = False, | ||||||
| ) -> float: | ) -> float: | ||||||
|     r""" |     r""" | ||||||
|     Calculate the non-Gaussian parameter. |     Calculate the non-Gaussian parameter. | ||||||
| @@ -442,27 +474,41 @@ def non_gaussian_parameter( | |||||||
|     else: |     else: | ||||||
|         vectors = displacements_without_drift(start_frame, end_frame, trajectory) |         vectors = displacements_without_drift(start_frame, end_frame, trajectory) | ||||||
|     if axis == "all": |     if axis == "all": | ||||||
|         r = (vectors**2).sum(axis=1) |         r2 = (vectors**2).sum(axis=1) | ||||||
|         dimensions = 3 |         dimensions = 3 | ||||||
|     elif axis == "xy" or axis == "yx": |     elif axis == "xy" or axis == "yx": | ||||||
|         r = (vectors[:, [0, 1]]**2).sum(axis=1) |         r2 = (vectors[:, [0, 1]]**2).sum(axis=1) | ||||||
|         dimensions = 2 |         dimensions = 2 | ||||||
|     elif axis == "xz" or axis == "zx": |     elif axis == "xz" or axis == "zx": | ||||||
|         r = (vectors[:, [0, 2]]**2).sum(axis=1) |         r2 = (vectors[:, [0, 2]]**2).sum(axis=1) | ||||||
|         dimensions = 2 |         dimensions = 2 | ||||||
|     elif axis == "yz" or axis == "zy": |     elif axis == "yz" or axis == "zy": | ||||||
|         r = (vectors[:, [1, 2]]**2).sum(axis=1) |         r2 = (vectors[:, [1, 2]]**2).sum(axis=1) | ||||||
|         dimensions = 2 |         dimensions = 2 | ||||||
|     elif axis == "x": |     elif axis == "x": | ||||||
|         r = vectors[:, 0] ** 2 |         r2 = vectors[:, 0] ** 2 | ||||||
|         dimensions = 1 |         dimensions = 1 | ||||||
|     elif axis == "y": |     elif axis == "y": | ||||||
|         r = vectors[:, 1] ** 2 |         r2 = vectors[:, 1] ** 2 | ||||||
|         dimensions = 1 |         dimensions = 1 | ||||||
|     elif axis == "z": |     elif axis == "z": | ||||||
|         r = vectors[:, 2] ** 2 |         r2 = vectors[:, 2] ** 2 | ||||||
|         dimensions = 1 |         dimensions = 1 | ||||||
|     else: |     else: | ||||||
|         raise ValueError('Parameter axis has to be ether "all", "x", "y", or "z"!') |         raise ValueError('Parameter axis has to be ether "all", "x", "y", or "z"!') | ||||||
|  |      | ||||||
|  |     m2 = np.mean(r2) | ||||||
|  |     m4 = np.mean(r2**2) | ||||||
|  |     if m2 == 0.0: | ||||||
|  |         if full_output: | ||||||
|  |             return 0.0, 0.0, 0.0 | ||||||
|  |         else: | ||||||
|  |             return 0.0 | ||||||
|  |  | ||||||
|  |     alpha_2 = (m4 / ((1 + 2 / dimensions) * m2**2)) - 1 | ||||||
|  |     if full_output: | ||||||
|  |         return alpha_2, m2, m4 | ||||||
|  |     else: | ||||||
|  |         return alpha_2 | ||||||
|  |  | ||||||
|  |  | ||||||
|     return (np.mean(r**2) / ((1 + 2 / dimensions) * (np.mean(r) ** 2))) - 1 |  | ||||||
|   | |||||||
| @@ -149,32 +149,21 @@ def nojump(frame: CoordinateFrame, usecache: bool = True) -> CoordinateFrame: | |||||||
|             i0 = 0 |             i0 = 0 | ||||||
|             delta = 0 |             delta = 0 | ||||||
|  |  | ||||||
|         delta = ( |         delta = (delta | ||||||
|             delta |             + np.vstack( | ||||||
|             + np.array( |                 [m[i0 : abstep + 1].sum(axis=0) for m in reader.nojump_matrices] | ||||||
|                 np.vstack( |             ).T) | ||||||
|                     [m[i0 : abstep + 1].sum(axis=0) for m in reader.nojump_matrices] |  | ||||||
|                 ).T |  | ||||||
|             ) |  | ||||||
|             @ frame.box |  | ||||||
|         ) |  | ||||||
|  |  | ||||||
|         reader._nojump_cache[abstep] = delta |         reader._nojump_cache[abstep] = delta | ||||||
|         while len(reader._nojump_cache) > NOJUMP_CACHESIZE: |         while len(reader._nojump_cache) > NOJUMP_CACHESIZE: | ||||||
|             reader._nojump_cache.popitem(last=False) |             reader._nojump_cache.popitem(last=False) | ||||||
|         delta = delta[selection, :] |  | ||||||
|     else: |     else: | ||||||
|         delta = ( |         delta = np.vstack( | ||||||
|             np.array( |                 [m[: frame.step + 1, selection].sum(axis=0) for m in reader.nojump_matrices] | ||||||
|                 np.vstack( |  | ||||||
|                     [ |  | ||||||
|                         m[: frame.step + 1, selection].sum(axis=0) |  | ||||||
|                         for m in reader.nojump_matrices |  | ||||||
|                     ] |  | ||||||
|                 ).T |                 ).T | ||||||
|             ) |      | ||||||
|             @ frame.box |     delta = delta[selection, :] | ||||||
|         ) |     delta = np.array(delta @ frame.box) | ||||||
|     return frame - delta |     return frame - delta | ||||||
|  |  | ||||||
|  |  | ||||||
|   | |||||||
| @@ -275,7 +275,7 @@ def load_nojump_matrices(reader: BaseReader): | |||||||
|                 "Loaded Nojump matrices: {}".format(nojump_load_filename(reader)) |                 "Loaded Nojump matrices: {}".format(nojump_load_filename(reader)) | ||||||
|             ) |             ) | ||||||
|         else: |         else: | ||||||
|             logger.info("Invlaid Nojump Data: {}".format(nojump_load_filename(reader))) |             logger.info("Invalid Nojump Data: {}".format(nojump_load_filename(reader))) | ||||||
|     except KeyError: |     except KeyError: | ||||||
|         logger.info("Removing zip-File: %s", zipname) |         logger.info("Removing zip-File: %s", zipname) | ||||||
|         os.remove(nojump_load_filename(reader)) |         os.remove(nojump_load_filename(reader)) | ||||||
|   | |||||||
| @@ -357,6 +357,37 @@ def quick1etau(t: ArrayLike, C: ArrayLike, n: int = 7) -> float: | |||||||
|     return tau_est |     return tau_est | ||||||
|  |  | ||||||
|  |  | ||||||
|  | def quicknongaussfit(t, C, width=2): | ||||||
|  |     """ | ||||||
|  |     Estimates the time and height of the peak in the non-Gaussian function. | ||||||
|  |     C is C(t) the correlation function | ||||||
|  |     """ | ||||||
|  |     def ffunc(t,y0,A_main,log_tau_main,sig_main): | ||||||
|  |         main_peak = A_main*np.exp(-(t - log_tau_main)**2 / (2 * sig_main**2)) | ||||||
|  |         return y0 + main_peak | ||||||
|  |      | ||||||
|  |     # first rough estimate, the closest time. This is returned if the interpolation fails! | ||||||
|  |     tau_est = t[np.argmax(C)] | ||||||
|  |     nG_max = np.amax(C) | ||||||
|  |     try: | ||||||
|  |         with np.errstate(invalid='ignore'): | ||||||
|  |             corr = C[t > 0] | ||||||
|  |             time = np.log10(t[t > 0]) | ||||||
|  |             tau = time[np.argmax(corr)] | ||||||
|  |             mask = (time>tau-width/2) & (time<tau+width/2) | ||||||
|  |             time = time[mask] ; corr = corr[mask] | ||||||
|  |             nG_min = C[t > 0].min() | ||||||
|  |             guess = [nG_min, nG_max-nG_min, tau, 0.6] | ||||||
|  |             popt = curve_fit(ffunc, time, corr, p0=guess, maxfev=10000)[0] | ||||||
|  |             tau_est = 10**popt[-2] | ||||||
|  |             nG_max = popt[0] + popt[1] | ||||||
|  |     except: | ||||||
|  |         pass | ||||||
|  |     if np.isnan(tau_est): | ||||||
|  |         tau_est = np.inf | ||||||
|  |     return tau_est, nG_max | ||||||
|  |  | ||||||
|  |  | ||||||
| def susceptibility( | def susceptibility( | ||||||
|     time: NDArray, correlation: NDArray, **kwargs |     time: NDArray, correlation: NDArray, **kwargs | ||||||
| ) -> tuple[NDArray, NDArray]: | ) -> tuple[NDArray, NDArray]: | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user