# Path: vasppy/procar.py
# class KPoint():
# class Procar:
#     def __init__( self, index, frac_coords, weight ):
#     def cart_coords( self, reciprocal_lattice ):
#     def __eq__( self, other ):
#     def __repr__( self ):
# def get_numbers_from_string( string ):
# def k_point_parser( string ):
# def projections_parser( string ):
# def area_of_a_triangle_in_cartesian_space( a, b, c ):
# def points_are_in_a_straight_line( points, tolerance=1e-7 ):
# def two_point_effective_mass( cartesian_k_points, eigenvalues ):
# def least_squares_effective_mass( cartesian_k_points, eigenvalues ):
#     def __init__( self, spin=1, negative_occupancies='warn' ):
#     def occupancy( self ):
#     def __add__( self, other ):
#     def parse_projections( self ):
#     def parse_k_points( self ):
#     def parse_bands( self ):
#     def sanity_check( self ):
#     def from_files( cls, filenames, **kwargs ):
#     def from_file( cls, filename, negative_occupancies='warn',
#                    select_zero_weighted_k_points=False ):
#     def read_from_file( self, filename ):
#     def _read_from_file( self, filename ):
#     def number_of_k_points( self ):
#     def number_of_bands( self ):
#     def spin_channels( self ):
#     def number_of_ions( self ):
#     def number_of_projections( self ):
#     def print_weighted_band_structure( self, spins=None, ions=None, orbitals=None, scaling=1.0, e_fermi=0.0, reciprocal_lattice=None ):
#     def weighted_band_structure( self, spins=None, ions=None, orbitals=None, scaling=1.0, e_fermi=0.0, reciprocal_lattice=None ):
#     def effective_mass_calc( self, k_point_indices, band_index, reciprocal_lattice, spin=1, printing=False ):
#     def x_axis( self, reciprocal_lattice=None ):
#     def bands( self ):
#     def k_points( self ):
#     def select_bands_by_kpoint( self, band_indices ):
#     def select_k_points( self, band_indices ):
# 
# Path: vasppy/outcar.py
# def reciprocal_lattice_from_outcar( filename ): # from https://github.com/MaterialsDiscovery/PyChemia
#     """
#     Finds and returns the reciprocal lattice vectors, if more than
#     one set present, it just returns the last one.
#     Args:
#         filename (Str): The name of the outcar file to be read
# 
#     Returns:
#         List(Float): The reciprocal lattice vectors.
#     """
#     outcar = open(filename, "r").read()
#     # just keeping the last component
#     recLat = re.findall(r"reciprocal\s*lattice\s*vectors\s*([-.\s\d]*)",
#                         outcar)[-1]
#     recLat = recLat.split()
#     recLat = np.array(recLat, dtype=float)
#     # up to now I have, both direct and rec. lattices (3+3=6 columns)
#     recLat.shape = (3, 6)
#     recLat = recLat[:, 3:]
#     return recLat


from vasppy import procar
from vasppy.outcar import reciprocal_lattice_from_outcar
import argparse
#! /usr/bin/env python3


def minimum_length( nmin ):
    class MinimumLength( argparse.Action ):
        def __call__( self, parser, args, values, option_string=None ):
            if not nmin <= len( values ):
                msg = 'argument "{f}" requires at least {nmin} arguments'.format( f = self.dest, nmin = nmin )
                raise argparse.ArgumentError( self, msg )
            setattr( args, self.dest, values )
    return MinimumLength
            
def main():
    parser = argparse.ArgumentParser( description='Calculate an effective mass from a VASP PROCAR using a fitted quadratic' )
    parser.add_argument( '-k', '--k-points', help='index of k-points for calculating effective mass', nargs='+', type=int, required=True, action=minimum_length( 2 ) )
    parser.add_argument( '-b', '--band-index', help='index of band for calculating effective mass', type=int, required=True )
    parser.add_argument( '-f', '--procar', help='PROCAR filename (default PROCAR)', type=str, default='PROCAR' )
    parser.add_argument( '-v', '--verbose', help='Verbose output', action='store_true' )
    parser.add_argument( '-o', '--outcar', help='OUTCAR filename (default OUTCAR)', type=str, default='OUTCAR' )
    parser.add_argument( '-s', '--spin', help='select spin channel (default 1 / non-spin-polarised)', type=int, default='1' )
    args = parser.parse_args()

    reciprocal_lattice = reciprocal_lattice_from_outcar( 'OUTCAR' ) # Move reading the reciprocal lattice to procar.py

    pcar = procar.Procar()

# Path: vasppy/procar.py
# class KPoint():
# class Procar:
#     def __init__( self, index, frac_coords, weight ):
#     def cart_coords( self, reciprocal_lattice ):
#     def __eq__( self, other ):
#     def __repr__( self ):
# def get_numbers_from_string( string ):
# def k_point_parser( string ):
# def projections_parser( string ):
# def area_of_a_triangle_in_cartesian_space( a, b, c ):
# def points_are_in_a_straight_line( points, tolerance=1e-7 ):
# def two_point_effective_mass( cartesian_k_points, eigenvalues ):
# def least_squares_effective_mass( cartesian_k_points, eigenvalues ):
#     def __init__( self, spin=1, negative_occupancies='warn' ):
#     def occupancy( self ):
#     def __add__( self, other ):
#     def parse_projections( self ):
#     def parse_k_points( self ):
#     def parse_bands( self ):
#     def sanity_check( self ):
#     def from_files( cls, filenames, **kwargs ):
#     def from_file( cls, filename, negative_occupancies='warn',
#                    select_zero_weighted_k_points=False ):
#     def read_from_file( self, filename ):
#     def _read_from_file( self, filename ):
#     def number_of_k_points( self ):
#     def number_of_bands( self ):
#     def spin_channels( self ):
#     def number_of_ions( self ):
#     def number_of_projections( self ):
#     def print_weighted_band_structure( self, spins=None, ions=None, orbitals=None, scaling=1.0, e_fermi=0.0, reciprocal_lattice=None ):
#     def weighted_band_structure( self, spins=None, ions=None, orbitals=None, scaling=1.0, e_fermi=0.0, reciprocal_lattice=None ):
#     def effective_mass_calc( self, k_point_indices, band_index, reciprocal_lattice, spin=1, printing=False ):
#     def x_axis( self, reciprocal_lattice=None ):
#     def bands( self ):
#     def k_points( self ):
#     def select_bands_by_kpoint( self, band_indices ):
#     def select_k_points( self, band_indices ):
# 
# Path: vasppy/outcar.py
# def reciprocal_lattice_from_outcar( filename ): # from https://github.com/MaterialsDiscovery/PyChemia
#     """
#     Finds and returns the reciprocal lattice vectors, if more than
#     one set present, it just returns the last one.
#     Args:
#         filename (Str): The name of the outcar file to be read
# 
#     Returns:
#         List(Float): The reciprocal lattice vectors.
#     """
#     outcar = open(filename, "r").read()
#     # just keeping the last component
#     recLat = re.findall(r"reciprocal\s*lattice\s*vectors\s*([-.\s\d]*)",
#                         outcar)[-1]
#     recLat = recLat.split()
#     recLat = np.array(recLat, dtype=float)
#     # up to now I have, both direct and rec. lattices (3+3=6 columns)
#     recLat.shape = (3, 6)
#     recLat = recLat[:, 3:]
#     return recLat


# Path: vasppy/scripts/effective_mass.py
from vasppy import procar
from vasppy.outcar import reciprocal_lattice_from_outcar
import argparse

#! /usr/bin/env python3


def minimum_length( nmin ):
    class MinimumLength( argparse.Action ):
        def __call__( self, parser, args, values, option_string=None ):
            if not nmin <= len( values ):
                msg = 'argument "{f}" requires at least {nmin} arguments'.format( f = self.dest, nmin = nmin )
                raise argparse.ArgumentError( self, msg )
            setattr( args, self.dest, values )
    return MinimumLength
            
def main():
    parser = argparse.ArgumentParser( description='Calculate an effective mass from a VASP PROCAR using a fitted quadratic' )
    parser.add_argument( '-k', '--k-points', help='index of k-points for calculating effective mass', nargs='+', type=int, required=True, action=minimum_length( 2 ) )
    parser.add_argument( '-b', '--band-index', help='index of band for calculating effective mass', type=int, required=True )
    parser.add_argument( '-f', '--procar', help='PROCAR filename (default PROCAR)', type=str, default='PROCAR' )
    parser.add_argument( '-v', '--verbose', help='Verbose output', action='store_true' )
    parser.add_argument( '-o', '--outcar', help='OUTCAR filename (default OUTCAR)', type=str, default='OUTCAR' )
    parser.add_argument( '-s', '--spin', help='select spin channel (default 1 / non-spin-polarised)', type=int, default='1' )
    args = parser.parse_args()

    reciprocal_lattice = reciprocal_lattice_from_outcar( 'OUTCAR' ) # Move reading the reciprocal lattice to procar.py

    pcar = procar.Procar()

    pcar.read_from_file( args.procar )