Coverage for model_workflow/analyses/thickness.py: 100%
32 statements
« prev ^ index » next coverage.py v7.9.2, created at 2025-07-23 10:54 +0000
« prev ^ index » next coverage.py v7.9.2, created at 2025-07-23 10:54 +0000
1from biobb_mem.lipyphilic_biobb.lpp_zpositions import lpp_zpositions, frame_df
2from model_workflow.utils.pyt_spells import get_reduced_pytraj_trajectory
3from model_workflow.utils.auxiliar import save_json
4from model_workflow.utils.constants import OUTPUT_THICKNESS_FILENAME
5from model_workflow.utils.type_hints import *
6from contextlib import redirect_stdout
7import os
10def thickness (
11 structure_file : 'File',
12 trajectory_file : 'File',
13 output_directory : str,
14 membrane_map: dict,
15 snapshots : int,
16 frames_limit: int = 100):
17 """Membrane thickness analysis."""
19 if membrane_map is None or membrane_map['n_mems'] == 0:
20 print('-> Skipping thickness analysis')
21 return
23 # Set the main output filepath
24 output_analysis_filepath = f'{output_directory}/{OUTPUT_THICKNESS_FILENAME}'
26 tj, frame_step, frames_count = get_reduced_pytraj_trajectory(
27 structure_file.path, trajectory_file.path, snapshots, frames_limit)
28 head_sel = []
29 for n in range(membrane_map['n_mems']):
30 head_sel.extend(membrane_map['mems'][str(n)]['polar_atoms']['top'])
31 head_sel.extend(membrane_map['mems'][str(n)]['polar_atoms']['bot'])
32 head_sel_mda = 'index ' + " ".join(map(str,(head_sel)))
33 # Run the analysis on the whole membrane
34 prop = {
35 'lipid_sel': head_sel_mda,
36 'steps': frame_step,
37 'height_sel': head_sel_mda,
38 'ignore_no_box': True,
39 'disable_logs': True
40 }
41 print(' Running BioBB LiPyphilic ZPositions')
42 with redirect_stdout(None):
43 lpp_zpositions(input_top_path=structure_file.path,
44 input_traj_path=trajectory_file.path,
45 output_positions_path='.zpositions.csv',
46 properties=prop)
47 df = frame_df('.zpositions.csv') # Per frame data
48 os.remove('.zpositions.csv')
50 # Calculate the mean z position of midplane wrt the box axis using pytraj
51 midplane_z = []
52 for i in range(0, frames_count):
53 frame = tj[i]
54 selected_atoms = frame[head_sel]
55 mean_z = selected_atoms.mean(axis=0)[2]
56 midplane_z.append(float(mean_z))
57 # Save the data
58 data = { 'data':{
59 'frame': df.index.tolist(),
60 'mean_positive': df['mean_positive'].tolist(),
61 'mean_negative': df['mean_negative'].tolist(),
62 'std_positive': df['std_positive'].tolist(),
63 'std_negative': df['std_negative'].tolist(),
64 'thickness': df['thickness'].tolist(),
65 'std_thickness': df['std_thickness'].tolist(),
66 'midplane_z': midplane_z,
67 'step': frame_step
68 }
69 }
70 save_json(data, output_analysis_filepath)