pyLoopSage 1.0.16__tar.gz → 1.0.18__tar.gz

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.
Files changed (23) hide show
  1. {pyloopsage-1.0.16/pyLoopSage.egg-info → pyloopsage-1.0.18}/PKG-INFO +66 -9
  2. {pyloopsage-1.0.16 → pyloopsage-1.0.18}/README.md +54 -7
  3. {pyloopsage-1.0.16 → pyloopsage-1.0.18}/loopsage/__init__.py +1 -1
  4. {pyloopsage-1.0.16 → pyloopsage-1.0.18}/loopsage/args_definition.py +4 -1
  5. {pyloopsage-1.0.16 → pyloopsage-1.0.18}/loopsage/md.py +26 -30
  6. {pyloopsage-1.0.16 → pyloopsage-1.0.18}/loopsage/run.py +2 -2
  7. {pyloopsage-1.0.16 → pyloopsage-1.0.18}/loopsage/stochastic_simulation.py +42 -28
  8. {pyloopsage-1.0.16 → pyloopsage-1.0.18/pyLoopSage.egg-info}/PKG-INFO +66 -9
  9. {pyloopsage-1.0.16 → pyloopsage-1.0.18}/setup.py +1 -1
  10. {pyloopsage-1.0.16 → pyloopsage-1.0.18}/LICENSE +0 -0
  11. {pyloopsage-1.0.16 → pyloopsage-1.0.18}/loopsage/em.py +0 -0
  12. {pyloopsage-1.0.16 → pyloopsage-1.0.18}/loopsage/forcefields/classic_sm_ff.xml +0 -0
  13. {pyloopsage-1.0.16 → pyloopsage-1.0.18}/loopsage/initial_structures.py +0 -0
  14. {pyloopsage-1.0.16 → pyloopsage-1.0.18}/loopsage/plots.py +0 -0
  15. {pyloopsage-1.0.16 → pyloopsage-1.0.18}/loopsage/preproc.py +0 -0
  16. {pyloopsage-1.0.16 → pyloopsage-1.0.18}/loopsage/utils.py +0 -0
  17. {pyloopsage-1.0.16 → pyloopsage-1.0.18}/loopsage/vizualization_tools.py +0 -0
  18. {pyloopsage-1.0.16 → pyloopsage-1.0.18}/pyLoopSage.egg-info/SOURCES.txt +0 -0
  19. {pyloopsage-1.0.16 → pyloopsage-1.0.18}/pyLoopSage.egg-info/dependency_links.txt +0 -0
  20. {pyloopsage-1.0.16 → pyloopsage-1.0.18}/pyLoopSage.egg-info/entry_points.txt +0 -0
  21. {pyloopsage-1.0.16 → pyloopsage-1.0.18}/pyLoopSage.egg-info/requires.txt +0 -0
  22. {pyloopsage-1.0.16 → pyloopsage-1.0.18}/pyLoopSage.egg-info/top_level.txt +0 -0
  23. {pyloopsage-1.0.16 → pyloopsage-1.0.18}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.2
2
2
  Name: pyLoopSage
3
- Version: 1.0.16
3
+ Version: 1.0.18
4
4
  Summary: An energy-based stochastic model of loop extrusion in chromatin.
5
5
  Home-page: https://github.com/SFGLab/pyLoopSage
6
6
  Author: Sebastian Korsak
@@ -31,6 +31,16 @@ Requires-Dist: statsmodels
31
31
  Requires-Dist: imageio
32
32
  Requires-Dist: imageio[ffmpeg]
33
33
  Requires-Dist: pillow
34
+ Dynamic: author
35
+ Dynamic: author-email
36
+ Dynamic: classifier
37
+ Dynamic: description
38
+ Dynamic: description-content-type
39
+ Dynamic: home-page
40
+ Dynamic: license
41
+ Dynamic: requires-dist
42
+ Dynamic: requires-python
43
+ Dynamic: summary
34
44
 
35
45
  # pyLoopSage
36
46
  Updated version of the stochastic loop extrusion model: LoopSage with capability to run incredibly fast, parallelized across CPU cores. This package is even more user-friendly and it can be installed via PyPI.
@@ -44,11 +54,6 @@ Updated version of the stochastic loop extrusion model: LoopSage with capability
44
54
  - Visualization functions.
45
55
  - Capability to run form terminal with a simple command `loopsage -c config.ini`.
46
56
 
47
- ## Publication
48
- Please cite the method paper in case that you would like to use this model for your work,
49
-
50
- * Korsak, Sevastianos, and Dariusz Plewczynski. "LoopSage: An energy-based Monte Carlo approach for the loop extrusion modelling of chromatin." Methods (2024).
51
-
52
57
  ## The model
53
58
 
54
59
  ### Stochastic Simulation
@@ -74,7 +79,7 @@ These $L(\cdot), R(\cdot)$ functions are two functions that define the binding p
74
79
 
75
80
  $$c_{\text{fold}}=-\dfrac{N_{\text{beads}}f}{N_{\text{lef}}\log(N_{\text{beads}}/N_{\text{lef}})},\quad c_{\text{bind}}=-\dfrac{N_{\text{beads}}b}{\sum_i \left(L(m_i)+R(n_i)\right)},\quad c_{\text{cross}}=\kappa \times 10^4.$$
76
81
 
77
- The parameters are defined in such a way that when $f=b=\kappa=1$, the three terms of the stochastic energy are balanced.
82
+ The parameters are defined in such a way that when $f=b=\kappa=1$, the three terms of the stochastic energy are balanced. To clarrify, this parametrization is slightly different than this of the original paper. We multiply with $N_{\text{beads}}$, so as to keep the input parameters $f,b,\kappa$ simpler close to 1. Therefore, a value $f=0.1$ leads to unfolded structures, and a value $f=2$ it leads to very fast propagating long loops.
78
83
 
79
84
  And the energy difference can be expressed as the energy difference of each term,
80
85
 
@@ -113,7 +118,7 @@ For the implementation of this model in python, we used OpenMM and CUDA accelera
113
118
  In general the user can run simulation in two different ways:
114
119
 
115
120
  1. **Energy minimization (EM)**: It means that for each sample of cohesin positions $C_{t_i}=(m_j(t_i),n_j(t_i))$ start from a different initial structure (usually 3D random walk) and we apply the forcefield. For each structure we start from a different initial condition. In general, it is suggested to run the model in this way because it is faster, less prone to errors and the structures are not correlated to each other.
116
- 2. **Molecular Dynamics (MD)**: In this case we have only one initial structure, we minimize the energy according to the forcefield only once and then we run a molecular dynamics simulation over time. This creates a continuous trajectory of structures, and it is cool for visualization pruposes. Novertheness, it is not suggested because it is more prone to errors and can lead to autocorrelated structures. We suggest our users to set the power of excluded volume $\alpha=1$ for the purposes of MD simulation. However, this depends on the research interests of the user.
121
+ 2. **Molecular Dynamics (MD)**: In this case we have only one initial structure, we minimize the energy according to the forcefield only once and then we run a molecular dynamics simulation over time. This creates a continuous trajectory of structures, and it is cool for visualization pruposes. It is also biophysically more correct, in the sense that loop extrusion should be time-dependent, and the structure at time $t_i$ has to me correlated with structures at time $t_{i\pm1}$. It is a little bit more prone to error, and you may need to change the simulation frequence and step in case of instability (smaller frequency and more steps to stabilize it).
117
122
 
118
123
  ## Installation
119
124
 
@@ -262,3 +267,55 @@ In the output folder there are another three subfolders:
262
267
  An example, illustrated with Chimera software, simulated trajectory of structures after running Simulated Annealing and molecular dynamics.
263
268
 
264
269
  ![siman_traj_GitHub](https://github.com/SFGLab/LoopSage/assets/49608786/c6626641-f709-46e0-b01b-42566b1829ef)
270
+
271
+ ### Long-table of LoopSage arguments
272
+
273
+ | Argument Name | Description | Type | Default Value |
274
+ |------------------------|-----------------------------------------------------------------------------------------------------------------|------------|---------------------|
275
+ | PLATFORM | Name of the platform. Available choices: CPU, CUDA, OpenCL | str | CPU |
276
+ | DEVICE | Device index for CUDA or OpenCL (count from 0) | str | None |
277
+ | N_BEADS | Number of Simulation Beads. | int | None |
278
+ | BEDPE_PATH | A .bedpe file path with loops. It is required. | str | None |
279
+ | OUT_PATH | Output folder name. | str | ../results |
280
+ | REGION_START | Starting region coordinate. | int | None |
281
+ | REGION_END | Ending region coordinate. | int | None |
282
+ | CHROM | Chromosome that corresponds to the modeling region of interest. | str | None |
283
+ | LEF_RW | True if cohesins slide as a random walk instead of one direction. | bool | True |
284
+ | LEF_DRIFT | True if LEFs are pushed back when they encounter other LEFs. | bool | False |
285
+ | N_STEPS | Number of Monte Carlo steps. | int | 40000 |
286
+ | N_LEF | Number of loop extrusion factors. | int | None |
287
+ | N_LEF2 | Number of second family loop extrusion factors. | int | 0 |
288
+ | MC_STEP | Monte Carlo frequency to avoid autocorrelated ensembles. | int | 200 |
289
+ | BURNIN | Burn-in period (steps before equilibrium). | int | 1000 |
290
+ | T_INIT | Initial Temperature of the Stochastic Model. | float | 2.0 |
291
+ | T_FINAL | Final Temperature of the Stochastic Model. | float | 1.0 |
292
+ | METHOD | Stochastic modeling method (Metropolis or Simulated Annealing). | str | 'Annealing' |
293
+ | FOLDING_COEFF | Folding coefficient. | float | 1.0 |
294
+ | FOLDING_COEFF2 | Folding coefficient for the second family of LEFs. | float | 0.0 |
295
+ | CROSS_COEFF | LEF crossing coefficient. | float | 1.0 |
296
+ | CROSS_LOOP | True if the penalty is applied when mi<mj<ni<nj. False if it applies only when mj=ni. When false it is better to enable LEF_DRIFT as well. | bool |True |
297
+ | BIND_COEFF | CTCF binding coefficient. | float | 1.0 |
298
+ | SAVE_PLOTS | True to save diagnostic plots. | bool | True |
299
+ | SAVE_MDT | True to save metadata of the stochastic simulation. | bool | True |
300
+ | INITIAL_STRUCTURE_TYPE | Choose from: rw, confined_rw, self_avoiding_rw, helix, circle, spiral, sphere. | str | rw |
301
+ | SIMULATION_TYPE | Either EM (energy minimizations) or MD (molecular dynamics). | str | None |
302
+ | INTEGRATOR_STEP | Step of the integrator. | Quantity | 100 femtosecond |
303
+ | FORCEFIELD_PATH | Path to XML file with forcefield. | str | default_xml_path |
304
+ | ANGLE_FF_STRENGTH | Angle force strength. | float | 200.0 |
305
+ | LE_FF_LENGTH | Equilibrium distance of loop forces. | float | 0.1 |
306
+ | LE_FF_STRENGTH | Interaction Strength of loop forces. | float | 50000.0 |
307
+ | EV_P | Probability that excluded volume is disabled. Enable it only in case of topoisomerase activity simulation. | float | 0.0 |
308
+ | EV_FF_STRENGTH | Excluded-volume strength. | float | 100.0 |
309
+ | EV_FF_POWER | Excluded-volume power. | float | 3.0 |
310
+ | FRICTION | Friction coefficient of the Langevin integrator. | float | 0.1 |
311
+ | TOLERANCE | Stopping condition for energy minimization. | float | 0.001 |
312
+ | VIZ_HEATS | True to visualize the output average heatmap. | bool | True |
313
+ | SIM_TEMP | Temperature of the 3D simulation (EM or MD). | Quantity | 310 kelvin |
314
+ | SIM_STEP | Amount of simulation steps for loop force adjustments. | int | 1000 |
315
+
316
+
317
+ ## Citation
318
+ Please cite the method and biological paper in case that you would like to use this model for your work,
319
+
320
+ * Korsak, Sevastianos, and Dariusz Plewczynski. "LoopSage: An energy-based Monte Carlo approach for the loop extrusion modelling of chromatin." Methods (2024).
321
+ * Jodkowska, K., Parteka-Tojek, Z., Agarwal, A., Denkiewicz, M., Korsak, S., Chiliński, M., Banecki, K., & Plewczynski, D. (2024). Improved cohesin HiChIP protocol and bioinformatic analysis for robust detection of chromatin loops and stripes. In bioRxiv (p. 2024.05.16.594268). https://doi.org/10.1101/2024.05.16.594268
@@ -10,11 +10,6 @@ Updated version of the stochastic loop extrusion model: LoopSage with capability
10
10
  - Visualization functions.
11
11
  - Capability to run form terminal with a simple command `loopsage -c config.ini`.
12
12
 
13
- ## Publication
14
- Please cite the method paper in case that you would like to use this model for your work,
15
-
16
- * Korsak, Sevastianos, and Dariusz Plewczynski. "LoopSage: An energy-based Monte Carlo approach for the loop extrusion modelling of chromatin." Methods (2024).
17
-
18
13
  ## The model
19
14
 
20
15
  ### Stochastic Simulation
@@ -40,7 +35,7 @@ These $L(\cdot), R(\cdot)$ functions are two functions that define the binding p
40
35
 
41
36
  $$c_{\text{fold}}=-\dfrac{N_{\text{beads}}f}{N_{\text{lef}}\log(N_{\text{beads}}/N_{\text{lef}})},\quad c_{\text{bind}}=-\dfrac{N_{\text{beads}}b}{\sum_i \left(L(m_i)+R(n_i)\right)},\quad c_{\text{cross}}=\kappa \times 10^4.$$
42
37
 
43
- The parameters are defined in such a way that when $f=b=\kappa=1$, the three terms of the stochastic energy are balanced.
38
+ The parameters are defined in such a way that when $f=b=\kappa=1$, the three terms of the stochastic energy are balanced. To clarrify, this parametrization is slightly different than this of the original paper. We multiply with $N_{\text{beads}}$, so as to keep the input parameters $f,b,\kappa$ simpler close to 1. Therefore, a value $f=0.1$ leads to unfolded structures, and a value $f=2$ it leads to very fast propagating long loops.
44
39
 
45
40
  And the energy difference can be expressed as the energy difference of each term,
46
41
 
@@ -79,7 +74,7 @@ For the implementation of this model in python, we used OpenMM and CUDA accelera
79
74
  In general the user can run simulation in two different ways:
80
75
 
81
76
  1. **Energy minimization (EM)**: It means that for each sample of cohesin positions $C_{t_i}=(m_j(t_i),n_j(t_i))$ start from a different initial structure (usually 3D random walk) and we apply the forcefield. For each structure we start from a different initial condition. In general, it is suggested to run the model in this way because it is faster, less prone to errors and the structures are not correlated to each other.
82
- 2. **Molecular Dynamics (MD)**: In this case we have only one initial structure, we minimize the energy according to the forcefield only once and then we run a molecular dynamics simulation over time. This creates a continuous trajectory of structures, and it is cool for visualization pruposes. Novertheness, it is not suggested because it is more prone to errors and can lead to autocorrelated structures. We suggest our users to set the power of excluded volume $\alpha=1$ for the purposes of MD simulation. However, this depends on the research interests of the user.
77
+ 2. **Molecular Dynamics (MD)**: In this case we have only one initial structure, we minimize the energy according to the forcefield only once and then we run a molecular dynamics simulation over time. This creates a continuous trajectory of structures, and it is cool for visualization pruposes. It is also biophysically more correct, in the sense that loop extrusion should be time-dependent, and the structure at time $t_i$ has to me correlated with structures at time $t_{i\pm1}$. It is a little bit more prone to error, and you may need to change the simulation frequence and step in case of instability (smaller frequency and more steps to stabilize it).
83
78
 
84
79
  ## Installation
85
80
 
@@ -228,3 +223,55 @@ In the output folder there are another three subfolders:
228
223
  An example, illustrated with Chimera software, simulated trajectory of structures after running Simulated Annealing and molecular dynamics.
229
224
 
230
225
  ![siman_traj_GitHub](https://github.com/SFGLab/LoopSage/assets/49608786/c6626641-f709-46e0-b01b-42566b1829ef)
226
+
227
+ ### Long-table of LoopSage arguments
228
+
229
+ | Argument Name | Description | Type | Default Value |
230
+ |------------------------|-----------------------------------------------------------------------------------------------------------------|------------|---------------------|
231
+ | PLATFORM | Name of the platform. Available choices: CPU, CUDA, OpenCL | str | CPU |
232
+ | DEVICE | Device index for CUDA or OpenCL (count from 0) | str | None |
233
+ | N_BEADS | Number of Simulation Beads. | int | None |
234
+ | BEDPE_PATH | A .bedpe file path with loops. It is required. | str | None |
235
+ | OUT_PATH | Output folder name. | str | ../results |
236
+ | REGION_START | Starting region coordinate. | int | None |
237
+ | REGION_END | Ending region coordinate. | int | None |
238
+ | CHROM | Chromosome that corresponds to the modeling region of interest. | str | None |
239
+ | LEF_RW | True if cohesins slide as a random walk instead of one direction. | bool | True |
240
+ | LEF_DRIFT | True if LEFs are pushed back when they encounter other LEFs. | bool | False |
241
+ | N_STEPS | Number of Monte Carlo steps. | int | 40000 |
242
+ | N_LEF | Number of loop extrusion factors. | int | None |
243
+ | N_LEF2 | Number of second family loop extrusion factors. | int | 0 |
244
+ | MC_STEP | Monte Carlo frequency to avoid autocorrelated ensembles. | int | 200 |
245
+ | BURNIN | Burn-in period (steps before equilibrium). | int | 1000 |
246
+ | T_INIT | Initial Temperature of the Stochastic Model. | float | 2.0 |
247
+ | T_FINAL | Final Temperature of the Stochastic Model. | float | 1.0 |
248
+ | METHOD | Stochastic modeling method (Metropolis or Simulated Annealing). | str | 'Annealing' |
249
+ | FOLDING_COEFF | Folding coefficient. | float | 1.0 |
250
+ | FOLDING_COEFF2 | Folding coefficient for the second family of LEFs. | float | 0.0 |
251
+ | CROSS_COEFF | LEF crossing coefficient. | float | 1.0 |
252
+ | CROSS_LOOP | True if the penalty is applied when mi<mj<ni<nj. False if it applies only when mj=ni. When false it is better to enable LEF_DRIFT as well. | bool |True |
253
+ | BIND_COEFF | CTCF binding coefficient. | float | 1.0 |
254
+ | SAVE_PLOTS | True to save diagnostic plots. | bool | True |
255
+ | SAVE_MDT | True to save metadata of the stochastic simulation. | bool | True |
256
+ | INITIAL_STRUCTURE_TYPE | Choose from: rw, confined_rw, self_avoiding_rw, helix, circle, spiral, sphere. | str | rw |
257
+ | SIMULATION_TYPE | Either EM (energy minimizations) or MD (molecular dynamics). | str | None |
258
+ | INTEGRATOR_STEP | Step of the integrator. | Quantity | 100 femtosecond |
259
+ | FORCEFIELD_PATH | Path to XML file with forcefield. | str | default_xml_path |
260
+ | ANGLE_FF_STRENGTH | Angle force strength. | float | 200.0 |
261
+ | LE_FF_LENGTH | Equilibrium distance of loop forces. | float | 0.1 |
262
+ | LE_FF_STRENGTH | Interaction Strength of loop forces. | float | 50000.0 |
263
+ | EV_P | Probability that excluded volume is disabled. Enable it only in case of topoisomerase activity simulation. | float | 0.0 |
264
+ | EV_FF_STRENGTH | Excluded-volume strength. | float | 100.0 |
265
+ | EV_FF_POWER | Excluded-volume power. | float | 3.0 |
266
+ | FRICTION | Friction coefficient of the Langevin integrator. | float | 0.1 |
267
+ | TOLERANCE | Stopping condition for energy minimization. | float | 0.001 |
268
+ | VIZ_HEATS | True to visualize the output average heatmap. | bool | True |
269
+ | SIM_TEMP | Temperature of the 3D simulation (EM or MD). | Quantity | 310 kelvin |
270
+ | SIM_STEP | Amount of simulation steps for loop force adjustments. | int | 1000 |
271
+
272
+
273
+ ## Citation
274
+ Please cite the method and biological paper in case that you would like to use this model for your work,
275
+
276
+ * Korsak, Sevastianos, and Dariusz Plewczynski. "LoopSage: An energy-based Monte Carlo approach for the loop extrusion modelling of chromatin." Methods (2024).
277
+ * Jodkowska, K., Parteka-Tojek, Z., Agarwal, A., Denkiewicz, M., Korsak, S., Chiliński, M., Banecki, K., & Plewczynski, D. (2024). Improved cohesin HiChIP protocol and bioinformatic analysis for robust detection of chromatin loops and stripes. In bioRxiv (p. 2024.05.16.594268). https://doi.org/10.1101/2024.05.16.594268
@@ -1,4 +1,4 @@
1
1
  # Importing specific functions or classes from submodules
2
2
  from .run import main
3
3
 
4
- __version__ = "1.0.16"
4
+ __version__ = "1.0.18"
@@ -145,6 +145,7 @@ args = ListOfArgs([
145
145
 
146
146
  # Stochastic Simulation parameters
147
147
  Arg('LEF_RW', help="True in case that you would like to make cohesins slide as random walk, instead of sliding only in one direction.", type=bool, default='True', val='True'),
148
+ Arg('LEF_DRIFT', help="True in case that LEFs are pushed back when they encounter other LEFs.", type=bool, default='False', val='False'),
148
149
  Arg('N_STEPS', help="Number of Monte Carlo steps.", type=int, default='40000', val='40000'),
149
150
  Arg('N_LEF', help="Number of loop extrusion factors (condensins and cohesins). If you leave it empty it would add for LEFs twice the number of CTCFs.", type=int, default='', val=''),
150
151
  Arg('N_LEF2', help="Number of second family loop extrusion factors, in case that you would like to simulate a second group with different speed.", type=int, default='0', val='0'),
@@ -156,6 +157,7 @@ args = ListOfArgs([
156
157
  Arg('FOLDING_COEFF', help="Folding coefficient.", type=float, default='1.0', val='1.0'),
157
158
  Arg('FOLDING_COEFF2', help="Folding coefficient for the second family of LEFs.", type=float, default='0.0', val='0.0'),
158
159
  Arg('CROSS_COEFF', help="LEF crossing coefficient.", type=float, default='1.0', val='1.0'),
160
+ Arg('CROSS_LOOP', help="It true if the penalty is applied for situations mi<mj<ni<nj and mi=nj, and false if it is applied only for mi=nj.", type=bool, default='True', val='True'),
159
161
  Arg('BIND_COEFF', help="CTCF binding coefficient.", type=float, default='1.0', val='1.0'),
160
162
  Arg('SAVE_PLOTS', help="It should be true in case that you would like to save diagnostic plots. In case that you use small MC_STEP or large N_STEPS is better to mark it as False.", type=bool, default='True', val='True'),
161
163
  Arg('SAVE_MDT', help="In case that you would liketo save metadata of the stochastic simulation.", type=bool, default='True', val='True'),
@@ -168,7 +170,8 @@ args = ListOfArgs([
168
170
  Arg('ANGLE_FF_STRENGTH', help="Angle force strength.", type=float, default='200.0', val='200.0'),
169
171
  Arg('LE_FF_LENGTH', help="Equillibrium distance of loop forces.", type=float, default='0.1', val='0.1'),
170
172
  Arg('LE_FF_STRENGTH', help="Interaction Strength of loop forces.", type=float, default='50000.0', val='50000.0'),
171
- Arg('EV_FF_STRENGTH', help="Excluded-volume strength.", type=float, default='10.0', val='10.0'),
173
+ Arg('EV_P', help="Probability that randomly excluded volume may be disabled.", type=float, default='0.0', val='0.0'),
174
+ Arg('EV_FF_STRENGTH', help="Excluded-volume strength.", type=float, default='100.0', val='100.0'),
172
175
  Arg('EV_FF_POWER', help="Excluded-volume power.", type=float, default='3.0', val='3.0'),
173
176
  Arg('FRICTION',help='Friction coefficient of the Langevin integrator.',type=float, default='0.1', val='0.1'),
174
177
  Arg('TOLERANCE', help="Tolerance that works as stopping condition for energy minimization.", type=float, default='0.001', val='0.001'),
@@ -12,20 +12,11 @@ from sys import stdout
12
12
  from mdtraj.reporters import HDF5Reporter
13
13
  from scipy import ndimage
14
14
  from openmm.app import PDBFile, PDBxFile, ForceField, Simulation, PDBReporter, PDBxReporter, DCDReporter, StateDataReporter, CharmmPsfFile
15
- import importlib.resources
16
15
  from .utils import *
17
16
  from .initial_structures import *
18
17
 
19
- # Dynamically set the default path to the XML file in the package
20
- try:
21
- with importlib.resources.path('loopsage.forcefields', 'classic_sm_ff.xml') as default_xml_path:
22
- default_xml_path = str(default_xml_path)
23
- except FileNotFoundError:
24
- # If running in a development setup without the resource installed, fallback to a relative path
25
- default_xml_path = 'loopsage/forcefields/classic_sm_ff.xml'
26
-
27
18
  class MD_LE:
28
- def __init__(self,M,N,N_beads,burnin,MC_step,path=None,platform='CPU',angle_ff_strength=200,le_distance=0.1,le_ff_strength=50000.0,ev_ff_strength=10.0,ev_ff_power=3.0,tolerance=0.001):
19
+ def __init__(self,M,N,N_beads,path=None,platform='CPU',angle_ff_strength=200,le_distance=0.1,le_ff_strength=50000.0,ev_ff_strength=100.0,ev_ff_power=3.0,tolerance=0.001):
29
20
  '''
30
21
  M, N (np arrays): Position matrix of two legs of cohesin m,n.
31
22
  Rows represent loops/cohesins and columns represent time
@@ -35,8 +26,8 @@ class MD_LE:
35
26
  '''
36
27
  self.M, self.N = M, N
37
28
  self.N_coh, self.N_steps = M.shape
38
- self.N_beads, self.step, self.burnin = N_beads, MC_step, burnin//MC_step
39
- self.path = path
29
+ self.N_beads = N_beads
30
+ self.path = path if path!=None else make_folder('../output')
40
31
  self.platform = platform
41
32
  self.angle_ff_strength = angle_ff_strength
42
33
  self.le_distance = le_distance
@@ -45,15 +36,12 @@ class MD_LE:
45
36
  self.ev_ff_power = ev_ff_power
46
37
  self.tolerance = tolerance
47
38
 
48
- def run_pipeline(self,run_MD=True, friction=0.1, integrator_step=100 * mm.unit.femtosecond, sim_step=1000, ff_path=default_xml_path, temperature=310, plots=False):
39
+ def run_pipeline(self,run_MD=True, friction=0.1, integrator_step=10 * mm.unit.femtosecond, sim_step=100, ff_path = 'forcefields/classic_sm_ff.xml',temperature=310, p_ev=0, plots=False):
49
40
  '''
50
41
  This is the basic function that runs the molecular simulation pipeline.
51
42
  '''
52
43
  # Parameters
53
- self.angle_ff_strength=200
54
- self.le_distance=0.1
55
- self.le_ff_strength=300000.0
56
- self.tolerance=0.001
44
+ self.p_ev = p_ev
57
45
 
58
46
  # Define initial structure
59
47
  print('Building initial structure...')
@@ -91,15 +79,17 @@ class MD_LE:
91
79
  start = time.time()
92
80
  heats = list()
93
81
  for i in range(1,self.N_steps):
82
+ # Define probabilities that EV would be disabled
83
+ if p_ev>0: self.ps_ev = np.random.rand(self.N_beads)
84
+ # Change forcefield
94
85
  self.change_loop(i)
86
+ self.change_ev()
95
87
  self.simulation.step(sim_step)
96
- if i>=self.burnin:
97
- self.state = self.simulation.context.getState(getPositions=True)
98
- PDBxFile.writeFile(pdb.topology, self.state.getPositions(), open(self.path+f'/ensemble/MDLE_{i-self.burnin+1}.cif', 'w'))
99
- heats.append(get_heatmap(self.state.getPositions(),save=False))
88
+ self.state = self.simulation.context.getState(getPositions=True)
89
+ PDBxFile.writeFile(pdb.topology, self.state.getPositions(), open(self.path+f'/ensemble/MDLE_{i}.cif', 'w'))
90
+ heats.append(get_heatmap(self.state.getPositions(),save=False))
100
91
  end = time.time()
101
92
  elapsed = end - start
102
-
103
93
  print(f'Everything is done! Simulation finished succesfully!\nMD finished in {elapsed/60:.2f} minutes.\n')
104
94
 
105
95
  self.avg_heat = np.average(heats,axis=0)
@@ -111,6 +101,12 @@ class MD_LE:
111
101
  self.plot_heat(self.avg_heat,f'/plots/avg_heatmap.svg')
112
102
  self.plot_heat(self.std_heat,f'/plots/std_heatmap.svg')
113
103
  return self.avg_heat
104
+
105
+ def change_ev(self):
106
+ ev_strength = (self.ps_ev>self.p_ev).astype(int)*np.sqrt(self.ev_ff_strength) if self.p_ev>0 else np.sqrt(self.ev_ff_strength)*np.ones(self.N_beads)
107
+ for n in range(self.N_beads):
108
+ self.ev_force.setParticleParameters(n,[ev_strength[n],0.05])
109
+ self.ev_force.updateParametersInContext(self.simulation.context)
114
110
 
115
111
  def change_loop(self,i):
116
112
  force_idx = self.system.getNumForces()-1
@@ -121,12 +117,12 @@ class MD_LE:
121
117
 
122
118
  def add_evforce(self):
123
119
  'Leonard-Jones potential for excluded volume'
124
- self.ev_force = mm.CustomNonbondedForce(f'epsilon*((sigma1+sigma2)/(r+r_small))^{self.ev_ff_power}')
125
- self.ev_force.addGlobalParameter('epsilon', defaultValue=self.ev_ff_strength)
126
- self.ev_force.addGlobalParameter('r_small', defaultValue=0.01)
120
+ self.ev_force = mm.CustomNonbondedForce(f'(epsilon1*epsilon2*(sigma1*sigma2)/(r+r_small))^{self.ev_ff_power}')
121
+ self.ev_force.addGlobalParameter('r_small', defaultValue=0.1)
127
122
  self.ev_force.addPerParticleParameter('sigma')
123
+ self.ev_force.addPerParticleParameter('epsilon')
128
124
  for i in range(self.N_beads):
129
- self.ev_force.addParticle([0.05])
125
+ self.ev_force.addParticle([np.sqrt(self.ev_ff_strength),0.05])
130
126
  self.system.addForce(self.ev_force)
131
127
 
132
128
  def add_bonds(self):
@@ -173,7 +169,7 @@ class MD_LE:
173
169
 
174
170
  def main():
175
171
  # A potential example
176
- M = np.load('/home/skorsak/Dropbox/LoopSage/files/region_[48100000,48700000]_chr3/Annealing_Nbeads500_ncoh50/Ms.npy')
177
- N = np.load('/home/skorsak/Dropbox/LoopSage/files/region_[48100000,48700000]_chr3/Annealing_Nbeads500_ncoh50/Ns.npy')
178
- md = MD_LE(4*M,4*N,2000,5,1)
179
- md.run_pipeline()
172
+ M = np.load('/home/skorsak/Projects/mine/RepliSage/output/other/Ms.npy')
173
+ N = np.load('/home/skorsak/Projects/mine/RepliSage/output/other/Ns.npy')
174
+ md = MD_LE(M,N,np.max(N)+1,platform='CUDA')
175
+ md.run_pipeline()
@@ -70,11 +70,11 @@ def main():
70
70
 
71
71
  # Run Simulation
72
72
  sim = StochasticSimulation(region,chrom,bedpe_file,out_dir=output_name,N_beads=N_beads,N_lef=N_lef,N_lef2=N_lef2)
73
- Es, Ms, Ns, Bs, Ks, Fs, ufs = sim.run_energy_minimization(N_steps,MC_step,burnin,T,T_min,mode=mode,viz=args.SAVE_PLOTS,save=args.SAVE_MDT,lef_rw=args.LEF_RW,f=f,f2=f2,b=b,kappa=kappa)
73
+ Es, Ms, Ns, Bs, Ks, Fs, ufs = sim.run_energy_minimization(N_steps,MC_step,burnin,T,T_min,mode=mode,viz=args.SAVE_PLOTS,save=args.SAVE_MDT,lef_rw=args.LEF_RW,f=f,f2=f2,b=b,kappa=kappa,lef_drift=args.LEF_DRIFT,cross_loop=args.CROSS_LOOP)
74
74
  if args.SIMULATION_TYPE=='EM':
75
75
  sim.run_EM(args.PLATFORM,args.ANGLE_FF_STRENGTH,args.LE_FF_LENGTH,args.LE_FF_STRENGTH,args.EV_FF_STRENGTH,args.EV_FF_POWER,args.TOLERANCE,args.FRICTION,args.INTEGRATOR_STEP,args.SIM_TEMP,args.VIZ_HEATS,args.FORCEFIELD_PATH)
76
76
  elif args.SIMULATION_TYPE=='MD':
77
- sim.run_MD(args.PLATFORM,args.ANGLE_FF_STRENGTH,args.LE_FF_LENGTH,args.LE_FF_STRENGTH,args.EV_FF_STRENGTH,args.EV_FF_POWER,args.TOLERANCE,args.FRICTION,args.INTEGRATOR_STEP,args.SIM_TEMP,args.SIM_STEP,args.VIZ_HEATS,args.FORCEFIELD_PATH)
77
+ sim.run_MD(args.PLATFORM,args.ANGLE_FF_STRENGTH,args.LE_FF_LENGTH,args.LE_FF_STRENGTH,args.EV_FF_STRENGTH,args.EV_FF_POWER,args.TOLERANCE,args.FRICTION,args.INTEGRATOR_STEP,args.SIM_TEMP,args.SIM_STEP,args.VIZ_HEATS,args.FORCEFIELD_PATH,args.EV_P)
78
78
  elif args.SIMULATION_TYPE==None:
79
79
  print('\n3D simulation did not run because it was not specified. Please specify argument SIMULATION_TYPE as EM or MD.')
80
80
  else:
@@ -5,6 +5,7 @@ import random as rd
5
5
  import scipy.stats as stats
6
6
  from numba import njit, prange
7
7
  from tqdm import tqdm
8
+ import importlib.resources
8
9
 
9
10
  # scipy
10
11
  from scipy.stats import norm
@@ -16,14 +17,23 @@ from .plots import *
16
17
  from .md import *
17
18
  from .em import *
18
19
 
20
+ # Dynamically set the default path to the XML file in the package
21
+ try:
22
+ with importlib.resources.path('loopsage.forcefields', 'classic_sm_ff.xml') as default_xml_path:
23
+ default_xml_path = str(default_xml_path)
24
+ except FileNotFoundError:
25
+ # If running in a development setup without the resource installed, fallback to a relative path
26
+ default_xml_path = 'loopsage/forcefields/classic_sm_ff.xml'
27
+
19
28
  @njit
20
- def Kappa(mi,ni,mj,nj):
29
+ def Kappa(mi,ni,mj,nj,cross_loop=True):
21
30
  '''
22
31
  Computes the crossing function of LoopSage.
23
32
  '''
24
33
  k=0.0
25
- if mi<mj and mj<ni and ni<nj: k+=1 # np.abs(ni-mj)+1
26
- if mj<mi and mi<nj and nj<ni: k+=1 # np.abs(nj-mi)+1
34
+ if cross_loop:
35
+ if mi<mj and mj<ni and ni<nj: k+=1 # np.abs(ni-mj)+1
36
+ if mj<mi and mi<nj and nj<ni: k+=1 # np.abs(nj-mi)+1
27
37
  if mj==ni or mi==nj or ni==nj or mi==mj: k+=1
28
38
  return k
29
39
 
@@ -37,14 +47,14 @@ def E_bind(L, R, ms, ns, bind_norm):
37
47
  return E_b
38
48
 
39
49
  @njit
40
- def E_cross(ms, ns, k_norm):
50
+ def E_cross(ms, ns, k_norm, cross_loop):
41
51
  '''
42
52
  The crossing energy.
43
53
  '''
44
54
  crossing = 0.0
45
55
  for i in prange(len(ms)):
46
56
  for j in range(i + 1, len(ms)):
47
- crossing += Kappa(ms[i], ns[i], ms[j], ns[j])
57
+ crossing += Kappa(ms[i], ns[i], ms[j], ns[j], cross_loop)
48
58
  return k_norm * crossing
49
59
 
50
60
  @njit
@@ -56,12 +66,12 @@ def E_fold(ms, ns, fold_norm):
56
66
  return fold_norm * folding
57
67
 
58
68
  @njit
59
- def get_E(L, R, bind_norm, fold_norm, fold_norm2, k_norm, ms, ns, N_lef, N_lef2):
69
+ def get_E(L, R, bind_norm, fold_norm, fold_norm2, k_norm, ms, ns, N_lef, N_lef2, cross_loop):
60
70
  ''''
61
71
  The total energy.
62
72
  '''
63
- energy = E_bind(L, R, ms, ns, bind_norm) + E_cross(ms, ns, k_norm) + E_fold(ms, ns, fold_norm)
64
- if fold_norm2!=0: energy += E_fold(ms[N_lef:N_lef+N_lef2],ns[N_lef:N_lef+N_lef2],fold_norm2)
73
+ energy = E_bind(L, R, ms, ns, bind_norm) + E_cross(ms, ns, k_norm, cross_loop) + E_fold(ms, ns, fold_norm)
74
+ if fold_norm2!=0: energy += E_fold(ms[N_lef:N_lef+N_lef2],ns[N_lef:N_lef+N_lef2], fold_norm2)
65
75
  return energy
66
76
 
67
77
  @njit
@@ -79,19 +89,19 @@ def get_dE_fold(fold_norm,ms,ns,m_new,n_new,idx):
79
89
  return fold_norm*(np.log(n_new-m_new)-np.log(ns[idx]-ms[idx]))
80
90
 
81
91
  @njit
82
- def get_dE_cross(ms, ns, m_new, n_new, idx, k_norm):
92
+ def get_dE_cross(ms, ns, m_new, n_new, idx, k_norm, cross_loop):
83
93
  '''
84
94
  Energy difference for crossing energy.
85
95
  '''
86
96
  K1, K2 = 0, 0
87
97
  for i in prange(len(ms)):
88
98
  if i != idx:
89
- K1 += Kappa(ms[idx], ns[idx], ms[i], ns[i])
90
- K2 += Kappa(m_new, n_new, ms[i], ns[i])
99
+ K1 += Kappa(ms[idx], ns[idx], ms[i], ns[i], cross_loop)
100
+ K2 += Kappa(m_new, n_new, ms[i], ns[i], cross_loop)
91
101
  return k_norm * (K2 - K1)
92
102
 
93
103
  @njit
94
- def get_dE(L, R, bind_norm, fold_norm, fold_norm2, k_norm, ms, ns, m_new, n_new, idx, N_lef, N_lef2):
104
+ def get_dE(L, R, bind_norm, fold_norm, fold_norm2, k_norm, ms, ns, m_new, n_new, idx, N_lef, N_lef2, cross_loop):
95
105
  '''
96
106
  Total energy difference.
97
107
  '''
@@ -99,9 +109,9 @@ def get_dE(L, R, bind_norm, fold_norm, fold_norm2, k_norm, ms, ns, m_new, n_new,
99
109
  if idx<N_lef:
100
110
  dE += get_dE_fold(fold_norm,ms[:N_lef],ns[:N_lef],m_new,n_new,idx)
101
111
  else:
102
- dE += get_dE_fold(fold_norm2,ms[N_lef:N_lef+N_lef2],ns[N_lef:N_lef2],m_new,n_new,idx-N_lef)
112
+ dE += get_dE_fold(fold_norm2,ms[N_lef:N_lef+N_lef2],ns[N_lef:N_lef+N_lef2],m_new,n_new,idx-N_lef)
103
113
  dE += get_dE_bind(L, R, bind_norm, ms, ns, m_new, n_new, idx)
104
- dE += get_dE_cross(ms, ns, m_new, n_new, idx, k_norm)
114
+ dE += get_dE_cross(ms, ns, m_new, n_new, idx, k_norm, cross_loop)
105
115
  return dE
106
116
 
107
117
  @njit
@@ -114,7 +124,7 @@ def unbind_bind(N_beads):
114
124
  return int(m_new), int(n_new)
115
125
 
116
126
  @njit
117
- def slide(m_old, n_old, N_beads, rw=True):
127
+ def slide(m_old, n_old, ms, ns, N_beads, rw=True, drift=True):
118
128
  '''
119
129
  Sliding Monte-Carlo step.
120
130
  '''
@@ -122,7 +132,11 @@ def slide(m_old, n_old, N_beads, rw=True):
122
132
  r1 = np.random.choice(choices) if rw else -1
123
133
  r2 = np.random.choice(choices) if rw else 1
124
134
  m_new = m_old + r1 if m_old + r1>=0 else 0
135
+ if np.any(ns==m_new) and drift and m_old-r1<n_old-1:
136
+ m_new = m_old - r1 if m_old + r1>=0 else 0
125
137
  n_new = n_old + r2 if n_old + r2<N_beads else N_beads-1
138
+ if np.any(ms==n_new) and drift and n_old-r2>m_old+1:
139
+ n_new = n_old - r2 if n_old + r2>=0 else 0
126
140
  return int(m_new), int(n_new)
127
141
 
128
142
  @njit
@@ -148,14 +162,14 @@ def initialize(N_beads,N_lef):
148
162
  return ms, ns
149
163
 
150
164
  @njit
151
- def run_simulation(N_beads,N_steps,MC_step,burnin,T,T_min,fold_norm,fold_norm2,bind_norm,k_norm,N_lef,N_lef2,L,R,mode,lef_rw=True):
165
+ def run_simulation(N_beads,N_steps,MC_step,burnin,T,T_min,fold_norm,fold_norm2,bind_norm,k_norm,N_lef,N_lef2,L,R,mode,lef_rw=True,lef_drift=True,cross_loop=True):
152
166
  '''
153
167
  Runs the Monte Carlo simulation.
154
168
  '''
155
169
  Ti = T
156
170
  bi = burnin//MC_step
157
171
  ms, ns = initialize(N_beads,N_lef+N_lef2)
158
- E = get_E(L, R, bind_norm, fold_norm, fold_norm2, k_norm, ms, ns, N_lef, N_lef2)
172
+ E = get_E(L, R, bind_norm, fold_norm, fold_norm2, k_norm, ms, ns, N_lef, N_lef2, cross_loop)
159
173
  Es,Ks,Fs,Bs,ufs = np.zeros(N_steps//MC_step, dtype=np.float64),np.zeros(N_steps//MC_step, dtype=np.float64),np.zeros(N_steps//MC_step, dtype=np.float64),np.zeros(N_steps//MC_step, dtype=np.float64),np.zeros(N_steps//MC_step, dtype=np.float64)
160
174
  Ms, Ns = np.zeros((N_lef+N_lef2,N_steps//MC_step), dtype=np.int64), np.zeros((N_lef+N_lef2,N_steps//MC_step), dtype=np.int64)
161
175
 
@@ -167,10 +181,10 @@ def run_simulation(N_beads,N_steps,MC_step,burnin,T,T_min,fold_norm,fold_norm2,b
167
181
  if r==0:
168
182
  m_new, n_new = unbind_bind(N_beads)
169
183
  else:
170
- m_new, n_new = slide(ms[j],ns[j],N_beads,lef_rw)
184
+ m_new, n_new = slide(ms[j],ns[j],ms,ns,N_beads,lef_rw,lef_drift)
171
185
 
172
186
  # Compute energy difference
173
- dE = get_dE(L, R, bind_norm, fold_norm, fold_norm2, k_norm, ms, ns, m_new, n_new, j, N_lef, N_lef2)
187
+ dE = get_dE(L, R, bind_norm, fold_norm, fold_norm2, k_norm, ms, ns, m_new, n_new, j, N_lef, N_lef2, cross_loop)
174
188
 
175
189
  if dE <= 0 or np.exp(-dE/Ti) > np.random.rand():
176
190
  ms[j], ns[j] = m_new, n_new
@@ -183,7 +197,7 @@ def run_simulation(N_beads,N_steps,MC_step,burnin,T,T_min,fold_norm,fold_norm2,b
183
197
  if i%MC_step==0:
184
198
  ufs[i//MC_step] = unfolding_metric(ms,ns,N_beads)
185
199
  Es[i//MC_step] = E
186
- Ks[i//MC_step] = E_cross(ms,ns,k_norm)
200
+ Ks[i//MC_step] = E_cross(ms,ns,k_norm,cross_loop)
187
201
  Fs[i//MC_step] = E_fold(ms,ns,fold_norm)
188
202
  Bs[i//MC_step] = E_bind(L,R,ms,ns,bind_norm)
189
203
  return Ms, Ns, Es, Ks, Fs, Bs, ufs
@@ -213,7 +227,7 @@ class StochasticSimulation:
213
227
  print('Number of LEFs:',self.N_lef+self.N_lef2)
214
228
  self.path = make_folder(out_dir)
215
229
 
216
- def run_energy_minimization(self,N_steps,MC_step,burnin,T=1,T_min=0,mode='Metropolis',viz=False,save=False, f=1.0, f2=0.0, b=1.0, kappa=1.0, lef_rw=True):
230
+ def run_energy_minimization(self,N_steps,MC_step,burnin,T=1,T_min=0,mode='Metropolis',viz=False,save=False, f=1.0, f2=0.0, b=1.0, kappa=1.0, lef_rw=True, lef_drift=True, cross_loop=True):
217
231
  '''
218
232
  Implementation of the stochastic Monte Carlo simulation.
219
233
 
@@ -233,7 +247,7 @@ class StochasticSimulation:
233
247
  print('\nRunning simulation (with parallelization across CPU cores)...')
234
248
  start = time.time()
235
249
  self.burnin = burnin
236
- self.Ms, self.Ns, self.Es, self.Ks, self.Fs, self.Bs, self.ufs = run_simulation(self.N_beads,N_steps,MC_step,burnin,T,T_min,fold_norm,fold_norm2,bind_norm,k_norm,self.N_lef,self.N_lef2,self.L,self.R,mode,lef_rw)
250
+ self.Ms, self.Ns, self.Es, self.Ks, self.Fs, self.Bs, self.ufs = run_simulation(self.N_beads,N_steps,MC_step,burnin,T,T_min,fold_norm,fold_norm2,bind_norm,k_norm,self.N_lef,self.N_lef2,self.L,self.R,mode,lef_rw,lef_drift,cross_loop)
237
251
  end = time.time()
238
252
  elapsed = end - start
239
253
  print(f'Computation finished succesfully in {elapsed//3600:.0f} hours, {elapsed%3600//60:.0f} minutes and {elapsed%60:.0f} seconds.')
@@ -242,13 +256,13 @@ class StochasticSimulation:
242
256
  if save:
243
257
  f = open(self.path+'/other/info.txt', "w")
244
258
  f.write(f'Number of beads {self.N_beads}.\n')
245
- f.write(f'Number of cohesins {self.N_lef}. Number of CTCFs {self.N_CTCF}.\n')
259
+ f.write(f'Number of cohesins {self.N_lef}. Number of cohesins in second family {self.N_lef2}. Number of CTCFs {self.N_CTCF}. \n')
246
260
  f.write(f'Bedpe file for CTCF binding is {self.bedpe_file}.\n')
247
261
  f.write(f'Initial temperature {T}. Minimum temperature {T_min}.\n')
248
262
  f.write(f'Monte Carlo optimization method: {mode}.\n')
249
263
  f.write(f'Monte Carlo steps {N_steps}. Sampling frequency {MC_step}. Burnin period {burnin}.\n')
250
264
  f.write(f'Crossing energy in equilibrium is {np.average(self.Ks[burnin//MC_step:]):.2f}. Crossing coefficient kappa={kappa}.\n')
251
- f.write(f'Folding energy in equilibrium is {np.average(self.Fs[burnin//MC_step:]):.2f}. Folding coefficient f={f}.\n')
265
+ f.write(f'Folding energy in equilibrium is {np.average(self.Fs[burnin//MC_step:]):.2f}. Folding coefficient f={f}. Folding coefficient for the second family f2={f2}\n')
252
266
  f.write(f'Binding energy in equilibrium is {np.average(self.Bs[burnin//MC_step:]):.2f}. Binding coefficient b={b}.\n')
253
267
  f.write(f'Energy at equillibrium: {np.average(self.Es[burnin//MC_step:]):.2f}.\n')
254
268
  f.close()
@@ -274,14 +288,14 @@ class StochasticSimulation:
274
288
  self.N_CTCF = np.max([np.count_nonzero(self.L),np.count_nonzero(self.R)])
275
289
  print('Number of CTCF:',self.N_CTCF)
276
290
 
277
- def run_EM(self,platform='CPU',angle_ff_strength=200,le_distance=0.0,le_ff_strength=300000.0,ev_ff_strength=10.0,ev_ff_power=3.0,tolerance=0.001,friction=0.1,integrator_step=100*mm.unit.femtosecond,temperature=310,save_plots=True,ff_path='forcefields/classic_sm_ff.xml'):
291
+ def run_EM(self,platform='CPU',angle_ff_strength=200,le_distance=0.0,le_ff_strength=300000.0,ev_ff_strength=10.0,ev_ff_power=3.0,tolerance=0.001,friction=0.1,integrator_step=100*mm.unit.femtosecond,temperature=310,save_plots=True,ff_path=default_xml_path):
278
292
  em = EM_LE(self.Ms,self.Ns,self.N_beads,self.burnin,self.MC_step,self.path,platform,angle_ff_strength,le_distance,le_ff_strength,ev_ff_strength,ev_ff_power,tolerance)
279
293
  sim_heat = em.run_pipeline(plots=save_plots,friction=friction,integrator_step=integrator_step,temperature=temperature,ff_path=ff_path)
280
294
  corr_exp_heat(sim_heat,self.bedpe_file,self.region,self.chrom,self.N_beads,self.path)
281
295
 
282
- def run_MD(self,platform='CPU',angle_ff_strength=200,le_distance=0.0,le_ff_strength=300000.0,ev_ff_strength=10.0,ev_ff_power=3.0,tolerance=0.001,friction=0.1,integrator_step=100*mm.unit.femtosecond,temperature=310,sim_step=1000,save_plots=True,ff_path='forcefields/classic_sm_ff.xml'):
283
- md = MD_LE(self.Ms,self.Ns,self.N_beads,self.burnin,self.MC_step,self.path,platform,angle_ff_strength,le_distance,le_ff_strength,ev_ff_strength,ev_ff_power,tolerance)
284
- sim_heat = md.run_pipeline(plots=save_plots,sim_step=sim_step,friction=friction,integrator_step=integrator_step,temperature=temperature,ff_path=ff_path)
296
+ def run_MD(self,platform='CPU',angle_ff_strength=200,le_distance=0.0,le_ff_strength=300000.0,ev_ff_strength=10.0,ev_ff_power=3.0,tolerance=0.001,friction=0.1,integrator_step=100*mm.unit.femtosecond,temperature=310,sim_step=1000,save_plots=True,ff_path=default_xml_path,p_ev=0):
297
+ md = MD_LE(self.Ms,self.Ns,self.N_beads,self.path,platform,angle_ff_strength,le_distance,le_ff_strength,ev_ff_strength,ev_ff_power,tolerance)
298
+ sim_heat = md.run_pipeline(plots=save_plots,sim_step=sim_step,friction=friction,integrator_step=integrator_step,temperature=temperature,ff_path=ff_path,p_ev=p_ev)
285
299
  corr_exp_heat(sim_heat,self.bedpe_file,self.region,self.chrom,self.N_beads,self.path)
286
300
 
287
301
  def main():
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.2
2
2
  Name: pyLoopSage
3
- Version: 1.0.16
3
+ Version: 1.0.18
4
4
  Summary: An energy-based stochastic model of loop extrusion in chromatin.
5
5
  Home-page: https://github.com/SFGLab/pyLoopSage
6
6
  Author: Sebastian Korsak
@@ -31,6 +31,16 @@ Requires-Dist: statsmodels
31
31
  Requires-Dist: imageio
32
32
  Requires-Dist: imageio[ffmpeg]
33
33
  Requires-Dist: pillow
34
+ Dynamic: author
35
+ Dynamic: author-email
36
+ Dynamic: classifier
37
+ Dynamic: description
38
+ Dynamic: description-content-type
39
+ Dynamic: home-page
40
+ Dynamic: license
41
+ Dynamic: requires-dist
42
+ Dynamic: requires-python
43
+ Dynamic: summary
34
44
 
35
45
  # pyLoopSage
36
46
  Updated version of the stochastic loop extrusion model: LoopSage with capability to run incredibly fast, parallelized across CPU cores. This package is even more user-friendly and it can be installed via PyPI.
@@ -44,11 +54,6 @@ Updated version of the stochastic loop extrusion model: LoopSage with capability
44
54
  - Visualization functions.
45
55
  - Capability to run form terminal with a simple command `loopsage -c config.ini`.
46
56
 
47
- ## Publication
48
- Please cite the method paper in case that you would like to use this model for your work,
49
-
50
- * Korsak, Sevastianos, and Dariusz Plewczynski. "LoopSage: An energy-based Monte Carlo approach for the loop extrusion modelling of chromatin." Methods (2024).
51
-
52
57
  ## The model
53
58
 
54
59
  ### Stochastic Simulation
@@ -74,7 +79,7 @@ These $L(\cdot), R(\cdot)$ functions are two functions that define the binding p
74
79
 
75
80
  $$c_{\text{fold}}=-\dfrac{N_{\text{beads}}f}{N_{\text{lef}}\log(N_{\text{beads}}/N_{\text{lef}})},\quad c_{\text{bind}}=-\dfrac{N_{\text{beads}}b}{\sum_i \left(L(m_i)+R(n_i)\right)},\quad c_{\text{cross}}=\kappa \times 10^4.$$
76
81
 
77
- The parameters are defined in such a way that when $f=b=\kappa=1$, the three terms of the stochastic energy are balanced.
82
+ The parameters are defined in such a way that when $f=b=\kappa=1$, the three terms of the stochastic energy are balanced. To clarrify, this parametrization is slightly different than this of the original paper. We multiply with $N_{\text{beads}}$, so as to keep the input parameters $f,b,\kappa$ simpler close to 1. Therefore, a value $f=0.1$ leads to unfolded structures, and a value $f=2$ it leads to very fast propagating long loops.
78
83
 
79
84
  And the energy difference can be expressed as the energy difference of each term,
80
85
 
@@ -113,7 +118,7 @@ For the implementation of this model in python, we used OpenMM and CUDA accelera
113
118
  In general the user can run simulation in two different ways:
114
119
 
115
120
  1. **Energy minimization (EM)**: It means that for each sample of cohesin positions $C_{t_i}=(m_j(t_i),n_j(t_i))$ start from a different initial structure (usually 3D random walk) and we apply the forcefield. For each structure we start from a different initial condition. In general, it is suggested to run the model in this way because it is faster, less prone to errors and the structures are not correlated to each other.
116
- 2. **Molecular Dynamics (MD)**: In this case we have only one initial structure, we minimize the energy according to the forcefield only once and then we run a molecular dynamics simulation over time. This creates a continuous trajectory of structures, and it is cool for visualization pruposes. Novertheness, it is not suggested because it is more prone to errors and can lead to autocorrelated structures. We suggest our users to set the power of excluded volume $\alpha=1$ for the purposes of MD simulation. However, this depends on the research interests of the user.
121
+ 2. **Molecular Dynamics (MD)**: In this case we have only one initial structure, we minimize the energy according to the forcefield only once and then we run a molecular dynamics simulation over time. This creates a continuous trajectory of structures, and it is cool for visualization pruposes. It is also biophysically more correct, in the sense that loop extrusion should be time-dependent, and the structure at time $t_i$ has to me correlated with structures at time $t_{i\pm1}$. It is a little bit more prone to error, and you may need to change the simulation frequence and step in case of instability (smaller frequency and more steps to stabilize it).
117
122
 
118
123
  ## Installation
119
124
 
@@ -262,3 +267,55 @@ In the output folder there are another three subfolders:
262
267
  An example, illustrated with Chimera software, simulated trajectory of structures after running Simulated Annealing and molecular dynamics.
263
268
 
264
269
  ![siman_traj_GitHub](https://github.com/SFGLab/LoopSage/assets/49608786/c6626641-f709-46e0-b01b-42566b1829ef)
270
+
271
+ ### Long-table of LoopSage arguments
272
+
273
+ | Argument Name | Description | Type | Default Value |
274
+ |------------------------|-----------------------------------------------------------------------------------------------------------------|------------|---------------------|
275
+ | PLATFORM | Name of the platform. Available choices: CPU, CUDA, OpenCL | str | CPU |
276
+ | DEVICE | Device index for CUDA or OpenCL (count from 0) | str | None |
277
+ | N_BEADS | Number of Simulation Beads. | int | None |
278
+ | BEDPE_PATH | A .bedpe file path with loops. It is required. | str | None |
279
+ | OUT_PATH | Output folder name. | str | ../results |
280
+ | REGION_START | Starting region coordinate. | int | None |
281
+ | REGION_END | Ending region coordinate. | int | None |
282
+ | CHROM | Chromosome that corresponds to the modeling region of interest. | str | None |
283
+ | LEF_RW | True if cohesins slide as a random walk instead of one direction. | bool | True |
284
+ | LEF_DRIFT | True if LEFs are pushed back when they encounter other LEFs. | bool | False |
285
+ | N_STEPS | Number of Monte Carlo steps. | int | 40000 |
286
+ | N_LEF | Number of loop extrusion factors. | int | None |
287
+ | N_LEF2 | Number of second family loop extrusion factors. | int | 0 |
288
+ | MC_STEP | Monte Carlo frequency to avoid autocorrelated ensembles. | int | 200 |
289
+ | BURNIN | Burn-in period (steps before equilibrium). | int | 1000 |
290
+ | T_INIT | Initial Temperature of the Stochastic Model. | float | 2.0 |
291
+ | T_FINAL | Final Temperature of the Stochastic Model. | float | 1.0 |
292
+ | METHOD | Stochastic modeling method (Metropolis or Simulated Annealing). | str | 'Annealing' |
293
+ | FOLDING_COEFF | Folding coefficient. | float | 1.0 |
294
+ | FOLDING_COEFF2 | Folding coefficient for the second family of LEFs. | float | 0.0 |
295
+ | CROSS_COEFF | LEF crossing coefficient. | float | 1.0 |
296
+ | CROSS_LOOP | True if the penalty is applied when mi<mj<ni<nj. False if it applies only when mj=ni. When false it is better to enable LEF_DRIFT as well. | bool |True |
297
+ | BIND_COEFF | CTCF binding coefficient. | float | 1.0 |
298
+ | SAVE_PLOTS | True to save diagnostic plots. | bool | True |
299
+ | SAVE_MDT | True to save metadata of the stochastic simulation. | bool | True |
300
+ | INITIAL_STRUCTURE_TYPE | Choose from: rw, confined_rw, self_avoiding_rw, helix, circle, spiral, sphere. | str | rw |
301
+ | SIMULATION_TYPE | Either EM (energy minimizations) or MD (molecular dynamics). | str | None |
302
+ | INTEGRATOR_STEP | Step of the integrator. | Quantity | 100 femtosecond |
303
+ | FORCEFIELD_PATH | Path to XML file with forcefield. | str | default_xml_path |
304
+ | ANGLE_FF_STRENGTH | Angle force strength. | float | 200.0 |
305
+ | LE_FF_LENGTH | Equilibrium distance of loop forces. | float | 0.1 |
306
+ | LE_FF_STRENGTH | Interaction Strength of loop forces. | float | 50000.0 |
307
+ | EV_P | Probability that excluded volume is disabled. Enable it only in case of topoisomerase activity simulation. | float | 0.0 |
308
+ | EV_FF_STRENGTH | Excluded-volume strength. | float | 100.0 |
309
+ | EV_FF_POWER | Excluded-volume power. | float | 3.0 |
310
+ | FRICTION | Friction coefficient of the Langevin integrator. | float | 0.1 |
311
+ | TOLERANCE | Stopping condition for energy minimization. | float | 0.001 |
312
+ | VIZ_HEATS | True to visualize the output average heatmap. | bool | True |
313
+ | SIM_TEMP | Temperature of the 3D simulation (EM or MD). | Quantity | 310 kelvin |
314
+ | SIM_STEP | Amount of simulation steps for loop force adjustments. | int | 1000 |
315
+
316
+
317
+ ## Citation
318
+ Please cite the method and biological paper in case that you would like to use this model for your work,
319
+
320
+ * Korsak, Sevastianos, and Dariusz Plewczynski. "LoopSage: An energy-based Monte Carlo approach for the loop extrusion modelling of chromatin." Methods (2024).
321
+ * Jodkowska, K., Parteka-Tojek, Z., Agarwal, A., Denkiewicz, M., Korsak, S., Chiliński, M., Banecki, K., & Plewczynski, D. (2024). Improved cohesin HiChIP protocol and bioinformatic analysis for robust detection of chromatin loops and stripes. In bioRxiv (p. 2024.05.16.594268). https://doi.org/10.1101/2024.05.16.594268
@@ -6,7 +6,7 @@ with open('README.md', 'r', encoding='utf-8') as f:
6
6
 
7
7
  setup(
8
8
  name='pyLoopSage', # Package name
9
- version='1.0.16', # Version of the software
9
+ version='1.0.18', # Version of the software
10
10
  description='An energy-based stochastic model of loop extrusion in chromatin.',
11
11
  long_description=long_description,
12
12
  long_description_content_type='text/markdown',
File without changes
File without changes
File without changes