1"""Phonopy command line argument parser."""
2# Copyright (C) 2016 Atsushi Togo
3# All rights reserved.
4#
5# This file is part of phonopy.
6#
7# Redistribution and use in source and binary forms, with or without
8# modification, are permitted provided that the following conditions
9# are met:
10#
11# * Redistributions of source code must retain the above copyright
12#   notice, this list of conditions and the following disclaimer.
13#
14# * Redistributions in binary form must reproduce the above copyright
15#   notice, this list of conditions and the following disclaimer in
16#   the documentation and/or other materials provided with the
17#   distribution.
18#
19# * Neither the name of the phonopy project nor the names of its
20#   contributors may be used to endorse or promote products derived
21#   from this software without specific prior written permission.
22#
23# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
26# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
27# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
28# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
29# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
30# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
31# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
33# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34# POSSIBILITY OF SUCH DAMAGE.
35
36import sys
37
38
39def fix_deprecated_option_names(argv):
40    """Replace underscore in command option name by hyphen."""
41    deprecated = []
42    for i, v in enumerate(argv[1:]):
43        if v[0] == '-':
44            tag = v.split('=')[0]
45            if '_' in tag:
46                correct_tag = tag.replace('_', '-')
47                deprecated.append(tag)
48                argv[i + 1] = v.replace(tag, correct_tag)
49
50    return deprecated
51
52
53def show_deprecated_option_warnings(deprecated):
54    """Show warning when underscore is included in command option name."""
55    lines = ["Option names with underscores are deprecated, by which",
56             "the underscores are replaced by dashes. Therefore"]
57    for tag in deprecated:
58        lines.append("'%s' has to be written as '%s'." %
59                     (tag, tag.replace('_', '-')))
60    maxlen = max([len(line) for line in lines])
61    print("*" * maxlen)
62    print('\n'.join(lines))
63    print("*" * maxlen)
64    print("")
65
66
67def get_parser(fc_symmetry=False,
68               is_nac=False,
69               include_born=False,
70               load_phonopy_yaml=False):
71    """Return ArgumentParser instance."""
72    deprecated = fix_deprecated_option_names(sys.argv)
73    import argparse
74    from phonopy.interface.calculator import (
75        add_arguments_of_calculators, calculator_info)
76    try:
77        parser = argparse.ArgumentParser(
78            description="Phonopy command-line-tool",
79            allow_abbrev=False)  # allow_abbrev requires >= python 3.5
80    except TypeError:
81        parser = argparse.ArgumentParser(
82            description="Phonopy command-line-tool")
83
84    add_arguments_of_calculators(parser, calculator_info)
85
86    parser.add_argument(
87        "--alm", dest="use_alm", action="store_true", default=None,
88        help="Use ALM for generating force constants")
89    parser.add_argument(
90        "--amplitude", dest="displacement_distance", type=float, default=None,
91        help="Distance of displacements")
92    parser.add_argument(
93        "--anime", nargs='+', dest="anime", default=None,
94        help="Same as ANIME tag")
95    parser.add_argument(
96        "--band", nargs='+', dest="band_paths", default=None,
97        help="Same behavior as BAND tag")
98    parser.add_argument(
99        "--band-connection", dest="is_band_connection", action="store_true",
100        default=None,
101        help="Treat band crossings")
102    parser.add_argument(
103        "--band-const-interval", dest="is_band_const_interval",
104        action="store_true", default=None,
105        help="Band paths are sampled with similar interval.")
106    parser.add_argument(
107        "--band-labels", nargs='+', dest="band_labels", default=None,
108        help="Show labels at band segments")
109    parser.add_argument(
110        "--band-format", dest="band_format", default=None,
111        help="Band structure output file-format")
112    parser.add_argument(
113        "--band-points", dest="band_points", type=int, default=None,
114        help=("Number of points calculated on a band segment in "
115              "the band structure mode"))
116    parser.add_argument(
117        "--bi", "--band-indices", nargs='+', dest="band_indices", default=None,
118        help=("Band indices to be included to calcualte thermal "
119              "properties"))
120    if not load_phonopy_yaml:
121        parser.add_argument(
122            "-c", "--cell", dest="cell_filename", metavar="FILE", default=None,
123            help="Read unit cell")
124    if load_phonopy_yaml:
125        parser.add_argument(
126            "--config", dest="conf_filename", metavar="FILE", default=None,
127            help="Phonopy configuration file")
128    parser.add_argument(
129        "--cutoff-freq", "--cutoff-frequency", dest="cutoff_frequency",
130        type=float, default=None,
131        help=("Thermal properties are not calculated below this "
132              "cutoff frequency."))
133    parser.add_argument(
134        "--cutoff-radius", dest="cutoff_radius", type=float, default=None,
135        help="Out of cutoff radius, force constants are set zero.")
136    parser.add_argument(
137        "-d", "--displacement", dest="is_displacement", action="store_true",
138        default=None,
139        help="Create supercells with displacements")
140    parser.add_argument(
141        "--dense-svecs", dest="store_dense_svecs", action="store_true",
142        default=None,
143        help="Pair shortest vectors in supercell are stored in dense format.")
144    parser.add_argument(
145        "--dim", nargs='+', dest="supercell_dimension", default=None,
146        help="Same behavior as DIM tag")
147    parser.add_argument(
148        "--dm-decimals", dest="dynamical_matrix_decimals", default=None,
149        type=int, help="Decimals of values of decimals")
150    parser.add_argument(
151        "--dos", dest="is_dos_mode", action="store_true", default=None,
152        help="Calculate (P)DOS")
153    parser.add_argument(
154        "--eigvecs", "--eigenvectors", dest="is_eigenvectors",
155        action="store_true", default=None,
156        help="Output eigenvectors")
157    if load_phonopy_yaml:
158        parser.add_argument(
159            "--exclude-born", "--exclude-nac-params",
160            dest="include_nac_params", action="store_false", default=None,
161            help=("Exclude born effective charge and dielectric tensor in "
162                  "phonopy.yaml"))
163    parser.add_argument(
164        "-f", "--force-sets", nargs='+', dest="create_force_sets",
165        default=None,
166        help="Create FORCE_SETS")
167    parser.add_argument(
168        "--factor", dest="frequency_conversion_factor", type=float,
169        default=None,
170        help="Frequency unit conversion factor")
171    parser.add_argument(
172        "--fc", "--force-constants", metavar="FILE",
173        dest="create_force_constants", default=None,
174        help=("Create FORCE_CONSTANTS from vaspurn.xml. "
175              "vasprun.xml has to be passed as argument."))
176    parser.add_argument(
177        "--fc-calc-opt", "--fc-calculator-options",
178        dest="fc_calculator_options", default=None,
179        help=("Options for force constants calculator as comma separated "
180              "string with the style of key = values"))
181    parser.add_argument(
182        "--fc-decimals", dest="force_constants_decimals", type=int,
183        default=None,
184        help="Decimals of values of force constants")
185    parser.add_argument(
186        "--fc-format", dest="fc_format", default=None,
187        help="Force constants input/output file-format")
188    parser.add_argument(
189        "--fc-spg-symmetry", dest="fc_spg_symmetry", action="store_true",
190        default=None,
191        help="Enforce space group symmetry to force constants")
192    if not fc_symmetry:
193        parser.add_argument(
194            "--fc-symmetry", "--sym-fc",
195            dest="fc_symmetry", action="store_true",
196            default=None, help="Symmetrize force constants")
197    parser.add_argument(
198        "--fits-debye-model", dest="fits_debye_model", action="store_true",
199        default=None,
200        help="Fits total DOS to a Debye model")
201    parser.add_argument(
202        "--freq-scale", dest="frequency_scale_factor", type=float,
203        default=None,
204        help=("Squared scale factor multiplied as fc2 * factor^2. Therefore "
205              "frequency is changed but the contribution from NAC is not "
206              "changed."))
207    parser.add_argument(
208        "--full-fc", dest="is_full_fc", action="store_true", default=None,
209        help="Calculate full supercell force constants matrix")
210    parser.add_argument(
211        "--fz", "--force-sets-zero", nargs='+', dest="create_force_sets_zero",
212        default=None,
213        help=("Create FORCE_SETS. disp.yaml in the current directory and "
214              "vapsrun.xml's for VASP or case.scf(m) for Wien2k as arguments "
215              "are required. The first argument is that of the perfect "
216              "supercell to subtract residual forces"))
217    parser.add_argument(
218        "--fmax", dest="fmax", type=float, default=None,
219        help="Maximum frequency used for DOS or moment calculation")
220    parser.add_argument(
221        "--fmin", dest="fmin", type=float, default=None,
222        help="Minimum frequency used for DOS or moment calculation")
223    parser.add_argument(
224        "--fpitch", dest="fpitch", type=float,
225        help="Frequency pitch used for DOS or moment calculation")
226    parser.add_argument(
227        "--gc", "--gamma-center", dest="is_gamma_center", action="store_true",
228        default=None,
229        help="Set mesh as Gamma center")
230    parser.add_argument(
231        "--gv", "--group-velocity", dest="is_group_velocity",
232        action="store_true", default=None,
233        help="Calculate group velocities at q-points")
234    parser.add_argument(
235        "--gv-delta-q", dest="gv_delta_q", type=float, default=None,
236        help="Delta-q distance used for group velocity calculation")
237    parser.add_argument(
238        "--hdf5", dest="is_hdf5", action="store_true", default=None,
239        help="Use hdf5 for force constants")
240    parser.add_argument(
241        "--hdf5-compression", dest="hdf5_compression", default=None,
242        help="hdf5 compression filter (default: gzip)")
243    parser.add_argument(
244        "--hiphive", dest="use_hiphive", action="store_true", default=None,
245        help="Use hiPhive for generating force constants")
246    parser.add_argument(
247        "--irreps", "--irreps-qpoint", nargs='+', dest="irreps_qpoint",
248        default=None,
249        help="A q-point where characters of irreps are calculated")
250    parser.add_argument(
251        "--include-fc", dest="include_fc", action="store_true", default=None,
252        help="Include force constants in phonopy.yaml")
253    parser.add_argument(
254        "--include-fs", dest="include_fs", action="store_true", default=None,
255        help="Include force sets in phonopy.yaml")
256    if not load_phonopy_yaml:
257        parser.add_argument(
258            "--include-born", "--include-nac-params",
259            dest="include_nac_params", action="store_true",
260            default=None,
261            help=("Include born effective charge and dielectric tensor in "
262                  "phonopy.yaml"))
263    parser.add_argument(
264        "--include-disp", dest="include_disp", action="store_true",
265        default=None,
266        help="Include displacements in phonopy.yaml")
267    parser.add_argument(
268        "--include-all", dest="include_all", action="store_true",
269        default=None,
270        help="Include all output file data in phonopy.yaml")
271    # parser.add_argument(
272    #     "--lapack-solver", dest="lapack_solver", action="store_true",
273    #     default=False,
274    #     help=("Use Lapack via Lapacke for solving phonons. This "
275    #           "option can be used only when phonopy is compiled "
276    #           "specially."))
277    parser.add_argument(
278        "--legend", dest="is_legend", action="store_true", default=None,
279        help="Legend of plots is shown in thermal displacements")
280    parser.add_argument(
281        "--legacy-plot", dest="is_legacy_plot", action="store_true",
282        default=None,
283        help="Legacy style band structure pl")
284    parser.add_argument(
285        "--lcg", "--little-cogroup", dest="is_little_cogroup",
286        action="store_true", default=None,
287        help=("Show irreps of little co-group (or point-group of "
288              "wave vector q) instead of little group"))
289    parser.add_argument(
290        "--loglevel", dest="loglevel", type=int, default=None,
291        help="Log level")
292    parser.add_argument(
293        "--mass", nargs='+', dest="masses", default=None,
294        help="Same as MASS tag")
295    parser.add_argument(
296        "--magmom", nargs='+', dest="magmoms", default=None,
297        help="Same as MAGMOM tag")
298    parser.add_argument(
299        "--mesh-format", dest="mesh_format", default=None,
300        help="Mesh output file-format")
301    parser.add_argument(
302        "--modulation", nargs='+', dest="modulation", default=None,
303        help="Same as MODULATION tag")
304    parser.add_argument(
305        "--mp", "--mesh", nargs='+', dest="mesh_numbers", default=None,
306        help="Same behavior as MP tag")
307    parser.add_argument(
308        "--moment", dest="is_moment", action="store_true", default=None,
309        help="Calculate moment of phonon states distribution")
310    parser.add_argument(
311        "--moment-order", dest="moment_order", default=None,
312        type=int, help="Order of moment of phonon states distribution")
313    if not is_nac:
314        parser.add_argument(
315            "--nac", dest="is_nac", action="store_true", default=None,
316            help="Non-analytical term correction")
317    parser.add_argument(
318        "--nac-method", dest="nac_method", default=None,
319        help="Non-analytical term correction method: Gonze (default) or Wang")
320    if fc_symmetry:
321        parser.add_argument(
322            "--no-fc-symmetry", "--no-sym-fc",
323            dest="fc_symmetry", action="store_false",
324            default=None, help="Do not symmetrize force constants")
325    parser.add_argument(
326        "--nodiag", dest="is_nodiag", action="store_true", default=None,
327        help="Set displacements parallel to axes")
328    parser.add_argument(
329        "--nomeshsym", dest="is_nomeshsym", action="store_true", default=None,
330        help="Symmetry is not imposed for mesh sampling.")
331    if is_nac:
332        parser.add_argument(
333            "--nonac", dest="is_nac", action="store_false", default=None,
334            help="Non-analytical term correction")
335    parser.add_argument(
336        "--nosym", dest="is_nosym", action="store_true", default=None,
337        help="Symmetry is not imposed.")
338    parser.add_argument(
339        "--nowritemesh", dest="write_mesh", action="store_false", default=None,
340        help="Do not write mesh.yaml or mesh.hdf5")
341    parser.add_argument(
342        "-p", "--plot", dest="is_graph_plot", action="store_true",
343        default=None,
344        help="Plot data")
345    parser.add_argument(
346        "--pa", "--primitive-axis", "--primitive-axes",
347        nargs='+', dest="primitive_axes", default=None,
348        help="Same as PRIMITIVE_AXES tag")
349    parser.add_argument(
350        "--pd", "--projection-direction", nargs='+',
351        dest="projection_direction", default=None,
352        help="Same as PROJECTION_DIRECTION tag")
353    parser.add_argument(
354        "--pdos", nargs='+', dest="pdos", default=None,
355        help="Same as PDOS tag")
356    parser.add_argument(
357        "--pm", dest="is_plusminus_displacements", action="store_true",
358        default=None,
359        help="Set plus minus displacements")
360    parser.add_argument(
361        "--pr", "--pretend-real", dest="pretend_real", action="store_true",
362        default=None,
363        help=("Use imaginary frequency as real for thermal property "
364              "calculation. For a testing purpose only, when a small "
365              "amount of imaginary branches obtained."))
366    parser.add_argument(
367        "--pt", "--projected-thermal-property",
368        dest="is_projected_thermal_properties", action="store_true",
369        default=None,
370        help="Output projected thermal properties")
371    parser.add_argument(
372        "--qpoints", nargs='+', dest="qpoints", default=None,
373        help="Calculate at specified q-points")
374    parser.add_argument(
375        "--qpoints-format", dest="qpoints_format", default=None,
376        help="Q-points output file-format")
377    parser.add_argument(
378        "--q-direction", nargs='+', dest="nac_q_direction", default=None,
379        help=("Direction of q-vector perturbation used for NAC at "
380              "q->0, and group velocity for degenerate phonon "
381              "mode in q-points mode"))
382    parser.add_argument(
383        "-q", "--quiet", dest="quiet", action="store_true", default=None,
384        help="Print out smallest information")
385    parser.add_argument(
386        "--random-seed", dest="random_seed", type=int, default=None,
387        help="Random seed by a 32 bit unsigned integer")
388    parser.add_argument(
389        "--rd", "--random-displacements", dest="random_displacements",
390        type=int, default=None,
391        help="Number of supercells with random displacements")
392    parser.add_argument(
393        "--readfc", dest="read_force_constants", action="store_true",
394        default=None,
395        help="Read FORCE_CONSTANTS")
396    parser.add_argument(
397        "--readfc-format", dest="readfc_format", default=None,
398        help="Force constants input file-format")
399    parser.add_argument(
400        "--read-qpoints", dest="read_qpoints", action="store_true",
401        default=None,
402        help="Read QPOITNS")
403    parser.add_argument(
404        "-s", "--save", dest="is_graph_save", action="store_true",
405        default=None,
406        help="Save plot data in pdf")
407    parser.add_argument(
408        "--sp", "--save-params", dest="save_params", action="store_true",
409        default=None,
410        help="Save parameters that can run phonopy in phonopy_params.yaml.")
411    parser.add_argument(
412        "--show-irreps", dest="show_irreps", action="store_true",
413        default=None,
414        help="Show IR-Reps along with characters")
415    parser.add_argument(
416        "--sigma", dest="sigma", default=None,
417        help="Smearing width for DOS")
418    parser.add_argument(
419        "--symmetry", dest="is_check_symmetry", action="store_true",
420        default=None,
421        help="Check crystal symmetry")
422    parser.add_argument(
423        "-t", "--thermal-property", dest="is_thermal_properties",
424        action="store_true", default=None,
425        help="Output thermal properties")
426    parser.add_argument(
427        "--td", "--thermal-displacements", dest="is_thermal_displacements",
428        action="store_true", default=None,
429        help="Output thermal displacements")
430    parser.add_argument(
431        "--tdm", "--thermal-displacement-matrix",
432        dest="is_thermal_displacement_matrices", action="store_true",
433        default=None,
434        help="Output thermal displacement matrices")
435    parser.add_argument(
436        "--tdm-cif", "--thermal-displacement-matrix-cif",
437        metavar='TEMPERATURE',
438        dest="thermal_displacement_matrices_cif", type=float,
439        default=None,
440        help="Write cif with aniso_U for which temperature is specified")
441    parser.add_argument(
442        "--temperature", dest="temperature", type=float, default=None,
443        metavar='TEMPERATURE', help="A temperature point")
444    parser.add_argument(
445        "--tmax", dest="tmax", type=float, default=None,
446        help="Maximum calculated temperature")
447    parser.add_argument(
448        "--tmin", dest="tmin", type=float, default=None,
449        help="Minimum calculated temperature")
450    parser.add_argument(
451        "--tolerance", dest="symmetry_tolerance", type=float, default=None,
452        help="Symmetry tolerance to search")
453    parser.add_argument(
454        "--trigonal", dest="is_trigonal_displacements", action="store_true",
455        default=None,
456        help="Set displacements of all trigonal axes ")
457    parser.add_argument(
458        "--tstep", dest="tstep", type=float, default=None,
459        help="Calculated temperature step")
460    parser.add_argument(
461        "-v", "--verbose", dest="verbose", action="store_true", default=None,
462        help="Detailed information is shown.")
463    parser.add_argument(
464        "--wien2k-p1", dest="is_wien2k_p1", action="store_true", default=None,
465        help="Assume Wien2k structs with displacements are P1")
466    parser.add_argument(
467        "--writefc", dest="write_force_constants", action="store_true",
468        default=None,
469        help="Write FORCE_CONSTANTS")
470    parser.add_argument(
471        "--writefc-format", dest="writefc_format", default=None,
472        help="Force constants output file-format")
473    parser.add_argument(
474        "--writedm", dest="write_dynamical_matrices", action="store_true",
475        default=None,
476        help=("Write dynamical matrices. This has to be used "
477              "with QPOINTS setting (or --qpoints)"))
478    parser.add_argument(
479        "--xyz-projection", dest="xyz_projection", action="store_true",
480        default=None,
481        help="Project PDOS x, y, z directions in Cartesian coordinates")
482    if load_phonopy_yaml:
483        parser.add_argument(
484            "filename", nargs='*', help="phonopy.yaml like file")
485    else:
486        parser.add_argument(
487            "filename", nargs='*', help="Phonopy configure file")
488
489    return parser, deprecated
490