示例#1
0
def test_add_bonds():

    atoms = bulk("NaCl", "rocksalt", 5.64)
    dct = atoms_to_dict(atoms, "NaCl")
    print()
    # print(dct)

    dct = add_bonds(dct, "Na", "Cl", 4, 0.5)

    expected_dct = {
        'elements': [{
            'type':
            'repeat_cell',
            'name':
            'NaCl',
            'centre': [2.82, 2.82, 2.82],
            'color_bbox':
            'black',
            'cell_vectors': {
                'a': [0.0, 2.82, 2.82],
                'b': [2.82, 0.0, 2.82],
                'c': [2.82, 2.82, 0.0]
            },
            'sites': [{
                'label': 'Na',
                'ccoord': [0.0, 0.0, 0.0],
                'cell': [0, 0, 0],
                'radius': 1.66,
                'color_fill': '#ab5cf2',
                'color_outline': None,
                'transparency': 1,
                'anum': 11
            }, {
                'label': 'Cl',
                'ccoord': [2.82, 0.0, 0.0],
                'cell': [0, 0, 0],
                'radius': 1.02,
                'color_fill': '#1ff01f',
                'color_outline': None,
                'transparency': 1,
                'anum': 17
            }],
            'bonds': [{
                "label": "Na",
                "coord_label": "Cl",
                "radius": 0.5,
                "max_dist": 4,
                "include_periodic": True,
                "color_by_dist": False,
                "cmap_name": "jet",
                "drange": (0, 10)
            }],
            'transforms': []
        }],
        'transforms': []
    }

    assert edict.diff(dct, expected_dct, np_allclose=True) == {}
示例#2
0
def test_format_maximal():
    file_obj = utils.MockPath('config.yml',
                              is_file=True,
                              content=example_file_maximal)
    output = format_config_yaml(file_obj)
    # handy for updating
    # import json
    # print(json.dumps(output, indent=4))
    assert edict.diff(output, expected_output_maximal) == {}
示例#3
0
def test_opt_scflog_merge():
    plugins.load_plugin_classes([CrystalOutputPlugin, CrystalSCFLogPlugin],
                                "parsers")
    opt = plugins.parse(os.path.join(file_folder, "scf_and_opt.crystal.out"))
    scflog = plugins.parse(
        os.path.join(file_folder, "scf_and_opt.crystal.scflog"))
    opt_all = edict.merge([opt, scflog], list_of_dicts=True)
    # with open(os.path.join(file_folder, "opt_merge_scflog.crystal.out.json"), "w") as f:
    #     json.dump(opt_all, f, indent=1, default=plugins.encode)

    expected = ejson.to_dict(
        os.path.join(file_folder, "opt_merge_scflog.crystal.out.json"))
    assert edict.diff(opt_all, expected, np_allclose=True) == {}
示例#4
0
def test_plugins(testplugin, filename):
    plugins.unload_all_plugins()
    plugins.load_plugin_classes([Encode_NDArray])
    plugins.load_plugin_classes([testplugin], "parsers")

    inpath = os.path.join(file_folder, filename)
    output = plugins.parse(inpath)
    # print(json.dumps(output, indent=2, default=plugins.encode))
    outpath = os.path.join(file_folder, filename + ".json")

    # if ".crystal.out" in filename:
    #     with open(outpath, "w") as f:
    #         json.dump(output, f, indent=1, default=plugins.encode)
    print("reading expected")
    expected = ejson.to_dict(outpath)

    assert edict.diff(output, expected, np_allclose=True, atol=1e-5) == {}
示例#5
0
def test_color_by_cna():
    atoms = bulk("Fe")

    dct = atoms_to_dict(atoms, "Iron")
    new_dct = color_by_cna(dct, color_outline=True)

    expected = {'elements': [
        {'type': 'repeat_cell', 'name': 'Iron', 'centre': [0.7175, 0.7175, 0.7175],
         'cell_vectors': {'a': [-1.435, 1.435, 1.435], 'b': [1.435, -1.435, 1.435], 'c': [1.435, 1.435, -1.435]},
         "color_bbox": "black",
         'sites': [
             {'ccoord': [0.0, 0.0, 0.0],
              'label': 'Fe, BCC',
              'anum': 26,
              'color_fill': 'green',
              'color_outline': 'green',
              'radius': 1.32, 'transparency': 1,
              'cell': [0, 0, 0]}],
         'transforms': []}],
        'transforms': []}

    assert edict.diff(new_dct, expected, np_allclose=True) == {}
示例#6
0
def ejdict_to_gcube(data,
                    fpath=None,
                    density=0,
                    include_atoms=True,
                    adata=None,
                    cell_tol=1E-3):
    """

    Parameters
    ----------
    data: dict
    fpath: str or None
        output file path or, if None, write to MockPath
    density: int
        take density from data["densities"][density]
    include_atoms: bool
        include atoms in gaussian cube
    adata: dict or None
        separate atom data (for instance for Crystal output)
    cell_tol: float or None
        if not None, raise and error if the data and adata cell vectors are not within this tolerance

    Returns
    -------
    fpath: pathlib.Path or jsonextended.mockpath.MockPath

    """
    if include_atoms and adata is not None:
        if cell_tol:
            cdiff = edict.diff(data["cell_vectors"],
                               adata["cell_vectors"],
                               np_allclose=True,
                               rtol=cell_tol,
                               atol=cell_tol)
            if cdiff:
                raise ValueError(
                    "data and adata have different cell vectors: {}".format(
                        cdiff))
        data["atoms"] = adata["atoms"]

    validate_against_schema(data, "edensity")

    if fpath is None:
        fpath = mockpath.MockPath("test.cube", is_file=True)
    else:
        fpath = pathlib.Path(fpath)

    with fpath.open("w") as f:
        data = units.combine_quantities(data)
        data = units.apply_unitschema(data, {
            "a": "angstrom",
            "b": "angstrom",
            "c": "angstrom",
            "ccoords": "angstrom"
        },
                                      as_quantity=False)
        natoms = 0 if "atoms" not in data or not include_atoms else len(
            data["atoms"]["ccoords"])

        avec = np.asarray(
            data["cell_vectors"]["a"]) / codata[("Bohr", "Angstrom")]
        bvec = np.asarray(
            data["cell_vectors"]["b"]) / codata[("Bohr", "Angstrom")]
        cvec = np.asarray(
            data["cell_vectors"]["c"]) / codata[("Bohr", "Angstrom")]
        centre = 0.5 * (avec + bvec + cvec)
        centre_offset = -1 * centre

        f.write(data["title"] + "\n")
        f.write(data["densities"][density]["type"] + "\n")
        dense = np.asarray(data["densities"][density]["magnitude"])
        na, nb, nc = dense.shape
        f.write("{0:6d} {1:10.6f} {2:10.6f} {3:10.6f}\n".format(
            natoms, *centre_offset.tolist()))
        f.write("{0:6d} {1:10.6f} {2:10.6f} {3:10.6f}\n".format(
            na,
            *(avec / na).tolist()))
        f.write("{0:6d} {1:10.6f} {2:10.6f} {3:10.6f}\n".format(
            nb,
            *(bvec / nb).tolist()))
        f.write("{0:6d} {1:10.6f} {2:10.6f} {3:10.6f}\n".format(
            nc,
            *(cvec / nc).tolist()))

        if data.get("atoms", False):
            for i, c in enumerate(data["atoms"]["ccoords"]):
                atomic_number = data["atoms"]["atomic_number"][i]
                nuclear_charge = data["atoms"]["nuclear_charge"][i]
                ccoord = (np.array(c) /
                          codata[("Bohr", "Angstrom")]) + centre_offset

                f.write(
                    "{0:6d} {1:10.6f} {2:10.6f} {3:10.6f} {4:10.6f}\n".format(
                        atomic_number, nuclear_charge, *ccoord.tolist()))
        dense = dense.flatten().tolist()
        dlength = len(dense)
        output = []
        for i in range(int(dlength / 6.) + 1):
            if dlength > i * 6 + 6:
                output.append(
                    "{0:12.5E} {1:12.5E} {2:12.5E} {3:12.5E} {4:12.5E} {5:12.5E}"
                    .format(*dense[i * 6:i * 6 + 6]))
            else:
                output.append(" ".join(
                    ["{0:12.5E}".format(v) for v in dense[i * 6:dlength]]))

        f.write("\n".join(output))

    return fpath
def test_full_run(new_database_with_daemon, new_workdir):
    """Test running a calculation"""
    from aiida.orm.data.singlefile import SinglefileData
    from aiida.common.datastructures import calc_states

    # get code
    code = get_basic_code(new_workdir, configure=True)

    # Prepare input parameters
    infile = SinglefileData(
        file=os.path.join(TEST_DIR, "input_files",
                          'mgo_sto3g_scf.crystal.d12'))

    # set up calculation
    calc = code.new_calc()

    inputs_dict = {
        "input_file": infile,
        "code": code,
        "options": {
            "resources": {
                "num_machines": 1,
                "num_mpiprocs_per_machine": 1
            },
            "withmpi": False,
            "max_wallclock_seconds": 30
        }
    }  # , "_use_cache": Bool(False)}

    process = calc.process()

    calcnode = run_get_node(process, inputs_dict)

    print(calcnode)

    assert '_aiida_cached_from' not in calcnode.extras()

    assert calcnode.get_state() == calc_states.FINISHED

    assert set(calcnode.get_outputs_dict().keys()).issuperset([
        'output_structure', 'output_parameters', 'output_settings', 'retrieved'
    ])

    expected_params = {
        'parser_version':
        str(aiida_crystal17.__version__),
        'ejplugins_version':
        str(ejplugins.__version__),
        'parser_class':
        'CryBasicParser',
        'parser_warnings':
        ["no initial structure available, creating new kinds for atoms"],
        'errors': [],
        'warnings': [],
        'energy': -2.7121814374931E+02 *
        27.21138602,
        'energy_units':
        'eV',  # hartree to eV
        'calculation_type':
        'restricted closed shell',
        'calculation_spin':
        False,
        # 'wall_time_seconds':
        # 3,
        'number_of_atoms':
        2,
        'number_of_assymetric':
        2,
        'scf_iterations':
        7,
        'volume':
        18.65461527264623,
    }

    outputs = calcnode.get_outputs_dict()['output_parameters'].get_dict()
    # remove wall time, because it is run dependent
    outputs.pop('wall_time_seconds', None)

    assert edict.diff(
        outputs,
        expected_params,
        np_allclose=True) == {}
def test_parser_opt(new_database, new_workdir):
    """ Test the parser

    """
    from aiida.parsers import ParserFactory
    from aiida.common.datastructures import calc_states
    from aiida.common.folders import SandboxFolder
    from aiida.orm import DataFactory

    code = get_basic_code(new_workdir)

    calc = code.new_calc()
    calc.set_resources({"num_machines": 1, "num_mpiprocs_per_machine": 1})

    calc.store_all()
    calc._set_state(calc_states.PARSING)

    parser_cls = ParserFactory("crystal17.basic")
    parser = parser_cls(calc)

    with SandboxFolder() as folder:
        main_out_path = os.path.join(
            os.path.dirname(tests.__file__), "output_files",
            "mgo_sto3g_opt.crystal.out")
        with open(main_out_path) as f:
            folder.create_file_from_filelike(f, "main.out")

        fdata = DataFactory("folder")()
        fdata.replace_with_folder(folder.abspath)

        mock_retrieved = {calc._get_linkname_retrieved(): fdata}
        success, node_list = parser.parse_with_retrieved(mock_retrieved)

    assert success

    node_dict = dict(node_list)
    assert set(['output_parameters', 'output_settings',
                'output_structure']) == set(node_dict.keys())

    expected_params = {
        'parser_version':
        str(aiida_crystal17.__version__),
        'ejplugins_version':
        str(ejplugins.__version__),
        'parser_class':
        'CryBasicParser',
        'parser_warnings':
        ["no initial structure available, creating new kinds for atoms"],
        'errors': [],
        'warnings':
        ['WARNING **** INT_SCREEN **** CELL PARAMETERS OPTIMIZATION ONLY'],
        'energy': -2.712596206888E+02 * 27.21138602,
        'energy_units':
        'eV',  # hartree to eV
        'calculation_type':
        'restricted closed shell',
        'calculation_spin':
        False,
        # 'wall_time_seconds':
        # 102,
        'number_of_atoms':
        2,
        'number_of_assymetric':
        2,
        'scf_iterations':
        8,
        'opt_iterations':
        6,
        'volume':
        14.652065094424696,
    }

    out_params_dict = node_dict['output_parameters'].get_dict()
    out_params_dict.pop('wall_time_seconds', None)

    assert edict.diff(
        out_params_dict,
        expected_params,
        np_allclose=True) == {}

    expected_struct_attrs = {
        'cell': [[0.0, 1.94218061274, 1.94218061274],
                 [1.94218061274, 0.0, 1.94218061274],
                 [1.94218061274, 1.94218061274, 0.0]],
        'kinds': [{'mass': 24.305,
                   'name': 'Mg',
                   'symbols': [u'Mg'],
                   'weights': [1.0]},
                  {'mass': 15.9994, 'name': 'O', 'symbols': ['O'], 'weights': [1.0]}],
        'pbc1': True,
        'pbc2': True,
        'pbc3': True,
        'sites': [{'kind_name': 'Mg', 'position': [0.0, 0.0, 0.0]},
                  {'kind_name': 'O',
                   'position': [1.94218061274, 1.94218061274, 1.94218061274]}]
    }

    assert edict.diff(
        dict(node_dict['output_structure'].get_attrs()),
        expected_struct_attrs, np_allclose=True) == {}
示例#9
0
def test_parser_with_init_struct(new_database, new_workdir):
    """ Test the parser

    """
    from aiida.parsers import ParserFactory
    from aiida.common.datastructures import calc_states
    from aiida.common.folders import SandboxFolder
    from aiida.orm import DataFactory

    code = get_main_code(new_workdir)

    calc = code.new_calc()
    calc.set_resources({"num_machines": 1, "num_mpiprocs_per_machine": 1})

    from aiida.orm.data.structure import StructureData
    struct = StructureData()
    struct.append_atom(position=[0, 0, 0], symbols="Mg", name="Mgx")
    struct.append_atom(position=[0.5, 0.5, 0.5], symbols="O", name="Ox")
    calc.use_structure(struct)

    calc.store_all()
    calc._set_state(calc_states.PARSING)

    parser_cls = ParserFactory("crystal17.basic")
    parser = parser_cls(calc)

    with SandboxFolder() as folder:
        main_out_path = os.path.join(os.path.dirname(tests.__file__),
                                     "output_files",
                                     "mgo_sto3g_scf.crystal.out")
        with open(main_out_path) as f:
            folder.create_file_from_filelike(f, "main.out")

        fdata = DataFactory("folder")()
        fdata.replace_with_folder(folder.abspath)

        mock_retrieved = {calc._get_linkname_retrieved(): fdata}
        success, node_list = parser.parse_with_retrieved(mock_retrieved)

    assert success

    node_dict = dict(node_list)
    assert set(['output_parameters',
                'output_settings']) == set(node_dict.keys())

    expected_params = {
        'parser_version': str(aiida_crystal17.__version__),
        'ejplugins_version': str(ejplugins.__version__),
        'parser_class': 'CryBasicParser',
        'parser_warnings': [],
        'errors': [],
        'warnings': [],
        'energy': -2.7121814374931E+02 * 27.21138602,
        'energy_units': 'eV',  # hartree to eV
        'calculation_type': 'restricted closed shell',
        'calculation_spin': False,
        'wall_time_seconds': 3,
        'number_of_atoms': 2,
        'number_of_assymetric': 2,
        'scf_iterations': 7,
        'volume': 18.65461527264623,
    }

    assert edict.diff(node_dict['output_parameters'].get_dict(),
                      expected_params,
                      np_allclose=True) == {}
def test_basic():
    """
    $a=1$ {#a b=$2$}

    ![a](a/b.jpg){b .x a=$1$ b=2}
    """
    in_json = {
        "meta": {},
        "pandoc-api-version": [1, 17, 5, 1],
        "blocks": [{
            "t":
            "Para",
            "c": [{
                "t": "Math",
                "c": [{
                    "t": "InlineMath"
                }, "a=1"]
            }, {
                "t": "Space"
            }, {
                "t": "Str",
                "c": "{#a"
            }, {
                "t": "Space"
            }, {
                "t": "Str",
                "c": ".a"
            }, {
                "t": "Space"
            }, {
                "t": "Str",
                "c": "b="
            }, {
                "t": "Math",
                "c": [{
                    "t": "InlineMath"
                }, "2"]
            }, {
                "t": "Str",
                "c": "}"
            }]
        }, {
            "t":
            "Para",
            "c": [{
                "t":
                "Image",
                "c": [["b", ["x"], [["a", "$1$"], ["b", "2"]]],
                      [{
                          "t": "Str",
                          "c": "a"
                      }], ["a/b.jpg", "fig:"]]
            }]
        }]
    }

    out_json = apply_to_json(in_json, main)

    assert edict.diff(
        out_json, {
            "pandoc-api-version": [1, 17, 5, 1],
            "meta": {
                "$$references": {
                    "t": "MetaMap",
                    "c": {
                        "a": {
                            "t": "MetaMap",
                            "c": {
                                "type": {
                                    "t": "MetaString",
                                    "c": "Math"
                                },
                                "number": {
                                    "t": "MetaString",
                                    "c": "1"
                                }
                            }
                        },
                        "b": {
                            "t": "MetaMap",
                            "c": {
                                "type": {
                                    "t": "MetaString",
                                    "c": "Image"
                                },
                                "number": {
                                    "t": "MetaString",
                                    "c": "1"
                                }
                            }
                        }
                    }
                }
            },
            "blocks": [{
                "t":
                "Para",
                "c": [{
                    "t":
                    "Span",
                    "c": [["a", ["labelled-Math", "a"], [["b", "2"]]],
                          [{
                              "t": "Math",
                              "c": [{
                                  "t": "InlineMath"
                              }, "a=1"]
                          }]]
                }]
            }, {
                "t":
                "Para",
                "c": [{
                    "t":
                    "Image",
                    "c": [["b", ["x"], [["a", "$1$"], ["b", "2"]]],
                          [{
                              "t": "Str",
                              "c": "a"
                          }], ["a/b.jpg", "fig:"]]
                }]
            }]
        }) == {}
示例#11
0
def test_full_read(input_str):
    output_dict, basis_sets, atom_props = extract_data(input_str)

    assert len(basis_sets) == 2

    assert atom_props == {
        'fragment': [1, 3],
        'ghosts': [5, 6],
        'spin_alpha': [1, 3],
        'spin_beta': [2, 4]
    }

    expected = {
        "title": "a title",
        "geometry": {
            "info_print": ["ATOMSYMM", "SYMMOPS"],
            "info_external": ["STRUCPRT"],
            "optimise": {
                "type": "FULLOPTG",
                "hessian": "HESSIDEN",
                "gradient": "NUMGRATO",
                "info_print": ["PRINTOPT", "PRINTFORCES"],
                "convergence": {
                    "TOLDEG": 0.0003,
                    "TOLDEX": 0.0012,
                    "TOLDEE": 7,
                    "MAXCYCLE": 50,
                    "FINALRUN": 4
                },
            }
        },
        "basis_set": {
            "CHARGED": True,
        },
        "scf": {
            "dft": {
                "xc": ["LDA", "PZ"],
                # or
                # "xc": "HSE06",
                # or
                # "xc": {
                #     "LSRSH-PBE": [0.11, 0.25, 0.00001]
                # },
                "SPIN": True,
                "grid": "XLGRID",
                "grid_weights": "BECKE",
                "numerical": {
                    "TOLLDENS": 6,
                    "TOLLGRID": 14,
                    "LIMBEK": 400
                }
            },
            # or
            # "single": "UHF",
            "k_points": [8, 8],
            "numerical": {
                "BIPOLAR": [18, 14],
                "BIPOSIZE": 4000000,
                "EXCHSIZE": 4000000,
                "EXCHPERM": True,
                "ILASIZE": 6000,
                "INTGPACK": 0,
                "MADELIND": 50,
                "POLEORDR": 4,
                "TOLINTEG": [6, 6, 6, 6, 12],
                "TOLPSEUD": 6,
                "FMIXING": 0,
                "MAXCYCLE": 50,
                "TOLDEE": 6,
                "LEVSHIFT": [2, 1],
                "SMEAR": 0.1
            },
            "fock_mixing": "DIIS",
            # or
            # "fock_mixing": ["BROYDEN", 0.0001, 50, 2],
            "spinlock": {
                "SPINLOCK": [1, 10]
            },
            "post_scf": ["GRADCAL", "PPAN"]
        }
    }

    assert edict.diff(output_dict, expected) == {}
示例#12
0
def test_bonds():
    atoms = bulk("NaCl", "rocksalt", 5.64)
    dct = atoms_to_dict(atoms, "NaCl")
    print()
    # print(dct)

    expected_dct = {
        'elements': [{
            'type':
            'repeat_cell',
            'name':
            'NaCl',
            'centre': [2.82, 2.82, 2.82],
            'color_bbox':
            'black',
            'cell_vectors': {
                'a': [0.0, 2.82, 2.82],
                'b': [2.82, 0.0, 2.82],
                'c': [2.82, 2.82, 0.0]
            },
            'sites': [{
                'label': 'Na',
                'ccoord': [0.0, 0.0, 0.0],
                'cell': [0, 0, 0],
                'radius': 1.66,
                'color_fill': '#ab5cf2',
                'color_outline': None,
                'transparency': 1,
                'anum': 11
            }, {
                'label': 'Cl',
                'ccoord': [2.82, 0.0, 0.0],
                'cell': [0, 0, 0],
                'radius': 1.02,
                'color_fill': '#1ff01f',
                'color_outline': None,
                'transparency': 1,
                'anum': 17
            }],
            'bonds': [],
            'transforms': []
        }],
        'transforms': []
    }

    dct['elements'][0]['bonds'] = [
        {
            "label": "Na",
            "coord_label": "Cl",
            "radius": 1,
            "max_dist": 4,
            "include_periodic": False,
            "color_by_dist": False,
            "cmap_name": "jet",
            "drange": (0, 10)
        },
        {
            "label": "Na",
            "coord_label": "Cl",
            "radius": 2,
            "max_dist": 4,
            "include_periodic": True,
            "color_by_dist": False,
            "cmap_name": "jet",
            "drange": (0, 10)
        },
        {
            "label": "Na",
            "coord_label": "Na",
            "radius": 3,
            "max_dist": 4,
            "include_periodic": False,
            "color_by_dist": False,
            "cmap_name": "jet",
            "drange": (0, 10)
        },
        {
            "label": "Na",
            "coord_label": "Na",
            "radius": 4,
            "max_dist": 4,
            "include_periodic": True,
            "color_by_dist": False,
            "cmap_name": "jet",
            "drange": (0, 10)
        },
    ]

    bonds = compute_bonds(dct)

    # edict.pprint(dict(enumerate(bonds)))
    #print(bonds)
    expected_bonds = [
        [[0.0, 0.0, 0.0], [2.82, 0.0, 0.0], '#ab5cf2', '#1ff01f', 1],
        [[0.0, 0.0, 0.0], [0.0, 2.82, 0.0], '#ab5cf2', '#1ff01f', 2],
        [[0.0, 0.0, 0.0], [0.0, -2.82, 0.0], '#ab5cf2', '#1ff01f', 2],
        [[0.0, 0.0, 0.0], [0.0, 0.0, 2.82], '#ab5cf2', '#1ff01f', 2],
        [[0.0, 0.0, 0.0], [-2.82, 0.0, 0.0], '#ab5cf2', '#1ff01f', 2],
        [[0.0, 0.0, 0.0], [2.82, 0.0, 0.0], '#ab5cf2', '#1ff01f', 2],
        [[0.0, 0.0, 0.0], [0.0, 0.0, -2.82], '#ab5cf2', '#1ff01f', 2],
        [[0.0, 0.0, 0.0], [0.0, 2.82, -2.82], '#ab5cf2', '#ab5cf2', 4],
        [[0.0, 0.0, 0.0], [-2.82, 2.82, 0.0], '#ab5cf2', '#ab5cf2', 4],
        [[0.0, 0.0, 0.0], [2.82, 2.82, 0.0], '#ab5cf2', '#ab5cf2', 4],
        [[0.0, 0.0, 0.0], [0.0, -2.82, 2.82], '#ab5cf2', '#ab5cf2', 4],
        [[0.0, 0.0, 0.0], [-2.82, 0.0, -2.82], '#ab5cf2', '#ab5cf2', 4],
        [[0.0, 0.0, 0.0], [0.0, 2.82, 2.82], '#ab5cf2', '#ab5cf2', 4],
        [[0.0, 0.0, 0.0], [-2.82, -2.82, 0.0], '#ab5cf2', '#ab5cf2', 4],
        [[0.0, 0.0, 0.0], [-2.82, 0.0, 2.82], '#ab5cf2', '#ab5cf2', 4],
        [[0.0, 0.0, 0.0], [0.0, -2.82, -2.82], '#ab5cf2', '#ab5cf2', 4],
        [[0.0, 0.0, 0.0], [2.82, 0.0, -2.82], '#ab5cf2', '#ab5cf2', 4],
        [[0.0, 0.0, 0.0], [2.82, -2.82, 0.0], '#ab5cf2', '#ab5cf2', 4],
        [[0.0, 0.0, 0.0], [2.82, 0.0, 2.82], '#ab5cf2', '#ab5cf2', 4]
    ]

    assert edict.diff(bonds, expected_bonds, np_allclose=True) == {}
示例#13
0
def test_full_run_nio_afm_opt(new_database_with_daemon, new_workdir):
    """Test running a calculation"""
    """Test submitting a calculation"""
    from aiida.orm import DataFactory
    from aiida.common.datastructures import calc_states
    StructureData = DataFactory('structure')
    from aiida_crystal17.data.basis_set import get_basissets_from_structure
    from aiida_crystal17.data.basis_set import BasisSetData
    upload_basisset_family = BasisSetData.upload_basisset_family

    # get code
    code = get_main_code(new_workdir, configure=True)

    # Prepare input parameters
    params = {
        "title": "NiO Bulk with AFM spin",
        "geometry.optimise.type": "FULLOPTG",
        "scf.single": "UHF",
        "scf.k_points": (8, 8),
        "scf.spinlock.SPINLOCK": (0, 15),
        "scf.numerical.FMIXING": 30,
        "scf.post_scf": ["PPAN"]
    }

    # Ni0
    atoms = crystal(symbols=[28, 8],
                    basis=[[0, 0, 0], [0.5, 0.5, 0.5]],
                    spacegroup=225,
                    cellpar=[4.164, 4.164, 4.164, 90, 90, 90])
    atoms.set_tags([1, 1, 2, 2, 0, 0, 0, 0])
    instruct = StructureData(ase=atoms)

    settings = {"kinds.spin_alpha": ["Ni1"], "kinds.spin_beta": ["Ni2"]}

    from aiida_crystal17.workflows.symmetrise_3d_struct import (
        run_symmetrise_3d_structure)
    instruct, settings = run_symmetrise_3d_structure(instruct, settings)

    upload_basisset_family(os.path.join(TEST_DIR, "input_files", "sto3g"),
                           "sto3g",
                           "minimal basis sets",
                           stop_if_existing=True,
                           extension=".basis")
    # basis_map = BasisSetData.get_basis_group_map("sto3g")

    # set up calculation
    calc = code.new_calc()

    params = calc.prepare_and_validate(params, instruct, settings, "sto3g",
                                       True)

    # set up calculation
    calc = code.new_calc()

    inputs_dict = {
        "parameters": params,
        "structure": instruct,
        "settings": settings,
        "basisset": get_basissets_from_structure(instruct,
                                                 "sto3g",
                                                 by_kind=False),
        "code": code,
        "options": {
            "resources": {
                "num_machines": 1,
                "num_mpiprocs_per_machine": 1
            },
            "withmpi": False,
            "max_wallclock_seconds": 30
        }
    }

    process = calc.process()

    calcnode = run_get_node(process, inputs_dict)

    print(calcnode)
    print(get_calc_log(calcnode))

    assert '_aiida_cached_from' not in calcnode.extras()

    try:
        print(calcnode.out.output_parameters.get_dict())
    except AttributeError:
        pass

    assert calcnode.get_state() == calc_states.FINISHED

    assert set(calcnode.get_outputs_dict().keys()).issuperset(
        ['output_structure', 'output_parameters', 'retrieved'])

    expected_params = {
        'parser_version':
        str(aiida_crystal17.__version__),
        'ejplugins_version':
        str(ejplugins.__version__),
        'parser_class':
        'CryBasicParser',
        'parser_warnings': [],
        'errors': [],
        'warnings':
        ['WARNING **** INT_SCREEN **** CELL PARAMETERS OPTIMIZATION ONLY'],
        'calculation_type':
        'unrestricted open shell',
        'calculation_spin':
        True,
        'wall_time_seconds':
        3018,
        'scf_iterations':
        16,
        'opt_iterations':
        19,
        'number_of_atoms':
        4,
        'number_of_assymetric':
        4,
        'volume':
        42.4924120856802,
        'energy':
        -85125.8766752194,
        'energy_units':
        'eV',
        'mulliken_charges': [0.363, 0.363, -0.363, -0.363],
        'mulliken_electrons': [27.637, 27.637, 8.363, 8.363],
        'mulliken_spin_total':
        0.0,
        'mulliken_spins': [3.234, -3.234, -0.172, 0.172]
    }

    assert edict.diff(
        calcnode.get_outputs_dict()['output_parameters'].get_dict(),
        expected_params,
        np_allclose=True) == {}

    expected_struct_attrs = {
        'cell': [[0.0, -2.17339440672, -2.17339440672],
                 [0.0, -2.17339440672, 2.17339440672],
                 [-4.49784306967, 0.0, 0.0]],
        'kinds': [{
            'mass': 58.6934,
            'name': 'Ni1',
            'symbols': ['Ni'],
            'weights': [1.0]
        }, {
            'mass': 58.6934,
            'name': 'Ni2',
            'symbols': ['Ni'],
            'weights': [1.0]
        }, {
            'mass': 15.9994,
            'name': 'O',
            'symbols': ['O'],
            'weights': [1.0]
        }],
        'pbc1':
        True,
        'pbc2':
        True,
        'pbc3':
        True,
        'sites': [{
            'kind_name': 'Ni1',
            'position': [0.0, -2.17339440672, -2.17339440672]
        }, {
            'kind_name': 'Ni2',
            'position': [-2.248921534835, -2.17339440672, 0.0]
        }, {
            'kind_name': 'O',
            'position': [-2.248921534835, -2.17339440672, -2.17339440672]
        }, {
            'kind_name': 'O',
            'position': [0.0, -2.17339440672, 0.0]
        }]
    }

    assert edict.diff(dict(calcnode.out.output_structure.get_attrs()),
                      expected_struct_attrs,
                      np_allclose=True,
                      atol=1e-3) == {}
示例#14
0
def test_full_run_nio_afm(new_database_with_daemon, new_workdir):
    """Test running a calculation"""
    """Test submitting a calculation"""
    from aiida.orm import DataFactory
    from aiida.common.datastructures import calc_states
    StructureData = DataFactory('structure')
    from aiida_crystal17.data.basis_set import get_basissets_from_structure
    from aiida_crystal17.data.basis_set import BasisSetData
    upload_basisset_family = BasisSetData.upload_basisset_family

    # get code
    code = get_main_code(new_workdir, configure=True)

    # Prepare input parameters
    params = {
        "title": "NiO Bulk with AFM spin",
        "scf.single": "UHF",
        "scf.k_points": (8, 8),
        "scf.spinlock.SPINLOCK": (0, 15),
        "scf.numerical.FMIXING": 30,
        "scf.post_scf": ["PPAN"]
    }

    # Ni0
    atoms = crystal(symbols=[28, 8],
                    basis=[[0, 0, 0], [0.5, 0.5, 0.5]],
                    spacegroup=225,
                    cellpar=[4.164, 4.164, 4.164, 90, 90, 90])
    atoms.set_tags([1, 1, 2, 2, 0, 0, 0, 0])
    instruct = StructureData(ase=atoms)

    settings = {"kinds.spin_alpha": ["Ni1"], "kinds.spin_beta": ["Ni2"]}

    from aiida_crystal17.workflows.symmetrise_3d_struct import run_symmetrise_3d_structure
    instruct, settings = run_symmetrise_3d_structure(instruct, settings)

    upload_basisset_family(os.path.join(TEST_DIR, "input_files", "sto3g"),
                           "sto3g",
                           "minimal basis sets",
                           stop_if_existing=True,
                           extension=".basis")
    # basis_map = BasisSetData.get_basis_group_map("sto3g")

    # set up calculation
    calc = code.new_calc()

    params = calc.prepare_and_validate(params, instruct, settings, "sto3g",
                                       True)

    # set up calculation
    calc = code.new_calc()

    inputs_dict = {
        "parameters": params,
        "structure": instruct,
        "settings": settings,
        "basisset": get_basissets_from_structure(instruct,
                                                 "sto3g",
                                                 by_kind=False),
        "code": code,
        "options": {
            "resources": {
                "num_machines": 1,
                "num_mpiprocs_per_machine": 1
            },
            "withmpi": False,
            "max_wallclock_seconds": 30
        }
    }

    process = calc.process()

    calcnode = run_get_node(process, inputs_dict)

    print(calcnode)

    assert '_aiida_cached_from' not in calcnode.extras()

    try:
        print(calcnode.out.output_parameters.get_dict())
    except AttributeError:
        pass

    assert calcnode.get_state() == calc_states.FINISHED

    assert set(calcnode.get_outputs_dict().keys()).issuperset(
        ['output_parameters', 'retrieved'])

    expected_params = {
        'parser_version': str(aiida_crystal17.__version__),
        'ejplugins_version': str(ejplugins.__version__),
        'number_of_atoms': 4,
        'errors': [],
        'warnings': [],
        'energy': -85124.8936673389,
        'number_of_assymetric': 4,
        'volume': 36.099581472,
        'scf_iterations': 13,
        'energy_units': 'eV',
        'calculation_type': 'unrestricted open shell',
        'parser_warnings': [],
        'wall_time_seconds': 187,
        'parser_class': 'CryBasicParser',
        'calculation_spin': True,
        'mulliken_spin_total': 0.0,
        'mulliken_spins': [3.057, -3.057, -0.072, 0.072],
        'mulliken_electrons': [27.602, 27.603, 8.398, 8.397],
        'mulliken_charges': [0.398, 0.396999999999998, -0.398, -0.397]
    }

    assert edict.diff(
        calcnode.get_outputs_dict()['output_parameters'].get_dict(),
        expected_params,
        np_allclose=True) == {}
def test_full_mgo_opt(db_test_app, data_regression):

    code = db_test_app.get_or_create_code("crystal17.main")

    with SandboxFolder() as folder:
        with open_resource_binary("crystal", "mgo_sto3g_opt", "INPUT") as handle:
            folder.create_file_from_filelike(handle, "INPUT", mode="wb")
        with open_resource_binary("crystal", "mgo_sto3g_opt", "main.out") as handle:
            folder.create_file_from_filelike(handle, "main.out", mode="wb")

        remote = RemoteData(
            remote_path=folder.abspath, computer=db_test_app.get_or_create_computer()
        )

        builder = populate_builder(remote, code=code, metadata=get_default_metadata())

        node = immigrate_existing(builder, remote)

    attributes = node.attributes
    attributes["remote_workdir"] = "path/to/remote"
    attributes["version"] = None

    data_regression.check(attributes)

    assert set(node.inputs) == set(
        ["basissets__Mg", "basissets__O", "parameters", "structure", "symmetry", "code"]
    )

    assert set(node.outputs) == set(
        ["results", "retrieved", "structure", "remote_folder"]
    )

    expected_instruct_attrs = {
        "cell": [[0.0, 2.105, 2.105], [2.105, 0.0, 2.105], [2.105, 2.105, 0.0]],
        "kinds": [
            {"mass": 24.305, "name": "Mg", "symbols": ["Mg"], "weights": [1.0]},
            {"mass": 15.9994, "name": "O", "symbols": ["O"], "weights": [1.0]},
        ],
        "pbc1": True,
        "pbc2": True,
        "pbc3": True,
        "sites": [
            {"kind_name": "Mg", "position": [0.0, 0.0, 0.0]},
            {"kind_name": "O", "position": [2.105, 2.105, 2.105]},
        ],
    }

    assert (
        edict.diff(
            dict(node.inputs.structure.attributes),
            expected_instruct_attrs,
            np_allclose=True,
            atol=1e-3,
        )
        == {}
    )

    expected_outstruct_attrs = {
        "cell": [
            [0.0, 1.94218061274, 1.94218061274],
            [1.94218061274, 0.0, 1.94218061274],
            [1.94218061274, 1.94218061274, 0.0],
        ],
        "kinds": [
            {"mass": 24.305, "name": "Mg", "symbols": ["Mg"], "weights": [1.0]},
            {"mass": 15.9994, "name": "O", "symbols": ["O"], "weights": [1.0]},
        ],
        "pbc1": True,
        "pbc2": True,
        "pbc3": True,
        "sites": [
            {"kind_name": "Mg", "position": [0.0, 0.0, 0.0]},
            {
                "kind_name": "O",
                "position": [1.94218061274, 1.94218061274, 1.94218061274],
            },
        ],
    }

    assert (
        edict.diff(
            dict(node.outputs.structure.attributes),
            expected_outstruct_attrs,
            np_allclose=True,
            atol=1e-3,
        )
        == {}
    )
示例#16
0
def read_cell(lines, start_line):
    """
    Read unit cell parameters from the PWSCF output file

    Parameters
    ----------
    lines: list

    Returns
    -------
    cell: dict

    """

    alat = None
    cell = {}
    # TODO you can get a section after the optimisation ("Begin final coordinates") but then a final scf calculation
    # followed by a recalculated final unit cell (see ejplugins/test_files/qe_vc_relax_with_multiple_final_coords.out)
    final_coords = False

    # additional unit cell information
    # bli_lines = [line for line in lines if 'bravais-lattice index' in line]
    # brav_latt_indices = [int(line.split('=')[1].strip()) for line in bli_lines]

    for i, line in enumerate(lines):
        line = line.strip()
        if 'lattice parameter (alat)' in line:
            if "a.u." not in line:
                raise_error("expecting alat in a.u.", line, i, start_line)
            if alat is not None and not final_coords:
                raise_error("found multiple alat values", line, i, start_line)
            alat = split_numbers(line)[0] * codata[("Bohr", "Angstrom")]

        # initial and final
        if 'crystal axes: (cart. coord. in units of alat)' in line:
            if cell and not final_coords:
                raise_error("found multiple cell coordinates", line, i,
                            start_line)
            if not alat:
                raise_error("expecting to have found alat before", line, i,
                            start_line)
            for key, newline in zip(["a", "b", "c"], lines[i + 1:i + 4]):
                x, y, z = split_numbers(newline.split('=')[1])
                cell[key] = {
                    "units": "angstrom",
                    "magnitude": (x * alat, y * alat, z * alat)
                }

        if "Begin final coordinates" in line:
            final_coords = True

        # optimisation step
        if fnmatch(line, "CELL_PARAMETERS*(*alat*=*)"):
            alat = split_numbers(line)[0] * codata[("Bohr", "Angstrom")]
            if cell and final_coords:
                # there can be a 'Begin/End final coordinates' in the final opt step
                new_cell = {}
                for key, newline in zip(["a", "b", "c"], lines[i + 1:i + 4]):
                    x, y, z = split_numbers(newline)
                    new_cell[key] = {
                        "units": "angstrom",
                        "magnitude": (x * alat, y * alat, z * alat)
                    }
                if edict.diff(cell, new_cell, np_allclose=True):
                    raise_error(
                        "normal and final cell coordinates are different",
                        line, i, start_line)
            elif cell:
                raise_error("found multiple cell coordinates", line, i,
                            start_line)
            else:

                for key, newline in zip(["a", "b", "c"], lines[i + 1:i + 4]):
                    x, y, z = split_numbers(newline)
                    cell[key] = {
                        "units": "angstrom",
                        "magnitude": (x * alat, y * alat, z * alat)
                    }

    return cell if cell else None
def test_multiple_on_line():
    """"
    $a=1$ {#a b=$2$} $g=3$ {#gid}

    ![a](a/b.jpg)
    """
    in_json = {
        "pandoc-api-version": [1, 17, 5, 1],
        "meta": {},
        "blocks": [{
            "t":
            "Para",
            "c": [{
                "t": "Math",
                "c": [{
                    "t": "InlineMath"
                }, "a=1"]
            }, {
                "t": "Space"
            }, {
                "t": "Str",
                "c": "{#a"
            }, {
                "t": "Space"
            }, {
                "t": "Str",
                "c": "b="
            }, {
                "t": "Math",
                "c": [{
                    "t": "InlineMath"
                }, "2"]
            }, {
                "t": "Str",
                "c": "}"
            }, {
                "t": "Space"
            }, {
                "t": "Math",
                "c": [{
                    "t": "InlineMath"
                }, "g=3"]
            }, {
                "t": "Space"
            }, {
                "t": "Str",
                "c": "{#gid}"
            }]
        }, {
            "t":
            "Para",
            "c": [{
                "t":
                "Image",
                "c": [["", [], []], [{
                    "t": "Str",
                    "c": "a"
                }], ["a/b.jpg", "fig:"]]
            }]
        }]
    }

    out_json = apply_to_json(in_json, main)

    assert edict.diff(
        out_json, {
            "pandoc-api-version": [1, 17, 5, 1],
            "meta": {
                "$$references": {
                    "t": "MetaMap",
                    "c": {
                        "a": {
                            "t": "MetaMap",
                            "c": {
                                "type": {
                                    "t": "MetaString",
                                    "c": "Math"
                                },
                                "number": {
                                    "t": "MetaString",
                                    "c": "1"
                                }
                            }
                        },
                        "gid": {
                            "t": "MetaMap",
                            "c": {
                                "type": {
                                    "t": "MetaString",
                                    "c": "Math"
                                },
                                "number": {
                                    "t": "MetaString",
                                    "c": "2"
                                }
                            }
                        }
                    }
                }
            },
            "blocks": [{
                "t":
                "Para",
                "c": [{
                    "t":
                    "Span",
                    "c": [["a", ["labelled-Math"], [["b", "2"]]],
                          [{
                              "t": "Math",
                              "c": [{
                                  "t": "InlineMath"
                              }, "a=1"]
                          }]]
                }, {
                    "t": "Space"
                }, {
                    "t":
                    "Span",
                    "c": [["gid", ["labelled-Math"], []],
                          [{
                              "t": "Math",
                              "c": [{
                                  "t": "InlineMath"
                              }, "g=3"]
                          }]]
                }]
            }, {
                "t":
                "Para",
                "c": [{
                    "t":
                    "Image",
                    "c": [["", [], []], [{
                        "t": "Str",
                        "c": "a"
                    }], ["a/b.jpg", "fig:"]]
                }]
            }]
        }) == {}
示例#18
0
def test_parser_external(new_database, new_workdir):
    """ Test the parser

    """
    from aiida.parsers import ParserFactory
    from aiida.common.datastructures import calc_states
    from aiida.common.folders import SandboxFolder
    from aiida.orm import DataFactory

    code = get_basic_code(new_workdir)

    calc = code.new_calc()
    calc.set_resources({"num_machines": 1, "num_mpiprocs_per_machine": 1})

    calc.store_all()
    calc._set_state(calc_states.PARSING)

    parser_cls = ParserFactory("crystal17.basic")
    parser = parser_cls(calc)

    with SandboxFolder() as folder:
        main_out_path = os.path.join(
            os.path.dirname(tests.__file__), "output_files",
            "mgo_sto3g_external.crystal.out")
        with open(main_out_path) as f:
            folder.create_file_from_filelike(f, "main.out")

        fdata = DataFactory("folder")()
        fdata.replace_with_folder(folder.abspath)

        mock_retrieved = {calc._get_linkname_retrieved(): fdata}
        success, node_list = parser.parse_with_retrieved(mock_retrieved)

    assert success

    node_dict = dict(node_list)
    assert set(['output_parameters', 'output_settings',
                'output_structure']) == set(node_dict.keys())

    expected_params = {
        'parser_version':
        str(aiida_crystal17.__version__),
        'ejplugins_version':
        str(ejplugins.__version__),
        'parser_class':
        'CryBasicParser',
        'parser_warnings':
        ["no initial structure available, creating new kinds for atoms"],
        'errors': [],
        'warnings': [],
        'energy': -2.7121814374931E+02 *
        27.21138602,
        'energy_units':
        'eV',  # hartree to eV
        'calculation_type':
        'restricted closed shell',
        'calculation_spin':
        False,
        # 'wall_time_seconds':
        # 3,
        'number_of_atoms':
        2,
        'number_of_assymetric':
        2,
        'scf_iterations':
        7,
        'volume':
        18.65461527264623,
        'mulliken_charges': [0.777, -0.777],
        'mulliken_electrons': [11.223, 8.777],
    }

    out_params_dict = node_dict['output_parameters'].get_dict()
    out_params_dict.pop('wall_time_seconds', None)

    assert edict.diff(
        out_params_dict,
        expected_params,
        np_allclose=True) == {}

    # read from nio_sto3g_afm.crystal.out
    expected_operations = [[
        1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0
    ], [0.0, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, -1.0, -1.0, 0.0, 0.0, 0.0], [
        -1.0, -1.0, -1.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0
    ], [0.0, 0.0, 1.0, -1.0, -1.0, -1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0], [
        0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0
    ], [0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0], [
        1.0, 0.0, 0.0, 0.0, 0.0, 1.0, -1.0, -1.0, -1.0, 0.0, 0.0, 0.0
    ], [1.0, 0.0, 0.0, -1.0, -1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0], [
        -1.0, -1.0, -1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0
    ], [0.0, 0.0, 1.0, 0.0, 1.0, 0.0, -1.0, -1.0, -1.0, 0.0, 0.0, 0.0], [
        0.0, 1.0, 0.0, -1.0, -1.0, -1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0
    ], [-1.0, -1.0, -1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0], [
        0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0
    ], [-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0], [
        0.0, 0.0, -1.0, 1.0, 1.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0
    ], [1.0, 1.0, 1.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 0.0, 0.0], [
        -1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0
    ], [0.0, 0.0, -1.0, 0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 0.0], [
        0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0
    ], [1.0, 1.0, 1.0, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0], [
        0.0, -1.0, 0.0, 1.0, 1.0, 1.0, -1.0, 0.0, 0.0, 0.0, 0.0, 0.0
    ], [0.0, -1.0, 0.0, 0.0, 0.0, -1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0], [
        1.0, 1.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0
    ], [-1.0, 0.0, 0.0, 1.0, 1.0, 1.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0], [
        -1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0
    ], [0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0], [
        1.0, 1.0, 1.0, 0.0, 0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0
    ], [0.0, 0.0, -1.0, 1.0, 1.0, 1.0, -1.0, 0.0, 0.0, 0.0, 0.0, 0.0], [
        0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0
    ], [0.0, -1.0, 0.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 0.0, 0.0], [
        -1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0
    ], [-1.0, 0.0, 0.0, 1.0, 1.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0], [
        1.0, 1.0, 1.0, 0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 0.0
    ], [0.0, 0.0, -1.0, 0.0, -1.0, 0.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0], [
        0.0, -1.0, 0.0, 1.0, 1.0, 1.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0
    ], [1.0, 1.0, 1.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0], [
        0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0
    ], [1.0, 0.0, 0.0, 0.0, 1.0, 0.0, -1.0, -1.0, -1.0, 0.0, 0.0, 0.0], [
        0.0, 0.0, 1.0, -1.0, -1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0
    ], [-1.0, -1.0, -1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0], [
        1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0
    ], [0.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0], [
        0.0, 0.0, 1.0, 1.0, 0.0, 0.0, -1.0, -1.0, -1.0, 0.0, 0.0, 0.0
    ], [-1.0, -1.0, -1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0], [
        0.0, 1.0, 0.0, -1.0, -1.0, -1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0
    ], [0.0, 1.0, 0.0, 0.0, 0.0, 1.0, -1.0, -1.0, -1.0, 0.0, 0.0, 0.0], [
        -1.0, -1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0
    ], [1.0, 0.0, 0.0, -1.0, -1.0, -1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0]]

    print(node_dict['output_settings'].data.operations)
    assert node_dict['output_settings'].compare_operations(
        expected_operations) == {}

    expected_struct_attrs = {
        'cell': [[0.0, 2.105, 2.105],
                 [2.105, 0.0, 2.105],
                 [2.105, 2.105, 0.0]],
        'kinds': [
            {'mass': 24.305,
             'name': 'Mg',
             'symbols': ['Mg'],
             'weights': [1.0]},
            {'mass': 15.9994, 'name': 'O',
             'symbols': ['O'], 'weights': [1.0]}],
        'pbc1': True,
        'pbc2': True,
        'pbc3': True,
        'sites': [{'kind_name': 'Mg', 'position': [0.0, 0.0, 0.0]},
                  {'kind_name': 'O', 'position': [2.105, 2.105, 2.105]}]
    }

    assert edict.diff(
        dict(node_dict['output_structure'].get_attrs()),
        expected_struct_attrs, np_allclose=True) == {}
def test_with_tables():
    """
    Some text

    a b c
    - - -
    1 2 3
    4 5 6

    Table: Caption. {#tbl:id}
    """
    in_json = {
        "pandoc-api-version": [1, 17, 5, 1],
        "meta": {},
        "blocks": [{
            "t":
            "Para",
            "c": [{
                "t": "Str",
                "c": "Some"
            }, {
                "t": "Space"
            }, {
                "t": "Str",
                "c": "text"
            }]
        }, {
            "t":
            "Table",
            "c": [[{
                "t": "Str",
                "c": "Caption."
            }, {
                "t": "Space"
            }, {
                "t": "Str",
                "c": "{#tbl:id}"
            }],
                  [{
                      "t": "AlignDefault"
                  }, {
                      "t": "AlignDefault"
                  }, {
                      "t": "AlignDefault"
                  }], [0, 0, 0],
                  [[{
                      "t": "Plain",
                      "c": [{
                          "t": "Str",
                          "c": "a"
                      }]
                  }], [{
                      "t": "Plain",
                      "c": [{
                          "t": "Str",
                          "c": "b"
                      }]
                  }], [{
                      "t": "Plain",
                      "c": [{
                          "t": "Str",
                          "c": "c"
                      }]
                  }]],
                  [[[{
                      "t": "Plain",
                      "c": [{
                          "t": "Str",
                          "c": "1"
                      }]
                  }], [{
                      "t": "Plain",
                      "c": [{
                          "t": "Str",
                          "c": "2"
                      }]
                  }], [{
                      "t": "Plain",
                      "c": [{
                          "t": "Str",
                          "c": "3"
                      }]
                  }]],
                   [[{
                       "t": "Plain",
                       "c": [{
                           "t": "Str",
                           "c": "4"
                       }]
                   }], [{
                       "t": "Plain",
                       "c": [{
                           "t": "Str",
                           "c": "5"
                       }]
                   }], [{
                       "t": "Plain",
                       "c": [{
                           "t": "Str",
                           "c": "6"
                       }]
                   }]]]]
        }],
    }

    out_json = apply_to_json(in_json, main)

    assert edict.diff(
        out_json, {
            "pandoc-api-version": [1, 17, 5, 1],
            "meta": {
                "$$references": {
                    "t": "MetaMap",
                    "c": {
                        "tbl:id": {
                            "t": "MetaMap",
                            "c": {
                                "type": {
                                    "t": "MetaString",
                                    "c": "Table"
                                },
                                "number": {
                                    "t": "MetaString",
                                    "c": "1"
                                }
                            }
                        }
                    }
                }
            },
            "blocks": [{
                "t":
                "Para",
                "c": [{
                    "t": "Str",
                    "c": "Some"
                }, {
                    "t": "Space"
                }, {
                    "t": "Str",
                    "c": "text"
                }]
            }, {
                "t":
                "Div",
                "c": [["tbl:id", ["labelled-Table"], []],
                      [{
                          "t":
                          "Table",
                          "c": [[{
                              "t": "Str",
                              "c": "Caption."
                          }, {
                              "t": "Space"
                          }],
                                [{
                                    "t": "AlignDefault"
                                }, {
                                    "t": "AlignDefault"
                                }, {
                                    "t": "AlignDefault"
                                }], [0, 0, 0],
                                [[{
                                    "t": "Plain",
                                    "c": [{
                                        "t": "Str",
                                        "c": "a"
                                    }]
                                }],
                                 [{
                                     "t": "Plain",
                                     "c": [{
                                         "t": "Str",
                                         "c": "b"
                                     }]
                                 }],
                                 [{
                                     "t": "Plain",
                                     "c": [{
                                         "t": "Str",
                                         "c": "c"
                                     }]
                                 }]],
                                [[[{
                                    "t": "Plain",
                                    "c": [{
                                        "t": "Str",
                                        "c": "1"
                                    }]
                                }],
                                  [{
                                      "t": "Plain",
                                      "c": [{
                                          "t": "Str",
                                          "c": "2"
                                      }]
                                  }],
                                  [{
                                      "t": "Plain",
                                      "c": [{
                                          "t": "Str",
                                          "c": "3"
                                      }]
                                  }]],
                                 [[{
                                     "t": "Plain",
                                     "c": [{
                                         "t": "Str",
                                         "c": "4"
                                     }]
                                 }],
                                  [{
                                      "t": "Plain",
                                      "c": [{
                                          "t": "Str",
                                          "c": "5"
                                      }]
                                  }],
                                  [{
                                      "t": "Plain",
                                      "c": [{
                                          "t": "Str",
                                          "c": "6"
                                      }]
                                  }]]]]
                      }]]
            }]
        }) == {}
def test_full_mgo_opt(new_database):
    from aiida.orm import DataFactory
    from aiida_crystal17.workflows.cry_main_immigrant import migrate_as_main
    # from aiida.common.datastructures import calc_states

    work_dir = TEST_DIR
    inpath = os.path.join("input_files", 'mgo_sto3g_opt.crystal.d12')
    outpath = os.path.join("output_files", 'mgo_sto3g_opt.crystal.out')

    node = migrate_as_main(
        work_dir,
        inpath,
        outpath,
        input_links={
            'structure': {
                "struct_setup": DataFactory('parameter')()
            }
        })

    print(list(node.attrs()))

    assert node.is_stored

    assert set(node.get_inputs_dict().keys()) == set(
        ['basis_Mg', 'basis_O', 'parameters', 'structure', 'settings'])

    struct = node.inp.structure
    assert "struct_setup" in struct.get_inputs_dict()[
        'structure'].get_inputs_dict()

    # print(node.get_outputs_dict())

    assert set(node.get_outputs_dict().keys()).issuperset(
        ['output_parameters', 'output_structure', 'retrieved'])

    assert '_aiida_cached_from' not in node.extras()

    # assert node.get_attr("state") == calc_states.FINISHED

    expected_instruct_attrs = {
        'cell': [
            [0.0, 2.105, 2.105],
            [2.105, 0.0, 2.105],
            [2.105, 2.105, 0.0]],
        'kinds': [
            {'mass': 24.305,
             'name': 'Mg',
             'symbols': ['Mg'],
             'weights': [1.0]},
            {'mass': 15.9994,
             'name': 'O',
             'symbols': ['O'],
             'weights': [1.0]}],
        'pbc1': True,
        'pbc2': True,
        'pbc3': True,
        'sites': [{'kind_name': 'Mg', 'position': [0.0, 0.0, 0.0]},
                  {'kind_name': 'O', 'position': [2.105, 2.105, 2.105]}]
    }

    assert edict.diff(
        dict(node.inp.structure.get_attrs()),
        expected_instruct_attrs, np_allclose=True, atol=1e-3) == {}

    expected_outstruct_attrs = {
        'cell': [
            [0.0, 1.94218061274, 1.94218061274],
            [1.94218061274, 0.0, 1.94218061274],
            [1.94218061274, 1.94218061274, 0.0]],
        'kinds': [
            {'mass': 24.305,
             'name': 'Mg',
             'symbols': ['Mg'],
             'weights': [1.0]},
            {'mass': 15.9994, 'name': 'O', 'symbols': ['O'], 'weights': [1.0]}],
        'pbc1': True,
        'pbc2': True,
        'pbc3': True,
        'sites': [
            {'kind_name': 'Mg',
             'position': [0.0, 0.0, 0.0]},
            {'kind_name': 'O',
             'position': [1.94218061274, 1.94218061274, 1.94218061274]}]
    }

    assert edict.diff(
        dict(node.get_outputs_dict()['output_structure'].get_attrs()),
        expected_outstruct_attrs, np_allclose=True, atol=1e-3) == {}