Coverage for model_workflow/analyses/rmsf.py: 86%
22 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
1# Generic analyses
2# Easy and fast trajectory analyses carried by Gromacs
4from numpy import mean, std
6from model_workflow.utils.auxiliar import save_json
7from model_workflow.utils.constants import GREY_HEADER, COLOR_END, OUTPUT_RMSF_FILENAME
8from model_workflow.utils.type_hints import *
10from MDAnalysis import Universe
11from MDAnalysis.analysis import rms
14# LORE: Fluctuation analysis was done with Gromacs before
15# LORE: However Gromacs required masses and atom radii, which was a problem in coarse grain
16def rmsf (
17 structure_file : 'File',
18 trajectory_file : 'File',
19 output_directory : str,
20 pbc_selection : 'Selection'):
21 """Perform the fluctuation analysis."""
22 # Set the main output filepath
23 output_analysis_filepath = f'{output_directory}/{OUTPUT_RMSF_FILENAME}'
25 # Load the MDAnalysis universe
26 # Make MDAnalysis warnings and logs grey
27 print(GREY_HEADER, end='\r')
28 universe = Universe(structure_file.path, trajectory_file.path)
29 print(COLOR_END, end='\r')
31 # Run the analysis in all atoms
32 # Even atoms to be excluded (e.g. PBC) are excluded later to don't mess atom results order
33 all_atoms = universe.select_atoms('all')
34 rmsf_analysis = rms.RMSF(all_atoms).run()
35 # Make a list of it because it is a ndarray, which is not JSON serializable
36 # Access to the values thorugh 'results.rmsf' instead of a direct 'rmsf' to avoid a deprecation warning
37 rmsf_values = list(rmsf_analysis.results.rmsf)
39 # Filter out values from PBC residue atoms since they may have not sense
40 for index in pbc_selection.atom_indices:
41 rmsf_values[index] = None
43 # Get all rmsf values which are not None
44 actual_rmsf_values = [ v for v in rmsf_values if v != None ]
45 # There may be none if the whole system is in PBC
46 if len(actual_rmsf_values) == 0:
47 print(' No actual values to do RMSF')
48 return
50 # Format data
51 rmsf_data = {
52 'y': {
53 'rmsf': {
54 'average': mean(actual_rmsf_values),
55 'stddev': std(actual_rmsf_values),
56 'min': min(actual_rmsf_values),
57 'max': max(actual_rmsf_values),
58 'data': rmsf_values # Keep all values here to make the list length match the number of atoms
59 }
60 },
61 'version': '0.1.0'
62 }
64 # Export formatted data to a json file
65 save_json(rmsf_data, output_analysis_filepath)