mrdna 6.6 KB
Newer Older
1
2
#! /usr/bin/env python
# -*- coding: utf-8 -*-
3
4
5
6
import sys
if sys.version_info[0] != 3:
    raise Exception("This script must be run with python3")
    
7
8
import argparse
import re
9
import pathlib
cmaffeo2's avatar
cmaffeo2 committed
10
from mrdna import __version__ as __version__
cmaffeo2's avatar
cmaffeo2 committed
11
from mrdna.simulate import multiresolution_simulation as simulate
12

13
14
"""Easy multiresolution simulations of DNA nanotechnology objects using ARBD"""

cmaffeo2's avatar
cmaffeo2 committed
15
parser = argparse.ArgumentParser(prog="mrdna",
16
17
18
				 description=__doc__,
                                 formatter_class=argparse.ArgumentDefaultsHelpFormatter,
)
19
20
21
22
23
24
25

parser.add_argument('-o','--output-prefix', type=str, default=None,
                    help="Name for your job's output")
parser.add_argument('-d','--directory', type=str,  default=None,
                    help='Directory for simulation; does not need to exist yet')
parser.add_argument('-g','--gpu', type=int, default=0,
                    help='GPU for simulation; check nvidia-smi for availability')
26
27
parser.add_argument('--output-period', type=float, default=1e4,
                    help='Simulation steps between DCD frames')
28
29
30
31
# parser.add_argument('--minimization-steps', type=float, default=0,
#                     help='Simulation steps between DCD frames')
parser.add_argument('--coarse-local-twist', action='store_true',
                    help='Use local twist for coarsest representation?')
32
parser.add_argument('--coarse-steps', type=float, default=1e7,
33
                    help='Simulation steps for coarse model (200 fs/step)')
34
parser.add_argument('--fine-steps', type=float, default=1e7,
35
36
37
                    help='Simulation steps for fine model (50 fs/step)')
parser.add_argument('--backbone-scale', type=float, default=1.0,
                    help='Factor to scale DNA backbone in atomic model; try 0.25 to avoid clashes for atomistic simulations')
38
39
parser.add_argument('--debug', action='store_true',
                    help='Run through the python debugger?')
40

41
parser.add_argument('--draw-cylinders', action='store_true',
cmaffeo2's avatar
cmaffeo2 committed
42
                    help='Whether or not to draw the cylinders')
43
parser.add_argument('--draw-tubes', action='store_true',
cmaffeo2's avatar
cmaffeo2 committed
44
                    help='Whether or not to draw the tubes')
45

cmaffeo2's avatar
cmaffeo2 committed
46
47
48
49
parser.add_argument('--version', action='version',
                    version='%(prog)s {}'.format(__version__),
                    help='Print the version of mrdna')

50
51
52
53
54
55
56
57
parser.add_argument('input_file', type=str,
                    help="""Any of the following:
                    (1) a cadnano JSON file;
                    (2) a vHelix Maya (.ma) file;
                    (3) an atomic PDB file""")

args = parser.parse_args()

58
def main():
59
    infile = pathlib.Path(args.input_file)
60
    try:
61
        prefix = infile.stem
62
        extension = infile.suffix
63
64
65
    except:
        raise Exception("Unrecognized input file '{}'".format(infile))
        
66
    if extension == '.json':
cmaffeo2's avatar
cmaffeo2 committed
67
        from mrdna.readers import read_cadnano as read_model
68
    elif extension == '.ma':
cmaffeo2's avatar
cmaffeo2 committed
69
        from mrdna.readers import read_vhelix as read_model
70
    elif extension == '.pdb':
cmaffeo2's avatar
cmaffeo2 committed
71
        from mrdna.readers import read_atomic_pdb as read_model
72
73
74
    else:
        raise Exception("Unrecognized input file '{}'".format(infile))
                    
75
    model = read_model( str(infile) )
76

77
78
    if args.output_prefix is not None:
        prefix = args.output_prefix
79
    
cmaffeo2's avatar
cmaffeo2 committed
80
81
82
83
84
85
86
87
    if args.draw_cylinders is True:
        output_name = prefix + ".cylinders.tcl"
        model.vmd_cylinder_tcl( output_name )
        if prefix == infile.stem and extension == ".pdb":
            print("Are you sure you want to overwrite '{}'? (you may provide '-o' option) [y/N]".format(infile))
            if input() not in ("y","Y","yes","Y","Yes","YES"):
                import sys
                sys.exit(1)
88
        model._clear_beads()
cmaffeo2's avatar
cmaffeo2 committed
89
90
91
92
93
94
95
96
97
98
99
100
101
        model._generate_atomic_model(scale=args.backbone_scale)            
        model.write_atomic_ENM( prefix )
        model.atomic_simulate( output_name = prefix )
    elif args.draw_tubes is True:
        output_name = prefix + ".tubes.tcl"
        model.vmd_tube_tcl( output_name )
        if prefix == infile.stem and extension == ".pdb":
            print("Are you sure you want to overwrite '{}'? (you may provide '-o' option) [y/N]".format(infile))
            if input() not in ("y","Y","yes","Y","Yes","YES"):
                import sys
                sys.exit(1)
        model._clear_beads()
        model._generate_atomic_model(scale=args.backbone_scale)            
102
103
104
105
106
107
108
109
110
        model.write_atomic_ENM( prefix )
        model.atomic_simulate( output_name = prefix )
    else:
        run_args = dict(
            model = model,
            output_name = prefix,
            job_id = "job-" + prefix,
            directory = args.directory,
            gpu = args.gpu,
111
112
            minimization_output_period = int(args.output_period),
            coarse_local_twist = args.coarse_local_twist,
113
114
            coarse_output_period = int(args.output_period),
            fine_output_period = int(args.output_period),
115
            minimization_steps = 0, # int(args.minimization_steps),
116
117
118
119
            coarse_steps = int(args.coarse_steps),
            fine_steps = int(args.fine_steps),
            backbone_scale = args.backbone_scale
        )
120

121
        simulate( **run_args )
122
123

if __name__ == '__main__':
124

125
126
127
128
129
130
131
132
133
134
135
136
137
138
    if args.debug:

        class Restart(Exception):
            """Causes a debugger to be restarted for the debugged python program."""
            pass

        import traceback
        import sys
        from pdb import Pdb
        pdb = Pdb()

        while True:
            try:
                # pdb._runscript(mainpyfile)
139
                self._user_requested_quit = False
140
141
142
143
144
145
146
147
148
                pdb.runcall(main)
                if pdb._user_requested_quit:
                    break
                print("The program finished and will be restarted")
            except Restart:
                print("Restarting...")
                print("\t" + " ".join(args))
            except SystemExit:
                # In most cases SystemExit does not warrant a post-mortem session.
149
150
                # print("The program exited via sys.exit(). Exit status:", end=' ')
                print("The program exited via sys.exit(). Exit status:")
151
152
153
154
155
156
157
158
159
160
161
162
163
164
                print(sys.exc_info()[1])
            except SyntaxError:
                traceback.print_exc()
                sys.exit(1)
            except:
                traceback.print_exc()
                print("Uncaught exception. Entering post mortem debugging")
                print("Running 'cont' or 'step' will restart the program")
                t = sys.exc_info()[2]
                pdb.interaction(None, t)
                print("Post mortem debugger finished. mrdna will be restarted")

    else:
        main()