diff --git a/ocaml/Input.ml b/ocaml/Input.ml index 49ac3152..01bb54a0 100644 --- a/ocaml/Input.ml +++ b/ocaml/Input.ml @@ -2,15 +2,10 @@ open Qputils;; open Qptypes;; open Core.Std;; - include Input_ao_basis;; -include Input_bielec_integrals;; include Input_bitmasks;; -include Input_cisd_sc2_selected;; include Input_determinants;; include Input_electrons;; -include Input_full_ci;; -include Input_hartree_fock;; include Input_mo_basis;; include Input_nuclei;; - +include Input_auto_generated;; \ No newline at end of file diff --git a/scripts/docopt.py b/scripts/docopt.py new file mode 100755 index 00000000..59830d53 --- /dev/null +++ b/scripts/docopt.py @@ -0,0 +1,590 @@ +"""Pythonic command-line interface parser that will make you smile. + + * http://docopt.org + * Repository and issue-tracker: https://github.com/docopt/docopt + * Licensed under terms of MIT license (see LICENSE-MIT) + * Copyright (c) 2013 Vladimir Keleshev, vladimir@keleshev.com + +""" +import sys +import re + + +__all__ = ['docopt'] +__version__ = '0.6.1' + + +class DocoptLanguageError(Exception): + + """Error in construction of usage-message by developer.""" + + +class DocoptExit(SystemExit): + + """Exit in case user invoked program with incorrect arguments.""" + + usage = '' + + def __init__(self, message=''): + SystemExit.__init__(self, (message + '\n' + self.usage).strip()) + + +class Pattern(object): + + def __eq__(self, other): + return repr(self) == repr(other) + + def __hash__(self): + return hash(repr(self)) + + def fix(self): + self.fix_identities() + self.fix_repeating_arguments() + return self + + def fix_identities(self, uniq=None): + """Make pattern-tree tips point to same object if they are equal.""" + if not hasattr(self, 'children'): + return self + uniq = list(set(self.flat())) if uniq is None else uniq + for i, child in enumerate(self.children): + if not hasattr(child, 'children'): + assert child in uniq + self.children[i] = uniq[uniq.index(child)] + else: + child.fix_identities(uniq) + + def fix_repeating_arguments(self): + """Fix elements that should accumulate/increment values.""" + either = [list(child.children) for child in transform(self).children] + for case in either: + for e in [child for child in case if case.count(child) > 1]: + if isinstance( + e, + Argument) or isinstance( + e, + Option) and e.argcount: + if e.value is None: + e.value = [] + elif not isinstance(e.value, list): + e.value = e.value.split() + if isinstance( + e, + Command) or isinstance( + e, + Option) and e.argcount == 0: + e.value = 0 + return self + + +def transform(pattern): + """Expand pattern into an (almost) equivalent one, but with single Either. + + Example: ((-a | -b) (-c | -d)) => (-a -c | -a -d | -b -c | -b -d) + Quirks: [-a] => (-a), (-a...) => (-a -a) + + """ + result = [] + groups = [[pattern]] + while groups: + children = groups.pop(0) + parents = [Required, Optional, OptionsShortcut, Either, OneOrMore] + if any(t in map(type, children) for t in parents): + child = [c for c in children if type(c) in parents][0] + children.remove(child) + if isinstance(child, Either): + for c in child.children: + groups.append([c] + children) + elif isinstance(child, OneOrMore): + groups.append(child.children * 2 + children) + else: + groups.append(child.children + children) + else: + result.append(children) + return Either(*[Required(*e) for e in result]) + + +class LeafPattern(Pattern): + + """Leaf/terminal node of a pattern tree.""" + + def __init__(self, name, value=None): + self.name, self.value = name, value + + def __repr__(self): + return '%s(%r, %r)' % (self.__class__.__name__, self.name, self.value) + + def flat(self, *types): + return [self] if not types or type(self) in types else [] + + def match(self, left, collected=None): + collected = [] if collected is None else collected + pos, match = self.single_match(left) + if match is None: + return False, left, collected + left_ = left[:pos] + left[pos + 1:] + same_name = [a for a in collected if a.name == self.name] + if type(self.value) in (int, list): + if isinstance(self.value, int): + increment = 1 + else: + increment = ([match.value] if isinstance(match.value, str) + else match.value) + if not same_name: + match.value = increment + return True, left_, collected + [match] + same_name[0].value += increment + return True, left_, collected + return True, left_, collected + [match] + + +class BranchPattern(Pattern): + + """Branch/inner node of a pattern tree.""" + + def __init__(self, *children): + self.children = list(children) + + def __repr__(self): + return '%s(%s)' % (self.__class__.__name__, + ', '.join(repr(a) for a in self.children)) + + def flat(self, *types): + if type(self) in types: + return [self] + return sum([child.flat(*types) for child in self.children], []) + + +class Argument(LeafPattern): + + def single_match(self, left): + for n, pattern in enumerate(left): + if isinstance(pattern, Argument): + return n, Argument(self.name, pattern.value) + return None, None + + @classmethod + def parse(class_, source): + name = re.findall('(<\S*?>)', source)[0] + value = re.findall('\[default: (.*)\]', source, flags=re.I) + return class_(name, value[0] if value else None) + + +class Command(Argument): + + def __init__(self, name, value=False): + self.name, self.value = name, value + + def single_match(self, left): + for n, pattern in enumerate(left): + if isinstance(pattern, Argument): + if pattern.value == self.name: + return n, Command(self.name, True) + else: + break + return None, None + + +class Option(LeafPattern): + + def __init__(self, short=None, long=None, argcount=0, value=False): + assert argcount in (0, 1) + self.short, self.long, self.argcount = short, long, argcount + self.value = None if value is False and argcount else value + + @classmethod + def parse(class_, option_description): + short, long, argcount, value = None, None, 0, False + options, _, description = option_description.strip().partition(' ') + options = options.replace(',', ' ').replace('=', ' ') + for s in options.split(): + if s.startswith('--'): + long = s + elif s.startswith('-'): + short = s + else: + argcount = 1 + if argcount: + matched = re.findall('\[default: (.*)\]', description, flags=re.I) + value = matched[0] if matched else None + return class_(short, long, argcount, value) + + def single_match(self, left): + for n, pattern in enumerate(left): + if self.name == pattern.name: + return n, pattern + return None, None + + @property + def name(self): + return self.long or self.short + + def __repr__(self): + return 'Option(%r, %r, %r, %r)' % (self.short, self.long, + self.argcount, self.value) + + +class Required(BranchPattern): + + def match(self, left, collected=None): + collected = [] if collected is None else collected + l = left + c = collected + for pattern in self.children: + matched, l, c = pattern.match(l, c) + if not matched: + return False, left, collected + return True, l, c + + +class Optional(BranchPattern): + + def match(self, left, collected=None): + collected = [] if collected is None else collected + for pattern in self.children: + m, left, collected = pattern.match(left, collected) + return True, left, collected + + +class OptionsShortcut(Optional): + + """Marker/placeholder for [options] shortcut.""" + + +class OneOrMore(BranchPattern): + + def match(self, left, collected=None): + assert len(self.children) == 1 + collected = [] if collected is None else collected + l = left + c = collected + l_ = None + matched = True + times = 0 + while matched: + # could it be that something didn't match but changed l or c? + matched, l, c = self.children[0].match(l, c) + times += 1 if matched else 0 + if l_ == l: + break + l_ = l + if times >= 1: + return True, l, c + return False, left, collected + + +class Either(BranchPattern): + + def match(self, left, collected=None): + collected = [] if collected is None else collected + outcomes = [] + for pattern in self.children: + matched, _, _ = outcome = pattern.match(left, collected) + if matched: + outcomes.append(outcome) + if outcomes: + return min(outcomes, key=lambda outcome: len(outcome[1])) + return False, left, collected + + +class Tokens(list): + + def __init__(self, source, error=DocoptExit): + self += source.split() if hasattr(source, 'split') else source + self.error = error + + @staticmethod + def from_pattern(source): + source = re.sub(r'([\[\]\(\)\|]|\.\.\.)', r' \1 ', source) + source = [s for s in re.split('\s+|(\S*<.*?>)', source) if s] + return Tokens(source, error=DocoptLanguageError) + + def move(self): + return self.pop(0) if len(self) else None + + def current(self): + return self[0] if len(self) else None + + +def parse_long(tokens, options): + """long ::= '--' chars [ ( ' ' | '=' ) chars ] ;""" + long, eq, value = tokens.move().partition('=') + assert long.startswith('--') + value = None if eq == value == '' else value + similar = [o for o in options if o.long == long] + if tokens.error is DocoptExit and similar == []: # if no exact match + similar = [o for o in options if o.long and o.long.startswith(long)] + if len(similar) > 1: # might be simply specified ambiguously 2+ times? + raise tokens.error('%s is not a unique prefix: %s?' % + (long, ', '.join(o.long for o in similar))) + elif len(similar) < 1: + argcount = 1 if eq == '=' else 0 + o = Option(None, long, argcount) + options.append(o) + if tokens.error is DocoptExit: + o = Option(None, long, argcount, value if argcount else True) + else: + o = Option(similar[0].short, similar[0].long, + similar[0].argcount, similar[0].value) + if o.argcount == 0: + if value is not None: + raise tokens.error('%s must not have an argument' % o.long) + else: + if value is None: + if tokens.current() in [None, '--']: + raise tokens.error('%s requires argument' % o.long) + value = tokens.move() + if tokens.error is DocoptExit: + o.value = value if value is not None else True + return [o] + + +def parse_shorts(tokens, options): + """shorts ::= '-' ( chars )* [ [ ' ' ] chars ] ;""" + token = tokens.move() + assert token.startswith('-') and not token.startswith('--') + left = token.lstrip('-') + parsed = [] + while left != '': + short, left = '-' + left[0], left[1:] + similar = [o for o in options if o.short == short] + if len(similar) > 1: + raise tokens.error('%s is specified ambiguously %d times' % + (short, len(similar))) + elif len(similar) < 1: + o = Option(short, None, 0) + options.append(o) + if tokens.error is DocoptExit: + o = Option(short, None, 0, True) + else: # why copying is necessary here? + o = Option(short, similar[0].long, + similar[0].argcount, similar[0].value) + value = None + if o.argcount != 0: + if left == '': + if tokens.current() in [None, '--']: + raise tokens.error('%s requires argument' % short) + value = tokens.move() + else: + value = left + left = '' + if tokens.error is DocoptExit: + o.value = value if value is not None else True + parsed.append(o) + return parsed + + +def parse_pattern(source, options): + tokens = Tokens.from_pattern(source) + result = parse_expr(tokens, options) + if tokens.current() is not None: + raise tokens.error('unexpected ending: %r' % ' '.join(tokens)) + return Required(*result) + + +def parse_expr(tokens, options): + """expr ::= seq ( '|' seq )* ;""" + seq = parse_seq(tokens, options) + if tokens.current() != '|': + return seq + result = [Required(*seq)] if len(seq) > 1 else seq + while tokens.current() == '|': + tokens.move() + seq = parse_seq(tokens, options) + result += [Required(*seq)] if len(seq) > 1 else seq + return [Either(*result)] if len(result) > 1 else result + + +def parse_seq(tokens, options): + """seq ::= ( atom [ '...' ] )* ;""" + result = [] + while tokens.current() not in [None, ']', ')', '|']: + atom = parse_atom(tokens, options) + if tokens.current() == '...': + atom = [OneOrMore(*atom)] + tokens.move() + result += atom + return result + + +def parse_atom(tokens, options): + """atom ::= '(' expr ')' | '[' expr ']' | 'options' + | long | shorts | argument | command ; + """ + token = tokens.current() + result = [] + if token in '([': + tokens.move() + matching, pattern = {'(': [')', Required], '[': [']', Optional]}[token] + result = pattern(*parse_expr(tokens, options)) + if tokens.move() != matching: + raise tokens.error("unmatched '%s'" % token) + return [result] + elif token == 'options': + tokens.move() + return [OptionsShortcut()] + elif token.startswith('--') and token != '--': + return parse_long(tokens, options) + elif token.startswith('-') and token not in ('-', '--'): + return parse_shorts(tokens, options) + elif token.startswith('<') and token.endswith('>') or token.isupper(): + return [Argument(tokens.move())] + else: + return [Command(tokens.move())] + + +def parse_argv(tokens, options, options_first=False): + """Parse command-line argument vector. + + If options_first: + argv ::= [ long | shorts ]* [ argument ]* [ '--' [ argument ]* ] ; + else: + argv ::= [ long | shorts | argument ]* [ '--' [ argument ]* ] ; + + """ + parsed = [] + while tokens.current() is not None: + if tokens.current() == '--': + return parsed + [Argument(None, v) for v in tokens] + elif tokens.current().startswith('--'): + parsed += parse_long(tokens, options) + elif tokens.current().startswith('-') and tokens.current() != '-': + parsed += parse_shorts(tokens, options) + elif options_first: + return parsed + [Argument(None, v) for v in tokens] + else: + parsed.append(Argument(None, tokens.move())) + return parsed + + +def parse_defaults(doc): + defaults = [] + for s in parse_section('options:', doc): + # FIXME corner case "bla: options: --foo" + _, _, s = s.partition(':') # get rid of "options:" + split = re.split('\n[ \t]*(-\S+?)', '\n' + s)[1:] + split = [s1 + s2 for s1, s2 in zip(split[::2], split[1::2])] + options = [Option.parse(s) for s in split if s.startswith('-')] + defaults += options + return defaults + + +def parse_section(name, source): + pattern = re.compile('^([^\n]*' + name + '[^\n]*\n?(?:[ \t].*?(?:\n|$))*)', + re.IGNORECASE | re.MULTILINE) + return [s.strip() for s in pattern.findall(source)] + + +def formal_usage(section): + _, _, section = section.partition(':') # drop "usage:" + pu = section.split() + return '( ' + ' '.join(') | (' if s == pu[0] else s for s in pu[1:]) + ' )' + + +def extras(help, version, options, doc): + if help and any((o.name in ('-h', '--help')) and o.value for o in options): + print(doc.strip("\n")) + sys.exit() + if version and any(o.name == '--version' and o.value for o in options): + print(version) + sys.exit() + + +class Dict(dict): + + def __repr__(self): + return '{%s}' % ',\n '.join('%r: %r' % i for i in sorted(self.items())) + + +def docopt(doc, argv=None, help=True, version=None, options_first=False): + """Parse `argv` based on command-line interface described in `doc`. + + `docopt` creates your command-line interface based on its + description that you pass as `doc`. Such description can contain + --options, , commands, which could be + [optional], (required), (mutually | exclusive) or repeated... + + Parameters + ---------- + doc : str + Description of your command-line interface. + argv : list of str, optional + Argument vector to be parsed. sys.argv[1:] is used if not + provided. + help : bool (default: True) + Set to False to disable automatic help on -h or --help + options. + version : any object + If passed, the object will be printed if --version is in + `argv`. + options_first : bool (default: False) + Set to True to require options precede positional arguments, + i.e. to forbid options and positional arguments intermix. + + Returns + ------- + args : dict + A dictionary, where keys are names of command-line elements + such as e.g. "--verbose" and "", and values are the + parsed values of those elements. + + Example + ------- + >>> from docopt import docopt + >>> doc = ''' + ... Usage: + ... my_program tcp [--timeout=] + ... my_program serial [--baud=] [--timeout=] + ... my_program (-h | --help | --version) + ... + ... Options: + ... -h, --help Show this screen and exit. + ... --baud= Baudrate [default: 9600] + ... ''' + >>> argv = ['tcp', '127.0.0.1', '80', '--timeout', '30'] + >>> docopt(doc, argv) + {'--baud': '9600', + '--help': False, + '--timeout': '30', + '--version': False, + '': '127.0.0.1', + '': '80', + 'serial': False, + 'tcp': True} + + See also + -------- + * For video introduction see http://docopt.org + * Full documentation is available in README.rst as well as online + at https://github.com/docopt/docopt#readme + + """ + argv = sys.argv[1:] if argv is None else argv + + usage_sections = parse_section('usage:', doc) + if len(usage_sections) == 0: + raise DocoptLanguageError('"usage:" (case-insensitive) not found.') + if len(usage_sections) > 1: + raise DocoptLanguageError('More than one "usage:" (case-insensitive).') + DocoptExit.usage = usage_sections[0] + + options = parse_defaults(doc) + pattern = parse_pattern(formal_usage(DocoptExit.usage), options) + # [default] syntax for argument is disabled + # for a in pattern.flat(Argument): + # same_name = [d for d in arguments if d.name == a.name] + # if same_name: + # a.value = same_name[0].value + argv = parse_argv(Tokens(argv), list(options), options_first) + pattern_options = set(pattern.flat(Option)) + for options_shortcut in pattern.flat(OptionsShortcut): + doc_options = parse_defaults(doc) + options_shortcut.children = list(set(doc_options) - pattern_options) + # if any_options: + # options_shortcut.children += [Option(o.short, o.long, o.argcount) + # for o in argv if type(o) is Option] + extras(help, version, argv, doc) + matched, left, collected = pattern.fix().match(argv) + if matched and left == []: # better error message if left? + return Dict((a.name, a.value) for a in (pattern.flat() + collected)) + raise DocoptExit() diff --git a/scripts/ezfio_interface/ei_handler.py b/scripts/ezfio_interface/ei_handler.py index 95a3e38c..8fad8511 100755 --- a/scripts/ezfio_interface/ei_handler.py +++ b/scripts/ezfio_interface/ei_handler.py @@ -1,26 +1,42 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- """ -Take a path in argv -Check if EZFIO.cfg exists. -EZFIO.cfg are in MODULE directories. -create : ezfio_interface.irp.f - folder_ezfio_inteface_config -Ezfio_dir : is equal to MODULE.lower! +Welcom the ei_handler. +We will create all the ezfio related stuff from a EZFIO.cfg file. +Usage: + ei_handler.py [--path] [--irpf90] [--ezfio_config] [--ocaml] [--ezfio_default] [--global] + +By default all the option are executed. + +Options: + -h --help + --path The path of the `EZFIO.cfg`, by default will look in the ${pwd} + --irpf90 Create the `ezfio_interface.ipf90` + who containt all the provider needed + (aka all with the `interface: input` parameter) + in `${pwd}` + --ezfio_config Create the `${module_lower}_ezfio_interface_config` in + `${QPACKAGE_ROOT}/EZFIO/config/` + This file is needed by *EZFIO* to create the `libezfio.so` + --ocaml Create the `Input_module.lower.ml` for the *qp_edit* + --ezfio_default Create the `${module_lower}_ezfio_interface_default` in + `${QPACKAGE_ROOT}/data/ezfio_defaults` needed by + the ocaml + --global Create all the stuff who need all the EZFIO.cfg Format specification : - [provider_name] : the name of the provider in irp.f90 - - doc : Is the doc - - Type : Is a fancy_type support by the ocaml - - ezfio_name : Will be the name of the file for the ezfio - (optional by default is the name of the provider) - - interface : The provider is a imput or a output - - default : The default value if interface == input: - - size : Is the string read in ezfio.cgf who containt the size information - (like 1 or =sum(ao_num) or (ao_num,3) ) + [provider_name] | the name of the provider in irp.f90 + doc:{str} | Is the doc + Type:{str} | Is a fancy_type support by the ocaml + ezfio_name:{str} | Will be the name of the file for the ezfio + (optional by default is the name of the provider) + interface:{str} | The provider is a imput or a output + default:{str} | The default value if interface == input: + size:{str} | the size information + (like 1 or =sum(ao_num) or (ao_num,3) ) -Example EZFIO.cfg: +Example of EZFIO.cfg: ``` [thresh_SCF] doc: Threshold on the convergence of the Hartree Fock energy @@ -34,8 +50,8 @@ type: double precision doc: Calculated HF energy interface: output ``` - """ +from docopt import docopt import sys import os @@ -79,7 +95,6 @@ def get_type_dict(): from os import listdir qpackage_root = os.environ['QPACKAGE_ROOT'] - fancy_type_pickle = qpackage_root + "/scripts/ezfio_interface/fancy_type.p" if fancy_type_pickle in listdir(os.getcwd()): @@ -131,7 +146,9 @@ def get_type_dict(): b = r.find('let untouched = "') e = r.find(';;', b) - l_un = [i for i in r[b:e].splitlines() if i.strip().startswith("module")] + l_un = [ + i for i in r[ + b:e].splitlines() if i.strip().startswith("module")] # ~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~ # # q p _ t y p e s _ g e n e r a t e # @@ -280,7 +297,6 @@ def create_ezfio_provider(dict_ezfio_cfg): return [code, ...] """ from ezfio_generate_provider import EZFIO_Provider - dict_code_provider = dict() ez_p = EZFIO_Provider() @@ -473,7 +489,7 @@ def save_ezfio_default(module_lower, str_ezfio_default): f.write(str_ezfio_default) -def create_ocaml_input(dict_ezfio_cfg,module_lower): +def create_ocaml_input(dict_ezfio_cfg, module_lower): # ~#~#~#~# # # I n i t # @@ -586,72 +602,180 @@ def save_ocaml_input(module_lower, str_ocaml_input): f.write(str_ocaml_input) -def main(): +def create_ocaml_input_global(): """ - Two condition: - -Take the EZFIO.cfg path in arg - or - -Look if EZFIO.cfg is present in the pwd - - Return : - ezfio_interface.irp.f - - folder_ezfio_inteface_config + Check for all the EZFIO.cfg get the module lower + then create incule {module_lower}.ml """ # ~#~#~#~# # # I n i t # # ~#~#~#~# # + from os import listdir + from os.path import isdir, join, exists + + mypath = "{0}/src".format(os.environ['QPACKAGE_ROOT']) + + onlyfodler = [f for f in listdir(mypath) if isdir(join(mypath, f))] + + l_module_lower = [f.lower() for f in onlyfodler + if exists("{0}/{1}/EZFIO.cfg".format(mypath, f))] + + # ~#~#~#~#~#~#~#~# # + # C r e a t i o n # + # ~#~#~#~#~#~#~#~# # + + from ezfio_generate_ocaml import EZFIO_ocaml + + qpackage_root = os.environ['QPACKAGE_ROOT'] + path = qpackage_root + "/scripts/ezfio_interface/qp_edit_template" + + with open(path, "r") as f: + template_raw = f.read() + + e = EZFIO_ocaml(l_module_lower=l_module_lower) + + template = template_raw.format(keywords=e.create_qp_keywords(), + keywords_to_string=e.create_qp_keywords_to_string(), + section_to_rst=e.create_qp_section_to_rst(), + write=e.create_qp_write(), + tasks=e.create_qp_tasks()) + + input_auto = e.create_input_auto_generated() + + return (template, input_auto) + + +def save_ocaml_input_auto(str_ocaml_input_global): + """ + Write the str_ocaml_input in + $QPACKAGE_ROOT/ocaml/Input_auto_generated.ml + """ + + path = "{0}/ocaml/Input_auto_generated.ml".format(os.environ['QPACKAGE_ROOT']) + try: - config_file_path = sys.argv[1] - except: - config_file_path = "EZFIO.cfg" - if "EZFIO.cfg" not in os.listdir(os.getcwd()): - sys.exit(0) + f = open(path, "r") + except IOError: + old_output = "" + else: + old_output = f.read() + f.close() - config_file_path = os.path.expanduser(config_file_path) - config_file_path = os.path.expandvars(config_file_path) - config_file_path = os.path.abspath(config_file_path) + if str_ocaml_input_global != old_output: + with open(path, "w+") as f: + f.write(str_ocaml_input_global) - # ~#~#~#~#~#~#~#~#~#~#~#~#~#~# # - # G e t _ m o d u l e _ d i r # - # ~#~#~#~#~#~#~#~#~#~#~#~#~#~# # - path_dirname = os.path.dirname(config_file_path) - module = [i for i in path_dirname.split("/") if i][-1] - module_lower = module.lower() +def save_ocaml_qp_edit(str_ocaml_qp_edit): + """ + Write the str_ocaml_qp_edit in + $QPACKAGE_ROOT/ocaml/qp_edit.ml + """ - # Because we only authorise this right now! - ezfio_dir = module_lower - dict_ezfio_cfg = get_dict_config_file(config_file_path, ezfio_dir) + path = "{0}/ocaml/qp_edit.ml".format(os.environ['QPACKAGE_ROOT']) - # ~#~#~#~#~#~# - # O c a m l # - # ~#~#~#~#~#~# + try: + f = open(path, "r") + except IOError: + old_output = "" + else: + old_output = f.read() + f.close() - str_ocaml_input = create_ocaml_input(dict_ezfio_cfg, module_lower) - save_ocaml_input(module_lower, str_ocaml_input) - - # ~#~#~#~#~#~#~#~# - # I R P . f 9 0 # - # ~#~#~#~#~#~#~#~# - - l_str_code = create_ezfio_provider(dict_ezfio_cfg) - save_ezfio_provider(path_dirname, l_str_code) - - # ~#~#~#~#~#~#~#~#~#~#~#~# # - # e z f i o _ c o n f i g # - # ~#~#~#~#~#~#~#~#~#~#~#~# # - - str_ezfio_config = create_ezfio_config(dict_ezfio_cfg) - save_ezfio_config(module_lower, str_ezfio_config) - - # ~#~#~#~#~#~#~#~#~#~#~#~#~#~ # - # e z f i o _ d e f a u l t # - # ~#~#~#~#~#~#~#~#~#~#~#~#~#~ # - - str_ezfio_default = create_ezfio_default(dict_ezfio_cfg) - save_ezfio_default(module_lower, str_ezfio_default) + if str_ocaml_qp_edit != old_output: + with open(path, "w+") as f: + f.write(str_ocaml_qp_edit) if __name__ == "__main__": - main() + arguments = docopt(__doc__) + + # ___ + # | ._ o _|_ + # _|_ | | | |_ + # + + if not arguments["--global"]: + if not arguments["--path"]: + config_file_path = "EZFIO.cfg" + if "EZFIO.cfg" not in os.listdir(os.getcwd()): + sys.exit(0) + else: + config_file_path = arguments["path"] + + # Get the full path + config_file_path = os.path.expanduser(config_file_path) + config_file_path = os.path.expandvars(config_file_path) + config_file_path = os.path.abspath(config_file_path) + + # ~#~#~#~#~#~#~#~#~#~#~#~#~#~# # + # G e t _ m o d u l e _ d i r # + # ~#~#~#~#~#~#~#~#~#~#~#~#~#~# # + + path_dirname = os.path.dirname(config_file_path) + module = [i for i in path_dirname.split("/") if i][-1] + module_lower = module.lower() + + # Because we only authorise this right now! + ezfio_dir = module_lower + dict_ezfio_cfg = get_dict_config_file(config_file_path, ezfio_dir) + + # _ + # / _ _| _ _ _ ._ _ ._ _. _|_ o _ ._ + # \_ (_) (_| (/_ (_| (/_ | | (/_ | (_| |_ | (_) | | + # _| + + # ~#~#~#~#~#~#~#~#~#~ # + # W h a t _ t o _ d o # + # ~#~#~#~#~#~#~#~#~#~ # + if any([arguments[i] for i in ["--irpf90", + "--ezfio_config", + "--ocaml", + "--ezfio_default", + "--global"]]): + # User changer somme argument, do what he want + do_all = False + else: + # Do all the stuff + do_all = True + + # ~#~#~#~#~#~#~ # + # I R P . f 9 0 # + # ~#~#~#~#~#~#~ # + + if do_all or arguments["--irpf90"]: + l_str_code = create_ezfio_provider(dict_ezfio_cfg) + save_ezfio_provider(path_dirname, l_str_code) + + # ~#~#~#~#~#~#~#~#~#~#~#~ # + # e z f i o _ c o n f i g # + # ~#~#~#~#~#~#~#~#~#~#~#~ # + + if do_all or arguments["--ezfio_config"]: + str_ezfio_config = create_ezfio_config(dict_ezfio_cfg) + save_ezfio_config(module_lower, str_ezfio_config) + + # ~#~#~#~#~#~# + # O c a m l # + # ~#~#~#~#~#~# + if do_all or arguments["--ocaml"]: + str_ocaml_input = create_ocaml_input(dict_ezfio_cfg, module_lower) + save_ocaml_input(module_lower, str_ocaml_input) + + # ~#~#~#~#~#~#~#~#~#~#~#~#~ # + # e z f i o _ d e f a u l t # + # ~#~#~#~#~#~#~#~#~#~#~#~#~ # + if do_all or arguments["--ezfio_default"]: + str_ezfio_default = create_ezfio_default(dict_ezfio_cfg) + save_ezfio_default(module_lower, str_ezfio_default) + + # ~#~#~#~#~#~#~#~#~#~#~#~#~ # + # e z f i o _ d e f a u l t # + # ~#~#~#~#~#~#~#~#~#~#~#~#~ # + + if do_all or arguments["--global"]: + str_ocaml_qp_edit, str_ocaml_input_auto = create_ocaml_input_global() + save_ocaml_input_auto(str_ocaml_input_auto) + save_ocaml_qp_edit(str_ocaml_qp_edit) diff --git a/scripts/ezfio_interface/ezfio_generate_ocaml.py b/scripts/ezfio_interface/ezfio_generate_ocaml.py index 21da15b7..25b6c55f 100755 --- a/scripts/ezfio_interface/ezfio_generate_ocaml.py +++ b/scripts/ezfio_interface/ezfio_generate_ocaml.py @@ -1,6 +1,7 @@ #!/usr/bin/env python import sys +import os # If type in **kwargs from ei_handler import Type @@ -227,7 +228,8 @@ class EZFIO_ocaml(object): "let write{ "] l_template += [" {0};".format(p) for p in self.l_ezfio_name] l_template += [" } ="] - l_template += [" write_{0:<30} {0};".format(p) for p in self.l_ezfio_name] + l_template += [" write_{0:<30} {0};".format(p) + for p in self.l_ezfio_name] l_template += [";;"] # ~#~#~#~#~#~ # @@ -324,3 +326,158 @@ class EZFIO_ocaml(object): # R e t u r n # # ~#~#~#~#~#~ # return "\n ".join(l_template) + + def create_input_auto_generated(self): + """ + Generate the include of all the Input_module.lower template + """ + + # ~#~#~#~#~#~#~#~ # + # C h e c k i n g # + # ~#~#~#~#~#~#~#~ # + + self.check_if_init(["l_module_lower"], + sys._getframe().f_code.co_name) + + # ~#~#~#~#~#~#~#~#~#~#~#~#~#~# # + # C r e a t e _ t e m pl a t e # + # ~#~#~#~#~#~#~#~#~#~#~#~#~#~# # + + l_template = ['open Qputils;;', + 'open Qptypes;;', + 'open Core.Std;;', + ''] + + for m in self.l_module_lower: + l_template += ["include Input_{0}".format(m)] + + # ~#~#~#~#~#~ # + # R e t u r n # + # ~#~#~#~#~#~ # + + return "\n".join(l_template) + + def create_qp_keywords(self): + """ + Generate keywords template + """ + + # ~#~#~#~#~#~#~#~ # + # C h e c k i n g # + # ~#~#~#~#~#~#~#~ # + + self.check_if_init(["l_module_lower"], + sys._getframe().f_code.co_name) + + # ~#~#~#~#~#~#~#~#~#~#~#~#~#~# # + # C r e a t e _ t e m pl a t e # + # ~#~#~#~#~#~#~#~#~#~#~#~#~#~# # + + l_template = ["| {0}".format(m.capitalize()) + for m in self.l_module_lower] + + # ~#~#~#~#~#~ # + # R e t u r n # + # ~#~#~#~#~#~ # + + return "\n".join(l_template) + + def create_qp_keywords_to_string(self): + """ + Generate keywords to string template + """ + + # ~#~#~#~#~#~#~#~ # + # C h e c k i n g # + # ~#~#~#~#~#~#~#~ # + + self.check_if_init(["l_module_lower"], + sys._getframe().f_code.co_name) + + # ~#~#~#~#~#~#~#~#~#~#~#~#~#~# # + # C r e a t e _ t e m pl a t e # + # ~#~#~#~#~#~#~#~#~#~#~#~#~#~# # + + l_template = ['| {0} -> "{0}"'.format(m.capitalize()) + for m in self.l_module_lower] + + # ~#~#~#~#~#~ # + # R e t u r n # + # ~#~#~#~#~#~ # + + return "\n".join(l_template) + + def create_qp_section_to_rst(self): + """ + Generate section to rst + """ + # ~#~#~#~#~#~#~#~ # + # C h e c k i n g # + # ~#~#~#~#~#~#~#~ # + + self.check_if_init(["l_module_lower"], + sys._getframe().f_code.co_name) + + # ~#~#~#~#~#~#~#~#~#~#~#~#~#~# # + # C r e a t e _ t e m pl a t e # + # ~#~#~#~#~#~#~#~#~#~#~#~#~#~# # + + l_template = [] + for m in self.l_module_lower: + m_cap = m.capitalize() + l_template += [" | {0} ->".format(m_cap), + " f {0}.(read, to_rst)".format(m_cap)] + + # ~#~#~#~#~#~ # + # R e t u r n # + # ~#~#~#~#~#~ # + + return "\n".join(l_template) + + def create_qp_write(self): + """ + Generate write + """ + # ~#~#~#~#~#~#~#~ # + # C h e c k i n g # + # ~#~#~#~#~#~#~#~ # + + self.check_if_init(["l_module_lower"], + sys._getframe().f_code.co_name) + + # ~#~#~#~#~#~#~#~#~#~#~#~#~#~# # + # C r e a t e _ t e m pl a t e # + # ~#~#~#~#~#~#~#~#~#~#~#~#~#~# # + + str_ = " | {0} -> write {0}.(of_rst, write) s" + l_template = [str_.format(m.capitalize()) for m in self.l_module_lower] + + # ~#~#~#~#~#~ # + # R e t u r n # + # ~#~#~#~#~#~ # + + return "\n".join(l_template) + + def create_qp_tasks(self): + """ + Generate taks + """ + # ~#~#~#~#~#~#~#~ # + # C h e c k i n g # + # ~#~#~#~#~#~#~#~ # + + self.check_if_init(["l_module_lower"], + sys._getframe().f_code.co_name) + + # ~#~#~#~#~#~#~#~#~#~#~#~#~#~# # + # C r e a t e _ t e m pl a t e # + # ~#~#~#~#~#~#~#~#~#~#~#~#~#~# # + + l_template = [" {0} ; ".format(m.capitalize()) + for m in self.l_module_lower] + + # ~#~#~#~#~#~ # + # R e t u r n # + # ~#~#~#~#~#~ # + + return "\n".join(l_template) diff --git a/ocaml/qp_edit.ml b/scripts/ezfio_interface/qp_edit_template similarity index 88% rename from ocaml/qp_edit.ml rename to scripts/ezfio_interface/qp_edit_template index df7635e0..8d52acfd 100644 --- a/ocaml/qp_edit.ml +++ b/scripts/ezfio_interface/qp_edit_template @@ -11,27 +11,21 @@ open Core.Std;; (** Keywords used to define input sections *) type keyword = | Ao_basis -| Bielec_integrals -| Cisd_sc2_selected | Determinants | Electrons -| Full_ci -| Hartree_fock | Mo_basis | Nuclei +{keywords} ;; let keyword_to_string = function | Ao_basis -> "AO basis" -| Bielec_integrals -> "Two electron integrals" -| Cisd_sc2_selected -> "CISD (SC)^2" | Determinants -> "Determinants" | Electrons -> "Electrons" -| Full_ci -> "Selected Full-CI" -| Hartree_fock -> "Hartree-Fock" | Mo_basis -> "MO basis" | Nuclei -> "Molecule" +{keywords_to_string} ;; @@ -70,24 +64,17 @@ let get s = begin let open Input in match s with - | Full_ci -> - f Full_ci.(read, to_rst) - | Hartree_fock -> - f Hartree_fock.(read, to_rst) | Mo_basis -> f Mo_basis.(read, to_rst) | Electrons -> f Electrons.(read, to_rst) - | Cisd_sc2_selected -> - f Cisd_sc2_selected.(read, to_rst) | Nuclei -> f Nuclei.(read, to_rst) | Ao_basis -> f Ao_basis.(read, to_rst) - | Bielec_integrals -> - f Bielec_integrals.(read, to_rst) | Determinants -> f Determinants.(read, to_rst) +{section_to_rst} end with | Sys_error msg -> (Printf.eprintf "Info: %s\n%!" msg ; "") @@ -125,11 +112,8 @@ let set str s = in let open Input in match s with - | Hartree_fock -> write Hartree_fock.(of_rst, write) s - | Full_ci -> write Full_ci.(of_rst, write) s +{write} | Electrons -> write Electrons.(of_rst, write) s - | Cisd_sc2_selected -> write Cisd_sc2_selected.(of_rst, write) s - | Bielec_integrals -> write Bielec_integrals.(of_rst, write) s | Determinants -> write Determinants.(of_rst, write) s | Nuclei -> write Nuclei.(of_rst, write) s | Ao_basis -> () (* TODO *) @@ -176,10 +160,7 @@ let run check_only ezfio_filename = Nuclei ; Ao_basis; Electrons ; - Bielec_integrals ; - Hartree_fock ; - Cisd_sc2_selected ; - Full_ci ; +{tasks} Mo_basis; Determinants ; ] diff --git a/src/CISD_SC2_selected/EZFIO.cfg b/src/CISD_SC2_selected/EZFIO.cfg index 84cefe2f..660f9fd6 100644 --- a/src/CISD_SC2_selected/EZFIO.cfg +++ b/src/CISD_SC2_selected/EZFIO.cfg @@ -19,11 +19,11 @@ default: 0.0001 [energy] type: double precision -doc: "Calculated Full CI energy" +doc: Calculated CISD_SC2 energy of ground_state interface: output [energy_pt2] type: double precision -doc: "Calculated Full CI energy" +doc: Calculated CISD_SC2 energy+pt2 of ground_state interface: output diff --git a/src/CISD_SC2_selected/cisd_sc2_selection.irp.f b/src/CISD_SC2_selected/cisd_sc2_selection.irp.f index 1c4b2ed0..55234fcb 100644 --- a/src/CISD_SC2_selected/cisd_sc2_selection.irp.f +++ b/src/CISD_SC2_selected/cisd_sc2_selection.irp.f @@ -62,6 +62,13 @@ program cisd_sc2_selected if (abort_all) then exit endif + + ! =~=~=~=~=~=~=~=~=~=~=~=~=~! + ! W r i t e _ o n _ d i s k ! + ! =~=~=~=~=~=~=~=~=~=~=~=~=~! + + call ezfio_set_full_ci_energy(CI_SC2_energy(1)) + enddo N_det = min(n_det_max_cisd_sc2,N_det) davidson_threshold = 1.d-10 @@ -98,6 +105,12 @@ program cisd_sc2_selected print*,'Degree of excitation of this determinant : ',degree enddo + + ! =~=~=~=~=~=~=~=~=~=~=~=~=~! + ! W r i t e _ o n _ d i s k ! + ! =~=~=~=~=~=~=~=~=~=~=~=~=~! + + call ezfio_set_full_ci_energy_pt2(CI_SC2_energy(i)+pt2(i)* (1.d0 + norm_pert) - H_pert_diag(i)) endif call save_wavefunction deallocate(pt2,norm_pert,H_pert_diag) diff --git a/src/MRCC/NEEDED_MODULES b/src/MRCC/NEEDED_MODULES index 3711786f..8ae0a127 100644 --- a/src/MRCC/NEEDED_MODULES +++ b/src/MRCC/NEEDED_MODULES @@ -1,2 +1,2 @@ -AOs BiInts Bitmask CAS_SD_selected Dets Electrons Ezfio_files Generators_CAS Generators_full Hartree_Fock MOGuess MonoInts MOs Nuclei Output Perturbation Properties Selectors_full Utils +AOs Bielec_integrals Bitmask CAS_SD_selected Dets Electrons Ezfio_files Generators_CAS Generators_full Hartree_Fock MOGuess MonoInts MOs Nuclei Output Perturbation Properties Selectors_full Utils