DynamiSpectra 1.0.4__py3-none-any.whl → 1.0.6__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,201 @@
1
+ import numpy as np
2
+ import matplotlib.pyplot as plt
3
+ from matplotlib.patches import Patch # Para criar elementos de legenda personalizados
4
+ import os
5
+
6
+ # Mapeamento dos estados secundários para números
7
+ state_mapping = {
8
+ 'H': 1, # Hélice-α
9
+ 'E': 2, # Folha-β
10
+ 'C': 0, # Loop/Coil
11
+ 'T': 3, # Turn
12
+ 'S': 4, # Bend
13
+ 'G': 5, # 3-Helix
14
+ '~': -1, # Sem estrutura definida
15
+ 'B': -1, # Tratar como sem estrutura
16
+ }
17
+
18
+ # Nomes das estruturas secundárias
19
+ state_names = {
20
+ 0: 'Loop/Coil',
21
+ 1: 'α-Helix',
22
+ 2: 'β-Sheet',
23
+ 3: 'Turn',
24
+ 4: 'Bend',
25
+ 5: '3-Helix',
26
+ }
27
+
28
+ def read_ss(file):
29
+ """
30
+ Reads secondary structure data from a .dat file.
31
+
32
+ Parameters:
33
+ -----------
34
+ file : str
35
+ Path to the .dat file.
36
+
37
+ Returns:
38
+ --------
39
+ ss_data : numpy.ndarray
40
+ Array of secondary structure data.
41
+ """
42
+ try:
43
+ print(f"Reading file: {file}")
44
+
45
+ # Open the file and process line by line
46
+ ss_data = []
47
+
48
+ with open(file, 'r') as f:
49
+ for line in f:
50
+ # Skip comment lines and empty lines
51
+ if line.startswith(('#', '@', ';')) or line.strip() == '':
52
+ continue
53
+
54
+ # Try to extract the secondary structure data
55
+ try:
56
+ ss_line = [state_mapping.get(char, -1) for char in line.strip()]
57
+ ss_data.append(ss_line)
58
+ except ValueError:
59
+ # Skip lines that cannot be converted to numbers
60
+ print(f"Error processing line: {line.strip()}")
61
+ continue
62
+
63
+ # Check if the data is valid
64
+ if len(ss_data) == 0:
65
+ raise ValueError(f"File {file} does not contain valid data.")
66
+
67
+ # Convert lists to numpy arrays
68
+ ss_data = np.array(ss_data)
69
+
70
+ return ss_data
71
+
72
+ except Exception as e:
73
+ print(f"Error reading file {file}: {e}")
74
+ return None
75
+
76
+ def calculate_probabilities(ss_data):
77
+ """
78
+ Calculates the probability of each secondary structure.
79
+
80
+ Parameters:
81
+ -----------
82
+ ss_data : numpy.ndarray
83
+ Array of secondary structure data.
84
+
85
+ Returns:
86
+ --------
87
+ probabilities : dict
88
+ Dictionary with probabilities for each secondary structure.
89
+ """
90
+ probabilities = {state: [] for state in state_names.values()}
91
+ total_frames = ss_data.shape[0] # Total de frames
92
+
93
+ for estado, nome in state_names.items():
94
+ probabilities[nome] = np.sum(ss_data == estado, axis=1) / ss_data.shape[1] # Probabilidade por frame
95
+
96
+ return probabilities
97
+
98
+ def plot_ss_boxplot(probabilities_list, labels, colors, output_folder):
99
+ """
100
+ Generates a boxplot for secondary structure probabilities.
101
+
102
+ Parameters:
103
+ -----------
104
+ probabilities_list : list of dict
105
+ List of dictionaries with probabilities for each simulation.
106
+ labels : list of str
107
+ Labels for each simulation.
108
+ colors : list of str
109
+ Colors for each simulation.
110
+ output_folder : str
111
+ Output folder to save the plots.
112
+ """
113
+ # Preparar dados para o boxplot
114
+ x_labels = list(state_names.values()) # Estruturas secundárias
115
+ x = np.arange(len(x_labels)) # Posições no eixo X
116
+
117
+ # Criar figura para o boxplot
118
+ plt.figure(figsize=(7, 6))
119
+ plt.plot()
120
+
121
+ # Função para plotar boxplots
122
+ def plot_boxplot(data, positions, color, label):
123
+ box = plt.boxplot(data, positions=positions, widths=0.4, patch_artist=True, labels=[label] * len(positions), showfliers=False) # Remover outliers
124
+ for boxplot in box['boxes']:
125
+ boxplot.set_facecolor(color)
126
+ boxplot.set_alpha(0.7)
127
+ for median in box['medians']:
128
+ median.set_color('black')
129
+ return box
130
+
131
+ # Plotar boxplots para cada simulação
132
+ for i, (probabilities, label, color) in enumerate(zip(probabilities_list, labels, colors)):
133
+ data = [probabilities[name] * 100 for name in x_labels]
134
+ plot_boxplot(data, x - 0.25 + i * 0.25, color, label)
135
+
136
+ # Configuração do gráfico
137
+ plt.xlabel('', fontsize=12)
138
+ plt.ylabel('Probability (%)', fontsize=12) # Eixo y em percentual
139
+ plt.title('', fontsize=14, fontweight='bold')
140
+ plt.xticks(x, x_labels, rotation=45, fontsize=10)
141
+ plt.yticks(fontsize=10)
142
+ plt.grid(False) # Remover a grade
143
+
144
+ # Cores e rótulos para a legenda
145
+ legend_elements = [
146
+ Patch(facecolor=color, edgecolor='black', linewidth=1.2, alpha=0.7, label=label)
147
+ for label, color in zip(labels, colors)
148
+ ]
149
+
150
+ # Posicionar a legenda
151
+ plt.legend(handles=legend_elements, frameon=False, fontsize=10, loc='upper right', edgecolor='black') # Borda ao redor da legenda
152
+
153
+ # Ajustar layout para evitar cortes
154
+ plt.tight_layout()
155
+
156
+ # Salvar o gráfico em 300 dpi (PNG e TIFF)
157
+ os.makedirs(output_folder, exist_ok=True) # Create the folder if it doesn't exist
158
+
159
+ # Salvar como PNG
160
+ plt.savefig(os.path.join(output_folder, 'secondary_structure_boxplot.png'), dpi=300, format='png', bbox_inches='tight')
161
+
162
+ # Salvar como TIFF
163
+ plt.savefig(os.path.join(output_folder, 'secondary_structure_boxplot.tiff'), dpi=300, format='tiff', bbox_inches='tight')
164
+
165
+ # Mostrar gráfico
166
+ plt.show()
167
+
168
+ def ss_analysis(output_folder, *simulation_files_groups):
169
+ r"""
170
+ Main function to generate secondary structure analysis and plots.
171
+
172
+ Parameters:
173
+ -----------
174
+ output_folder : str
175
+ Output folder to save the plots.
176
+ \*simulation_files_groups : list of str
177
+ List of paths to .dat files for each simulation group.
178
+ You can pass 1, 2, or 3 groups.
179
+ """
180
+ # Helper function to process a group of files
181
+ def process_group(file_paths):
182
+ ss_data = []
183
+ for file in file_paths:
184
+ data = read_ss(file)
185
+ ss_data.append(data)
186
+ return ss_data
187
+
188
+ # Process each group of files
189
+ probabilities_list = []
190
+ labels = []
191
+ colors = ['#333333', '#6A9EDA', '#54b36a'] # Cores para cada simulação
192
+
193
+ for i, group in enumerate(simulation_files_groups):
194
+ if group: # Check if the list is not empty
195
+ ss_data = process_group(group)
196
+ probabilities = calculate_probabilities(ss_data[0]) # Assume only one file per group
197
+ probabilities_list.append(probabilities)
198
+ labels.append(f'Simulation {i + 1}')
199
+
200
+ # Generate plots
201
+ plot_ss_boxplot(probabilities_list, labels, colors[:len(probabilities_list)], output_folder)
@@ -0,0 +1,21 @@
1
+ # src/__init__.py
2
+ from .Hbond import read_hbond, hbond_analysis
3
+ from .RMSD import rmsd_analysis
4
+ from .RMSF import read_rmsf, rmsf_analysis
5
+ from .SASA import read_sasa, sasa_analysis
6
+ from .Rg import read_rg, rg_analysis
7
+ from .PCA import pca_analysis
8
+ from .SecondaryStructure import (
9
+ read_ss,
10
+ calculate_probabilities,
11
+ plot_ss_boxplot,
12
+ ss_analysis,
13
+ state_mapping,
14
+ state_names
15
+ )
16
+ from .FractionSS import fractions_ss_analysis
17
+ from .saltbridge import saltbridge_analysis
18
+ from .ligand_density import ligand_density_analysis
19
+
20
+
21
+ __all__ = ['read_hbond', 'hbond_analysis', 'read_rmsd', 'rmsd_analysis', 'read_rmsf', 'rmsf_analysis', 'read_sasa', 'sasa_analysis', 'read_rg', 'rg_analysis', 'pca_analysis', 'read_ss', 'calculate_probabilities', 'plot_ss_boxplot', 'ss_analysis', 'state_mapping', 'state_names', 'fractions_ss_analysis', 'saltbridge_analysis', 'ligand_density_analysis']
dynamispectra/cly.py ADDED
File without changes
@@ -0,0 +1,55 @@
1
+ import numpy as np
2
+ import matplotlib.pyplot as plt
3
+ import os
4
+
5
+ def read_xpm(file_path):
6
+ with open(file_path, 'r') as f:
7
+ lines = f.readlines()
8
+
9
+ lines = [l.strip() for l in lines if l.strip().startswith('"')]
10
+ header_line = lines[0].strip().strip('",')
11
+ width, height, ncolors, chars_per_pixel = map(int, header_line.split())
12
+
13
+ color_map = {}
14
+ for i in range(1, ncolors + 1):
15
+ line = lines[i].strip().strip('",')
16
+ symbol = line[:chars_per_pixel]
17
+ color_map[symbol] = i - 1
18
+
19
+ matrix = []
20
+ for line in lines[ncolors + 1:]:
21
+ line = line.strip().strip('",')
22
+ row = [color_map[line[i:i+chars_per_pixel]] for i in range(0, len(line), chars_per_pixel)]
23
+ matrix.append(row)
24
+
25
+ return np.array(matrix)
26
+
27
+ def plot_density(matrix, cmap='inferno', xlabel='X', ylabel='Y', title='',
28
+ colorbar_label='Relative density', save_path=None):
29
+ """
30
+ Plots the density matrix and optionally saves it as .png and .tiff in 300 dpi.
31
+ """
32
+ plt.figure()
33
+ plt.imshow(matrix, cmap=cmap, origin='lower', aspect='auto')
34
+ plt.colorbar(label=colorbar_label)
35
+ plt.xlabel(xlabel)
36
+ plt.ylabel(ylabel)
37
+ plt.title(title)
38
+ plt.tight_layout()
39
+
40
+ if save_path:
41
+ base, _ = os.path.splitext(save_path)
42
+ plt.savefig(f"{base}.png", dpi=300)
43
+ plt.savefig(f"{base}.tiff", dpi=300)
44
+ print(f"Gráficos salvos como {base}.png e {base}.tiff")
45
+
46
+ plt.show()
47
+
48
+ def ligand_density_analysis(xpm_file_path, plot=True, save_path=None):
49
+ """
50
+ Reads an XPM file, plots the ligand density, and optionally saves the figure.
51
+ """
52
+ matrix = read_xpm(xpm_file_path)
53
+ if plot:
54
+ plot_density(matrix, save_path=save_path)
55
+ return matrix
dynamispectra/main.py ADDED
@@ -0,0 +1,4 @@
1
+ # src/dynamispectra/main.py
2
+
3
+ def main():
4
+ print("DynamiSpectra is working!")
@@ -0,0 +1,171 @@
1
+ import numpy as np
2
+ import matplotlib.pyplot as plt
3
+ from scipy.stats import gaussian_kde
4
+ import os
5
+
6
+ def read_saltbridge(file):
7
+ """
8
+ Reads salt-bridge distance data from a .xvg file.
9
+
10
+ Parameters:
11
+ -----------
12
+ file : str
13
+ Path to the .xvg file.
14
+
15
+ Returns:
16
+ --------
17
+ times : numpy.ndarray
18
+ Time values from simulation.
19
+ distances : numpy.ndarray
20
+ Salt-bridge distances.
21
+ """
22
+ try:
23
+ print(f"Reading file: {file}")
24
+ times, distances = [], []
25
+
26
+ with open(file, 'r') as f:
27
+ for line in f:
28
+ if line.startswith(('#', '@', ';')) or line.strip() == '':
29
+ continue
30
+ try:
31
+ values = line.split()
32
+ if len(values) >= 2:
33
+ time, distance = map(float, values[:2])
34
+ times.append(time / 1000.0) # Convert ps to ns
35
+ distances.append(distance)
36
+ except ValueError:
37
+ print(f"Error processing line: {line.strip()}")
38
+ continue
39
+
40
+ if len(times) == 0 or len(distances) == 0:
41
+ raise ValueError(f"File {file} does not contain valid data.")
42
+
43
+ return np.array(times), np.array(distances)
44
+
45
+ except Exception as e:
46
+ print(f"Error reading file {file}: {e}")
47
+ return None, None
48
+
49
+ def check_simulation_times(*time_arrays):
50
+ for i in range(1, len(time_arrays)):
51
+ if not np.allclose(time_arrays[0], time_arrays[i]):
52
+ raise ValueError(f"Simulation times do not match between file 1 and file {i+1}")
53
+
54
+ def plot_saltbridge(time1, mean1, std1,
55
+ time2, mean2, std2,
56
+ time3, mean3, std3,
57
+ output_folder):
58
+ """
59
+ Generates the salt-bridge distance plot with mean and standard deviation.
60
+ """
61
+ plt.figure(figsize=(7, 6))
62
+
63
+ if time1 is not None:
64
+ plt.plot(time1, mean1, label='Simulation 1', color='#333333', linewidth=2)
65
+ plt.fill_between(time1, mean1 - std1, mean1 + std1, color='#333333', alpha=0.2)
66
+
67
+ if time2 is not None:
68
+ plt.plot(time2, mean2, label='Simulation 2', color='#6A9EDA', linewidth=2)
69
+ plt.fill_between(time2, mean2 - std2, mean2 + std2, color='#6A9EDA', alpha=0.2)
70
+
71
+ if time3 is not None:
72
+ plt.plot(time3, mean3, label='Simulation 3', color='#54b36a', linewidth=2)
73
+ plt.fill_between(time3, mean3 - std3, mean3 + std3, color='#54b36a', alpha=0.2)
74
+
75
+ plt.xlabel('Time (ns)', fontsize=12)
76
+ plt.ylabel('Salt-Bridge Distance (nm)', fontsize=12)
77
+ plt.legend(frameon=False, loc='upper right', fontsize=10)
78
+ plt.tick_params(axis='both', which='major', labelsize=10)
79
+ plt.grid(False)
80
+
81
+ # Ajuste do limite do eixo x para o último tempo dos dados
82
+ max_time = max(
83
+ max(time1) if time1 is not None else 0,
84
+ max(time2) if time2 is not None else 0,
85
+ max(time3) if time3 is not None else 0,
86
+ )
87
+ plt.xlim(0, max_time)
88
+
89
+ plt.tight_layout()
90
+
91
+ os.makedirs(output_folder, exist_ok=True)
92
+ plt.savefig(os.path.join(output_folder, 'saltbridge_plot.tiff'), format='tiff', dpi=300)
93
+ plt.savefig(os.path.join(output_folder, 'saltbridge_plot.png'), format='png', dpi=300)
94
+ plt.show()
95
+
96
+ def plot_density(mean1, mean2, mean3, output_folder):
97
+ """
98
+ Generates the density plot for salt-bridge mean values.
99
+ """
100
+ plt.figure(figsize=(6, 6))
101
+
102
+ if mean1 is not None:
103
+ kde1 = gaussian_kde(mean1)
104
+ x_vals = np.linspace(0, max(mean1), 1000)
105
+ plt.fill_between(x_vals, kde1(x_vals), color='#333333', alpha=0.5, label='Simulation 1')
106
+
107
+ if mean2 is not None:
108
+ kde2 = gaussian_kde(mean2)
109
+ x_vals = np.linspace(0, max(mean2), 1000)
110
+ plt.fill_between(x_vals, kde2(x_vals), color='#6A9EDA', alpha=0.5, label='Simulation 2')
111
+
112
+ if mean3 is not None:
113
+ kde3 = gaussian_kde(mean3)
114
+ x_vals = np.linspace(0, max(mean3), 1000)
115
+ plt.fill_between(x_vals, kde3(x_vals), color='#54b36a', alpha=0.5, label='Simulation 3')
116
+
117
+ plt.xlabel('Salt-Bridge Distance (nm)', fontsize=12)
118
+ plt.ylabel('Density', fontsize=12)
119
+ plt.legend(frameon=False, loc='upper right', fontsize=10)
120
+ plt.tick_params(axis='both', which='major', labelsize=10)
121
+ plt.grid(False)
122
+ plt.tight_layout()
123
+
124
+ plt.savefig(os.path.join(output_folder, 'saltbridge_density.tiff'), format='tiff', dpi=300)
125
+ plt.savefig(os.path.join(output_folder, 'saltbridge_density.png'), format='png', dpi=300)
126
+ plt.show()
127
+
128
+ def saltbridge_analysis(output_folder, *simulation_files_groups):
129
+ """
130
+ Main function to generate salt-bridge analysis and plots.
131
+
132
+ Parameters:
133
+ -----------
134
+ output_folder : str
135
+ Output folder to save plots.
136
+ *simulation_files_groups : list of str
137
+ List of .xvg files for each simulation group.
138
+ """
139
+ def process_group(file_paths):
140
+ times, distances = [], []
141
+ for file in file_paths:
142
+ time, dist = read_saltbridge(file)
143
+ times.append(time)
144
+ distances.append(dist)
145
+ check_simulation_times(*times)
146
+ mean_dist = np.mean(distances, axis=0)
147
+ std_dist = np.std(distances, axis=0)
148
+ return times[0], mean_dist, std_dist
149
+
150
+ results = []
151
+ for group in simulation_files_groups:
152
+ if group:
153
+ time, mean, std = process_group(group)
154
+ results.append((time, mean, std))
155
+
156
+ if len(results) == 1:
157
+ plot_saltbridge(results[0][0], results[0][1], results[0][2],
158
+ None, None, None, None, None, None, output_folder)
159
+ plot_density(results[0][1], None, None, output_folder)
160
+ elif len(results) == 2:
161
+ plot_saltbridge(results[0][0], results[0][1], results[0][2],
162
+ results[1][0], results[1][1], results[1][2],
163
+ None, None, None, output_folder)
164
+ plot_density(results[0][1], results[1][1], None, output_folder)
165
+ elif len(results) == 3:
166
+ plot_saltbridge(results[0][0], results[0][1], results[0][2],
167
+ results[1][0], results[1][1], results[1][2],
168
+ results[2][0], results[2][1], results[2][2], output_folder)
169
+ plot_density(results[0][1], results[1][1], results[2][1], output_folder)
170
+ else:
171
+ raise ValueError("You must provide at least one group of simulation files.")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: DynamiSpectra
3
- Version: 1.0.4
3
+ Version: 1.0.6
4
4
  Summary: Scripts for Molecular dynamics analysis
5
5
  Home-page: https://github.com/Conradoou/DynamiSpectra
6
6
  Author: Iverson Conrado-Bezerra
@@ -0,0 +1,18 @@
1
+ dynamispectra/FractionSS.py,sha256=-4GiRsvTiwyn5rN17hNKfbmzfevnEOqOm1TxMl8gQOs,3647
2
+ dynamispectra/Hbond.py,sha256=-Mb4g-tITqxEG1VbvYae4TgmTsIRyMis3NEm3Ey9Zu0,8658
3
+ dynamispectra/PCA.py,sha256=nwQ7jEMvuhRAIvRRiGboQ8Cl0qrm15xSgHYCX0HlKiU,3482
4
+ dynamispectra/RMSD.py,sha256=EUSv1Ql0f7P3VRhx6175NxjEn-2cIXx4lbVfeI88Gbk,8622
5
+ dynamispectra/RMSF.py,sha256=M2b-KfvogfFbLUtv6PgZB4_nxWBeg9XbBpY0HjNQ9fw,8545
6
+ dynamispectra/Rg.py,sha256=4F_vjdgcRG9LNqNCig1kdaUpMIRZrtQppYwL2OpJFYk,8557
7
+ dynamispectra/SASA.py,sha256=o6_hcsmeY9yjAKUgsd0RpMikwC9VhoKAmQ1JLtPuXos,8661
8
+ dynamispectra/SecondaryStructure.py,sha256=7jiYnqRgDaiR-16Zk40aCyv060y-1R__m44AVkhvm9g,6764
9
+ dynamispectra/__init__.py,sha256=iIXzlsDvnIF4DFUSxotB10EHWA5aQtZZQYr4tEyLIi0,919
10
+ dynamispectra/cly.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
11
+ dynamispectra/ligand_density.py,sha256=oNAnVkbeLKhG88Q6JEzCYsbyCkm78wj7-hBnjQJDzpU,1802
12
+ dynamispectra/main.py,sha256=YhivGFXZb1qwRCPUNmST5LeejqTyHmthMhzJs9uebJY,84
13
+ dynamispectra/saltbridge.py,sha256=lN16ArvXU_sngvNvpUkGSh7enANNMbVz41TD8-OT2lM,6553
14
+ dynamispectra-1.0.6.dist-info/METADATA,sha256=-6HEb3F7PmP8q9PkNaw_ZSTpqM8ElbwwNINnv9IXyl0,3807
15
+ dynamispectra-1.0.6.dist-info/WHEEL,sha256=Nw36Djuh_5VDukK0H78QzOX-_FQEo6V37m3nkm96gtU,91
16
+ dynamispectra-1.0.6.dist-info/entry_points.txt,sha256=aaQocKWsZi_lJ7MZMsxHmc2DpQF4BSY0fwfE1s0CLxo,37
17
+ dynamispectra-1.0.6.dist-info/top_level.txt,sha256=MDRYQBL4n7V0YVNSoOO_yf7iv_Kz3JGoVUEHiq_zT6U,14
18
+ dynamispectra-1.0.6.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (79.0.0)
2
+ Generator: setuptools (80.7.1)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -0,0 +1 @@
1
+ dynamispectra
@@ -1,5 +0,0 @@
1
- dynamispectra-1.0.4.dist-info/METADATA,sha256=XPOtwawaixbvV5DXlrinQ5uT6_ioStAXufmtQyIAXyI,3807
2
- dynamispectra-1.0.4.dist-info/WHEEL,sha256=pxyMxgL8-pra_rKaQ4drOZAegBVuX-G_4nRHjjgWbmo,91
3
- dynamispectra-1.0.4.dist-info/entry_points.txt,sha256=aaQocKWsZi_lJ7MZMsxHmc2DpQF4BSY0fwfE1s0CLxo,37
4
- dynamispectra-1.0.4.dist-info/top_level.txt,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
5
- dynamispectra-1.0.4.dist-info/RECORD,,
@@ -1 +0,0 @@
1
-