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

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 

8 

9 

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.""" 

18 

19 if membrane_map is None or membrane_map['n_mems'] == 0: 

20 print('-> Skipping thickness analysis') 

21 return 

22 

23 # Set the main output filepath 

24 output_analysis_filepath = f'{output_directory}/{OUTPUT_THICKNESS_FILENAME}' 

25 

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') 

49 

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)