
from pandas import read_excel, concat
from numpy import zeros

#Ofertas de oportunidad inyeccion
def readofertas_ooi(predespacho_file):
    """Lee del archivo Excel la información del Predespacho.
    
    Retorna un DataFrame con las columnas siguientes:
        
        1. nodo_io        : Nodo de inyección de la oferta
        2. Generador	  : Potencia ofertada
        3. Precio bloque 1: Oferta en dólares por la compra de DF
        4. Magnitud bloque 1: Precio del MWh ofertado 
    """

    ofer_ooi = read_excel(predespacho_file,sheet_name='ooi')
    ofer_ooi.columns = ['nodo_i','Generador','precio_ooi','magnitud_ooi']
    
    return ofer_ooi

def readofertas_oois(predespacho_file):
    """Lee del archivo Excel la información del Predespacho.
    
    Retorna un DataFrame con las columnas siguientes:
        
        1. nodo_io        : Nodo de inyección de la oferta
        2. Generador	  : Potencia ofertada
        3. Precio bloque 1: Oferta en dólares por la compra de DF
        4. Magnitud bloque 1: Precio del MWh ofertado 
    """

    ofer_ooi = read_excel(predespacho_file,sheet_name='ooi')
    ofer_ooi.columns = ['N°','nodo_i','Generador','precio_ooi1','magnitud_ooi1','precio_ooi2','magnitud_ooi2','precio_ooi3','magnitud_ooi3','precio_ooi4','magnitud_ooi4','precio_ooi5','magnitud_ooi5']
    
    return ofer_ooi


#Ofertas de oportunidad retiro
def readofertas_oor(predespacho_file):
    """Lee del archivo Excel la información del Predespacho.
    
    Retorna un DataFrame con las columnas siguientes:
        
        1. nodo_r        : Nodo de retiro de la oferta
        2. Generador	  : Potencia ofertada
        3. Precio bloque 1: Oferta en dólares por la compra de DF
        4. Magnitud bloque 1: Precio del MWh ofertado 
    """

    ofer_oor = read_excel(predespacho_file,sheet_name='oor')
    ofer_oor.columns = ['nodo_oor','generador', 'precio_oor','magnitud_oor']
    
    return ofer_oor

def readofertas_oors(predespacho_file):
    """Lee del archivo Excel la información del Predespacho.

    Retorna un DataFrame con las columnas siguientes:
        
        1. nodo_io        : Nodo de inyección de la oferta
        2. Generador	  : Potencia ofertada
        3. Precio bloque 1: Oferta en dólares por la compra de DF
        4. Magnitud bloque 1: Precio del MWh ofertado 
        5. Precio bloque 2: Oferta en dólares por la compra de DF
        6. Magnitud bloque 2: Precio del MWh ofertado 
        7. Precio bloque 3: Oferta en dólares por la compra de DF
        8. Magnitud bloque 3: Precio del MWh ofertado 
        9. Precio bloque 4: Oferta en dólares por la compra de DF
        10. Magnitud bloque 4: Precio del MWh ofertado 
        11. Precio bloque 5: Oferta en dólares por la compra de DF
        12. Magnitud bloque 5: Precio del MWh ofertado 
    """

    ofer_oor = read_excel(predespacho_file,sheet_name='oor')
    ofer_oor.columns = ['N°','nodo_oor','generador','precio_oor1','magnitud_oor1','precio_oor2','magnitud_oor2','precio_oor3','magnitud_oor3','precio_oor4','magnitud_oor4','precio_oor5','magnitud_oor5']

    return ofer_oor

#Ofertas de contrato firme
def readofertas_cf(predespacho_file):
    """Lee del archivo Excel la información del Predespacho.
    
    Retorna un DataFrame con las columnas siguientes:
        
        1. nodo_i        : Nodo de inyección de la oferta
        2. Generador	  : Potencia ofertada
	  3.Nodo_r:		    Nodo de retiro
	  4. Energía Declarada: Ofertas en dólares de CF
        5. Potencia requerida: Oferta en dólares por la compra de DF
        6. Precio bloque 1: Precio del MWh ofertado 
	  7. Magnitud bloque 1 : Cantidad de MW a flexibilizar	  
    """

    ofer_cf = read_excel(predespacho_file,sheet_name='cf')
    ofer_cf.columns = ['nodo_cfi','generador','nodo_cfr','energía_dec','potencia_req','precio_cf','magnitu_cf']
    
    return ofer_cf

def readofertas_cfs(predespacho_file):
    """Lee del archivo Excel la información del Predespacho.
    
    Retorna un DataFrame con las columnas siguientes:
        
        1. nodo_i        : Nodo de inyección de la oferta
        2. Generador	  : Potencia ofertada
	    3.Nodo_r:		    Nodo de retiro
	    4. Energía Declarada: Ofertas en dólares de CF
        5. Potencia requerida: Oferta en dólares por la compra de DF
        6. Precio bloque 1: Precio del MWh ofertado 
	    7. Magnitud bloque 1 : Cantidad de MW a flexibilizar	
        8. Precio bloque 2: Precio del MWh ofertado 
	    9. Magnitud bloque 2 : Cantidad de MW a flexibilizar
        10. Precio bloque 3: Precio del MWh ofertado 
	    11. Magnitud bloque 3: Cantidad de MW a flexibilizar
        12. Precio bloque 4: Precio del MWh ofertado 
	    13. Magnitud bloque 4: Cantidad de MW a flexibilizar
        14. Precio bloque 5: Precio del MWh ofertado 
	    15. Magnitud bloque 5: Cantidad de MW a flexibilizar  
    """

    ofer_cf = read_excel(predespacho_file,sheet_name='cf')
    ofer_cf.columns = ['N°','nodo_cfi','generador','nodo_cfr','energía_dec','potencia_req','precio_cf1','magnitu_cf1','precio_cf2','magnitu_cf2','precio_cf3','magnitu_cf3','precio_cf4','magnitu_cf4','precio_cf5','magnitu_cf5']
    
    return ofer_cf


def read_D_G(predespacho_file):
    """Lee del archivo Excel la información del Predespacho.
    
    Retorna un DataFrame con la demanda y generacion en el nodo:
        
    1. nodo        : Nodo de inyección de la oferta
    2. Generador	  : Potencia ofertada
	3.Nodo_r:		    Nodo de retiro	  
    """

    nodos_d_m = read_excel(predespacho_file,sheet_name='g_m')
    nodos_d_m.columns = ['nodo','generacion','demanda']
    
    return nodos_d_m

#Ofertas contratos no firmes físicos flexible
def readofertas_cnfff(predespacho_file):
    """Lee del archivo Excel la información del Predespacho.
    
    Retorna un DataFrame con las columnas siguientes:
        
        1. nodo_i        : Nodo de inyección de la oferta
        2. Generador	  : Potencia ofertada
	    3.Nodo_r:		    Nodo de retiro
	    4. Energía Declarada: Ofertas en dólares de CF
        5. Potencia requerida: Oferta en dólares por la compra de DF
        6. Precio bloque inyeccion 1: Precio del MWh ofertado 
	    7. Magnitud bloque  inyeccion 1 : Cantidad de MW a flexibilizar
        8. Precio bloque retiro 1: Precio del MWh ofertado 
	    9. Magnitud bloque  retiro 1 : Cantidad de MW a flexibilizar
        10. k(cff) sin hay ofertas de max CVT va le 0 sino 1
        11. Precio bloque max CVT 1: Precio del MWh ofertado 
	    12. Magnitud bloque MAX CVT 1 : Cantidad de MW a flexibilizar
    """

    ofer_cnfffi = read_excel(predespacho_file,sheet_name='cnfff')
    ofer_cnfffi.columns = ['nodo_cnfffi','generador','nodo_cnfffr','energía_dec','precio_i','magnitud_i','precio_r','magnitud_r','k','precio_cvt','magnitud_cvt']
    
    return ofer_cnfffi

def readofertas_cnfffs(predespacho_file):
    """Lee del archivo Excel la información del Predespacho.
    
    Retorna un DataFrame con las columnas siguientes:
        
        1. nodo_i        : Nodo de inyección de la oferta
        2. Generador	  : Potencia ofertada
	    3.Nodo_r:		    Nodo de retiro
	    4. Energía Declarada: Ofertas en dólares de CF
        5. Precio bloque inyeccion 1: Precio del MWh ofertado 
	    6. Magnitud bloque  inyeccion 1 : Cantidad de MW a flexibilizar
        7. Precio bloque inyeccion 2: Precio del MWh ofertado 
	    8. Magnitud bloque  inyeccion 2 : Cantidad de MW a flexibilizar
        9. Precio bloque inyeccion 3: Precio del MWh ofertado 
	    10. Magnitud bloque  inyeccion 3: Cantidad de MW a flexibilizar
        11. Precio bloque inyeccion 4: Precio del MWh ofertado 
	    12. Magnitud bloque  inyeccion 4: Cantidad de MW a flexibilizar
        13. Precio bloque inyeccion 5: Precio del MWh ofertado 
	    14. Magnitud bloque  inyeccion 5: Cantidad de MW a flexibilizar
        15. Precio bloque retiro 1: Precio del MWh ofertado 
	    16. Magnitud bloque  retiro 1 : Cantidad de MW a flexibilizar
        17. Precio bloque retiro 2: Precio del MWh ofertado 
	    18. Magnitud bloque  retiro 2: Cantidad de MW a flexibilizar
        19. Precio bloque retiro 3: Precio del MWh ofertado 
	    20. Magnitud bloque  retiro 3: Cantidad de MW a flexibilizar
        21. Precio bloque retiro 4: Precio del MWh ofertado 
	    22. Magnitud bloque  retiro 4: Cantidad de MW a flexibilizar
        23. Precio bloque retiro 5: Precio del MWh ofertado 
	    24. Magnitud bloque  retiro 5: Cantidad de MW a flexibilizar
        25. k si hay ofertas de max CVT va le 0 sino 1
        26. Precio bloque max CVT 1: Precio del MWh ofertado 
	    27. Magnitud bloque MAX CVT 1 : Cantidad de MW a flexibilizar
        28. Precio bloque max CVT 2: Precio del MWh ofertado 
	    29. Magnitud bloque MAX CVT 2: Cantidad de MW a flexibilizar
        30. Precio bloque max CVT 3: Precio del MWh ofertado 
	    31. Magnitud bloque MAX CVT 3: Cantidad de MW a flexibilizar
        32. Precio bloque max CVT 4: Precio del MWh ofertado 
	    33. Magnitud bloque MAX CVT 4: Cantidad de MW a flexibilizar
        34. Precio bloque max CVT 5: Precio del MWh ofertado 
	    35. Magnitud bloque MAX CVT 5: Cantidad de MW a flexibilizar
    """

    ofer_cnfffi = read_excel(predespacho_file,sheet_name='cnfff')
    ofer_cnfffi.columns = ['N°','nodo_cnfffi','generador','nodo_cnfffr','energía_dec','precio_i1','magnitud_i1','precio_i2','magnitud_i2','precio_i3','magnitud_i3','precio_i4','magnitud_i4','precio_i5','magnitud_i5','precio_r1','magnitud_r1','precio_r2','magnitud_r2','precio_r3','magnitud_r3','precio_r4','magnitud_r4','precio_r5','magnitud_r5','k','precio_cvt1','magnitud_cvt1','precio_cvt2','magnitud_cvt2','precio_cvt3','magnitud_cvt3','precio_cvt4','magnitud_cvt4','precio_cvt5','magnitud_cvt5']
    
    return ofer_cnfffi

def MATRIZ_OOI(bus, ex):
    """Construye el vector de variables binareas de las  Ofertas de Oportunidad de Inyeccion existentes
    
    Vector cuya dimensión es C{nb}, en donde nb es el número de nodos, y cuyas
    componentes son todas nulas, salvo la correspondiente al nodo de retiro
    del derecho firme donde tiene el valor de 1
    
    La función regresa una matriz de dimensión C{nb x ne}, en donde C{nb} es el
    número de nodos y C{ne} es el número de derechos firmes existentes. Cada
    columna de la matriz es el vector VRTEe de cada derecho firme e.
    
    """
    
    _vooi = zeros((bus.shape[0], ex.shape[0]))
    
    for i in range(0, ex.shape[0]):
        _vooi[bus[bus == ex.iloc[i].nodo_i].index[0],i] = 1
        
    return _vooi

def MATRIZ_OOR(bus, ex):
    """Construye el vector de variables binareas de las  Ofertas de Oportunidad de Retiro existentes
    
    Vector cuya dimensión es C{nb}, en donde nb es el número de nodos, y cuyas
    componentes son todas nulas, salvo la correspondiente al nodo de retiro
    del derecho firme donde tiene el valor de 1
    
    La función regresa una matriz de dimensión C{nb x ne}, en donde C{nb} es el
    número de nodos y C{ne} es el número de derechos firmes existentes. Cada
    columna de la matriz es el vector VRTEe de cada derecho firme e.
    """
    
    _voor = zeros((bus.shape[0], ex.shape[0]))
    
    for i in range(0, ex.shape[0]):
        _voor[bus[bus == ex.iloc[i].nodo_oor].index[0],i] = 1
        
    return _voor



def MATRIZ_CFR(bus, ex):
    """Construye el vector VCD de Potencia Requerida 
    
    Vector cuya dimensión es C{nb}, en donde nb es el número de nodos, y cuyas
    componentes son todas nulas, salvo la correspondiente al nodo de retiro
    del derecho firme donde tiene el valor correspondiene a la inyección
    asociada al derecho
    
    La función regresa una matriz de dimensión C{nb x ne}, en donde C{nb} es el
    número de nodos y C{ne} es el número de derechos firmes existentes. Cada
    columna de la matriz es el vector VRTEe de cada derecho firme e.
    
    """
    
    _vcf_pr = zeros((bus.shape[0], ex.shape[0]))
    
    for i in range(0, ex.shape[0]):
        _vcf_pr[bus[bus == ex.iloc[i].nodo_cfr].index[0],i] = 1
        
    return _vcf_pr

def MATRIZ_CFI(bus, ex):
    """Construye el vector VCD de Precio del bloque 1 Requerida 
    
    Vector cuya dimensión es C{nb}, en donde nb es el número de nodos, y cuyas
    componentes son todas nulas, salvo la correspondiente al nodo de retiro
    del derecho firme donde tiene el valor correspondiene a la inyección
    asociada al derecho
    
    La función regresa una matriz de dimensión C{nb x ne}, en donde C{nb} es el
    número de nodos y C{ne} es el número de derechos firmes existentes. Cada
    columna de la matriz es el vector VRTEe de cada derecho firme e.
    
    """
    
    _vcf_p = zeros((bus.shape[0], ex.shape[0]))
    
    for i in range(0, ex.shape[0]):
        _vcf_p[bus[bus == ex.iloc[i].nodo_cfi].index[0],i] = 1
        
    return _vcf_p

def VCF_M(bus, ex):
    """Construye el vector VCD de Magnitud en MW del bloque 1 Requerida 
    
    Vector cuya dimensión es C{nb}, en donde nb es el número de nodos, y cuyas
    componentes son todas nulas, salvo la correspondiente al nodo de retiro
    del derecho firme donde tiene el valor correspondiene a la inyección
    asociada al derecho
    
    La función regresa una matriz de dimensión C{nb x ne}, en donde C{nb} es el
    número de nodos y C{ne} es el número de derechos firmes existentes. Cada
    columna de la matriz es el vector VRTEe de cada derecho firme e.
    
    """
    
    _vcf_m = zeros((bus.shape[0], ex.shape[0]))
    
    for i in range(0, ex.shape[0]):
        _vcf_m[bus[bus == ex.iloc[i].nodo_cfi].index[0],i] = 1
        
    return _vcf_m

def MATRIZ_VNFFF_I(bus, ex):
    """Construye el vector VNFFF dela Magnitud del bloque declarada en MW del bloque 1 Requerida 
    
    Vector cuya dimensión es C{nb}, en donde nb es el número de nodos, y cuyas
    componentes son todas nulas, salvo la correspondiente al nodo de retiro
    del derecho firme donde tiene el valor correspondiene a la inyección
    asociada al derecho
    
    La función regresa una matriz de dimensión C{nb x ne}, en donde C{nb} es el
    número de nodos y C{ne} es el número de derechos firmes existentes. Cada
    columna de la matriz es el vector VRTEe de cada derecho firme e.
    
    """
    
    _vnfff_m_i = zeros((bus.shape[0], ex.shape[0]))
    
    for i in range(0, ex.shape[0]):
        _vnfff_m_i[bus[bus == ex.iloc[i].nodo_cnfffi].index[0],i] = 1
        
    return _vnfff_m_i

def MATRIZ_VNFFF_R(bus, ex):
    """Construye el vector VNFFF dela Magnitud del bloque declarada en MW del bloque 1 Requerida 
    
    Vector cuya dimensión es C{nb}, en donde nb es el número de nodos, y cuyas
    componentes son todas nulas, salvo la correspondiente al nodo de retiro
    del derecho firme donde tiene el valor correspondiene a la inyección
    asociada al derecho
    
    La función regresa una matriz de dimensión C{nb x ne}, en donde C{nb} es el
    número de nodos y C{ne} es el número de derechos firmes existentes. Cada
    columna de la matriz es el vector VRTEe de cada derecho firme e.
    
    """
    
    _vnfff_m_r = zeros((bus.shape[0], ex.shape[0]))
    
    for i in range(0, ex.shape[0]):
        _vnfff_m_r[bus[bus == ex.iloc[i].nodo_cnfffr].index[0],i] = 1
        
    return _vnfff_m_r
