Coverage for biobb_dna / stiffness / basepair_stiffness.py: 97%
65 statements
« prev ^ index » next coverage.py v7.13.0, created at 2025-12-15 18:49 +0000
« prev ^ index » next coverage.py v7.13.0, created at 2025-12-15 18:49 +0000
1#!/usr/bin/env python3
3"""Module containing the HelParStiffness class and the command line interface."""
5from pathlib import Path
6from typing import Optional
8import matplotlib.pyplot as plt
9import numpy as np
10import pandas as pd
11from biobb_common.generic.biobb_object import BiobbObject
12from biobb_common.tools.file_utils import launchlogger
14from biobb_dna.utils.common import _from_string_to_list
15from biobb_dna.utils.loader import load_data
18class BPStiffness(BiobbObject):
19 """
20 | biobb_dna BPStiffness
21 | Calculate stiffness constants matrix between all six helical parameters for a single base pair step.
22 | Calculate stiffness constants matrix between all six helical parameters for a single base pair step.
24 Args:
25 input_filename_shift (str): Path to csv file with data for helical parameter 'shift'. File type: input. `Sample file <https://raw.githubusercontent.com/bioexcel/biobb_dna/master/biobb_dna/test/data/stiffness/series_shift_AA.csv>`_. Accepted formats: csv (edam:format_3752)
26 input_filename_slide (str): Path to csv file with data for helical parameter 'slide'. File type: input. `Sample file <https://raw.githubusercontent.com/bioexcel/biobb_dna/master/biobb_dna/test/data/stiffness/series_slide_AA.csv>`_. Accepted formats: csv (edam:format_3752)
27 input_filename_rise (str): Path to csv file with data for helical parameter 'rise'. File type: input. `Sample file <https://raw.githubusercontent.com/bioexcel/biobb_dna/master/biobb_dna/test/data/stiffness/series_rise_AA.csv>`_. Accepted formats: csv (edam:format_3752)
28 input_filename_tilt (str): Path to csv file with data for helical parameter 'tilt'. File type: input. `Sample file <https://raw.githubusercontent.com/bioexcel/biobb_dna/master/biobb_dna/test/data/stiffness/series_tilt_AA.csv>`_. Accepted formats: csv (edam:format_3752)
29 input_filename_roll (str): Path to csv file with data for helical parameter 'roll'. File type: input. `Sample file <https://raw.githubusercontent.com/bioexcel/biobb_dna/master/biobb_dna/test/data/stiffness/series_roll_AA.csv>`_. Accepted formats: csv (edam:format_3752)
30 input_filename_twist (str): Path to csv file with data for helical parameter 'twist'. File type: input. `Sample file <https://raw.githubusercontent.com/bioexcel/biobb_dna/master/biobb_dna/test/data/stiffness/series_twist_AA.csv>`_. Accepted formats: csv (edam:format_3752)
31 output_csv_path (str): Path to directory where stiffness matrix file is saved as a csv file. File type: output. `Sample file <https://raw.githubusercontent.com/bioexcel/biobb_dna/master/biobb_dna/test/reference/stiffness/stiffbp_ref.csv>`_. Accepted formats: csv (edam:format_3752)
32 output_jpg_path (str): Path to directory where stiffness heatmap image is saved as a jpg file. File type: output. `Sample file <https://raw.githubusercontent.com/bioexcel/biobb_dna/master/biobb_dna/test/reference/stiffness/stiffbp_ref.jpg>`_. Accepted formats: jpg (edam:format_3579)
33 properties (dict):
34 * **KT** (*float*) - (0.592186827) Value of Boltzmann temperature factor.
35 * **scaling** (*list*) - ([1, 1, 1, 10.6, 10.6, 10.6]) Values by which to scale stiffness. Positions correspond to helical parameters in the order: shift, slide, rise, tilt, roll, twist.
36 * **remove_tmp** (*bool*) - (True) [WF property] Remove temporal files.
37 * **restart** (*bool*) - (False) [WF property] Do not execute if output files exist.
38 * **sandbox_path** (*str*) - ("./") [WF property] Parent path to the sandbox directory.
40 Examples:
41 This is a use example of how to use the building block from Python::
43 from biobb_dna.stiffness.basepair_stiffness import basepair_stiffness
45 prop = {
46 'KT': 0.592186827,
47 'scaling': [1, 1, 1, 10.6, 10.6, 10.6]
48 }
49 basepair_stiffness(
50 input_filename_shift='path/to/basepair/shift.csv',
51 input_filename_slide='path/to/basepair/slide.csv',
52 input_filename_rise='path/to/basepair/rise.csv',
53 input_filename_tilt='path/to/basepair/tilt.csv',
54 input_filename_roll='path/to/basepair/roll.csv',
55 input_filename_twist='path/to/basepair/twist.csv',
56 output_csv_path='path/to/output/file.csv',
57 output_jpg_path='path/to/output/plot.jpg',
58 properties=prop)
59 Info:
60 * wrapped_software:
61 * name: In house
62 * license: Apache-2.0
63 * ontology:
64 * name: EDAM
65 * schema: http://edamontology.org/EDAM.owl
67 """
69 def __init__(
70 self,
71 input_filename_shift,
72 input_filename_slide,
73 input_filename_rise,
74 input_filename_tilt,
75 input_filename_roll,
76 input_filename_twist,
77 output_csv_path,
78 output_jpg_path,
79 properties=None,
80 **kwargs,
81 ) -> None:
82 properties = properties or {}
84 # Call parent class constructor
85 super().__init__(properties)
86 self.locals_var_dict = locals().copy()
88 # Input/Output files
89 self.io_dict = {
90 "in": {
91 "input_filename_shift": input_filename_shift,
92 "input_filename_slide": input_filename_slide,
93 "input_filename_rise": input_filename_rise,
94 "input_filename_tilt": input_filename_tilt,
95 "input_filename_roll": input_filename_roll,
96 "input_filename_twist": input_filename_twist,
97 },
98 "out": {
99 "output_csv_path": output_csv_path,
100 "output_jpg_path": output_jpg_path,
101 },
102 }
104 self.properties = properties
105 self.KT = properties.get("KT", 0.592186827)
106 self.scaling = [
107 int(elem)
108 for elem in _from_string_to_list(
109 properties.get("scaling", [1, 1, 1, 10.6, 10.6, 10.6])
110 )
111 ]
113 # Check the properties
114 self.check_properties(properties)
115 self.check_arguments()
117 @launchlogger
118 def launch(self) -> int:
119 """Execute the :class:`BPStiffness <stiffness.basepair_stiffness.BPStiffness>` object."""
121 # Setup Biobb
122 if self.check_restart():
123 return 0
124 self.stage_files()
126 # read input
127 shift = load_data(self.stage_io_dict["in"]["input_filename_shift"])
128 slide = load_data(self.stage_io_dict["in"]["input_filename_slide"])
129 rise = load_data(self.stage_io_dict["in"]["input_filename_rise"])
130 tilt = load_data(self.stage_io_dict["in"]["input_filename_tilt"])
131 roll = load_data(self.stage_io_dict["in"]["input_filename_roll"])
132 twist = load_data(self.stage_io_dict["in"]["input_filename_twist"])
134 # build matrix cols_arr from helpar input data files
135 coordinates = ["shift", "slide", "rise", "tilt", "roll", "twist"]
136 basepairname = shift.columns[0]
137 helpar_matrix = pd.concat([shift, slide, rise, tilt, roll, twist], axis=1)
138 helpar_matrix.columns = coordinates
139 # covariance
140 cov_df = helpar_matrix.cov()
141 # stiffness
142 stiff = np.linalg.inv(cov_df) * self.KT
143 stiff_diag = stiff * np.array(self.scaling)
144 stiff_df = pd.DataFrame(stiff_diag, columns=cov_df.columns, index=cov_df.index)
145 stiff_df.index.name = basepairname
147 # save csv data
148 stiff_df.to_csv(Path(self.stage_io_dict["out"]["output_csv_path"]))
150 # create heatmap
151 fig, axs = plt.subplots(1, 1, dpi=300, tight_layout=True)
152 axs.pcolor(stiff_df)
153 # Loop over data dimensions and create text annotations.
154 for i in range(len(stiff_df)):
155 for j in range(len(stiff_df)):
156 axs.text(
157 j + 0.5,
158 i + 0.5,
159 f"{stiff_df[coordinates[j]].loc[coordinates[i]]:.2f}",
160 ha="center",
161 va="center",
162 color="w",
163 )
164 axs.text(
165 0,
166 -1.35,
167 "Units:\n"
168 "Diagonal Shift/Slide/Rise in kcal/(mol*Ų), Diagonal Tilt/Roll/Twist in kcal/(mol*degree²)\n"
169 "Out of Diagonal: Shift/Slide/Rise in kcal/(mol*Å), Out of Diagonal Tilt/Roll/Twist in kcal/(mol*degree)",
170 fontsize=6,
171 )
172 axs.set_xticks([i + 0.5 for i in range(len(stiff_df))])
173 axs.set_xticklabels(stiff_df.columns, rotation=90)
174 axs.set_yticks([i + 0.5 for i in range(len(stiff_df))])
175 axs.set_yticklabels(stiff_df.index)
176 axs.set_title(f"Stiffness Constants for Base Pair Step '{basepairname}'")
177 fig.tight_layout()
178 fig.savefig(self.stage_io_dict["out"]["output_jpg_path"], format="jpg")
179 plt.close()
181 # Copy files to host
182 self.copy_to_host()
184 # Remove temporary file(s)
185 self.remove_tmp_files()
187 self.check_arguments(output_files_created=True, raise_exception=False)
189 return 0
192def basepair_stiffness(
193 input_filename_shift: str,
194 input_filename_slide: str,
195 input_filename_rise: str,
196 input_filename_tilt: str,
197 input_filename_roll: str,
198 input_filename_twist: str,
199 output_csv_path: str,
200 output_jpg_path: str,
201 properties: Optional[dict] = None,
202 **kwargs,
203) -> int:
204 """Create :class:`BPStiffness <stiffness.basepair_stiffness.BPStiffness>` class and
205 execute the :meth:`launch() <stiffness.basepair_stiffness.BPStiffness.BPStiffness.launch>` method."""
206 return BPStiffness(**dict(locals())).launch()
209basepair_stiffness.__doc__ = BPStiffness.__doc__
210main = BPStiffness.get_main(basepair_stiffness, "Calculate stiffness constants matrix between all six helical parameters for a single base pair step.")
212if __name__ == '__main__':
213 main()