Coverage for biobb_dna/stiffness/basepair_stiffness.py: 80%
83 statements
« prev ^ index » next coverage.py v7.5.1, created at 2024-05-07 09:06 +0000
« prev ^ index » next coverage.py v7.5.1, created at 2024-05-07 09:06 +0000
1#!/usr/bin/env python3
3"""Module containing the HelParStiffness class and the command line interface."""
4import argparse
5from pathlib import Path
7import pandas as pd
8import numpy as np
9import matplotlib.pyplot as plt
11from biobb_common.generic.biobb_object import BiobbObject
12from biobb_common.configuration import settings
13from biobb_common.tools import file_utils as fu
14from biobb_common.tools.file_utils import launchlogger
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.
23 Args:
24 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)
25 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)
26 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)
27 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)
28 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)
29 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)
30 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)
31 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)
32 properties (dict):
33 * **KT** (*float*) - (0.592186827) Value of Boltzmann temperature factor.
34 * **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.
35 * **remove_tmp** (*bool*) - (True) [WF property] Remove temporal files.
36 * **restart** (*bool*) - (False) [WF property] Do not execute if output files exist.
38 Examples:
39 This is a use example of how to use the building block from Python::
41 from biobb_dna.stiffness.basepair_stiffness import basepair_stiffness
43 prop = {
44 'KT': 0.592186827,
45 'scaling': [1, 1, 1, 10.6, 10.6, 10.6]
46 }
47 basepair_stiffness(
48 input_filename_shift='path/to/basepair/shift.csv',
49 input_filename_slide='path/to/basepair/slide.csv',
50 input_filename_rise='path/to/basepair/rise.csv',
51 input_filename_tilt='path/to/basepair/tilt.csv',
52 input_filename_roll='path/to/basepair/roll.csv',
53 input_filename_twist='path/to/basepair/twist.csv',
54 output_csv_path='path/to/output/file.csv',
55 output_jpg_path='path/to/output/plot.jpg',
56 properties=prop)
57 Info:
58 * wrapped_software:
59 * name: In house
60 * license: Apache-2.0
61 * ontology:
62 * name: EDAM
63 * schema: http://edamontology.org/EDAM.owl
65 """
67 def __init__(self, input_filename_shift, input_filename_slide,
68 input_filename_rise, input_filename_tilt,
69 input_filename_roll, input_filename_twist,
70 output_csv_path, output_jpg_path, properties=None, **kwargs) -> None:
71 properties = properties or {}
73 # Call parent class constructor
74 super().__init__(properties)
75 self.locals_var_dict = locals().copy()
77 # Input/Output files
78 self.io_dict = {
79 'in': {
80 'input_filename_shift': input_filename_shift,
81 'input_filename_slide': input_filename_slide,
82 'input_filename_rise': input_filename_rise,
83 'input_filename_tilt': input_filename_tilt,
84 'input_filename_roll': input_filename_roll,
85 'input_filename_twist': input_filename_twist
86 },
87 'out': {
88 'output_csv_path': output_csv_path,
89 'output_jpg_path': output_jpg_path
90 }
91 }
93 self.properties = properties
94 self.KT = properties.get(
95 "KT", 0.592186827)
96 self.scaling = properties.get(
97 "scaling", [1, 1, 1, 10.6, 10.6, 10.6])
99 # Check the properties
100 self.check_properties(properties)
101 self.check_arguments()
103 @launchlogger
104 def launch(self) -> int:
105 """Execute the :class:`BPStiffness <stiffness.basepair_stiffness.BPStiffness>` object."""
107 # Setup Biobb
108 if self.check_restart():
109 return 0
110 self.stage_files()
112 # Creating temporary folder
113 self.tmp_folder = fu.create_unique_dir(prefix="bp_stiffness_")
114 fu.log('Creating %s temporary folder' % self.tmp_folder, self.out_log)
116 # read input
117 shift = load_data(
118 self.io_dict["in"]["input_filename_shift"])
119 slide = load_data(
120 self.io_dict["in"]["input_filename_slide"])
121 rise = load_data(
122 self.io_dict["in"]["input_filename_rise"])
123 tilt = load_data(
124 self.io_dict["in"]["input_filename_tilt"])
125 roll = load_data(
126 self.io_dict["in"]["input_filename_roll"])
127 twist = load_data(
128 self.io_dict["in"]["input_filename_twist"])
130 # build matrix cols_arr from helpar input data files
131 coordinates = ["shift", "slide", "rise", "tilt", "roll", "twist"]
132 basepairname = shift.columns[0]
133 helpar_matrix = pd.concat(
134 [shift, slide, rise, tilt, roll, twist], axis=1)
135 helpar_matrix.columns = coordinates
136 # covariance
137 cov_df = helpar_matrix.cov()
138 # stiffness
139 stiff = np.linalg.inv(cov_df) * self.KT
140 stiff_diag = stiff * np.array(self.scaling)
141 stiff_df = pd.DataFrame(
142 stiff_diag,
143 columns=cov_df.columns,
144 index=cov_df.index)
145 stiff_df.index.name = basepairname
147 # save csv data
148 stiff_df.to_csv(Path(self.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+.5,
158 i+.5,
159 f"{stiff_df[coordinates[j]].loc[coordinates[i]]:.2f}",
160 ha="center",
161 va="center",
162 color="w")
163 axs.text(
164 0, -1.35,
165 "Units:\n"
166 "Diagonal Shift/Slide/Rise in kcal/(mol*Ų), Diagonal Tilt/Roll/Twist in kcal/(mol*degree²)\n"
167 "Out of Diagonal: Shift/Slide/Rise in kcal/(mol*Å), Out of Diagonal Tilt/Roll/Twist in kcal/(mol*degree)",
168 fontsize=6)
169 axs.set_xticks([i + 0.5 for i in range(len(stiff_df))])
170 axs.set_xticklabels(stiff_df.columns, rotation=90)
171 axs.set_yticks([i+0.5 for i in range(len(stiff_df))])
172 axs.set_yticklabels(stiff_df.index)
173 axs.set_title(
174 f"Stiffness Constants for Base Pair Step \'{basepairname}\'")
175 fig.tight_layout()
176 fig.savefig(
177 self.io_dict['out']['output_jpg_path'],
178 format="jpg")
179 plt.close()
181 # Remove temporary file(s)
182 self.tmp_files.extend([
183 self.stage_io_dict.get("unique_dir"),
184 self.tmp_folder
185 ])
186 self.remove_tmp_files()
188 self.check_arguments(output_files_created=True, raise_exception=False)
190 return 0
193def basepair_stiffness(
194 input_filename_shift: str, input_filename_slide: str,
195 input_filename_rise: str, input_filename_tilt: str,
196 input_filename_roll: str, input_filename_twist: str,
197 output_csv_path: str, output_jpg_path: str, properties: dict = None, **kwargs) -> int:
198 """Create :class:`BPStiffness <stiffness.basepair_stiffness.BPStiffness>` class and
199 execute the :meth:`launch() <stiffness.basepair_stiffness.BPStiffness.BPStiffness.launch>` method."""
201 return BPStiffness(
202 input_filename_shift=input_filename_shift,
203 input_filename_slide=input_filename_slide,
204 input_filename_rise=input_filename_rise,
205 input_filename_tilt=input_filename_tilt,
206 input_filename_roll=input_filename_roll,
207 input_filename_twist=input_filename_twist,
208 output_csv_path=output_csv_path,
209 output_jpg_path=output_jpg_path,
210 properties=properties, **kwargs).launch()
213def main():
214 """Command line execution of this building block. Please check the command line documentation."""
215 parser = argparse.ArgumentParser(description='Calculate stiffness constants matrix between all six helical parameters for a single base pair step.',
216 formatter_class=lambda prog: argparse.RawTextHelpFormatter(prog, width=99999))
217 parser.add_argument('--config', required=False, help='Configuration file')
219 required_args = parser.add_argument_group('required arguments')
220 required_args.add_argument('--input_filename_shift', required=True,
221 help='Path to csv file with shift inputs. Accepted formats: csv.')
222 required_args.add_argument('--input_filename_slide', required=True,
223 help='Path to csv file with slide inputs. Accepted formats: csv.')
224 required_args.add_argument('--input_filename_rise', required=True,
225 help='Path to csv file with rise inputs. Accepted formats: csv.')
226 required_args.add_argument('--input_filename_tilt', required=True,
227 help='Path to csv file with tilt inputs. Accepted formats: csv.')
228 required_args.add_argument('--input_filename_roll', required=True,
229 help='Path to csv file with roll inputs. Accepted formats: csv.')
230 required_args.add_argument('--input_filename_twist', required=True,
231 help='Path to csv file with twist inputs. Accepted formats: csv.')
232 required_args.add_argument('--output_csv_path', required=True,
233 help='Path to output covariance data file. Accepted formats: csv.')
234 required_args.add_argument('--output_jpg_path', required=True,
235 help='Path to output covariance data file. Accepted formats: csv.')
237 args = parser.parse_args()
238 args.config = args.config or "{}"
239 properties = settings.ConfReader(config=args.config).get_prop_dic()
241 basepair_stiffness(
242 input_filename_shift=args.input_filename_shift,
243 input_filename_slide=args.input_filename_slide,
244 input_filename_rise=args.input_filename_rise,
245 input_filename_tilt=args.input_filename_tilt,
246 input_filename_roll=args.input_filename_roll,
247 input_filename_twist=args.input_filename_twist,
248 output_csv_path=args.output_csv_path,
249 output_jpg_path=args.output_jpg_path,
250 properties=properties)
253if __name__ == '__main__':
254 main()