def test_load_save_hdf5(self): with tempfile.NamedTemporaryFile() as tmp_file: make_hdf5(tmp_file.name, self.test_data.shape, tables.Int64Atom()) save_hdf5(tmp_file.name, self.test_data, 0) self.assertTrue( shape_check_hdf5(tmp_file.name, (1, ) + self.test_data.shape)) load_data = load_hdf5(tmp_file.name, 0) self.assertTrue(np.allclose(self.test_data, load_data)) new_test_data = self.test_data * 20 save_hdf5(tmp_file.name, new_test_data, 0, mode='r+') load_data = load_hdf5(tmp_file.name, 0) self.assertTrue(np.allclose(new_test_data, load_data))
def create_intrinsic_den_curve_dist(directory, file_name, qm, n0, phi, nframe, nslice, dim, nz=100, recon=0, ow_hist=False): """ Calculate density and curvature distributions across surface Parameters ---------- directory: str File path of directory of alias analysis. file_name: str File name of trajectory being analysed. qm: int Maximum number of wave frequencies in Fouier Sum representing intrinsic surface n0: int Maximum number of molecular pivots in intrinsic surface phi: float Weighting factor of minimum surface area term in surface optimisation function nframe: int Number of frames in simulation trajectory nslice: int Number of bins in density histogram along axis normal to surface dim: float, array_like; shape=(3) XYZ dimensions of simulation cell nz: int (optional) Number of bins in curvature histogram along axis normal to surface (default=100) recon: bool (optional) Whether to use surface reconstructe coefficients (default=False) ow_count: bool (optional) Whether to overwrite density and curvature distributions (default=False) """ print("\n--- Running Intrinsic Density and Curvature Routine --- \n") pos_dir = os.path.join(directory, 'pos') intpos_dir = os.path.join(directory, 'intpos') intden_dir = os.path.join(directory, 'intden') if not os.path.exists(intden_dir): os.mkdir(intden_dir) file_name_pos = create_file_name( [file_name, qm, n0, int(1. / phi + 0.5), nframe]) file_name_coeff = file_name_pos file_name_hist = create_file_name( [file_name, nslice, nz, qm, n0, int(1. / phi + 0.5), nframe]) if recon: file_name_pos += '_r' file_name_hist += '_r' file_name_coeff += '_r' count_data_file = os.path.join(intden_dir, file_name_hist) if not os.path.exists(count_data_file + '_count_corr.hdf5'): make_hdf5(count_data_file + '_count_corr', (qm + 1, nslice, nz), tables.Float64Atom()) file_check = False elif not ow_hist: "Checking number of frames in current distribution files" try: file_check = shape_check_hdf5(count_data_file + '_count_corr', (nframe, qm + 1, nslice, nz)) except FileNotFoundError: file_check = False else: file_check = False if not file_check: pos_data_file = os.path.join(pos_dir + file_name) zmol = load_npy(pos_data_file + '_{}_zmol'.format(nframe)) COM = load_npy(pos_data_file + '_{}_com'.format(nframe)) nmol = zmol.shape[1] com_tile = np.moveaxis(np.tile(COM, (nmol, 1, 1)), [0, 1, 2], [2, 1, 0])[2] zmol = zmol - com_tile for frame in range(nframe): "Checking number of frames in hdf5 files" frame_check_count_corr = frame_check_hdf5( count_data_file + '_count_corr', frame) mode_count_corr = mode_check_hdf5(frame_check_count_corr, ow_hist) if mode_count_corr: sys.stdout.write( "Calculating position and curvature distributions:" f" frame {frame}\r") sys.stdout.flush() intpos_data_file = os.path.join(intpos_dir + file_name_pos) int_z_mol = load_hdf5(intpos_data_file + '_int_z_mol', frame) int_dxdy_mol = load_hdf5(intpos_data_file + '_int_dxdy_mol', frame) count_corr_array = make_den_curve(zmol[frame], int_z_mol, int_dxdy_mol, nmol, nslice, nz, qm, dim) save_hdf5(count_data_file + '_count_corr', count_corr_array, frame, mode_count_corr)
def av_intrinsic_distributions(directory, file_name, dim, nslice, qm, n0, phi, nframe, nsample, nz=100, recon=False, ow_dist=False): """ Summate average density and curvature distributions Parameters ---------- directory: str File path of directory of alias analysis. file_name: str File name of trajectory being analysed. dim: float, array_like; shape=(3) XYZ dimensions of simulation cell nslice: int Number of bins in density histogram along axis normal to surface qm: int Maximum number of wave frequencies in Fouier Sum representing intrinsic surface n0: int Maximum number of molecular pivots in intrinsic surface phi: float Weighting factor of minimum surface area term in surface optimisation function nframe: int Number of frames in simulation trajectory nsample: int Number of frames to average over nz: int (optional) Number of bins in curvature histogram along axis normal to surface (default=100) recon: bool (optional) Whether to use surface reconstructe coefficients (default=False) ow_dist: bool (optional) Whether to overwrite average density and curvature distributions (default=False) Returns ------- int_den_curve_matrix: float, array_like; shape=(qm+1, nslice, nz) Average intrinsic density-curvature distribution for each resolution across nsample frames int_density: float, array_like; shape=(qm+1, nslice) Average intrinsic density distribution for each resolution across nsample frames int_curvature: float, array_like; shape=(qm+1, nz) Average intrinsic surface curvature distribution for each resolution across nsample frames """ intden_dir = os.path.join(directory, 'intden') file_name_hist = create_file_name( [file_name, nslice, nz, qm, n0, int(1. / phi + 0.5), nframe]) file_name_dist = create_file_name( [file_name, nslice, nz, qm, n0, int(1. / phi + 0.5), nsample]) if recon: file_name_hist += '_r' file_name_dist += '_r' count_data_file = os.path.join(intden_dir, file_name_hist) curve_data_file = os.path.join(intden_dir, file_name_dist) if not os.path.exists(curve_data_file + '_int_den_curve.npy') or ow_dist: int_den_curve_matrix = np.zeros((qm + 1, nslice, nz)) print("\n--- Loading in Density and Curvature Distributions ---\n") lslice = dim[2] / nslice Vslice = dim[0] * dim[1] * lslice for frame in range(nsample): sys.stdout.write("Frame {}\r".format(frame)) sys.stdout.flush() count_corr_array = load_hdf5(count_data_file + '_count_corr', frame) int_den_curve_matrix += count_corr_array / (nsample * Vslice) np.save(curve_data_file + "_int_den_curve.npy", int_den_curve_matrix) else: int_den_curve_matrix = load_npy(curve_data_file + '_int_den_curve') int_density = np.sum(int_den_curve_matrix, axis=2) / 2. int_curvature = np.sum(np.moveaxis(int_den_curve_matrix, 1, 2), axis=2) / 2. return int_den_curve_matrix, int_density, int_curvature
def create_intrinsic_positions_dxdyz(directory, file_name, nmol, nframe, qm, n0, phi, dim, recon=0, ow_pos=False): """ Calculate distances and derivatives at each molecular position with respect to intrinsic surface in simulation frame Parameters ---------- directory: str File path of directory of alias analysis. file_name: str File name of trajectory being analysed. nmol: int Number of molecules in simulation nframe: int Number of frames in simulation trajectory qm: int Maximum number of wave frequencies in Fourier Sum representing intrinsic surface n0: int Maximum number of molecular pivots in intrinsic surface phi: float Weighting factor of minimum surface area term in surface optimisation function dim: float, array_like; shape=(3) XYZ dimensions of simulation cell recon: bool (default=False) Whether to use surface reconstructe coefficients ow_pos: bool (default=False) Whether to overwrite positions and derivatives (default=False) """ print("\n--- Running Intrinsic Positions and Derivatives Routine ---\n") surf_dir = os.path.join(directory, 'surface') pos_dir = os.path.join(directory, 'pos') intpos_dir = os.path.join(directory, 'intpos') if not os.path.exists(intpos_dir): os.mkdir(intpos_dir) file_name_pos = create_file_name( [file_name, qm, n0, int(1 / phi + 0.5), nframe]) file_name_coeff = file_name_pos if recon: file_name_coeff += '_r' file_name_pos += '_r' intpos_data_file = os.path.join(intpos_dir + file_name_pos) if not os.path.exists(intpos_data_file + "_int_z_mol.hdf5"): make_hdf5(intpos_data_file + '_int_z_mol', (2, qm + 1, nmol), tables.Float64Atom()) make_hdf5(intpos_data_file + '_int_dxdy_mol', (4, qm + 1, nmol), tables.Float64Atom()) make_hdf5(intpos_data_file + '_int_ddxddy_mol', (4, qm + 1, nmol), tables.Float64Atom()) file_check = False elif not ow_pos: "Checking number of frames in current distance files" try: file_check = shape_check_hdf5(intpos_data_file + '_int_z_mol', (nframe, 2, qm + 1, nmol)) file_check *= shape_check_hdf5(intpos_data_file + '_int_dxdy_mol', (nframe, 4, qm + 1, nmol)) file_check *= shape_check_hdf5( intpos_data_file + '_int_ddxddy_mol', (nframe, 4, qm + 1, nmol)) except FileNotFoundError: file_check = False else: file_check = False pos_data_file = os.path.join(pos_dir + file_name) if not file_check: xmol = load_npy(pos_data_file + f'_{nframe}_xmol', frames=range(nframe)) ymol = load_npy(pos_data_file + f'_{nframe}_ymol', frames=range(nframe)) for frame in range(nframe): "Checking number of frames in int_z_mol file" frame_check_int_z_mol = frame_check_hdf5( intpos_data_file + '_int_z_mol', frame) frame_check_int_dxdy_mol = frame_check_hdf5( intpos_data_file + '_int_dxdy_mol', frame) frame_check_int_ddxddy_mol = frame_check_hdf5( intpos_data_file + '_int_ddxddy_mol', frame) mode_int_z_mol = mode_check_hdf5(frame_check_int_z_mol, ow_pos) mode_int_dxdy_mol = mode_check_hdf5(frame_check_int_dxdy_mol, ow_pos) mode_int_ddxddy_mol = mode_check_hdf5(frame_check_int_ddxddy_mol, ow_pos) check = mode_int_z_mol or mode_int_dxdy_mol or mode_int_ddxddy_mol if not check: sys.stdout.write("Calculating molecular distances " f"and derivatives: frame {frame}\r") sys.stdout.flush() surf_data_file = os.path.join(surf_dir, file_name_coeff) coeff = load_hdf5(surf_data_file + '_coeff', frame) int_z_mol, int_dxdy_mol, int_ddxddy_mol = make_pos_dxdy( xmol[frame], ymol[frame], coeff, nmol, dim, qm) save_hdf5(intpos_data_file + '_int_z_mol', int_z_mol, frame, mode_int_z_mol) save_hdf5(intpos_data_file + '_int_dxdy_mol', int_dxdy_mol, frame, mode_int_dxdy_mol) save_hdf5(intpos_data_file + '_int_ddxddy_mol', int_ddxddy_mol, frame, mode_int_ddxddy_mol)
def pivot_diffusion(file_name, surface_dir, mol_traj, cell_dim, mol_vec, surf_param, n_frame=20): print("Density Coefficient = {}".format(surf_param.pivot_density)) print("Using pivot number = {}".format(surf_param.n_pivots)) tot_piv_n1 = np.zeros((n_frame, surf_param.n_pivots), dtype=int) tot_piv_n2 = np.zeros((n_frame, surf_param.n_pivots), dtype=int) coeff_file_name = create_surface_file_path( file_name, surface_dir, surf_param.q_m, surf_param.n_pivots, surf_param.phi, surf_param.n_frames, surf_param.recon ) if not os.path.exists(coeff_file_name + '_coeff.hdf5'): make_hdf5(coeff_file_name + '_coeff', (2, surf_param.n_waves ** 2), tables.Float64Atom()) make_hdf5(coeff_file_name + '_pivot', (2, surf_param.n_pivots), tables.Int64Atom()) for frame in range(n_frame): dim = cell_dim[frame] "Checking number of frames in coeff and pivot files" frame_check_coeff = frame_check_hdf5( coeff_file_name + '_coeff', frame) frame_check_pivot = frame_check_hdf5( coeff_file_name + '_pivot', frame) mode_coeff = mode_check_hdf5(frame_check_coeff) mode_pivot = mode_check_hdf5(frame_check_pivot) if not mode_coeff and not mode_pivot: pivot = load_hdf5(coeff_file_name + '_pivot', frame) else: sys.stdout.write( f"Optimising Intrinsic Surface coefficients:" f" frame {frame}\n") sys.stdout.flush() if frame == 0: surf_0 = [-dim[2] / 4, dim[2] / 4] else: index = (2 * surf_param.q_m + 1) ** 2 / 2 coeff = load_hdf5(coeff_file_name + '_coeff', frame - 1) surf_0 = [coeff[0][index], coeff[1][index]] coeff, pivot = build_surface( mol_traj[frame, :, 0], mol_traj[frame, :, 1], mol_traj[frame, :, 2], dim, surf_param.q_m, surf_param.n_pivots, surf_param.phi, surf_param.tau, surf_param.max_r, ncube=surf_param.n_cube, vlim=surf_param.v_lim, recon=surf_param.recon, surf_0=surf_0, zvec=mol_vec[frame, :, 2]) save_hdf5( coeff_file_name + '_coeff', coeff, frame, mode_coeff) save_hdf5( coeff_file_name + '_pivot', pivot, frame, mode_pivot) tot_piv_n1[frame] += pivot[0] tot_piv_n2[frame] += pivot[1] ex_1, ex_2 = mol_exchange(tot_piv_n1, tot_piv_n2) return ex_1, ex_2