<commit_before>"""
Classes for writing GW Input and analyzing GW data. The underlying classes can handle the use of VASP and ABINIT via the
code interfaces provided in codeinterfaces.
Reads the POSCAR_name in the the current folder and outputs GW input to subfolders name or lists of structures
"""

from __future__ import division

__author__ = "<NAME>"
__copyright__ = " "
__version__ = "0.9"
__maintainer__ = "<NAME>"
__email__ = "<EMAIL>"
__date__ = "May 2014"

import os
import stat
import os.path
import ast
import pymatgen as pmg
import pymongo
import json

from abc import abstractproperty, abstractmethod, ABCMeta
from pymatgen.io.vaspio.vasp_input import Poscar, Kpoints
from pymatgen.matproj.rest import MPRester, MPRestError
from pymatgen.serializers.json_coders import MSONable
from pymatgen.io.gwwrapper.convergence import test_conv
from pymatgen.io.gwwrapper.helpers import print_gnuplot_header, s_name, add_gg_gap
from pymatgen.io.gwwrapper.codeinterfaces import get_code_interface
from pymatgen.core.structure import Structure
from pymatgen.transformations.standard_transformations import OxidationStateRemovalTransformation


MODULE_DIR = os.path.dirname(os.path.abspath(__file__))


class AbstractAbinitioSpec(MSONable):
    """
    Contains all non GW specific methods
    todo for some reason I can not make this class have both a metaclass and subcalss from msonable ...
    """
    __metaclass__ = ABCMeta

    def __init__(self):
        self.data = {'code': 'VASP',
                     'source': 'mp-vasp',
                     'mode': 'ceci',
                     'test': False,
                     'converge': False,
                     'functional': 'PBE',
                     'prec': 'm',
                     'kp_grid_dens': 500,
                     'tol': 0.0001}
        self.warnings = []
        self.errors = []
        self.update_code_interface()

    def __getitem__(self, item):
        return self.data[item]

    def update_code_interface(self):
        self.code_interface = get_code_interface(self.get_code())

    def get_code(self):
        return self['code']

    def write_to_file(self, filename):
        f = open(filename, mode='w')
        f.write(str(self.to_dict()))
        f.close()

    def read_from_file(self, filename):
        try:
            f = open(filename, mode='r')
            self.data = ast.literal_eval(f.read())
            f.close()
        except OSError:
            print 'Inputfile ', filename, ' not found exiting.'
            exit()
        self.update_code_interface()

    def update_interactive(self):
        """
        method to make changes to the GW input setting interactively
        """
        key = 'tmp'
        while len(key) != 0:
            print self
            key = raw_input('enter key to change (h for help): ')
            if key in self.data.keys():
                value = raw_input('enter new value: ')
                if isinstance(self.data[key], list):                        # list
                    if len(value) == 0:
                        print 'removed', self.data[key].pop(-1)
                    else:
                        self.data[key].append(value)
                elif isinstance(self.data[key], bool):                      # logical
                    if value.lower() in ['true', 't']:
                        self.data[key] = True
                    elif value.lower() in ['false', 'f']:
                        self.data[key] = False
                    else:
                        print 'undefined value, should be True or False'
                elif isinstance(self.data[key], int):                       # integer
                    self.data[key] = int(value)
                elif isinstance(self.data[key], float):                     # float
                    self.data[key] = float(value)
                elif isinstance(self.data[key], str):                       # string
                    self.data[key] = value
            elif key in ['help', 'h']:
                print self.help
            elif len(key) == 0:
                print 'setup finished'
            else:
                print 'undefined key'
        self.data['functional'] = self.data['functional'].upper()
        self.update_code_interface()

    def loop_structures(self, mode='i'):
        """
        reading the structures specified in spec, add special points, and excecute the specs
        mode:
        i: loop structures for input generation
        o: loop structures for output parsing
        """
        print 'loop structures mode ', mode
        mp_key = os.environ['MP_KEY']

        mp_list_vasp = ['mp-149', 'mp-2534', 'mp-8062', 'mp-2469', 'mp-1550', 'mp-830', 'mp-1986', 'mp-10695', 'mp-66',
                        'mp-1639', 'mp-1265', 'mp-1138', 'mp-23155', 'mp-111']

        if self.data['source'] == 'mp-vasp':
            items_list = mp_list_vasp
        elif self.data['source'] == 'poscar':
            files = os.listdir('.')
            items_list = files
        elif self.data['source'] == 'mar_exp':
            items_list = []
            local_serv = pymongo.Connection("marilyn.pcpm.ucl.ac.be")
            local_db_gaps = local_serv.band_gaps
            pwd = os.environ['<PASSWORD>']
            local_db_gaps.authenticate("setten", pwd)
            for c in local_db_gaps.exp.find():
                print Structure.from_dict(c['icsd_data']['structure']).composition.reduced_formula, c['icsd_id'], c['MP_id']
                items_list.append({'name': 'mp-' + c['MP_id'], 'icsd': c['icsd_id'], 'mp': c['MP_id']})
        else:
            items_list = [line.strip() for line in open(self.data['source'])]

        for item in items_list:
            print '\n'
            # special case, this should be encaptulated
            if self.data['source'] == 'mar_exp':
                print 'structure from marilyn', item['name'], item['icsd'], item['mp']
                exp = local_db_gaps.exp.find({'MP_id': item['mp']})[0]
                structure = Structure.from_dict(exp['icsd_data']['structure'])
                try:
                    kpts = local_db_gaps.GGA_BS.find({'transformations.history.0.id': item['icsd']})[0]['calculations']\
                    [-1]['band_structure']['kpoints']
                except (IndexError, KeyError):
                    kpts = [[0.0, 0.0, 0.0], [0.0, 0.0, 0.0]]
                #print structure
                remove_ox = OxidationStateRemovalTransformation()
                structure = remove_ox.apply_transformation(structure)
                structure.kpts = kpts
                print 'kpoints:', structure.kpts[0], structure.kpts[1]
                structure.item = item['name']
            else:
                if item.startswith('POSCAR_'):
                    structure = pmg.read_structure(item)
                    comment = Poscar.from_file(item).comment
                    # print comment
                    if comment.startswith("gap"):
                        structure.vbm_l = comment.split(" ")[1]
                        structure.vbm = (comment.split(" ")[2], comment.split(" ")[3], comment.split(" ")[4])
                        structure.cbm_l = comment.split(" ")[5]
                        structure.cbm = (comment.split(" ")[6], comment.split(" ")[7], comment.split(" ")[8])<commit_msg>make the structures read form marilyn primitive<commit_after>"""
Classes for writing GW Input and analyzing GW data. The underlying classes can handle the use of VASP and ABINIT via the
code interfaces provided in codeinterfaces.
Reads the POSCAR_name in the the current folder and outputs GW input to subfolders name or lists of structures
"""

from __future__ import division

__author__ = "<NAME>"
__copyright__ = " "
__version__ = "0.9"
__maintainer__ = "<NAME>"
__email__ = "<EMAIL>"
__date__ = "May 2014"

import os
import stat
import os.path
import ast
import pymatgen as pmg
import pymongo
import json

from abc import abstractproperty, abstractmethod, ABCMeta
from pymatgen.io.vaspio.vasp_input import Poscar, Kpoints
from pymatgen.matproj.rest import MPRester, MPRestError
from pymatgen.serializers.json_coders import MSONable
from pymatgen.io.gwwrapper.convergence import test_conv
from pymatgen.io.gwwrapper.helpers import print_gnuplot_header, s_name, add_gg_gap
from pymatgen.io.gwwrapper.codeinterfaces import get_code_interface
from pymatgen.core.structure import Structure
from pymatgen.transformations.standard_transformations import OxidationStateRemovalTransformation, PrimitiveCellTransformation


MODULE_DIR = os.path.dirname(os.path.abspath(__file__))


class AbstractAbinitioSpec(MSONable):
    """
    Contains all non GW specific methods
    todo for some reason I can not make this class have both a metaclass and subcalss from msonable ...
    """
    __metaclass__ = ABCMeta

    def __init__(self):
        self.data = {'code': 'VASP',
                     'source': 'mp-vasp',
                     'mode': 'ceci',
                     'test': False,
                     'converge': False,
                     'functional': 'PBE',
                     'prec': 'm',
                     'kp_grid_dens': 500,
                     'tol': 0.0001}
        self.warnings = []
        self.errors = []
        self.update_code_interface()

    def __getitem__(self, item):
        return self.data[item]

    def update_code_interface(self):
        self.code_interface = get_code_interface(self.get_code())

    def get_code(self):
        return self['code']

    def write_to_file(self, filename):
        f = open(filename, mode='w')
        f.write(str(self.to_dict()))
        f.close()

    def read_from_file(self, filename):
        try:
            f = open(filename, mode='r')
            self.data = ast.literal_eval(f.read())
            f.close()
        except OSError:
            print 'Inputfile ', filename, ' not found exiting.'
            exit()
        self.update_code_interface()

    def update_interactive(self):
        """
        method to make changes to the GW input setting interactively
        """
        key = 'tmp'
        while len(key) != 0:
            print self
            key = raw_input('enter key to change (h for help): ')
            if key in self.data.keys():
                value = raw_input('enter new value: ')
                if isinstance(self.data[key], list):                        # list
                    if len(value) == 0:
                        print 'removed', self.data[key].pop(-1)
                    else:
                        self.data[key].append(value)
                elif isinstance(self.data[key], bool):                      # logical
                    if value.lower() in ['true', 't']:
                        self.data[key] = True
                    elif value.lower() in ['false', 'f']:
                        self.data[key] = False
                    else:
                        print 'undefined value, should be True or False'
                elif isinstance(self.data[key], int):                       # integer
                    self.data[key] = int(value)
                elif isinstance(self.data[key], float):                     # float
                    self.data[key] = float(value)
                elif isinstance(self.data[key], str):                       # string
                    self.data[key] = value
            elif key in ['help', 'h']:
                print self.help
            elif len(key) == 0:
                print 'setup finished'
            else:
                print 'undefined key'
        self.data['functional'] = self.data['functional'].upper()
        self.update_code_interface()

    def loop_structures(self, mode='i'):
        """
        reading the structures specified in spec, add special points, and excecute the specs
        mode:
        i: loop structures for input generation
        o: loop structures for output parsing
        """
        print 'loop structures mode ', mode
        mp_key = os.environ['MP_KEY']

        mp_list_vasp = ['mp-149', 'mp-2534', 'mp-8062', 'mp-2469', 'mp-1550', 'mp-830', 'mp-1986', 'mp-10695', 'mp-66',
                        'mp-1639', 'mp-1265', 'mp-1138', 'mp-23155', 'mp-111']

        if self.data['source'] == 'mp-vasp':
            items_list = mp_list_vasp
        elif self.data['source'] == 'poscar':
            files = os.listdir('.')
            items_list = files
        elif self.data['source'] == 'mar_exp':
            items_list = []
            local_serv = pymongo.Connection("marilyn.pcpm.ucl.ac.be")
            local_db_gaps = local_serv.band_gaps
            pwd = os.environ['MAR_PAS']
            local_db_gaps.authenticate("setten", pwd)
            for c in local_db_gaps.exp.find():
                print Structure.from_dict(c['icsd_data']['structure']).composition.reduced_formula, c['icsd_id'], c['MP_id']
                items_list.append({'name': 'mp-' + c['MP_id'], 'icsd': c['icsd_id'], 'mp': c['MP_id']})
        else:
            items_list = [line.strip() for line in open(self.data['source'])]

        for item in items_list:
            print '\n'
            # special case, this should be encaptulated
            if self.data['source'] == 'mar_exp':
                print 'structure from marilyn', item['name'], item['icsd'], item['mp']
                exp = local_db_gaps.exp.find({'MP_id': item['mp']})[0]
                structure = Structure.from_dict(exp['icsd_data']['structure'])
                try:
                    kpts = local_db_gaps.GGA_BS.find({'transformations.history.0.id': item['icsd']})[0]['calculations']\
                    [-1]['band_structure']['kpoints']
                except (IndexError, KeyError):
                    kpts = [[0.0, 0.0, 0.0], [0.0, 0.0, 0.0]]
                #print structure
                remove_ox = OxidationStateRemovalTransformation()
                print structure
                structure = remove_ox.apply_transformation(structure)
                print structure
                get_prim = PrimitiveCellTransformation()
                structure = get_prim.apply_transformation(structure)
                print structure
                structure.kpts = kpts
                print 'kpoints:', structure.kpts[0], structure.kpts[1]
                structure.item = item['name']
            else:
                if item.startswith('POSCAR_'):
                    structure = pmg.read_structure(item)
                    comment = Poscar.from_file(item).comment
                    # print comment
                    if comment.startswith("gap"):
                        structure.vbm_l = comment.split(" ")[1]
                        structure.vbm = (comment.split(" ")[2], comment.split(" ")[3], comment.split(" ")[4])
                        structure.cbm_l = comment.split(" ")[5]
                        structure.cbm = (comment.split(" ")[6], comment.split(" ")[7], comment.split(" ")[8])
{'fraction_non_alphanumeric': 0.11885959041627626, 'fraction_numerical': 0.012983536340516664, 'mean_word_length': 1.8511734401831712, 'pattern_counts': {'":': 0, '<': 10, '<?xml version=': 0, '>': 10, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3298638', 'n_tokens_mistral': 4450, 'n_tokens_neox': 4141, 'n_words': 1040}