Coverage for ase / gui / ag.py: 53.85%
52 statements
« prev ^ index » next coverage.py v7.13.3, created at 2026-02-04 10:20 +0000
« prev ^ index » next coverage.py v7.13.3, created at 2026-02-04 10:20 +0000
1# fmt: off
3# Copyright 2008, 2009
4# CAMd (see accompanying license files for details).
5import warnings
8class CLICommand:
9 """ASE's graphical user interface.
11 ASE-GUI. See the online manual
12 (https://ase-lib.org/ase/gui/gui.html)
13 for more information.
14 """
16 @staticmethod
17 def add_arguments(parser):
18 add = parser.add_argument
19 add('filenames', nargs='*',
20 help='Files to open. Append @SLICE to a filename to pick '
21 'a subset of images from that file. See --image-number '
22 'for SLICE syntax.')
23 add('-n', '--image-number', metavar='SLICE', default=':',
24 help='Pick individual image or slice from each of the files. '
25 'SLICE can be a number or a Python slice-like expression '
26 'such as :STOP, START:STOP, or START:STOP:STEP, '
27 'where START, STOP, and STEP are integers. '
28 'Indexing counts from 0. '
29 'Negative numbers count backwards from last image. '
30 'Using @SLICE syntax for a filename overrides this option '
31 'for that file.')
32 add('-r', '--repeat',
33 default='1',
34 help='Repeat unit cell. Use "-r 2" or "-r 2,3,1".')
35 add('-R', '--rotations', default='',
36 help='Examples: "-R -90x", "-R 90z,-30x".')
37 add('-o', '--output', metavar='FILE',
38 help='Write configurations to FILE.')
39 add('-g', '--graph',
40 # TRANSLATORS: EXPR abbreviates 'expression'
41 metavar='EXPR',
42 help='Plot x,y1,y2,... graph from configurations or '
43 'write data to sdtout in terminal mode. Use the '
44 'symbols: i, s, d, fmax, e, ekin, A, R, E and F. See '
45 'https://ase-lib.org/ase/gui/gui.html'
46 '#plotting-data for more details.')
47 add('-t', '--terminal',
48 action='store_true',
49 default=False,
50 help='Run in terminal window - no GUI.')
51 add('--interpolate',
52 type=int, metavar='N',
53 help='Interpolate N images between 2 given images.')
54 add('-b', '--bonds',
55 action='store_true',
56 default=False,
57 help='Draw bonds between atoms.')
58 add('-s', '--scale', dest='radii_scale', metavar='FLOAT',
59 default=None, type=float,
60 help='Scale covalent radii.')
62 @staticmethod
63 def run(args):
64 from ase.atoms import Atoms
65 from ase.gui.images import Images
67 images = Images()
69 if args.filenames:
70 images.read(args.filenames, args.image_number)
71 else:
72 images.initialize([Atoms()])
74 if args.interpolate:
75 images.interpolate(args.interpolate)
77 if args.repeat != '1':
78 r = args.repeat.split(',')
79 if len(r) == 1:
80 r = 3 * r
81 images.repeat_images([int(c) for c in r])
83 if args.radii_scale:
84 images.scale_radii(args.radii_scale)
86 if args.output is not None:
87 warnings.warn('You should be using "ase convert ..." instead!')
88 images.write(args.output, rotations=args.rotations)
89 args.terminal = True
91 if args.terminal:
92 if args.graph is not None:
93 data = images.graph(args.graph)
94 for line in data.T:
95 for x in line:
96 print(x, end=' ')
97 print()
98 else:
99 import os
101 import matplotlib
103 from ase.gui.gui import GUI
105 # When using Jupyter or some other interactive interpreter,
106 # matplotlib is set up to use an inline backend such as:
107 # 'inline'
108 # 'module://ipykernel.pylab.backend_inline'
109 # 'module://matplotlib_inline.backend_inline'
110 # However, these would cause plots in the GUI to break so
111 # we need to switch to Tk
112 backend = matplotlib.get_backend()
113 if 'inline' in backend:
114 os.environ['MPLBACKEND'] = 'TkAgg'
116 gui = GUI(images, args.rotations, args.bonds, args.graph)
117 gui.run()
119 # Reinstate the backend used before the GUI was opened
120 os.environ['MPLBACKEND'] = backend