import os
import sys
import glob
import argparse
import math
import string
import copy as _copy
from collections import namedtuple
from operator import attrgetter
import datetime

# psstools.ImportPSSE(33)
# psstools.EnableExceptions()
import psstools
import psspy
psspy.psseinit(100000)
import xlrd
import xlwt
import xlutils
from xlutils.copy import copy
import openpyxl
# import setHvdcDispatch
import setHvdcDispatch_state2

temp_sum = 0
WSCCArea = 15
test_index = 0 

_f, _i, _s = psspy._f, psspy._i, psspy._s 

# Branch = namedtuple("Branch", 'bus1 bus2 id')
# class InsufficientSourceError(Exception):
	# def __init__(self):
		# print "INSUFFICIENT SOURCE ASSET"	
		
		
		
class InsufficientSourceError(Exception):
	def __init__(self, load_AIES, gen_AIES, loss_total_AIES, comment):
		print "INSUFFICIENT SOURCE ASSET"
		self.load_AIES = load_AIES
		self.gen_AIES = gen_AIES
		self.loss_total_AIES = loss_total_AIES
		self.comment = comment

class iterationLimitError(Exception):
	def __init__(self, mismatch, iterationNumber, load_AIES, gen_AIES, loss_total_AIES):
		self.iterationNumber = iterationNumber
		self.mismatch = mismatch
		self.load_AIES = load_AIES
		self.gen_AIES = gen_AIES
		self.loss_total_AIES = loss_total_AIES

class solutionError(Exception):
	def __init__(self, solvedMsg, load_AIES, gen_AIES, loss_total_AIES):
		self.solvedMsg = solvedMsg
		self.load_AIES = load_AIES
		self.gen_AIES = gen_AIES
		self.loss_total_AIES = loss_total_AIES

class HvdcSolutionError(Exception):
	def __init__(self, load_AIES, gen_AIES, loss_total_AIES):
		print "HVDC Solution ERROR"
		self.load_AIES = load_AIES
		self.gen_AIES = gen_AIES
		self.loss_total_AIES = loss_total_AIES

class tieFlowMismatchError(Exception):
	def __init__(self, load_AIES, gen_AIES, loss_total_AIES):
		print "Tie Flow Mismatch ERROR"
		self.load_AIES = load_AIES
		self.gen_AIES = gen_AIES
		self.loss_total_AIES = loss_total_AIES
		
def col2num(c):
    ###"""Return number corresponding to excel-style column."""
    number=-25
    for l in c:
        if not l in string.ascii_letters:
            return False
        number+=ord(l.upper())-64+25-1
		
    return number



def solve_initial():
	psspy.solution_parameters_4([_i,50,_i,_i,10],[_f,_f,_f,_f,_f,_f,_f,_f,_f,_f,_f,_f,_f,_f,_f,_f,_f,_f,_f])
	psspy.fnsl([0,0,0,1,2,0,99,0]) #### FNSL_Lock tap_ Enable SVC
	err = psspy.solved()
	assert err == 0
	
	return err


def checkSol():
	psspy.fnsl([0,0,0,1,2,0,99,0]) #### FNSL_Lock tap_ Enable SVC
	psspy.fnsl([0,0,0,1,2,0,99,0]) #### FNSL_Lock tap_ Enable SVC
	solved = psspy.solved()
	if solved == 0:
		psspy.progress("+++++++++++++++++++++++++ SOLVED PROPERLY +++++++++++++++++ \n")
		# print iterN
		return solved
	# elif solved ==1 :
		# return solved
	else:
		print "Not Solved"
		solvedMsg = {0: "Solved", 1: "Iteration limit exceeded", 2: "Blown up", 5: "Singular Jacobian or voltage of 0.0 detected"}[solved]
		
		load_AIES, gen_AIES, loss_total_AIES, loss_alshnt = GetSystemTotals(True)
		
		psspy.progress("+++++++++++++++++++++++++ NOT SOLVED PROPERLY +++++++++++++++++ \n")
		psspy.progress("+++++++++++++++++++++++++ NOT SOLVED PROPERLY +++++++++++++++++ \n")
		psspy.progress("+++++++++++  %s ++++++++++++ \n" %solvedMsg)
		
		raise solutionError(solvedMsg, load_AIES, gen_AIES, loss_total_AIES+loss_alshnt)
		
def caseprep_Solve():
	def fdnsSolveLocked():
		psspy.progress("\n FDNS - Lock tap Lock All\n")
		psspy.fdns([0,0,0,1,0,0,99,0])
		psspy.fdns([0,0,0,1,0,0,99,0])
		# psspy.fdns([0,0,0,1,1,0,99,0])
		psspy.progress("\n FDNS - Lock tap Enable SVC Only\n")
		psspy.fdns([0,0,0,1,2,0,99,0])
		psspy.fdns([0,0,0,1,2,0,99,0])
	def fnslSolveLocked():
		psspy.progress("\n FNSL - Lock tap Lock All\n")
		psspy.fnsl([0,0,0,1,0,0,99,0])
		psspy.fnsl([0,0,0,1,0,0,99,0])
		# psspy.fnsl([0,0,0,1,1,0,99,0])
		psspy.progress("\n FNSL - Lock tap Enable SVC Only\n")
		psspy.fnsl([0,0,0,1,2,0,99,0])
		psspy.fnsl([0,0,0,1,2,0,99,0])
		
	def fnslSolve():
		psspy.progress("\n FNSL - Lock tap Enable All\n")
		psspy.fnsl([0,0,0,1,1,0,99,0])
		psspy.fnsl([0,0,0,1,1,0,99,0])
		psspy.progress("\n FNSL - Lock tap Enable SVC Only\n")
		psspy.fnsl([0,0,0,1,2,0,99,0])
		psspy.fnsl([0,0,0,1,2,0,99,0])
		
	def fdnsSolve():
		psspy.progress("\n FDNS - Lock tap Enable all shunts\n")
		psspy.fdns([0,0,0,1,1,0,99,0])
		psspy.fdns([0,0,0,1,1,0,99,0])
		psspy.progress("\n FDNS - Lock tap Enable SVC Only\n")
		psspy.fdns([0,0,0,1,2,0,99,0])
		psspy.fdns([0,0,0,1,2,0,99,0])
		
		
	psspy.save("Saved_working_case_temp.sav")
	fnslSolve()
	solved = psspy.solved()
	if solved != 0:
		psspy.case("Saved_working_case_temp.sav")
		fdnsSolve()
		solved = psspy.solved()
	if solved != 0:
		psspy.case("Saved_working_case_temp.sav")
		fnslSolveLocked()
		solved = psspy.solved()
	if solved != 0:
		psspy.case("Saved_working_case_temp.sav")
		fdnsSolveLocked()
		solved = psspy.solved()
	checkSol()
	

		
		
# class solutionError(Exception):
	# def __init__(self, solvedMsg):
		# self.solvedMsg = solvedMsg
		
		

def TieMeasure():
	##############
	#####20-Mar-2019
	print "Measure Ab-Bc Tie Flow (+Ve is Import, -Ve is Export) ... "
	Pm = 0
	# ab_bc
	for br in ab_bc:
		# print br
		err, temp_flow = psspy.brnflo(br[0], br[1], br[2])
		Pm += temp_flow.real
	
	# abbc_tieFlow = -Pm.real
	abbc_tieFlow = Pm.real
	print "AB-BC Tie Flow MW (+Ve is Import, -Ve is Export): ", abbc_tieFlow
	
	if abbc_tieFlow >= 0:
		print("Import")  
	else: 
		print("Export")
	
	return abbc_tieFlow

def GetSystemTotals_rev0(excludeWSCC):
	###### Updated by SDR
	############ 20-Mar-2019
	print "Determine System Total ..."
	# system99load = GetSystem99Load(excludeWSCC)
	ierr, totals2, motors2 = psspy.scal_2(0, 1, 0, (0, 0, 0, 0, 0), (0, 0, 0, 0, 0, 0, 0))
	motorLoad = -totals2[6]
	# totalLoad_99_plus_motor = system99load + motorLoad
	# print system99load, motorLoad
	if not excludeWSCC:
		err, load = psspy.systot("LOAD")
		err, gen = psspy.systot("GEN")
		err, loss = psspy.systot("LOSS") 
		err, alshnt = psspy.systot("ALSHNT") 
		
		status, sk_pload, sk_qload = getLoadData(skTie_bus, skTie_loadId)
		status, mt_pgen, pmax, pmin, qmax, qmin, mbase = GetGenData(mtTie_genbus, mtTie_genId)
		
		# if pload < 0:
			# totalLoad = load.real - pload
		# else:
			# totalLoad = load.real - pload
		
		totalLoad = load.real - sk_pload
		totalGen = gen.real - mt_pgen
		# if mt_pgen>0:
			# totalGen = gen.real - mt_pgen
		# else:
			# totalGen = gen.real
		# return load.real, gen.real, loss.real, alshnt.real
		return totalLoad, totalGen, loss.real, alshnt.real
	
	
	load_AIES, gen_AIES, loss_AIES, loss_alshnt = GetSystemTotals(False)
	# print load_AIES, gen_AIES, loss_AIES, loss_alshnt
	# load_AIES, gen_AIES, loss_AIES, loss_alshnt = excludeWSCCinfo()
	err, load_wscc = psspy.ardat(WSCCArea, 'LOAD')
	err, gen_wscc = psspy.ardat(WSCCArea, 'GEN')
	err, loss_wscc = psspy.ardat(WSCCArea, 'LOSS')
	err, loss_alshnt = psspy.systot("ALSHNT")
	
	# print load_wscc, gen_wscc, loss_wscc, loss_alshnt
	# raw_input()
	if load_wscc != None:
		load_AIES = load_AIES - load_wscc.real
	else:
		load_AIES = load_AIES
	
	gen_AIES = gen_AIES - gen_wscc.real
	loss_AIES = loss_AIES - loss_wscc.real
	loss_alshnt = loss_alshnt.real
	loss_total_AIES = loss_AIES
	print "load_AIES	gen_AIES	loss_total_AIES"
	print load_AIES, gen_AIES, loss_total_AIES+loss_alshnt
	# raw_input("---")
	
	return load_AIES, gen_AIES, loss_total_AIES, loss_alshnt


def GetSystemTotals(excludeWSCC):
	########## Updated - 27 Apr - 2020
	print "Determine System Total ..."
	# system99load = GetSystem99Load(excludeWSCC)
	ierr, totals2, motors2 = psspy.scal_2(0, 1, 0, (0, 0, 0, 0, 0), (0, 0, 0, 0, 0, 0, 0))
	motorLoad = -totals2[6]
	# totalLoad_99_plus_motor = system99load + motorLoad
	# print system99load, motorLoad
	if not excludeWSCC:
		err, load = psspy.systot("LOAD")
		err, gen = psspy.systot("GEN")
		err, loss = psspy.systot("LOSS")
		err, alshnt = psspy.systot("ALSHNT")
		
		sk_pload = 0
		mt_pgen = 0
		
		if skTie_bus != "N/A" and skTie_loadId != "N/A":
			status, sk_pload, sk_qload = getLoadData(skTie_bus, skTie_loadId)
		
		if mtTie_genbus != "N/A" and mtTie_genId != "N/A":
			status, mt_pgen, pmax, pmin, qmax, qmin, mbase = GetGenData(mtTie_genbus, mtTie_genId)
		
		# if pload < 0:
		# totalLoad = load.real - pload
		# else:
		# totalLoad = load.real - pload
		
		totalLoad = load.real - sk_pload
		totalGen = gen.real - mt_pgen
		# if mt_pgen>0:
		# totalGen = gen.real - mt_pgen
		# else:
		# totalGen = gen.real
		# return load.real, gen.real, loss.real, alshnt.real
		return totalLoad, totalGen, loss.real, alshnt.real
	
	load_AIES, gen_AIES, loss_AIES, loss_alshnt = GetSystemTotals(False)
	# print load_AIES, gen_AIES, loss_AIES, loss_alshnt
	# load_AIES, gen_AIES, loss_AIES, loss_alshnt = excludeWSCCinfo()
	err, load_wscc = psspy.ardat(WSCCArea, 'LOAD')
	err, gen_wscc = psspy.ardat(WSCCArea, 'GEN')
	err, loss_wscc = psspy.ardat(WSCCArea, 'LOSS')
	err, loss_alshnt = psspy.systot("ALSHNT")
	
	# print load_wscc, gen_wscc, loss_wscc, loss_alshnt
	# raw_input()
	if load_wscc != None:
		load_AIES = load_AIES - load_wscc.real
	else:
		load_AIES = load_AIES
	
	gen_AIES = gen_AIES - gen_wscc.real
	loss_AIES = loss_AIES - loss_wscc.real
	loss_alshnt = loss_alshnt.real
	loss_total_AIES = loss_AIES
	print
	"load_AIES	gen_AIES	loss_total_AIES"
	print
	load_AIES, gen_AIES, loss_total_AIES + loss_alshnt
	# raw_input("---")
	
	return load_AIES, gen_AIES, loss_total_AIES, loss_alshnt


class mpidObject(object):  ## Updated by SDR 20 Mar 2019
	# def __init__(self, mpidName, facilityName, loadmpid, tag, lfTaG, generators, loads, interfaceBus, MPID_buses, netFlow ):
	def __init__(self, mpidName=None, facilityName=None, lfTag=None, loadmpids=None, emmoOffer=None, loadOffer=None, locationType=None, generators=None, onsiteLoads=None, loadDistributionFactor=None, interfaceBus=None, MPID_buses=None, netFlow=None ):
		self.mpidName = mpidName
		self.facilityName = facilityName
		self.lfTag = lfTag
		self.loadmpids = loadmpids
		self.emmoOffer = emmoOffer
		self.loadOffer = loadOffer 
		
		self.locationType = locationType
		
		self.generators = generators
		self.onsiteLoads = onsiteLoads
		self.loadDistributionFactor = loadDistributionFactor
		
		self.interfaceBus = interfaceBus
		self.MPID_buses = MPID_buses
		self.netFlow = netFlow	
		
class Case(object):
	
	# def __init__(self, topologyCase, filename, intertie, MPIDs, MOList, loadData, loadMapping, tssData):
	# def __init__(self, topologyCase, intertie, MPIDs, MOList, hourly_output_dir, month, year, state1_munit, s1_hvdcParameters):
	def __init__(self, caseFile, intertie, MPIDs, currentHourEMMO, currentHourLoad, currentHourMvarLoad, hourly_output_dir, month, year, state1_munitInfo, state1_hvdcInfo, state1_totalInfo, state1_IE_flows):
		
		self.topologyCase = caseFile
		self.currentHourEMMO_original = currentHourEMMO
		self.currentHourEMMO = []
		self.currentHourLoad = currentHourLoad
		self.currentHourMvarLoad = currentHourMvarLoad
		
		self.MPIDs = MPIDs
		self.currentHourExports, self.Total_currentHourExports_MW = self.determineTotalExport()
		
		self.hourly_output_dir = hourly_output_dir
		self.month = month
		self.year = year
		
		##### Information from Initial State #####
		self.state1_munitInfo = state1_munitInfo
		self.state1_hvdcInfo = state1_hvdcInfo
		self.state1_totalInfo = state1_totalInfo
		self.state1_IE_flows = state1_IE_flows
		
		self.state1_owsp = state1_hvdcInfo["OWSP"] 
		self.state1_oesp = state1_hvdcInfo["OESP"]
		self.state1_watlflow = state1_hvdcInfo["watlFlow"] 
		self.state1_eatlflow = state1_hvdcInfo["eatlFlow"] 
		
		self.state1_initialVolumeDict = dict()
		
		self.state1_deductibleNetLoadDict = dict()
		self.state1_reducedNetLoadDict = dict()
		# self.state1_deltaLoadDict = dict()
		# self.state1_deltaLoadDict = dict()
		
		
		######################################
		##########################################
		self.MarginalUnit = meritorderData()
		self.MarginalUnitReserve = 0
		
		
		self.LFMPID = ''
		self.LFMPID_mUnit = meritorderData()
		self.LFMPID_mpidUnit = mpidObject()
		
		self.initial_btfGen_dispatched = 0
		self.btfGen_ss_net_gross = dict()
		self.initial_btfGen_dispatched, self.btfGen_ss_net_gross = self.determine_BTFGen_for_netEMMO_GrossLoad()
		
		# self.state1_loss = self.state1_totalInfo["total_aies_loss"] - determine_mpidInternalLoss(self.MPIDs)
		self.state1_totalAiesLoss = 0
		self.state1_totalCustomerLoss = 0
		self.state1_systemLoss = 0
		
		
		########### These Info Will be Updated for each MPID ###
		self.state1_initialVolume = 0
		self.state1_deltaLoad = 0
		
		########### Re-dispatched state Info .......
		self.state2_RedispVolume = dict()
		self.state2_readjustedNetLoadDict = dict()
		self.state2_totalAiesLoss = dict()
		self.state2_totalCustomerLoss = dict()
		self.state2_systemLoss = dict()
		
		self.state2_MarginalUnit = dict()
		self.state2_MarginalUnitReserve = dict()
		
		self.state2_owsp = dict()
		self.state2_oesp = dict()
		self.state2_watlflow = dict()
		self.state2_eatlflow = dict()
		
		self.state2_total_load = dict()
		self.state2_total_gen = dict()
		self.state2_IE_flows = dict()
		self.state2_marginalUnitMismatch = dict()
		self.state2_rlf = dict()
		
		self.state2_status = dict()
		self.state2_comment = dict()
		
		self.state2_psselogFile = dict()
		self.state2_emmoLog = dict()
		
		self.bcTieMismatch = dict()
		self.skTieMismatch = dict()
		self.mtTieMismatch = dict()
		
		self.bcTieFlow = dict()
		self.skTieFlow = dict()
		self.mtTieFlow = dict()
		
		
		
		print len(self.currentHourEMMO_original)
		# for eachemmo in self.currentHourEMMO_original:
			# MPID = self.findMU_MPID_info(currentHourEMMO_original)
			# if MPID == []:
				# self.currentHourEMMO.remove(currentHourEMMO_original)
			
		# print len(self.currentHourEMMO_original)
		
	def determineAvailableMW(self, currentHourEMMO, mpidName):
		############# Updated by SDR - 24May2019
		totalAvailableMW = 0
		foundTag = 0
		if len(currentHourEMMO) != 0:
			for eachrow in currentHourEMMO:
				if eachrow.assetName == mpidName:
					foundTag = 1
					totalAvailableMW = totalAvailableMW + eachrow.availablePower
		return totalAvailableMW, foundTag
		
	
	
	def determine_BTFGen_for_netEMMO_GrossLoad(self):
		############# Updated by SDR - 24May2019
		############################
		mpidlist_ss_net_gross = []
		btfGen_ss_net_gross = dict()
		for MPID in self.MPIDs:
			if MPID.locationType == "Self-supply":
				if MPID.emmoOffer == "Net-to-grid" and MPID.loadOffer == "Gross":
					mpidlist_ss_net_gross.append(MPID)
		
		total_btfGen_dispatched = 0
		for eachMPID in mpidlist_ss_net_gross:
			totalAvailableMW, foundTag = self.determineAvailableMW(self.currentHourEMMO_original, eachMPID.mpidName)
			if totalAvailableMW > 0 and foundTag == 1:
				loadmpids = eachMPID.loadmpids
				onsiteLoads = eachMPID.onsiteLoads
				genMPID = eachMPID.mpidName
				# dataToUseTag = 'Load Data'
				btfLoad_mwData = 0
				if len(loadmpids) > 0:
					for loadmpid in loadmpids:
						loads = onsiteLoads[loadmpid]
						btfLoad_mwData += getLoadMWData(loadmpid, self.currentHourLoad) * eachMPID.loadDistributionFactor	
				btfGen_mwData = btfLoad_mwData
				control = "Increase"
				# UpdateWorkingMPID(btfGen_mwData, eachMPID, control, fulldispatchamount=None)
				btfGen_ss_net_gross[eachMPID.mpidName] = btfGen_mwData
				
				total_btfGen_dispatched = total_btfGen_dispatched + btfGen_mwData
		# enable_print()
		print total_btfGen_dispatched, btfGen_ss_net_gross
		# raw_input()
		return total_btfGen_dispatched, btfGen_ss_net_gross
	
	
	def determineTotalExport(self):
		
		currentHourExports = dict()
		Total_currentHourExports_MW = 0
		for exportService in exportServices:
			# currentSerial = row.serial
			# currentAssetName = row.assetName
			totalExportMW = 0
			for eachrow in self.currentHourEMMO_original:
				if eachrow.Import_Export == "E" and eachrow.assetName == exportService:
					totalExportMW = totalExportMW + eachrow.availablePower
			# currentHourExports.append(export(mpidName, totalExportMW))
			currentHourExports[exportService] = totalExportMW
			Total_currentHourExports_MW += currentHourExports[exportService]
		
		return currentHourExports, -Total_currentHourExports_MW
				
				
				
				
				
	def findMU_MPID_info(self, eachemmo):
		MPID = []
		for eachMPID in self.MPIDs:
			if eachMPID.mpidName == eachemmo.assetName:
				MPID = eachMPID
				break
		# if MPID == []:
			# raise ValueError
		return MPID
		
	def SetSwingBus(self):
		buses, types = psspy.abusint(-1, 1, ("NUMBER", "TYPE"))
		for bus, type in zip(buses, types):
			if type == 3:
				psspy.bus_chng_3(bus, (2, ))
				break
		psspy.bus_chng_3(self.swingBus, (3, ))
		
	def GetSwingBusMW(self):
		p = 0
		try:
			psspy.inimac(self.swingBus)
			psstools.IgnoreErrorCodes = set((4,))
			while True:
				id = psspy.nxtmac(self.swingBus)
				status = psspy.macint(self.swingBus, id, 'STATUS')
				if status == 1:
					p += psspy.macdat(self.swingBus, id, 'P')
		except :
			pass
		psstools.IgnoreErrorCodes = set()
		return p
		
	def MeasureSwingBus(self):
		psstools.IgnoreErrorCodes = set((4,))
		gen = psspy.gendat(self.swingBus).real
		psstools.IgnoreErrorCodes = set()
		return 
		
	
	# def findMUReserve(self, MarginalUnit):
		# print MarginalUnit.assetName, "----", int(MarginalUnit.serial)
		# for eachMPID in self.MPIDs:
			# if eachMPID.mpidName == MarginalUnit.assetName:
				# MPID = eachMPID
				# break
		# Pdisp, totalPmax = determineMPID_Gen(MPID)
		# # Ptotal_uptoCurrentBlock = MarginalUnit.totalDisp_eachMPID    ###determineMU_Info(MarginalUnit)  ### Define
		# # Ptotal_previousBlock = MarginalUnit.totalDisp_eachMPID - MarginalUnit.availablePower
		# munit_reserve = MarginalUnit.totalDisp_eachMPID - Pdisp
		# print "munit_reserve : ", munit_reserve 
		# # raw_input()

		# return munit_reserve
	
	
		
	def FindMarginalUnit(self, LFMPID):  ###### Updated by SDR
		##### UPdated by SDR - 29 Mar2019
		#####################################
		print "Find Marginal Unit .... "
		print "LFMPID : " , LFMPID
		tag = ''
		# MarginalUnit = 0
		for mUnit in self.currentHourEMMO:
			# print mUnit.serial, LFMPID, self.state1_munitInfo["serial"]
			# raw_input()
			if tag != 'STOP':
				if mUnit.serial == self.state1_munitInfo["serial"]:
					if mUnit.assetName != LFMPID:
						MarginalUnit = mUnit
						tag = 'STOP'
						print mUnit.P_export_dict
						# raw_input()
						break
					else:
						MarginalUnit = self.UpdateMarginalUnit_caseprep(mUnit, 'NEXT', LFMPID)
						tag = 'STOP'
						break
			else:
				break
		print "MarginalUnit : ", MarginalUnit.serial, MarginalUnit.assetName, MarginalUnit.P_export_dict
		
		# sys.exit()
		return MarginalUnit
	
	
	def UpdateMarginalUnit_caseprep(self, currentMarginalUnit, cntrl, LFMPID):
		##########Update Marginal Unit################
		############# Updated by SDR - 20Mar2019######
		##############################################
		print "---------------------------"
		print "Update Marginal Unit .... ", cntrl
		Match = False
		tag = "Unavailable"
		
		target_bctie = 0
		update_target_bcie = 'False'
		
		if cntrl == 'NEXT':
			for GSOUnit in self.currentHourEMMO:      
				# print "Hello" , GSOUnit.gsoMPID, GSOUnit.gsoNumber
				if not Match:
					if GSOUnit.serial == currentMarginalUnit.serial:
						Match = True
					continue
				else :
					if GSOUnit.availablePower == 0 or GSOUnit.assetName == LFMPID:
						continue
					
					# print "GSOUnit.gsoNumber - mpid", GSOUnit.gsoNumber , GSOUnit.gsoMPID
					tag = "Found"
					print "---Return Update MU-----"
					return GSOUnit 
					break
				
		elif cntrl == 'PREV':
			for GSOUnit in reversed(self.currentHourEMMO):    
					
				if not Match:
					if GSOUnit.serial == currentMarginalUnit.serial:
						Match = True
					continue
				else :
					if GSOUnit.availablePower == 0 or GSOUnit.assetName == LFMPID:
						continue
					
					# print "GSOUnit.gsoNumber - mpid", GSOUnit.gsoNumber , GSOUnit.gsoMPID
					
					tag = "Found"
					print "---Return Update MU-----"
					return GSOUnit 
					break			
		if tag == "Unavailable":
			load_AIES, gen_AIES, loss_total_AIES, loss_alshnt = GetSystemTotals(True)
			raise InsufficientSourceError(load_AIES, gen_AIES, loss_total_AIES+loss_alshnt, "UpdateMarginalUnit_caseprep")
			# raise InsufficientSourceError

					
	
	
					
	
	def ProcessMPID(self, MPID):
		# psspy.startrecording(1, os.path.join(self.path, "%s.py" % mpidCaseName))
		
		# psspy.case(self.filename)
		# psspy.solution_parameters_4((psspy._i, 50), (psspy._f,) *5 + (0.01, ))
		
		
		
		
		def findMarginalUnitReserve_v0(MarginalUnit):
			########## Determine MU reserve .....
			############# Updated by SDR - 20Mar2019
			print "Determine MU Reserve ... "
			MPID = findMarginalUnit_MPID_info(MarginalUnit)
			totalPgen, totalPmax = determineMPID_Gen(MPID) 
			
			if MarginalUnit.relatedImportAsset == bc_imp:
				# MarginalUnitReserve = MarginalUnit.P_netImportExport - totalPgen
				MarginalUnitReserve = MarginalUnit.P_netImportExport_dict[bc] - totalPgen
			elif MarginalUnit.relatedImportAsset == sk_imp:
				# MarginalUnitReserve = MarginalUnit.P_netImportExport - totalPgen
				MarginalUnitReserve = MarginalUnit.P_netImportExport_dict[sk] - totalPgen
			elif MarginalUnit.relatedImportAsset == mt_imp:
				# MarginalUnitReserve = MarginalUnit.P_netImportExport - totalPgen
				MarginalUnitReserve = MarginalUnit.P_netImportExport_dict[mt] - totalPgen
			
			else:
				if MarginalUnit.reduceLoadTag.upper() == 'YES' and MarginalUnit.finalNTGLoad > 0:
					MarginalUnitReserve = MarginalUnit.finalNTGLoad + MarginalUnit.totalDisp_eachMPID - totalPgen
				else:
					MarginalUnitReserve = MarginalUnit.totalDisp_eachMPID - totalPgen
			
			
			
			
			print "MarginalUnitReserve : ", MarginalUnitReserve
			return MarginalUnitReserve	
		
		def findMarginalUnitReserve(MarginalUnit):
			########## Determine MU reserve .....
			############# Updated by SDR - 27May2019
			print "Determine MU Reserve ... "
			MPID = findMarginalUnit_MPID_info(MarginalUnit)
			totalPgen, totalPmax = determineMPID_Gen(MPID) 
			print "Current Pgen : ", totalPgen
			
			if MarginalUnit.relatedImportAsset == bc_imp or MarginalUnit.relatedImportAsset == sk_imp or MarginalUnit.relatedImportAsset == mt_imp:
				MarginalUnitReserve = MarginalUnit.P_netImportExport - totalPgen
			else:
				if MarginalUnit.reduceLoadTag.upper() == 'YES' and MarginalUnit.finalNTGLoad > 0:
					MarginalUnitReserve = MarginalUnit.finalNTGLoad + MarginalUnit.totalDisp_eachMPID - totalPgen
				else:
					if MPID.emmoOffer == "Net-to-grid" and MPID.loadOffer == "Gross":
						MarginalUnitReserve = MarginalUnit.totalDisp_eachMPID - (totalPgen - self.btfGen_ss_net_gross[MPID.mpidName])
					else:
						MarginalUnitReserve = MarginalUnit.totalDisp_eachMPID - totalPgen
			print "MarginalUnitReserve : ", MarginalUnitReserve
			return MarginalUnitReserve
		
		def UpdateWorkingMPID(delta, workingMPID, control, fulldispatchamount=None):
			########## Update Working MPID Generation.....
			############# Updated by SDR - 20Mar2019
			print "--------------------------------------------"
			print "Updating Working MPID ....... "
			delta = abs(delta)
			MPID = workingMPID
			totalPgen, totalPmax = determineMPID_Gen(MPID)
			totalPload, totalQload = determineMPID_Load(MPID)
			print MPID.mpidName, "Current Total Pgen : ", totalPgen
			print MPID.mpidName, "Current Total PLoad : ", totalPload
			print "Control Mode : ", control
			print "Delta : ", delta
			print "---------------------------------------------"
			
			if control == "Reduce":
				mpidgenerators = MPID.generators
				sortedmpidgenerators = sorted(mpidgenerators, key=attrgetter('id'), reverse = True)
				for gen in sortedmpidgenerators:
					status, pgen, pmax, pmin, qmax, qmin, mbase = GetGenData(gen.bus, gen.id)
					print "pgen  : ", pgen
					if status == 0 :
						raise 
					else:
					# if status != 0 :
						if delta>pgen:
							newpgen = 0
							newstatus = 1
							delta = delta - pgen
							UpdateGen(gen.bus, gen.id, newpgen, newstatus)
							# raw_input("=====")
							print "delta :", delta
							# raw_input()
						elif delta<pgen:
							newpgen = pgen - delta
							delta = 0
							newstatus  = 1
							UpdateGen(gen.bus, gen.id, newpgen, newstatus)
							# raw_input("=====")
							print "delta :", delta
							break
						elif delta == pgen:
							newpgen = 0
							delta = 0
							newstatus = 1
							UpdateGen(gen.bus, gen.id, newpgen, newstatus)
							# raw_input("=====")
							print "delta :", delta
							break
			elif control == "Increase":
				mpidgenerators = MPID.generators
				sortedmpidgenerators = sorted(mpidgenerators, key=attrgetter('id'), reverse = False)
				for gen in sortedmpidgenerators:
					status, pgen, pmax, pmin, qmax, qmin, mbase = GetGenData(gen.bus, gen.id)
					print gen.bus, gen.id, status, pgen, pmax, pmin, qmax, qmin, mbase
					# raw_input()
					print delta
					if status == 0 :
						raise "Gen Turned Off.....!!!!!!!!!!!!!"
					if pgen < pmax:
						if (delta+pgen) > pmax:
							newpgen = pmax
							newstatus = 1
							delta = delta - (pmax - pgen)
							# raw_input("=====")
							print newpgen, newstatus, delta
							UpdateGen(gen.bus, gen.id, newpgen, newstatus)
							
						else: ## delta < pmax
							newpgen = pgen + delta
							delta = 0
							newstatus = 1 
							# raw_input("=====")
							print newpgen, newstatus, delta
							UpdateGen(gen.bus, gen.id, newpgen, newstatus)
							break
					else:
						continue
				if delta != 0 :
					print delta
					# raw_input("Could not dispatch all")
					sortedmpidgenerators = sorted(mpidgenerators, key=attrgetter('id'), reverse = True)
					for gen in sortedmpidgenerators:
						status, pgen, pmax, pmin, qmax, qmin, mbase = GetGenData(gen.bus, gen.id)
						print gen.bus, gen.id, status, pgen, pmax, pmin, qmax, qmin, mbase
						if status != 0:
							newstatus = 1
							UpdateGen_Max(gen.bus, gen.id, pgen+delta, pgen+delta, newstatus)
							break
					
				sortedmpidgenerators = sorted(mpidgenerators, key=attrgetter('id'), reverse = False)
				temp = 0
				for gen in sortedmpidgenerators:
					status, pgen, pmax, pmin, qmax, qmin, mbase = GetGenData(gen.bus, gen.id)
					print gen.bus, gen.id, status, pgen, pmax
					temp = temp + pgen
				print temp
				# raw_input()
			
			elif control == "Increase Load":
				if len(MPID.loadmpids) > 0:
					for loadmpid in MPID.loadmpids:
						loads = MPID.onsiteLoads[loadmpid]
						# mwData = getLoadMWData(loadmpid, dataToUse) * MPID.loadDistributionFactor
						mwData = delta /len(MPID.loadmpids)
						pf = getLoadPfData(loadmpid, self.currentHourMvarLoad)
						print "==============================="
						print loadmpid, mwData
						
						for load in loads:
							
							loadbus = int(load.split("-")[0])
							loadid = load.split("-")[1]
							status, pload, qload = getLoadData(loadbus, loadid)
							
							del_pload = mwData/len(loads)
							# pf = 0.9
							del_qload = del_pload * math.tan(math.acos(pf)) 
							
							if pload != 0:
								status = 1
							else:
								status = 0
							
							
							print (loadbus, loadid, status, pload+del_pload, qload+del_qload)
							
							psspy.progress ("\n %s, %s, %s, %s, %s\n" %(loadbus, loadid, status, pload+del_pload, qload+del_qload))
							psspy.progress("\n Updating Load...\n")
							
							UpdateLoad(loadbus, loadid, status, pload+del_pload, qload+del_qload)						
			
			elif control == "Reduce Load":
				if len(MPID.loadmpids) > 0:
					for loadmpid in MPID.loadmpids:
						loads = MPID.onsiteLoads[loadmpid]
						# mwData = getLoadMWData(loadmpid, dataToUse) * MPID.loadDistributionFactor
						mwData = delta/len(MPID.loadmpids)
						pf = getLoadPfData(loadmpid, self.currentHourMvarLoad)
						print "==============================="
						print loadmpid, mwData
						
						for load in loads:
							
							loadbus = int(load.split("-")[0])
							loadid = load.split("-")[1]
							status, pload, qload = getLoadData(loadbus, loadid)
							
							del_pload = mwData/len(loads)
							# pf = 0.9
							del_qload = del_pload * math.tan(math.acos(pf)) 
							
							if pload != 0:
								status = 1
							else:
								status = 0
							
							print (loadbus, loadid, status, pload-del_pload, qload-del_qload)
							
							psspy.progress ("\n %s, %s, %s, %s, %s\n" %(loadbus, loadid, status, pload-del_pload, qload-del_qload))
							psspy.progress("\n Updating Load...\n")
							
							UpdateLoad(loadbus, loadid, status, pload-del_pload, qload-del_qload)						
				
				

			
			elif control == "SwitchOff":
				mpidgenerators = MPID.generators
				sortedmpidgenerators = sorted(mpidgenerators, key=attrgetter('id'), reverse = True)
				for gen in sortedmpidgenerators:
					newpgen = 0
					newstatus = 0 
					UpdateGen(gen.bus, gen.id, newpgen, newstatus)
			elif control == "Full Dispatch":
				mpidgenerators = MPID.generators
				sortedmpidgenerators = sorted(mpidgenerators, key=attrgetter('id'), reverse = False)
				for gen in sortedmpidgenerators:
					status, pgen, pmax, pmin, qmax, qmin, mbase = GetGenData(gen.bus, gen.id)
					newpgen = pmax
					newstatus = 1
					UpdateGen(gen.bus, gen.id, newpgen, newstatus)
				totalPgen, totalPmax = determineMPID_Gen(MPID)
				print totalPgen, totalPmax
				# raw_input()
				if fulldispatchamount != totalPgen:
					sortedmpidgenerators = sorted(mpidgenerators, key=attrgetter('id'), reverse = True)
					extra = fulldispatchamount - totalPgen
					print extra
					for gen in sortedmpidgenerators:
						status, pgen, pmax, pmin, qmax, qmin, mbase = GetGenData(gen.bus, gen.id)
						newpgen = pmax
						newstatus = 1
						UpdateGen_Max(gen.bus, gen.id, pmax+extra, pmax+extra, newstatus)
			
			
			print "================Update Working MPID - DONE ==============="
			totalPgen, totalPmax = determineMPID_Gen(MPID)
			totalPload, totalQload = determineMPID_Load(MPID)
			print MPID.mpidName, "Current Total Pgen : ", totalPgen
			print MPID.mpidName, "Current Total PLoad : ", totalPload
			print "---------------------Return-----------------------------"
		
		
		
		def UpdateSystem_v0(deltaNetFlow, MarginalUnit, control, LFMPID):
			########## Update System Generation .....
			############# Updated by SDR - 20Mar2019
			print "====================Update System+++++++++++++++++++++++++++++++"
			
			MarginalUnitReserve = findMarginalUnitReserve(MarginalUnit)
			print "MU : ", MarginalUnit.serial, MarginalUnit.assetName, MarginalUnit.blockNumber, MarginalUnit.assetShortName
			print "MarginalUnitReserve ", MarginalUnitReserve
			print "control : ", control
			print "........................................."
			
			if MarginalUnit.relatedImportAsset == bc_imp:
				# desiredSwingBus = assignSwingBus(MarginalUnit)
				target_bctie = MarginalUnit.P_netImportExport_dict[bc]
				minimum_bctie_blockValue = MarginalUnit.availablePower
				previous_target_bctie = MarginalUnit.P_prev_netImportExport_dict[bc]
				caseprep_Solve()
				current_bctie = TieMeasure()
				print target_bctie, previous_target_bctie, current_bctie
				# raw_input("=====Check=====")
				if current_bctie > target_bctie:
					mismatch = abs(current_bctie - target_bctie)
					print "mismatch : ", mismatch
					MarginalUnit = self.UpdateMarginalUnit_caseprep(MarginalUnit, "NEXT", LFMPID)
					MarginalUnitReserve = findMarginalUnitReserve(MarginalUnit)
					MarginalUnit = UpdateSystem(mismatch, MarginalUnit, "Increase", LFMPID)
					caseprep_Solve()
					current_bctie = TieMeasure()
					
					mismatch = abs(current_bctie - target_bctie)
					print "MU : ", MarginalUnit.serial, MarginalUnit.assetName, MarginalUnit.blockNumber
					print "MarginalUnitReserve :", MarginalUnitReserve
					print "current_bctie :", current_bctie
					print "mismatch :", mismatch
				elif current_bctie <= previous_target_bctie:
					mismatch = abs(current_bctie - previous_target_bctie)
					print "mismatch : ", mismatch
					MarginalUnit = self.UpdateMarginalUnit_caseprep(MarginalUnit, "PREV", LFMPID)
					MarginalUnitReserve = findMarginalUnitReserve(MarginalUnit)
					MarginalUnit = UpdateSystem(mismatch, MarginalUnit, "Reduce", LFMPID)
					caseprep_Solve()
					current_bctie = TieMeasure()
					mismatch = abs(current_bctie - previous_target_bctie)
					print "MU : ", MarginalUnit.assetName, MarginalUnit.blockNumber
					print "MarginalUnitReserve :", MarginalUnitReserve
					print "current_bctie :", current_bctie
					print "mismatch :", mismatch
				elif current_bctie <= target_bctie and current_bctie > previous_target_bctie:
					MarginalUnitReserve = findMarginalUnitReserve(MarginalUnit)
					print "MU : ", MarginalUnit.serial, MarginalUnit.assetName, MarginalUnit.blockNumber
					print "MarginalUnitReserve :", MarginalUnitReserve
					print "current_bctie :", current_bctie
					# raw_input()
			elif MarginalUnit.relatedImportAsset == sk_imp:
				MPID = findMarginalUnit_MPID_info(MarginalUnit)
				# saskbus = 1473
				# saskImploadid = '34'
				delta = abs(deltaNetFlow)
				target_sasktie = MarginalUnit.P_netImportExport_dict[sk]
				previous_target_sasktie = MarginalUnit.P_prev_netImportExport_dict[sk]
				minimum_sasktie_blockValue = MarginalUnit.availablePower
				current_sasktie, temp = determineMPID_Gen(MPID)
				
				if control == "Increase":
					final_sasktie = current_sasktie + delta
										
					if final_sasktie >= target_sasktie:
						status = 1
						setSk_Tie(target_sasktie)
						# err = psspy.load_chng_4(skTie_bus, skTie_loadId, (status,_i,_i,_i,_i,_i), (-target_sasktie, _f, _f,_f,_f,_f)  )
						# MarginalUnit, MarginalUnitReserve = self.UpdateMarginalUnit_caseprep(MarginalUnit, "NEXT", "")
						MarginalUnit = self.UpdateMarginalUnit_caseprep(MarginalUnit, "NEXT", LFMPID)
						delta = final_sasktie - target_sasktie
					elif final_sasktie < target_sasktie and final_sasktie >= previous_target_sasktie:
						status = 1
						setSk_Tie(final_sasktie)
						# err = psspy.load_chng_4(skTie_bus, skTie_loadId, (status,_i,_i,_i,_i,_i), (-final_sasktie, _f, _f,_f,_f,_f)  )
						delta = 0
					
				elif control == "Reduce":
					final_sasktie = current_sasktie - delta	
					if final_sasktie < target_sasktie and final_sasktie >= previous_target_sasktie:
						status = 1
						setSk_Tie(final_sasktie)
						# err = psspy.load_chng_4(skTie_bus, skTie_loadId, (status,_i,_i,_i,_i,_i), (-final_sasktie, _f, _f,_f,_f,_f))
						delta = 0
					elif final_sasktie < previous_target_sasktie:
						status = 0
						setSk_Tie(previous_target_sasktie)
						# err = psspy.load_chng_4(skTie_bus, skTie_loadId, (status,_i,_i,_i,_i,_i), (-previous_target_sasktie, _f, _f,_f,_f,_f))
						MarginalUnit = self.UpdateMarginalUnit_caseprep(MarginalUnit, "PREV", LFMPID)
						delta = previous_target_sasktie - final_sasktie
			elif MarginalUnit.relatedImportAsset == mt_imp:
				MPID = findMarginalUnit_MPID_info(MarginalUnit)
				delta = abs(deltaNetFlow)
				target_mtTie = MarginalUnit.P_netImportExport_dict[mt]
				previous_target_mtTie = MarginalUnit.P_prev_netImportExport_dict[mt]
				# minimum_sasktie_blockValue = MarginalUnit.availablePower
				current_mtTie, temp = determineMPID_Gen(MPID)
				
				if control == "Increase":
					final_mtTie = current_mtTie + delta
										
					if final_mtTie >= target_mtTie:
						status = 1
						setMT_Tie(target_mtTie)
						# err = psspy.load_chng_4(skTie_bus, skTie_loadId, (status,_i,_i,_i,_i,_i), (-target_mtTie, _f, _f,_f,_f,_f)  )
						# MarginalUnit, MarginalUnitReserve = self.UpdateMarginalUnit_caseprep(MarginalUnit, "NEXT", "")
						MarginalUnit = self.UpdateMarginalUnit_caseprep(MarginalUnit, "NEXT", LFMPID)
						delta = final_mtTie - target_mtTie
					elif final_mtTie < target_mtTie and final_mtTie >= previous_target_mtTie:
						status = 1
						setMT_Tie(final_mtTie)
						# err = psspy.load_chng_4(skTie_bus, skTie_loadId, (status,_i,_i,_i,_i,_i), (-final_mtTie, _f, _f,_f,_f,_f)  )
						delta = 0
					
				elif control == "Reduce":
					final_mtTie = current_mtTie - delta	
					if final_mtTie < target_mtTie and final_mtTie >= previous_target_mtTie:
						status = 1
						setMT_Tie(final_mtTie)
						# err = psspy.load_chng_4(skTie_bus, skTie_loadId, (status,_i,_i,_i,_i,_i), (-final_mtTie, _f, _f,_f,_f,_f))
						delta = 0
					elif final_mtTie < previous_target_mtTie:
						status = 0
						setMT_Tie(previous_target_mtTie)
						# err = psspy.load_chng_4(skTie_bus, skTie_loadId, (status,_i,_i,_i,_i,_i), (-previous_target_mtTie, _f, _f,_f,_f,_f))
						MarginalUnit = self.UpdateMarginalUnit_caseprep(MarginalUnit, "PREV", LFMPID)
						delta = previous_target_mtTie - final_mtTie	
			else:
				if control == "Increase":
				# if deltaNetFlow<0:  #### Working MPID Gen was reduced to nullify the netFlow - Increase Total Gen Dispatch
					delta = abs(deltaNetFlow)
					for mUnit in self.currentHourEMMO:
						if mUnit.serial == MarginalUnit.serial:
							MU_MPID = findMarginalUnit_MPID_info(MarginalUnit)
							MarginalUnitReserve = findMarginalUnitReserve(MarginalUnit)
							if delta > MarginalUnitReserve:
								print "delta ", delta
								# raw_input()
								if mUnit.reduceLoadTag.upper() == 'YES' and mUnit.finalNTGLoad > 0:
									UpdateWorkingMPID(mUnit.finalNTGLoad, MU_MPID, "Reduce Load")
									MarginalUnitReserve = MarginalUnitReserve - mUnit.finalNTGLoad
									mUnit.finalNTGLoad = 0
									UpdateWorkingMPID(MarginalUnitReserve, MU_MPID, "Increase")
								else:
									UpdateWorkingMPID(MarginalUnitReserve, MU_MPID, "Increase")
								delta = delta - MarginalUnitReserve
								# MarginalUnit, MarginalUnitReserve = self.UpdateMarginalUnit(MarginalUnit, "NEXT", LFMPID)
								MarginalUnit = self.UpdateMarginalUnit_caseprep(MarginalUnit, "NEXT", LFMPID)
								MarginalUnitReserve = findMarginalUnitReserve(MarginalUnit)
								# MarginalUnitReserve = MarginalUnit.availablePower
								continue
							elif delta <= MarginalUnitReserve:
								print "delta ", delta
								# raw_input()
								if mUnit.reduceLoadTag.upper() == 'YES' and mUnit.finalNTGLoad > 0:
									if delta > mUnit.finalNTGLoad:
										UpdateWorkingMPID(mUnit.finalNTGLoad, MU_MPID, "Reduce Load")
										delta = delta - mUnit.finalNTGLoad
										mUnit.finalNTGLoad = 0
										UpdateWorkingMPID(delta, MU_MPID, "Increase")
										delta = 0
									else:
										UpdateWorkingMPID(delta, MU_MPID, "Reduce Load")
										delta = 0
								else:
									UpdateWorkingMPID(delta, MU_MPID, "Increase")
								MarginalUnitReserve = findMarginalUnitReserve(MarginalUnit)
								break
				elif control == "Reduce":
				# elif deltaNetFlow>0:  #### Working MPID Ges was reduced to nullify the netFlow - Increase Total Gen Dispatch
					delta = abs(deltaNetFlow)
					for mUnit in self.currentHourEMMO:
						if mUnit.serial == MarginalUnit.serial:
							MU_MPID = findMarginalUnit_MPID_info(MarginalUnit)
							MarginalUnitReserve = findMarginalUnitReserve(MarginalUnit)
							Pdisp = mUnit.availablePower - MarginalUnitReserve
							if mUnit.reduceLoadTag.upper() == 'YES':
								reducedLoad = mUnit.deductibleNTGLoad - mUnit.finalNTGLoad
								if mUnit.finalNTGLoad >= 0 and Pdisp <= 0:
									if delta <= reducedLoad:
										UpdateWorkingMPID(delta, MU_MPID, "Increase Load")
										mUnit.finalNTGLoad = mUnit.finalNTGLoad + delta
										MarginalUnitReserve = MarginalUnitReserve + delta
										delta = 0
										break
									else:
										UpdateWorkingMPID(reducedLoad, MU_MPID, "Increase Load")
										mUnit.finalNTGLoad = mUnit.finalNTGLoad + reducedLoad
										MarginalUnit = self.UpdateMarginalUnit_caseprep(MarginalUnit, "PREV", LFMPID)
										MarginalUnitReserve = 0
										delta = delta - reducedLoad
										continue
								elif mUnit.finalNTGLoad == 0 and Pdisp > 0:
									if delta <= Pdisp:
										UpdateWorkingMPID(delta, MU_MPID, "Reduce")
										MarginalUnitReserve = MarginalUnitReserve + delta
										delta = 0
										break
									else:  ##delta > Pdisp:
										UpdateWorkingMPID(Pdisp, MU_MPID, "Reduce")
										MarginalUnitReserve = MarginalUnitReserve + Pdisp
										delta = delta - Pdisp
										if delta >= reducedLoad:
											UpdateWorkingMPID(reducedLoad, MU_MPID, "Increase Load")
											mUnit.finalNTGLoad = mUnit.finalNTGLoad + reducedLoad
											MarginalUnit = self.UpdateMarginalUnit_caseprep(MarginalUnit, "PREV", LFMPID)
											delta = delta - reducedLoad
											continue
										else: ## delta < reducedLoad:
											UpdateWorkingMPID(delta, MU_MPID, "Increase Load")
											mUnit.finalNTGLoad = mUnit.finalNTGLoad + delta
											MarginalUnitReserve = MarginalUnitReserve + delta
											delta = 0
											break
							else:
								print "Pdisp :", Pdisp
								# raw_input()
								if delta > Pdisp:
									UpdateWorkingMPID(Pdisp, MU_MPID, "Reduce")
									delta = delta - Pdisp
									MarginalUnit = self.UpdateMarginalUnit_caseprep(MarginalUnit, "PREV", LFMPID)
									MarginalUnitReserve = 0
									continue
								else: ## delta <= Pdisp:
									UpdateWorkingMPID(delta, MU_MPID, "Reduce")
									MarginalUnitReserve = MarginalUnitReserve + delta
									delta = 0
									# raw_input("=====")
									print "delta :", delta
									break
			print "============================Return From Update System-----------"
			print MarginalUnit.serial, MarginalUnit.assetName
			# raw_input()
			
			return MarginalUnit
			
		def UpdateSystem(deltaNetFlow, MarginalUnit, control, LFMPID):
			########## Update System Generation .....
			############# Updated by SDR - 20Mar2019
			print "====================Update System+++++++++++++++++++++++++++++++"
			
			MarginalUnitReserve = findMarginalUnitReserve(MarginalUnit)
			print "MU : ", MarginalUnit.serial, MarginalUnit.assetName, MarginalUnit.blockNumber, MarginalUnit.assetShortName
			print "MarginalUnitReserve ", MarginalUnitReserve
			print "control : ", control
			print "........................................."
			
			if MarginalUnit.relatedImportAsset == bc_imp:
				# desiredSwingBus = assignSwingBus(MarginalUnit)
				target_bctie = MarginalUnit.P_netImportExport_dict[bc]
				minimum_bctie_blockValue = MarginalUnit.availablePower
				previous_target_bctie = MarginalUnit.P_prev_netImportExport_dict[bc]
				caseprep_Solve()
				current_bctie = TieMeasure()
				print target_bctie, previous_target_bctie, current_bctie
				# raw_input("=====Check=====")
				if current_bctie > target_bctie:
					mismatch = abs(current_bctie - target_bctie)
					print "mismatch : ", mismatch
					MarginalUnit = self.UpdateMarginalUnit_caseprep(MarginalUnit, "NEXT", LFMPID)
					MarginalUnitReserve = findMarginalUnitReserve(MarginalUnit)
					MarginalUnit = UpdateSystem(mismatch, MarginalUnit, "Increase", LFMPID)
					caseprep_Solve()
					current_bctie = TieMeasure()
					
					mismatch = abs(current_bctie - target_bctie)
					print "MU : ", MarginalUnit.serial, MarginalUnit.assetName, MarginalUnit.blockNumber
					print "MarginalUnitReserve :", MarginalUnitReserve
					print "current_bctie :", current_bctie
					print "mismatch :", mismatch
				elif current_bctie <= previous_target_bctie:
					mismatch = abs(current_bctie - previous_target_bctie)
					print "mismatch : ", mismatch
					MarginalUnit = self.UpdateMarginalUnit_caseprep(MarginalUnit, "PREV", LFMPID)
					MarginalUnitReserve = findMarginalUnitReserve(MarginalUnit)
					MarginalUnit = UpdateSystem(mismatch, MarginalUnit, "Reduce", LFMPID)
					caseprep_Solve()
					current_bctie = TieMeasure()
					mismatch = abs(current_bctie - previous_target_bctie)
					print "MU : ", MarginalUnit.assetName, MarginalUnit.blockNumber
					print "MarginalUnitReserve :", MarginalUnitReserve
					print "current_bctie :", current_bctie
					print "mismatch :", mismatch
				elif current_bctie <= target_bctie and current_bctie > previous_target_bctie:
					MarginalUnitReserve = findMarginalUnitReserve(MarginalUnit)
					print "MU : ", MarginalUnit.serial, MarginalUnit.assetName, MarginalUnit.blockNumber
					print "MarginalUnitReserve :", MarginalUnitReserve
					print "current_bctie :", current_bctie
					# raw_input()
			elif MarginalUnit.relatedImportAsset == sk_imp:
				MPID = findMarginalUnit_MPID_info(MarginalUnit)
				# saskbus = 1473
				# saskImploadid = '34'
				delta = abs(deltaNetFlow)
				target_sasktie = MarginalUnit.P_netImportExport_dict[sk]
				previous_target_sasktie = MarginalUnit.P_prev_netImportExport_dict[sk]
				minimum_sasktie_blockValue = MarginalUnit.availablePower
				current_sasktie, temp = determineMPID_Gen(MPID)
				
				if control == "Increase":
					final_sasktie = current_sasktie + delta
										
					if final_sasktie >= target_sasktie:
						status = 1
						setSk_Tie(target_sasktie)
						# err = psspy.load_chng_4(skTie_bus, skTie_loadId, (status,_i,_i,_i,_i,_i), (-target_sasktie, _f, _f,_f,_f,_f)  )
						# MarginalUnit, MarginalUnitReserve = self.UpdateMarginalUnit_caseprep(MarginalUnit, "NEXT", "")
						MarginalUnit = self.UpdateMarginalUnit_caseprep(MarginalUnit, "NEXT", LFMPID)
						delta = final_sasktie - target_sasktie
					elif final_sasktie < target_sasktie and final_sasktie >= previous_target_sasktie:
						status = 1
						setSk_Tie(final_sasktie)
						# err = psspy.load_chng_4(skTie_bus, skTie_loadId, (status,_i,_i,_i,_i,_i), (-final_sasktie, _f, _f,_f,_f,_f)  )
						delta = 0
					
				elif control == "Reduce":
					final_sasktie = current_sasktie - delta	
					if final_sasktie < target_sasktie and final_sasktie >= previous_target_sasktie:
						status = 1
						setSk_Tie(final_sasktie)
						# err = psspy.load_chng_4(skTie_bus, skTie_loadId, (status,_i,_i,_i,_i,_i), (-final_sasktie, _f, _f,_f,_f,_f))
						delta = 0
					elif final_sasktie < previous_target_sasktie:
						status = 0
						setSk_Tie(previous_target_sasktie)
						# err = psspy.load_chng_4(skTie_bus, skTie_loadId, (status,_i,_i,_i,_i,_i), (-previous_target_sasktie, _f, _f,_f,_f,_f))
						MarginalUnit = self.UpdateMarginalUnit_caseprep(MarginalUnit, "PREV", LFMPID)
						delta = previous_target_sasktie - final_sasktie
			elif MarginalUnit.relatedImportAsset == mt_imp:
				MPID = findMarginalUnit_MPID_info(MarginalUnit)
				delta = abs(deltaNetFlow)
				target_mtTie = MarginalUnit.P_netImportExport_dict[mt]
				previous_target_mtTie = MarginalUnit.P_prev_netImportExport_dict[mt]
				# minimum_sasktie_blockValue = MarginalUnit.availablePower
				current_mtTie, temp = determineMPID_Gen(MPID)
				
				if control == "Increase":
					final_mtTie = current_mtTie + delta
										
					if final_mtTie >= target_mtTie:
						status = 1
						setMT_Tie(target_mtTie)
						# err = psspy.load_chng_4(skTie_bus, skTie_loadId, (status,_i,_i,_i,_i,_i), (-target_mtTie, _f, _f,_f,_f,_f)  )
						# MarginalUnit, MarginalUnitReserve = self.UpdateMarginalUnit_caseprep(MarginalUnit, "NEXT", "")
						MarginalUnit = self.UpdateMarginalUnit_caseprep(MarginalUnit, "NEXT", LFMPID)
						delta = final_mtTie - target_mtTie
					elif final_mtTie < target_mtTie and final_mtTie >= previous_target_mtTie:
						status = 1
						setMT_Tie(final_mtTie)
						# err = psspy.load_chng_4(skTie_bus, skTie_loadId, (status,_i,_i,_i,_i,_i), (-final_mtTie, _f, _f,_f,_f,_f)  )
						delta = 0
					
				elif control == "Reduce":
					final_mtTie = current_mtTie - delta	
					if final_mtTie < target_mtTie and final_mtTie >= previous_target_mtTie:
						status = 1
						setMT_Tie(final_mtTie)
						# err = psspy.load_chng_4(skTie_bus, skTie_loadId, (status,_i,_i,_i,_i,_i), (-final_mtTie, _f, _f,_f,_f,_f))
						delta = 0
					elif final_mtTie < previous_target_mtTie:
						status = 0
						setMT_Tie(previous_target_mtTie)
						# err = psspy.load_chng_4(skTie_bus, skTie_loadId, (status,_i,_i,_i,_i,_i), (-previous_target_mtTie, _f, _f,_f,_f,_f))
						MarginalUnit = self.UpdateMarginalUnit_caseprep(MarginalUnit, "PREV", LFMPID)
						delta = previous_target_mtTie - final_mtTie	
			else:
				if control == "Increase":
				# if deltaNetFlow<0:  #### Working MPID Gen was reduced to nullify the netFlow - Increase Total Gen Dispatch
					delta = abs(deltaNetFlow)
					for mUnit in self.currentHourEMMO:
						if mUnit.serial == MarginalUnit.serial:
							MU_MPID = findMarginalUnit_MPID_info(MarginalUnit)
							MarginalUnitReserve = findMarginalUnitReserve(MarginalUnit)
							if delta > MarginalUnitReserve:
								print "delta ", delta
								# raw_input()
								if mUnit.reduceLoadTag.upper() == 'YES' and mUnit.finalNTGLoad > 0:
									UpdateWorkingMPID(mUnit.finalNTGLoad, MU_MPID, "Reduce Load")
									MarginalUnitReserve = MarginalUnitReserve - mUnit.finalNTGLoad
									mUnit.finalNTGLoad = 0
									UpdateWorkingMPID(MarginalUnitReserve, MU_MPID, "Increase")
								else:
									UpdateWorkingMPID(MarginalUnitReserve, MU_MPID, "Increase")
								
								delta = delta - MarginalUnitReserve
								MarginalUnit = self.UpdateMarginalUnit_caseprep(MarginalUnit, "NEXT", LFMPID)
								MarginalUnitReserve = findMarginalUnitReserve(MarginalUnit)
								MarginalUnit = UpdateSystem(delta, MarginalUnit, "Increase", LFMPID)
								break
							elif delta <= MarginalUnitReserve:
								print "delta ", delta
								# raw_input()
								if mUnit.reduceLoadTag.upper() == 'YES' and mUnit.finalNTGLoad > 0:
									if delta > mUnit.finalNTGLoad:
										UpdateWorkingMPID(mUnit.finalNTGLoad, MU_MPID, "Reduce Load")
										delta = delta - mUnit.finalNTGLoad
										mUnit.finalNTGLoad = 0
										UpdateWorkingMPID(delta, MU_MPID, "Increase")
										delta = 0
									else:
										UpdateWorkingMPID(delta, MU_MPID, "Reduce Load")
										delta = 0
								else:
									UpdateWorkingMPID(delta, MU_MPID, "Increase")
								MarginalUnitReserve = findMarginalUnitReserve(MarginalUnit)
								break
				elif control == "Reduce":
				# elif deltaNetFlow>0:  #### Working MPID Ges was reduced to nullify the netFlow - Increase Total Gen Dispatch
					delta = abs(deltaNetFlow)
					for mUnit in self.currentHourEMMO:
						if mUnit.serial == MarginalUnit.serial:
							MU_MPID = findMarginalUnit_MPID_info(MarginalUnit)
							MarginalUnitReserve = findMarginalUnitReserve(MarginalUnit)
							Pdisp = mUnit.availablePower - MarginalUnitReserve
							if mUnit.reduceLoadTag.upper() == 'YES':
								reducedLoad = mUnit.deductibleNTGLoad - mUnit.finalNTGLoad
								if mUnit.finalNTGLoad >= 0 and Pdisp <= 0:
									if delta <= reducedLoad:
										UpdateWorkingMPID(delta, MU_MPID, "Increase Load")
										mUnit.finalNTGLoad = mUnit.finalNTGLoad + delta
										MarginalUnitReserve = MarginalUnitReserve + delta
										delta = 0
										break
									else:
										UpdateWorkingMPID(reducedLoad, MU_MPID, "Increase Load")
										mUnit.finalNTGLoad = mUnit.finalNTGLoad + reducedLoad
										MarginalUnit = self.UpdateMarginalUnit_caseprep(MarginalUnit, "PREV", LFMPID)
										MarginalUnitReserve = 0
										delta = delta - reducedLoad
										MarginalUnit = UpdateSystem(delta, MarginalUnit, "Reduce", LFMPID)
										break
										# continue
								elif mUnit.finalNTGLoad == 0 and Pdisp > 0:
									if delta <= Pdisp:
										UpdateWorkingMPID(delta, MU_MPID, "Reduce")
										MarginalUnitReserve = MarginalUnitReserve + delta
										delta = 0
										break
									else:  ##delta > Pdisp:
										UpdateWorkingMPID(Pdisp, MU_MPID, "Reduce")
										MarginalUnitReserve = MarginalUnitReserve + Pdisp
										delta = delta - Pdisp
										if delta >= reducedLoad:
											UpdateWorkingMPID(reducedLoad, MU_MPID, "Increase Load")
											mUnit.finalNTGLoad = mUnit.finalNTGLoad + reducedLoad
											MarginalUnit = self.UpdateMarginalUnit_caseprep(MarginalUnit, "PREV", LFMPID)
											delta = delta - reducedLoad
											MarginalUnit = UpdateSystem(delta, MarginalUnit, "Reduce", LFMPID)
											break
											# continue
										else: ## delta < reducedLoad:
											UpdateWorkingMPID(delta, MU_MPID, "Increase Load")
											mUnit.finalNTGLoad = mUnit.finalNTGLoad + delta
											MarginalUnitReserve = MarginalUnitReserve + delta
											delta = 0
											break
							else:
								print "Pdisp :", Pdisp
								# raw_input()
								if delta > Pdisp:
									UpdateWorkingMPID(Pdisp, MU_MPID, "Reduce")
									delta = delta - Pdisp
									MarginalUnit = self.UpdateMarginalUnit_caseprep(MarginalUnit, "PREV", LFMPID)
									MarginalUnitReserve = 0
									MarginalUnit = UpdateSystem(delta, MarginalUnit, "Reduce", LFMPID)
									break
									# continue
								else: ## delta <= Pdisp:
									UpdateWorkingMPID(delta, MU_MPID, "Reduce")
									MarginalUnitReserve = MarginalUnitReserve + delta
									delta = 0
									# raw_input("=====")
									print "delta :", delta
									break
			print "============================Return From Update System-----------"
			print MarginalUnit.serial, MarginalUnit.assetName
			# raw_input()
			
			return MarginalUnit
			
		
		def checkMarginalUnit(MarginalUnit, MOList, MPIDs):
			print MarginalUnit.assetName, "----", int(MarginalUnit.serial)
			for eachMPID in MPIDs:
				if eachMPID.mpidName == MarginalUnit.assetName:
					MPID = eachMPID
					break
			Pdisp, totalPmax = determineMPID_Gen(MPID)
			Pavailable = MarginalUnit.totalDisp_eachMPID    ###determineMU_Info(MarginalUnit)  ### Define
			Palready = MarginalUnit.totalDisp_eachMPID - MarginalUnit.availablePower
			print Pdisp, totalPmax, Pavailable   
			# raw_input("--------------------")
			
			if Pdisp > Palready and Pdisp < Pavailable:
				delta = 0
				return delta, MarginalUnit
			elif Pdisp < Palready:
				control = "Increase"
				print "-----", control
				delta = abs(Palready - Pdisp)
				UpdateWorkingMPID(0, MPID, control)
				MarginalUnit, xx = self.UpdateMarginalUnit(MarginalUnit, "PREV", LFMPID)
				return delta, MarginalUnit
			elif Pdisp > Pavailable:
				control = "Reduce"
				print "-----", control
				delta = abs(Pavailable - Pdisp)
				UpdateWorkingMPID(delta, MPID, control)
				MarginalUnit, xx = self.UpdateMarginalUnit(MarginalUnit, "NEXT", LFMPID)
				return delta, MarginalUnit
		
		
		def checkMarginalUnit_Mismatch(MarginalUnit):
			########## Determine BC Tie Mismatch.....
			############# Updated by SDR - 20Mar2019
			print "Determine Marginal Unit Mismatch........... "
			psspy.progress("Determine Marginal Unit Mismatch........... ")
			
			for eachMPID in self.MPIDs:
				if eachMPID.mpidName == MarginalUnit.assetName:
					MPID = eachMPID
					break
			
			if MarginalUnit.assetName == bc_imp or MarginalUnit.assetName == bc_exp:
				current = TieMeasure()
				previous = MarginalUnit.P_prev_netImportExport_dict[bc]
				target = MarginalUnit.P_netImportExport_dict[bc]
			elif MarginalUnit.assetName == sk_imp or MarginalUnit.assetName == sk_exp:
				current, xx = determineMPID_Gen(MPID)
				previous = MarginalUnit.P_prev_netImportExport_dict[sk]
				target = MarginalUnit.P_netImportExport_dict[sk]
			
				if current <= previous:
					mismatch = current - previous
				elif current > previous and current <= target:
					mismatch = 0
				elif current > target:
					mismatch = current - target
				
				if mismatch == 0:
					current = TieMeasure()
					previous = MarginalUnit.P_prev_netImportExport_dict[bc]
					target = MarginalUnit.P_netImportExport_dict[bc]
					
			elif MarginalUnit.assetName == mt_imp or MarginalUnit.assetName == mt_exp:
				current, xx = determineMPID_Gen(MPID)
				previous = MarginalUnit.P_prev_netImportExport_dict[mt]
				target = MarginalUnit.P_netImportExport_dict[mt]
			else:
				current, xx = determineMPID_Gen(MPID)
				if MPID.emmoOffer == "Net-to-grid" and MPID.loadOffer == "Gross": 
					target = MarginalUnit.totalDisp_eachMPID + self.btfGen_ss_net_gross[MPID.mpidName]
					previous = (MarginalUnit.totalDisp_eachMPID - MarginalUnit.availablePower) + self.btfGen_ss_net_gross[MPID.mpidName]
				else:
					target = MarginalUnit.totalDisp_eachMPID
					previous = MarginalUnit.totalDisp_eachMPID - MarginalUnit.availablePower
			
			
			if current <= previous:
				mismatch = current - previous
			elif current > previous and current <= target:
				mismatch = 0
			elif current >= target:
				mismatch = current - target 
			print "current, previous, target : ", current, previous, target
			print MarginalUnit.assetName, "Mismatch : ", mismatch
			print "AB-BC :", TieMeasure()
			# raw_input()
			return mismatch	
		
		def assignSwingBus(MarginalUnit, LFMPID):
			# enable_print()
			print " +==== Asigning Swing Bus +++++++++ "
			if MarginalUnit.assetName == bc_imp or MarginalUnit.assetName == bc_exp:
				desiredSwingBus = 1520
			elif MarginalUnit.assetName == sk_imp or MarginalUnit.assetName == sk_exp:
				desiredSwingBus = 1520
			else:
				munitMPID = findMarginalUnit_MPID_info(MarginalUnit)
				mpidgenerators = munitMPID.generators
				sortedmpidgenerators = sorted(mpidgenerators, key=attrgetter('id'), reverse = True)
				for gen in sortedmpidgenerators:
					status, pgen, pmax, pmin, qmax, qmin, mbase = GetGenData(gen.bus, gen.id) ##(gen.bus, gen.id)
					if status != 0:
						desiredSwingBus = gen.bus
						break
			for eachmpid in self.MPIDs:
				if eachmpid.mpidName == LFMPID:
					MPID = eachmpid
					break
			working_mpid_generators = MPID.generators
			workingmpid_gen_buses = []
			for gen in working_mpid_generators:
				workingmpid_gen_buses.append(gen.bus)
			
			print "===== Desired Sw bus : ", desiredSwingBus
			if desiredSwingBus in workingmpid_gen_buses:
				if desiredSwingBus != 1520 and MarginalUnit.assetName not in [sk_exp, bc_exp, mt_exp]:
					raise
			else:
				############ Change the previous swing bus back to Type - 2
				err, [buses, types] = psspy.abusint(-1, 1, ("NUMBER", "TYPE"))
				for bus, type in zip(buses, types):
					if type == 3:
						print "Prev. Swing Bus - ", bus
						psspy.bus_chng_3(bus, (2, ))
						# # if bus == 1473:
							# # # psspy.machine_chng_2(1473,r"""3""",[0,_i,_i,_i,_i,_i],[_f,_f,_f,_f,_f,_f,_f,_f,_f,_f,_f,_f,_f,_f,_f,_f,_f])
							# # psspy.purgmac(1473,r"""3""")
						break
				####  Assign new swing Bus -- Type Code 3
				print "New Swing Bus : ", desiredSwingBus 
				psspy.bus_chng_3(desiredSwingBus,[3,_i,_i,_i],[_f,_f,_f,_f,_f,_f,_f],_s)
				caseprep_Solve()
				return desiredSwingBus
			
		def findMarginalUnit_MPID_info(MarginalUnit):
			# print MarginalUnit.assetName, MarginalUnit.serial
			# raw_input()
			MPID = mpidObject()
			for eachMPID in self.MPIDs:
				if eachMPID.mpidName == MarginalUnit.assetName:
					MPID = eachMPID
					break
			# if MPID == []:
				# raise ValueError
			return MPID
		
		def find_MPID_Object(mpidName):
			# print MarginalUnit.assetName, MarginalUnit.serial
			# raw_input()
			MPID = mpidObject()
			for eachMPID in self.MPIDs:
				if eachMPID.mpidName == mpidName:
					MPID = eachMPID
					break
			# if MPID == []:
				# raise ValueError
			return MPID
		
		def determineMismatch(MarginalUnit):
			########## Determine BC Tie Mismatch.....
			############# Updated by SDR - 20Mar2019
			print "Determine BC Tie Mismatch........... "
			psspy.progress("Determine BC Tie Mismatch........... ")
			
			current_bctie = TieMeasure()
			previous_target_bctie = MarginalUnit.P_prev_netImportExport_dict[bc]
			target_bctie = MarginalUnit.P_netImportExport_dict[bc]
			# if MarginalUnit.assetName != "BCHIMP":
			print MarginalUnit.assetName
			print target_bctie, current_bctie, previous_target_bctie
			
			if MarginalUnit.assetName != bc_imp and MarginalUnit.assetName != bc_exp:
				mismatch = (current_bctie - target_bctie)
			else:
				if current_bctie <= previous_target_bctie:
					mismatch = current_bctie - previous_target_bctie
				elif current_bctie > previous_target_bctie and current_bctie <= target_bctie:
					mismatch = 0
				elif current_bctie > target_bctie:
					mismatch = current_bctie - target_bctie 
			print "Mismatch : ", mismatch
			# raw_input()
			return mismatch
			
		def bctiematch(deltaNetFlow, MarginalUnit, MarginalUnitReserve):
			print "BC Tie Matching .... "
			
			mismatch = determineMismatch(MarginalUnit)
			
			iterationNumber = 1
			print "iterationNumber : ", iterationNumber
			while abs(mismatch) > flowTolerance and iterationNumber < iterationLimit:   #### Reduced Gen in Working MPID - Dispatch Up Total Gen from Merit Order
				
				if mismatch > 0:
					control = "Increase"
				elif mismatch < 0:
					control = "Reduce"
				MarginalUnit = UpdateSystem(mismatch, MarginalUnit, control, self.LFMPID)
				caseprep_Solve()
				mismatch = determineMismatch(MarginalUnit)
				MarginalUnitReserve = findMarginalUnitReserve(MarginalUnit)
				print "mismatch :", mismatch, MarginalUnit.assetName, MarginalUnitReserve
				iterationNumber += 1
				print "iterationNumber : ", iterationNumber
				# raw_input()
			
			if abs(mismatch) > flowTolerance and iterationNumber >= iterationLimit:
				Load, Gen, Loss, ShuntLoss = GetSystemTotals(True)
				raise iterationLimitError(mismatch, iterationNumber, Load, Gen, Loss+ShuntLoss) 
			else:
				print mismatch
				MarginalUnitReserve = findMarginalUnitReserve(MarginalUnit)
				print MarginalUnit.serial, MarginalUnit.assetName, MarginalUnitReserve
				
				
				return MarginalUnit
		

		

		#########################################
		
		def hvdcDispatch():
			print "HVDC Dispatch ...................."
			psspy.progress("\n\n===================================== HVDC Dispatch ==============================================\n")
			caseName = os.path.basename(self.topologyCase)
			outputCaseName = caseName.split(".sav")[0] + "_" + MPID.mpidName + "_BeforeHVDC.sav"
			outputCaseName = os.path.join(self.hourly_output_dir, outputCaseName)
			s1_hvdcParameters = [self.state1_owsp, self.state1_oesp, self.state1_watlflow, self.state1_eatlflow]
			# psspy.save(outputCaseName)
			
			# try:
			# import setHvdcDispatch
			# setHvdcDispatch.hvdcMain(self.month, self.s1_hvdcParameters)
			
			if int(self.year) <= 2015:
				psspy.progress("============HVDC Lines don't Exist===========")
				savedOWSP = "N/A"
				savedOESP = "N/A"
				newWATL = "N/A" 
				newEATL = "N/A"
			else:
				# savedOWSP, savedOESP, newWATL, newEATL = setHvdcDispatch_state2.hvdcMain(self.month, self.year, self.s1_hvdcParameters)
				try: 
					savedOWSP, savedOESP, newWATL, newEATL = setHvdcDispatch_state2.hvdcMain(self.month, self.year, s1_hvdcParameters)
				except:
					Load, Gen, Loss, ShuntLoss = GetSystemTotals(True)
					raise HvdcSolutionError(Load, Gen, Loss+ShuntLoss)
					
			
			
			caseprep_Solve()
			print "==================HVDC Dispatch Done=========="
			psspy.progress("\n ==================HVDC Dispatch Done==========  \n")
			
			caseName = os.path.basename(self.topologyCase)
			outputCaseName = caseName.split(".sav")[0] + "_" + MPID.mpidName + "_AfterHVDC.sav"
			outputCaseName = os.path.join(self.hourly_output_dir, outputCaseName)
			# psspy.save(outputCaseName)
				
			return savedOWSP, savedOESP, newWATL, newEATL
				
		def fineTuneMU_System(marginalUnitMismatch, MarginalUnit, LFMPID):
			print "Fine tuning MUnit............"
			
			# iterLimit = 50
			iterationNumber = 0
			MarginalUnitReserve = findMarginalUnitReserve(MarginalUnit)
			print marginalUnitMismatch, MarginalUnit.assetName
			print "iterationNumber : ", iterationNumber
			while abs(marginalUnitMismatch) > 0.5 and iterationNumber < iterationLimit:
				
				deltaGen = marginalUnitMismatch
				MU_MPID = findMarginalUnit_MPID_info(MarginalUnit)
				print("Adjusting Current MU inside the EMMO dispatch level.....")
				print marginalUnitMismatch, MarginalUnit.assetName, MU_MPID.mpidName
				# raw_input()
				if MU_MPID.mpidName not in [bc_imp, bc_exp, sk_imp, sk_exp]:
					if marginalUnitMismatch > 0:
						# raw_input("Reduce LF gen")
						print ("Reduce LF gen")
						UpdateWorkingMPID(abs(marginalUnitMismatch), MU_MPID, "Reduce")  
					elif marginalUnitMismatch < 0:
						print ("Increase LF gen")
						UpdateWorkingMPID(abs(marginalUnitMismatch), MU_MPID, "Increase")
					
					if marginalUnitMismatch > 0 :
						control = "Increase"
						print "Increase System Total Gen"
					elif marginalUnitMismatch < 0:
						control = "Reduce" 
						print "Reduce System Total Gen"
					
					MarginalUnit = UpdateSystem(marginalUnitMismatch, MarginalUnit, control, self.LFMPID)
				
				
				else:
					MarginalUnit = bctiematch(marginalUnitMismatch, MarginalUnit, MarginalUnitReserve)
				
				MarginalUnitReserve = findMarginalUnitReserve(MarginalUnit) 
				desiredSwingBus = assignSwingBus(MarginalUnit, self.LFMPID)
				caseprep_Solve()
				marginalUnitMismatch = checkMarginalUnit_Mismatch(MarginalUnit)
				print "marginalUnitMismatch : ", marginalUnitMismatch
				# raw_input()
				iterationNumber += 1
				print "iterationNumber : ", iterationNumber
				
			if abs(marginalUnitMismatch) > flowTolerance and iterationNumber >= iterationLimit:
				Load, Gen, Loss, ShuntLoss = GetSystemTotals(True)
				raise iterationLimitError(marginalUnitMismatch, iterationNumber, Load, Gen, Loss+ShuntLoss) 
				
			return 	marginalUnitMismatch, MarginalUnit	
		
		
		def assessSourceAssets(MarginalUnit, MarginalUnitReserve):
			############
			#########Updated by SDR - 01-Apr-2019
			print "assess Source Assets ... "
			remainingCapability = 0
			remainingCapability = remainingCapability + MarginalUnitReserve
			# MarginalUnit, MarginalUnitReserve = UpdateMarginalUnit(MarginalUnit)
			tag = "notMatched"
			for Munit in self.currentHourEMMO:
				if Munit.serial == MarginalUnit.serial:
					tag = "match"
					continue
				else:
					if tag == "match":
						# print Munit.availablePower
						if Munit.reduceLoadTag.upper() == 'YES':
							remainingCapability = remainingCapability + Munit.availablePower + Munit.deductibleNTGLoad
						else:
							remainingCapability = remainingCapability + Munit.availablePower
						# print remainingCapability
					else:
						continue
			print "remainingCapability " , remainingCapability
			# raw_input()
			return remainingCapability
			
		def extractImportExport(MarginalUnit):
			### Updated by SDR - 20 Mar 2019
			print "Extracting Import and Export Flows .... "
			# raw_input()
			
			IE_flows = dict()
			MarginalUnitReserve = findMarginalUnitReserve(MarginalUnit)
			print MarginalUnit.assetName, MarginalUnit.serial, MarginalUnitReserve
			
			# raw_input()
			
			
			IE_flows[bc_imp] = MarginalUnit.P_import_dict[bc]
			IE_flows[bc_exp] = MarginalUnit.P_export_dict[bc]
			IE_flows[sk_imp] = MarginalUnit.P_import_dict[sk]
			IE_flows[sk_exp] = MarginalUnit.P_export_dict[sk]
			IE_flows[mt_imp] = MarginalUnit.P_import_dict[mt]
			IE_flows[mt_exp] = MarginalUnit.P_export_dict[mt]
			
			# for mUnit in self.currentHourEMMO:
				# if mUnit.serial == MarginalUnit.serial:
			if MarginalUnit.assetName == bc_imp:
				IE_flows[bc_imp] = MarginalUnit.P_import_dict[bc] - MarginalUnitReserve
			elif MarginalUnit.assetName == bc_exp:
				IE_flows[bc_exp] = MarginalUnit.P_export_dict[bc] - MarginalUnitReserve
			elif MarginalUnit.assetName == sk_imp:
				IE_flows[sk_imp] = MarginalUnit.P_import_dict[sk] - MarginalUnitReserve
			elif MarginalUnit.assetName == sk_exp:
				IE_flows[sk_exp] = MarginalUnit.P_export_dict[sk] - MarginalUnitReserve
			elif MarginalUnit.assetName == mt_imp:
				IE_flows[mt_imp] = MarginalUnit.P_import_dict[mt] - MarginalUnitReserve
			elif MarginalUnit.assetName == mt_exp:
				IE_flows[mt_exp] = MarginalUnit.P_export_dict[mt] - MarginalUnitReserve	
			
			print IE_flows
			
			
			
			bcTieFlow, skTieFlow, mtTieFlow = determine_All_TieFlows()
			
			print "BC Tie	SK Tie	MT Tie"
			print bcTieFlow, skTieFlow, mtTieFlow
			print IE_flows[bc_imp]+IE_flows[bc_exp], IE_flows[sk_imp]+IE_flows[sk_exp], IE_flows[mt_imp]+IE_flows[mt_exp]
			
			# self.bcTieMismatch[self.LFMPID] = bcTieFlow - (IE_flows[bc_imp]+IE_flows[bc_exp])
			# self.skTieMismatch[self.LFMPID] = skTieFlow - (IE_flows[sk_imp]+IE_flows[sk_exp])
			# self.mtTieMismatch[self.LFMPID] = mtTieFlow - (IE_flows[mt_imp]+IE_flows[mt_exp]) 
			
			self.bcTieMismatch[self.LFMPID], self.skTieMismatch[self.LFMPID], self.mtTieMismatch[self.LFMPID] = determine_All_TieMismatch(MarginalUnit)
			
			return IE_flows
					
		
		def determine_All_TieFlows():
			### Last Updatred - 25 Apr 2020 
			########## Determine All Tie Mismatch.....
			############# Updated by SDR - 20Mar2019
			bcTieFlow = TieMeasure()
			
			# mpidObject_skImp = find_MPID_Object(sk_imp)
			mpidObject_skImp = mpidObject()
			mpidObject_skImp.mpidName = sk_imp
			skTieFlow, temp1 = determineMPID_Gen(mpidObject_skImp)
			
			# mpidObject_mt_imp = find_MPID_Object(mt_imp)
			mpidObject_mt_imp = mpidObject()
			mpidObject_mt_imp.mpidName = mt_imp
			mtTieFlow, temp2 = determineMPID_Gen(mpidObject_mt_imp)
			
			return bcTieFlow, skTieFlow, mtTieFlow
		
		def determine_All_TieMismatch(MarginalUnit):
			### Last Updatred - 25 Apr 2020 
			########## Determine All Tie Mismatch.....
			############# Updated by SDR - 20Mar2019
			print "Determine All Tie Mismatch........... "
			psspy.progress("Determine All Tie Mismatch........... ")
			
			for eachMPID in self.MPIDs:
				if eachMPID.mpidName == MarginalUnit.assetName:
					MPID = eachMPID
					break
			
			
			current_bc = TieMeasure()
			previous_bc = MarginalUnit.P_prev_netImportExport_dict[bc]
			target_bc = MarginalUnit.P_netImportExport_dict[bc]
			if current_bc <= previous_bc:
				bcTieMismatch = current_bc - previous_bc
			elif current_bc > previous_bc and current_bc <= target_bc:
				bcTieMismatch = 0
			elif current_bc >= target_bc:
				bcTieMismatch = current_bc - target_bc
			
			# mpidObject_skImp = find_MPID_Object(sk_imp)
			mpidObject_skImp = mpidObject()
			mpidObject_skImp.mpidName = sk_imp
			current_sk, tempSK = determineMPID_Gen(mpidObject_skImp)
			previous_sk = MarginalUnit.P_prev_netImportExport_dict[sk]
			target_sk = MarginalUnit.P_netImportExport_dict[sk]
			if current_sk <= previous_sk:
				skTieMismatch = current_sk - previous_sk
			elif current_sk > previous_sk and current_sk <= target_sk:
				skTieMismatch = 0
			elif current_sk >= target_sk:
				skTieMismatch = current_sk - target_sk
			
			# mpidObject_mt_imp = find_MPID_Object(mt_imp)
			mpidObject_mt_imp = mpidObject()
			mpidObject_mt_imp.mpidName = mt_imp
			current_mt, tempMT = determineMPID_Gen(mpidObject_mt_imp)
			previous_mt = MarginalUnit.P_prev_netImportExport_dict[mt]
			target_mt = MarginalUnit.P_netImportExport_dict[mt]
			if current_mt <= previous_mt:
				mtTieMismatch = current_mt - previous_mt
			elif current_mt > previous_mt and current_mt <= target_mt:
				mtTieMismatch = 0
			elif current_mt >= target_mt:
				mtTieMismatch = current_mt - target_mt
			
			
			return bcTieMismatch, skTieMismatch, mtTieMismatch
		
		
		def determineMPID_netFlow_init(MPID):
			####### Updated by SDR 29-Mar-2019
			print "Determining NTG of MPID - ", MPID.mpidName, "..." 
			print "Net Flow Definition : ", MPID.netFlow
			# raw_input()
			# MPID.netFlow = MPID.netFlow.upper()
			if MPID.netFlow != '':
				if MPID.mpidName == bc_imp:
					# totalFlow = TieMeasure()
					totalFlow = self.state1_IE_flows[bc_imp]
				elif MPID.mpidName == sk_imp:
					totalFlow = self.state1_IE_flows[sk_imp]
				elif MPID.mpidName == mt_imp:
					totalFlow = self.state1_IE_flows[mt_imp]
				else:
					if MPID.locationType == "DOS":
						mpidLoad, mpidQ = determineMPID_Load(MPID)
						totalFlow = mpidLoad
					else:
						totalFlow = 0
						if MPID.netFlow.upper() == "GEN-LOAD":
							totalPload, totalQload = determineMPID_Load(MPID)
							totalPgen, totalPmax = determineMPID_Gen(MPID)
							totalFlow = totalPgen - totalPload
						else:
							netFlowdef_temp = MPID.netFlow 
							netFlowdef = netFlowdef_temp.split(",")
							print netFlowdef
							branches = []
							
							for text in netFlowdef:
								branches.append(text.strip(" "))
							print branches
							for branch in branches:
								print "branch :  ", branch 
								if ("-(" in branch) and ("DL" not in branch.upper()):
									temp = branch.split("-(")
									# print temp
									temp = temp[1].strip(")")
									# print temp
									[fromBus, toBus, id] = temp.split("-")
									print [fromBus, toBus, id]
									# raw_input()
									[status, flow, loss] = getBranchFlow(int(fromBus), int(toBus), id, "negative")
								elif ("(" in branch) and ("DL" not in branch.upper()):
									temp = branch.split("(")
									# print temp
									temp = temp[1].strip(")")
									# print temp
									[fromBus, toBus, id] = temp.split("-")
									print [fromBus, toBus, id]
									# raw_input()
									[status, flow, loss] = getBranchFlow(int(fromBus), int(toBus), id, "positive")
								elif "LOAD" in branch.upper():
									pload, qload = determineMPID_Load(MPID)
									if "-" in branch:
										flow = -pload
									else:
										flow = pload
								elif "DL" in branch.upper():
									temp = branch.split("(")
									temp = temp[1].strip(")")
									[loadbus, loadid] = temp.split("-")
									loadid = str(loadid)
									loadbus = int(loadbus)
									print loadid
									# raw_input()
									status, pload, qload = getLoadData(loadbus, loadid)
									print loadbus, loadid, status, pload, qload
									if "-DL" in branch:
										flow = -pload
									else:
										flow = pload
								elif "3W" in branch.upper():
									temp = branch.split("(")
									# print temp
									temp = temp[1].strip(")")
									# print temp
									[fromBus, toBus, id] = temp.split("-")
									print [fromBus, toBus, id]
									# raw_input()
									if "-3W" in branch.upper():
										[status, flow, loss] = get3WBranchFlow(int(fromBus), int(toBus), id, "negative")
									else:
										[status, flow, loss] = get3WBranchFlow(int(fromBus), int(toBus), id, "positive")
									
								else:
									[fromBus, toBus, id] = branch.split("-")
									[status, flow, loss] = getBranchFlow(int(fromBus), int(toBus), id, "positive")
								print "Flow :", flow
								# totalFlow = totalFlow + flow[1]
								totalFlow = totalFlow + flow
								# print totalFlow
								# raw_input()
			else:
				raise "MPID Netflow Definition is Blank - See in the corresponding Gen Mapping"
			print "totalNTGFlow : ", totalFlow
			return totalFlow
		
		def determineMPID_netFlow(MPID):
			####### Updated by SDR 29-Mar-2019
			print "Determining NTG of MPID - ", MPID.mpidName, "..." 
			print "Net Flow Definition : ", MPID.netFlow
			# raw_input()
			# MPID.netFlow = MPID.netFlow.upper()
			if MPID.netFlow != '':
				if MPID.mpidName == bc_imp:
					# totalFlow = TieMeasure()
					IE_flows = extractImportExport(self.MarginalUnit)
					totalFlow = IE_flows[bc_imp]
				elif MPID.mpidName == sk_imp:
					# mpidLoad, mpidQ = determineMPID_Load(MPID)
					# totalFlow = -mpidLoad
					IE_flows = extractImportExport(self.MarginalUnit)
					totalFlow = IE_flows[sk_imp]
				elif MPID.mpidName == mt_imp:
					# mpidLoad, mpidQ = determineMPID_Load(MPID)
					# totalFlow = -mpidLoad
					IE_flows = extractImportExport(self.MarginalUnit)
					totalFlow = IE_flows[mt_imp]
				else:
					if MPID.locationType == "DOS":
						mpidLoad, mpidQ = determineMPID_Load(MPID)
						totalFlow = mpidLoad
					else:
						totalFlow = 0
						if MPID.netFlow.upper() == "GEN-LOAD":
							totalPload, totalQload = determineMPID_Load(MPID)
							totalPgen, totalPmax = determineMPID_Gen(MPID)
							totalFlow = totalPgen - totalPload
						else:
							netFlowdef_temp = MPID.netFlow 
							netFlowdef = netFlowdef_temp.split(",")
							print netFlowdef
							branches = []
							
							for text in netFlowdef:
								branches.append(text.strip(" "))
							print branches
							for branch in branches:
								print "branch :  ", branch 
								if ("-(" in branch) and ("DL" not in branch.upper()):
									temp = branch.split("-(")
									# print temp
									temp = temp[1].strip(")")
									# print temp
									[fromBus, toBus, id] = temp.split("-")
									print [fromBus, toBus, id]
									# raw_input()
									[status, flow, loss] = getBranchFlow(int(fromBus), int(toBus), id, "negative")
								elif ("(" in branch) and ("DL" not in branch.upper()):
									temp = branch.split("(")
									# print temp
									temp = temp[1].strip(")")
									# print temp
									[fromBus, toBus, id] = temp.split("-")
									print [fromBus, toBus, id]
									# raw_input()
									[status, flow, loss] = getBranchFlow(int(fromBus), int(toBus), id, "positive")
								elif "LOAD" in branch.upper():
									pload, qload = determineMPID_Load(MPID)
									if "-" in branch:
										flow = -pload
									else:
										flow = pload
								elif "DL" in branch.upper():
									temp = branch.split("(")
									temp = temp[1].strip(")")
									[loadbus, loadid] = temp.split("-")
									loadid = str(loadid)
									loadbus = int(loadbus)
									print loadid
									# raw_input()
									status, pload, qload = getLoadData(loadbus, loadid)
									print loadbus, loadid, status, pload, qload
									if "-DL" in branch:
										flow = -pload
									else:
										flow = pload
								elif "3W" in branch.upper():
									temp = branch.split("(")
									# print temp
									temp = temp[1].strip(")")
									# print temp
									[fromBus, toBus, id] = temp.split("-")
									print [fromBus, toBus, id]
									# raw_input()
									if "-3W" in branch.upper():
										[status, flow, loss] = get3WBranchFlow(int(fromBus), int(toBus), id, "negative")
									else:
										[status, flow, loss] = get3WBranchFlow(int(fromBus), int(toBus), id, "positive")
									
								else:
									[fromBus, toBus, id] = branch.split("-")
									[status, flow, loss] = getBranchFlow(int(fromBus), int(toBus), id, "positive")
								print "Flow :", flow
								# totalFlow = totalFlow + flow[1]
								totalFlow = totalFlow + flow
								# print totalFlow
								# raw_input()
			else:
				raise
			print "totalNTGFlow : ", totalFlow
			return totalFlow
		
		
		def getLFMPID_mUnit(LFMPID):
			tag = ''
			LFMPID_mUnit = meritorderData()
			# enable_print()
			for mUnit in self.currentHourEMMO:
				
				# print mUnit.assetName, mUnit.serial
				
				if mUnit.assetName == LFMPID:
					tag = 'FOUND'
					LFMPID_mUnit = mUnit
					break
			
			print LFMPID_mUnit.assetName, LFMPID_mUnit.serial, LFMPID_mUnit.reduceLoadTag, LFMPID_mUnit.deductibleNTGLoad, LFMPID_mUnit.finalNTGLoad
			
			# sys.exit()
			
			return LFMPID_mUnit
		
		def reduceImports_in_MU(mpidName):
			
			# enable_print()
			
			relatedExport_mpidName = ''
			relatedTieName = ''
			if mpidName == bc_imp:
				relatedExport_mpidName = bc_exp
				relatedTieName = bc
			elif mpidName == sk_imp:
				relatedExport_mpidName = sk_exp
				relatedTieName = sk
			elif mpidName == mt_imp:
				relatedExport_mpidName = mt_exp
				relatedTieName = mt
			print relatedExport_mpidName, relatedTieName
			print -self.currentHourExports[relatedExport_mpidName]
			P_import = 0
			
			P_export = -self.currentHourExports[relatedExport_mpidName]
			P_netImportExport = P_import + P_export
			P_prev_netImportExport = P_netImportExport
			
			# print P_export, P_netImportExport, P_prev_netImportExport
			
			for mUnit in self.currentHourEMMO:
				mUnit.P_import_dict[relatedTieName] = 0
				# mUnit.P_export_dict[relatedTieName] = P_export
				mUnit.P_netImportExport_dict[relatedTieName] = mUnit.P_import_dict[relatedTieName] + mUnit.P_export_dict[relatedTieName]
				
				mUnit.P_prev_netImportExport_dict[relatedTieName] = P_prev_netImportExport
				
				P_prev_netImportExport = mUnit.P_netImportExport_dict[relatedTieName]
				
				
				
				
			for mUnit in self.currentHourEMMO:
				if mUnit.assetName == mpidName or mUnit.assetName == relatedExport_mpidName:
					mUnit.P_import = 0
					mUnit.P_netImportExport = mUnit.P_export + mUnit.P_import
			
			
				
		
		def saveInformation(condition, load_AIES=None, gen_AIES=None, loss_AIES=None, comment=None, ):
			if condition == "XS-NODISP":
				self.state1_initialVolumeDict[self.LFMPID] = self.state1_initialVolume
				
				
				self.state2_RedispVolume[self.LFMPID] = 'N/A'
				self.state2_readjustedNetLoadDict[self.LFMPID] = 'N/A'
				
				self.state2_totalAiesLoss[self.LFMPID] = 'N/A'
				self.state2_totalCustomerLoss[self.LFMPID] = 'N/A'
				self.state2_systemLoss[self.LFMPID] = 'N/A'
				
				self.state2_MarginalUnit[self.LFMPID] = meritorderData()
				self.state2_MarginalUnit[self.LFMPID].assetName = "N/A"
				self.state2_MarginalUnit[self.LFMPID].serial = "N/A"
				self.state2_MarginalUnit[self.LFMPID].blockNumber = "N/A"
				self.state2_MarginalUnit[self.LFMPID].offerPrice = "N/A"
				self.state2_MarginalUnit[self.LFMPID].availablePower = "N/A"
				self.state2_MarginalUnitReserve[self.LFMPID] = 'N/A'
				
				self.state2_owsp[self.LFMPID] = 'N/A'
				self.state2_oesp[self.LFMPID] = 'N/A'
				self.state2_watlflow[self.LFMPID] = 'N/A'
				self.state2_eatlflow[self.LFMPID] = 'N/A'
				
				self.state2_total_load[self.LFMPID] = 'N/A'
				self.state2_total_gen[self.LFMPID] = 'N/A'
				
				self.state2_IE_flows[self.LFMPID] = dict()
				for eachService in Import_Export_Services:
					self.state2_IE_flows[self.LFMPID][eachService] = 'N/A'
				
				self.state2_marginalUnitMismatch[self.LFMPID] = 'N/A'
				self.state2_rlf[self.LFMPID] = 'N/A'
				self.state2_status[self.LFMPID] = "XS-NODISP"
				self.state2_comment[self.LFMPID] = "NTG < 1 MW"
				
				self.bcTieMismatch[self.LFMPID] = "N/A"
				self.skTieMismatch[self.LFMPID] = "N/A"
				self.mtTieMismatch[self.LFMPID] = "N/A"
				
				self.bcTieFlow[self.LFMPID] = "N/A"
				self.skTieFlow[self.LFMPID] = "N/A"
				self.mtTieFlow[self.LFMPID] = "N/A"
			
			elif condition == "XS-INSUF2":
				self.state1_initialVolumeDict[self.LFMPID] = self.state1_initialVolume
				
				self.state2_RedispVolume[self.LFMPID] = 'N/A'
				self.state2_readjustedNetLoadDict[self.LFMPID] = 'N/A'
				
				self.state2_totalAiesLoss[self.LFMPID] = loss_AIES
				self.state2_totalCustomerLoss[self.LFMPID] = 'N/A'
				self.state2_systemLoss[self.LFMPID] = 'N/A'
				
				self.state2_MarginalUnit[self.LFMPID] = meritorderData()
				self.state2_MarginalUnit[self.LFMPID].assetName = "N/A"
				self.state2_MarginalUnit[self.LFMPID].serial = "N/A"
				self.state2_MarginalUnit[self.LFMPID].blockNumber = "N/A"
				self.state2_MarginalUnit[self.LFMPID].offerPrice = "N/A"
				self.state2_MarginalUnit[self.LFMPID].availablePower = "N/A"
				self.state2_MarginalUnitReserve[self.LFMPID] = 'N/A'
				
				self.state2_owsp[self.LFMPID] = 'N/A'
				self.state2_oesp[self.LFMPID] = 'N/A'
				self.state2_watlflow[self.LFMPID] = 'N/A'
				self.state2_eatlflow[self.LFMPID] = 'N/A'
				
				self.state2_total_load[self.LFMPID] = load_AIES
				self.state2_total_gen[self.LFMPID] = gen_AIES
				
				self.state2_IE_flows[self.LFMPID] = dict()
				for eachService in Import_Export_Services:
					self.state2_IE_flows[self.LFMPID][eachService] = 'N/A'
					
				self.state2_marginalUnitMismatch[self.LFMPID] = 'N/A'
				self.state2_rlf[self.LFMPID] = 'N/A'
				self.state2_status[self.LFMPID] = "XS-INSUF2"
				self.state2_comment[self.LFMPID] = comment
				
				self.bcTieMismatch[self.LFMPID] = "N/A"
				self.skTieMismatch[self.LFMPID] = "N/A"
				self.mtTieMismatch[self.LFMPID] = "N/A"
				
				self.bcTieFlow[self.LFMPID] = "N/A"
				self.skTieFlow[self.LFMPID] = "N/A"
				self.mtTieFlow[self.LFMPID] = "N/A"
			
			elif condition == "XS-UNSOL2":
				self.state1_initialVolumeDict[self.LFMPID] = self.state1_initialVolume
				
				self.state2_RedispVolume[self.LFMPID] = 'N/A'
				self.state2_readjustedNetLoadDict[self.LFMPID] = 'N/A'
				
				self.state2_totalAiesLoss[self.LFMPID] = loss_AIES
				self.state2_totalCustomerLoss[self.LFMPID] = 'N/A'
				self.state2_systemLoss[self.LFMPID] = 'N/A'
				
				self.state2_MarginalUnit[self.LFMPID] = meritorderData()
				self.state2_MarginalUnit[self.LFMPID].assetName = "N/A"
				self.state2_MarginalUnit[self.LFMPID].serial = "N/A"
				self.state2_MarginalUnit[self.LFMPID].blockNumber = "N/A"
				self.state2_MarginalUnit[self.LFMPID].offerPrice = "N/A"
				self.state2_MarginalUnit[self.LFMPID].availablePower = "N/A"
				self.state2_MarginalUnitReserve[self.LFMPID] = 'N/A'
				
				self.state2_owsp[self.LFMPID] = 'N/A'
				self.state2_oesp[self.LFMPID] = 'N/A'
				self.state2_watlflow[self.LFMPID] = 'N/A'
				self.state2_eatlflow[self.LFMPID] = 'N/A'
				
				self.state2_total_load[self.LFMPID] = load_AIES
				self.state2_total_gen[self.LFMPID] = gen_AIES
				
				self.state2_IE_flows[self.LFMPID] = dict()
				for eachService in Import_Export_Services:
					self.state2_IE_flows[self.LFMPID][eachService] = 'N/A'
				
				self.state2_marginalUnitMismatch[self.LFMPID] = 'N/A'
				self.state2_rlf[self.LFMPID] = 'N/A'
				self.state2_status[self.LFMPID] = "XS-UNSOL2"
				self.state2_comment[self.LFMPID] = comment
				
				self.bcTieMismatch[self.LFMPID] = "N/A"
				self.skTieMismatch[self.LFMPID] = "N/A"
				self.mtTieMismatch[self.LFMPID] = "N/A"
				
				self.bcTieFlow[self.LFMPID] = "N/A"
				self.skTieFlow[self.LFMPID] = "N/A"
				self.mtTieFlow[self.LFMPID] = "N/A"
				
			
			elif condition == "UNKNOWN":
				self.state1_initialVolumeDict[self.LFMPID] = self.state1_initialVolume
				
				self.state2_RedispVolume[self.LFMPID] = 'N/A'
				self.state2_readjustedNetLoadDict[self.LFMPID] = 'N/A'
				
				self.state2_totalAiesLoss[self.LFMPID] = 'N/A'
				self.state2_totalCustomerLoss[self.LFMPID] = 'N/A'
				self.state2_systemLoss[self.LFMPID] = 'N/A'
				
				self.state2_MarginalUnit[self.LFMPID] = meritorderData()
				self.state2_MarginalUnit[self.LFMPID].assetName = "N/A"
				self.state2_MarginalUnit[self.LFMPID].serial = "N/A"
				self.state2_MarginalUnit[self.LFMPID].blockNumber = "N/A"
				self.state2_MarginalUnit[self.LFMPID].offerPrice = "N/A"
				self.state2_MarginalUnit[self.LFMPID].availablePower = "N/A"
				self.state2_MarginalUnitReserve[self.LFMPID] = 'N/A'
				
				self.state2_owsp[self.LFMPID] = 'N/A'
				self.state2_oesp[self.LFMPID] = 'N/A'
				self.state2_watlflow[self.LFMPID] = 'N/A'
				self.state2_eatlflow[self.LFMPID] = 'N/A'
				
				self.state2_total_load[self.LFMPID] = 'N/A'
				self.state2_total_gen[self.LFMPID] = 'N/A'
				
				self.state2_IE_flows[self.LFMPID] = dict()
				for eachService in Import_Export_Services:
					self.state2_IE_flows[self.LFMPID][eachService] = 'N/A'
				
				self.state2_marginalUnitMismatch[self.LFMPID] = 'N/A'
				self.state2_rlf[self.LFMPID] = 'N/A'
				self.state2_status[self.LFMPID] = "UNKNOWN"
				self.state2_comment[self.LFMPID] = "ERROR"
				
				self.bcTieMismatch[self.LFMPID] = "N/A"
				self.skTieMismatch[self.LFMPID] = "N/A"
				self.mtTieMismatch[self.LFMPID] = "N/A"
				
				self.bcTieFlow[self.LFMPID] = "N/A"
				self.skTieFlow[self.LFMPID] = "N/A"
				self.mtTieFlow[self.LFMPID] = "N/A"
			
		#############################
		########################################Updated by SDR 
		########################################27Mar2019
		#######################################################
		
		
		# enable_print()
		
		### Create PSSE Progress Files ###
		caseName = os.path.basename(self.topologyCase)
		psselogFileName = "Progress_" + caseName.split(".sav")[0] + "_" + MPID.mpidName +".log"
		self.psselogFile = os.path.join(self.hourly_output_dir, psselogFileName)
		psspy.progress_output(2,self.psselogFile,[0,0])
		
		###### Open Case ##########
		psspy.progress("\n\n===================================== Opening the case ==============================================\n")
		psspy.case(self.topologyCase)
		psspy.solution_parameters_4((psspy._i, 50), (psspy._f,) *5 + (0.01, ))
		# Solve()
		solve_initial()
		
		
		psspy.progress("\n\nFinding Initial State Information ==============================================")
		psspy.progress("\n==========================================================================\n")
		print "======================================================"
		print "Finding Initial State Information ........."
		print "======================================"
		
		
		
		###############################
		AB_BC_Tie = TieMeasure()
		print "BC Tie Flow: ", AB_BC_Tie
		
		###### Process LF MPID#############
		####################################
		#########################################
		############### Gather Initial Info 
		# enable_print()
		self.LFMPID_mpidUnit = MPID
		self.LFMPID = self.LFMPID_mpidUnit.mpidName
		print MPID.mpidName
		
		self.currentHourEMMO = []
		for element in self.currentHourEMMO_original:
			copied_element = _copy.deepcopy(element)
			self.currentHourEMMO.append(copied_element)
		
		self.state1_initialVolume = round(determineMPID_netFlow_init(MPID), 4)
		print " Initial NTG : ", self.state1_initialVolume
		self.state1_totalAiesLoss = self.state1_totalInfo["total_aies_loss"]
		self.state1_totalCustomerLoss = determine_mpidInternalLoss(self.MPIDs)
		self.state1_systemLoss = self.state1_totalAiesLoss - self.state1_totalCustomerLoss
		
		self.LFMPID_mUnit = getLFMPID_mUnit(self.LFMPID)
		# enable_print()
		print self.LFMPID_mUnit.assetName, self.LFMPID_mUnit.serial, self.LFMPID_mUnit.reduceLoadTag, self.LFMPID_mUnit.deductibleNTGLoad, self.LFMPID_mUnit.finalNTGLoad
		
		self.state1_deductibleNetLoadDict[self.LFMPID] = self.LFMPID_mUnit.deductibleNTGLoad
		self.state1_reducedNetLoadDict[self.LFMPID] = self.LFMPID_mUnit.finalNTGLoad
		
		################################## State-2############################
		
		try:
			# self.MarginalUnit = self.FindMarginalUnit(self.LFMPID)
			# state1_MarginalUnit_forS2 = self.MarginalUnit
			# self.MarginalUnitReserve = findMarginalUnitReserve(self.MarginalUnit)
			
			psspy.progress("\n\nProcessing Re-dispatched State Information ==============================================")
			psspy.progress("\n==========================================================================\n")
			print "======================================================"
			print "Processing Re-dispatched State Information ........."
			print "MPID : ", self.LFMPID 
			print "======================================"
			
			
			if self.state1_initialVolume >= 1: #### Check if State-2 is required ? ########
				
				################ Produce State-2 Cases ######
				##########################
				try:
					if MPID.locationType != "DOS":
						# self.LFMPID_mUnit = getLFMPID_mUnit(self.LFMPID)
						# # enable_print()
						# print self.LFMPID_mUnit.assetName, self.LFMPID_mUnit.serial, self.LFMPID_mUnit.reduceLoadTag, self.LFMPID_mUnit.deductibleNTGLoad, self.LFMPID_mUnit.finalNTGLoad
						
						# raw_input()
						if self.LFMPID_mUnit.reduceLoadTag.upper() == 'YES' and self.LFMPID_mUnit.finalNTGLoad == 0:
							self.state1_netDeltaFlow = self.LFMPID_mUnit.deductibleNTGLoad + self.state1_initialVolume
							self.state1_deltaLoad = self.LFMPID_mUnit.deductibleNTGLoad 
						else:
							self.state1_netDeltaFlow = self.state1_initialVolume
							self.state1_deltaLoad = 0 
					else:
						self.state1_netDeltaFlow = self.state1_initialVolume
						self.state1_deltaLoad = 0
					
					print self.state1_initialVolume, self.state1_deltaLoad, self.state1_netDeltaFlow
					# sys.exit()
					
					if self.LFMPID == bc_imp:
						
						reduceImports_in_MU(self.LFMPID)
						# write_hourlyEMMOlogfile("EMMO_%s_ImportReduced.log" %self.LFMPID, self.currentHourEMMO)
						self.MarginalUnit = self.FindMarginalUnit(self.LFMPID)
						state1_MarginalUnit_forS2 = self.MarginalUnit
						self.MarginalUnitReserve = findMarginalUnitReserve(self.MarginalUnit)
						
						
						remainingCapability = assessSourceAssets(self.MarginalUnit, self.MarginalUnitReserve)
						if remainingCapability < self.state1_netDeltaFlow: 
							Load, Gen, Loss, ShuntLoss = GetSystemTotals(True)
							raise InsufficientSourceError(Load, Gen, Loss+ShuntLoss, "S2_initial_remainingCapability_Check")
						
						
						deltaNetFlow = self.state1_initialVolume
						self.MarginalUnit = bctiematch(deltaNetFlow, self.MarginalUnit, self.MarginalUnitReserve)
						
						
						state2_owsp, state2_oesp, state2_watlflow, state2_eatlflow = hvdcDispatch()
						caseprep_Solve()
						
						bc_mismatch = determineMismatch(self.MarginalUnit)
						self.MarginalUnit = bctiematch(bc_mismatch, self.MarginalUnit, self.MarginalUnitReserve)
						desiredSwingBus = assignSwingBus(self.MarginalUnit, self.LFMPID)
						caseprep_Solve()
						
						
						marginalUnitMismatch = checkMarginalUnit_Mismatch(self.MarginalUnit)
						print "marginalUnitMismatch : ", marginalUnitMismatch
						marginalUnitMismatch, self.MarginalUnit = fineTuneMU_System(marginalUnitMismatch, self.MarginalUnit, self.LFMPID)
						
						self.MarginalUnitReserve = findMarginalUnitReserve(self.MarginalUnit)
						state2_IE_flows = extractImportExport(self.MarginalUnit)
						
					elif self.LFMPID == sk_imp or self.LFMPID == mt_imp: ##and MPID.mpidName != 'MATLIMP': # Not BC Intertie (has swing bus): 
						
						reduceImports_in_MU(self.LFMPID)
						# write_hourlyEMMOlogfile("EMMO_%s_ImportReduced.log" %self.LFMPID, self.currentHourEMMO)
						self.MarginalUnit = self.FindMarginalUnit(self.LFMPID)
						state1_MarginalUnit_forS2 = self.MarginalUnit
						self.MarginalUnitReserve = findMarginalUnitReserve(self.MarginalUnit)
						
						remainingCapability = assessSourceAssets(self.MarginalUnit, self.MarginalUnitReserve)
						if remainingCapability < self.state1_netDeltaFlow: 
							Load, Gen, Loss, ShuntLoss = GetSystemTotals(True)
							raise InsufficientSourceError(Load, Gen, Loss+ShuntLoss, "S2_initial_remainingCapability_Check")
						
						
						deltaNetFlow = self.state1_initialVolume
						# IE_flows = extractImportExport(self.MarginalUnit)
						if self.LFMPID == sk_imp:
							mpidObject_skImp = find_MPID_Object(sk_imp)
							skTieFlow, temp1 = determineMPID_Gen(mpidObject_skImp)
							targetNetFlow = skTieFlow - deltaNetFlow
							setSk_Tie(targetNetFlow)
							
						elif self.LFMPID == mt_imp:
							mpidObject_mt_imp = find_MPID_Object(mt_imp)
							mtTieFlow, temp2 = determineMPID_Gen(mpidObject_mt_imp)
							targetNetFlow = mtTieFlow - deltaNetFlow
							setMT_Tie(targetNetFlow)
						
						caseprep_Solve()
						bc_mismatch = determineMismatch(self.MarginalUnit)
						self.MarginalUnit = bctiematch(bc_mismatch, self.MarginalUnit, self.MarginalUnitReserve)
						
						
						state2_owsp, state2_oesp, state2_watlflow, state2_eatlflow = hvdcDispatch()
						caseprep_Solve()
						
						bc_mismatch = determineMismatch(self.MarginalUnit)
						self.MarginalUnit = bctiematch(bc_mismatch, self.MarginalUnit, self.MarginalUnitReserve)
						
						desiredSwingBus = assignSwingBus(self.MarginalUnit, self.LFMPID)
						caseprep_Solve()
						marginalUnitMismatch = checkMarginalUnit_Mismatch(self.MarginalUnit)
						marginalUnitMismatch, self.MarginalUnit = fineTuneMU_System(marginalUnitMismatch, self.MarginalUnit, self.LFMPID)
						
						self.MarginalUnitReserve = findMarginalUnitReserve(self.MarginalUnit)
						state2_IE_flows = extractImportExport(self.MarginalUnit)
						
					else:
						self.MarginalUnit = self.FindMarginalUnit(self.LFMPID)
						state1_MarginalUnit_forS2 = self.MarginalUnit
						self.MarginalUnitReserve = findMarginalUnitReserve(self.MarginalUnit)
						
						remainingCapability = assessSourceAssets(self.MarginalUnit, self.MarginalUnitReserve)
						if remainingCapability < self.state1_netDeltaFlow: 
							Load, Gen, Loss, ShuntLoss = GetSystemTotals(True)
							raise InsufficientSourceError(Load, Gen, Loss+ShuntLoss, "S2_initial_remainingCapability_Check")
						
						
						deltaNetFlow = self.state1_initialVolume
						deltaLoad = self.state1_netDeltaFlow - self.state1_initialVolume
						
						print " state1_netDeltaFlow :", self.state1_netDeltaFlow
						iterationNumber = 1
						
						if MPID.locationType == "DOS":
							print "Processing DOS"
							psspy.progress("==========================Progressing DOS ====================")
							# loadmpids = MPID.loadmpids
							# onsiteLoads = MPID.onsiteLoads
							
							for loadmpid in MPID.loadmpids:
								loads = MPID.onsiteLoads[loadmpid]
								for load in loads:
									loadbus = int(load.split('-')[0] )
									loadid = (load.split('-')[1])
									UpdateLoad(loadbus, loadid, 0, 0, 0)
							control = "Reduce" 
							print "Reduce System Total Gen"
							self.MarginalUnit = UpdateSystem(deltaNetFlow, self.MarginalUnit, control, self.LFMPID)
							self.MarginalUnitReserve = findMarginalUnitReserve(self.MarginalUnit)
							print "MU serial, AssetName, blockNumber :", self.MarginalUnit.serial, self.MarginalUnit.assetName, self.MarginalUnitReserve
							
							
							caseprep_Solve()
							
							deltaNetFlow = determineMPID_netFlow(MPID)
							print "State-2 deltaNetFlow : ", deltaNetFlow
							
							bc_mismatch = determineMismatch(self.MarginalUnit)
							self.MarginalUnit = bctiematch(bc_mismatch, self.MarginalUnit, self.MarginalUnitReserve)
							############# DISABLED############
							# desiredSwingBus = assignSwingBus(self.MarginalUnit, self.LFMPID)
							# caseprep_Solve()
							
							
							# marginalUnitMismatch = checkMarginalUnit_Mismatch(self.MarginalUnit)
							# print "marginalUnitMismatch : ", marginalUnitMismatch
							# marginalUnitMismatch, self.MarginalUnit = fineTuneMU_System(marginalUnitMismatch, self.MarginalUnit, self.LFMPID)
							#####################################
							
							state2_owsp, state2_oesp, state2_watlflow, state2_eatlflow = hvdcDispatch()
							caseprep_Solve()
							# raw_input("=============")
							bc_mismatch = determineMismatch(self.MarginalUnit)
							self.MarginalUnit = bctiematch(bc_mismatch, self.MarginalUnit, self.MarginalUnitReserve)
							desiredSwingBus = assignSwingBus(self.MarginalUnit, self.LFMPID)
							caseprep_Solve()
							
							marginalUnitMismatch = checkMarginalUnit_Mismatch(self.MarginalUnit)
							print "marginalUnitMismatch : ", marginalUnitMismatch
							marginalUnitMismatch, self.MarginalUnit = fineTuneMU_System(marginalUnitMismatch, self.MarginalUnit, self.LFMPID)
							
							self.MarginalUnitReserve = findMarginalUnitReserve(self.MarginalUnit)
							state2_IE_flows = extractImportExport(self.MarginalUnit)
							
						else:
							######################## Making Working MPID NTG to zero #########
							
							if deltaNetFlow > 0:
								print ("Reduce LF gen")
								UpdateWorkingMPID(abs(deltaNetFlow), MPID, "Reduce")  
							elif deltaNetFlow < 0:
								print "NTG < 0 MW (Target)"
							
							deltaGen = deltaNetFlow
							print "deltaGen : ", deltaGen, deltaNetFlow
							#### Dispatch Up Total Gen from Merit Order
							if deltaGen > 0 :
								control = "Increase"
								print "Increase System Total Gen"
							elif deltaGen < 0:
								control = "Reduce" 
								print "Reduce System Total Gen"
							
							self.MarginalUnit = UpdateSystem(deltaNetFlow, self.MarginalUnit, control, self.LFMPID)
							self.MarginalUnitReserve = findMarginalUnitReserve(self.MarginalUnit)
							print "MU serial, AssetName, blockNumber :", self.MarginalUnit.serial, self.MarginalUnit.assetName, self.MarginalUnitReserve
							
							# print "Update swing Bus .... "
							# desiredSwingBus = assignSwingBus(self.MarginalUnit, self.LFMPID)
							caseprep_Solve()
							
							deltaNetFlow = determineMPID_netFlow(MPID)
							print "Updated NTG : ", round(deltaNetFlow,5)
							# raw_input("======= Saved - Changed Swing Bus =======")
							############ Fine tuning......Making Working MPID NTG zero ############
							print "iterationNumber : ", iterationNumber
							print "===== Fine tuning ..... Making Working MPID NTG to zero ======= "
							while abs(deltaNetFlow) > flowTolerance and iterationNumber < iterationLimit:
								if deltaNetFlow > 0:
									# raw_input("Reduce LF gen")
									print ("Reduce LF gen")
									UpdateWorkingMPID(abs(deltaNetFlow), MPID, "Reduce")  
								elif deltaNetFlow < 0:
									print ("Increase LF gen")
									UpdateWorkingMPID(abs(deltaNetFlow), MPID, "Increase")
									# break
								caseprep_Solve()
								deltaNetFlow = determineMPID_netFlow(MPID)
								print "deltaNetFlow : ", deltaNetFlow
								# raw_input()
								iterationNumber += 1
							
							print deltaNetFlow
							
							if abs(deltaNetFlow) > flowTolerance and iterationNumber >= iterationLimit:
								Load, Gen, Loss, ShuntLoss = GetSystemTotals(True)
								raise iterationLimitError(deltaNetFlow, iterationNumber, Load, Gen, Loss+ShuntLoss) 
							
							self.MarginalUnitReserve = findMarginalUnitReserve(self.MarginalUnit)
							print "MU serial, AssetName, Reserve (MW) :", self.MarginalUnit.serial, self.MarginalUnit.assetName, self.MarginalUnitReserve
							
							if self.state1_deltaLoad > 0:
								UpdateWorkingMPID(abs(self.state1_deltaLoad), MPID, "Increase Load")
								
							# a, b = determineMPID_Load(MPID)
							# print a, b
							# raw_input()
							
							caseprep_Solve()
							
							bc_mismatch = determineMismatch(self.MarginalUnit)
							self.MarginalUnit = bctiematch(bc_mismatch, self.MarginalUnit, self.MarginalUnitReserve)
							
							
							##########DISABLED############
							# desiredSwingBus = assignSwingBus(self.MarginalUnit, self.LFMPID)
							# caseprep_Solve()
							
							# marginalUnitMismatch = checkMarginalUnit_Mismatch(self.MarginalUnit)
							# marginalUnitMismatch, self.MarginalUnit = fineTuneMU_System(marginalUnitMismatch, self.MarginalUnit, self.LFMPID)
							######################
							
							state2_owsp, state2_oesp, state2_watlflow, state2_eatlflow = hvdcDispatch()
							caseprep_Solve()
							
							bc_mismatch = determineMismatch(self.MarginalUnit)
							self.MarginalUnit = bctiematch(bc_mismatch, self.MarginalUnit, self.MarginalUnitReserve)
							desiredSwingBus = assignSwingBus(self.MarginalUnit, self.LFMPID)
							caseprep_Solve()
							
							marginalUnitMismatch = checkMarginalUnit_Mismatch(self.MarginalUnit)
							marginalUnitMismatch, self.MarginalUnit = fineTuneMU_System(marginalUnitMismatch, self.MarginalUnit, self.LFMPID)
							
							state2_IE_flows = extractImportExport(self.MarginalUnit)
							self.MarginalUnitReserve = findMarginalUnitReserve(self.MarginalUnit)
							
						
					######################### Save the State-2 case ######
					#############################################################
					
					
					############ Saving Final Case ############
					
					self.bcTieFlow[self.LFMPID], self.skTieFlow[self.LFMPID], self.mtTieFlow[self.LFMPID] = determine_All_TieFlows()
					
					solutionStatus = checkSol()
					
					caseName = os.path.basename(self.topologyCase)
					outputCaseName = caseName.split(".sav")[0] + "_" + MPID.mpidName + ".sav"
					outputCaseName = os.path.join(self.hourly_output_dir, outputCaseName)
					print outputCaseName
					psspy.save(outputCaseName)
					
					
					outputEmmoLogName = "S2EMMO_" + caseName.split(".sav")[0] + "_" + MPID.mpidName + ".log"
					self.state2_emmoLog[self.LFMPID] = os.path.join(self.hourly_output_dir, outputEmmoLogName)
					write_hourlyEMMOlogfile(self.state2_emmoLog[self.LFMPID], self.currentHourEMMO)
					
					
					
					
					finalLoad, finalGen, finalLoss, finalShuntLoss = GetSystemTotals(True)
					#################### Final Information Extracting
					self.state1_initialVolumeDict[self.LFMPID] = self.state1_initialVolume
					
					
					
					# self.state1_deltaLoadDict[self.LFMPID] = self.state1_deltaLoad
					
					self.state2_RedispVolume[self.LFMPID] = determineMPID_netFlow(MPID)
					self.state2_readjustedNetLoadDict[self.LFMPID] = self.state1_deltaLoad
					
					
					self.state2_totalAiesLoss[self.LFMPID] = finalLoss + finalShuntLoss
					self.state2_totalCustomerLoss[self.LFMPID] = determine_mpidInternalLoss(self.MPIDs)
					self.state2_systemLoss[self.LFMPID] = self.state2_totalAiesLoss[self.LFMPID] - self.state2_totalCustomerLoss[self.LFMPID]
					
					self.state2_MarginalUnit[self.LFMPID] = self.MarginalUnit
					self.state2_MarginalUnitReserve[self.LFMPID] = self.MarginalUnitReserve
					
					if int(self.year) <= 2015:
						self.state2_owsp[self.LFMPID] = 'N/A'
						self.state2_oesp[self.LFMPID] = 'N/A'
						self.state2_watlflow[self.LFMPID] = 'N/A'
						self.state2_eatlflow[self.LFMPID] = 'N/A'
					else:
						self.state2_owsp[self.LFMPID] = state2_owsp
						self.state2_oesp[self.LFMPID] = state2_oesp
						self.state2_watlflow[self.LFMPID] = state2_watlflow
						self.state2_eatlflow[self.LFMPID] = state2_eatlflow
					
					self.state2_total_load[self.LFMPID] = finalLoad
					self.state2_total_gen[self.LFMPID] = finalGen
					self.state2_IE_flows[self.LFMPID] = state2_IE_flows
					
					self.state2_marginalUnitMismatch[self.LFMPID] = marginalUnitMismatch
					self.state2_rlf[self.LFMPID] = (self.state1_systemLoss - self.state2_systemLoss[self.LFMPID])/self.state1_initialVolumeDict[self.LFMPID]
					self.state2_status[self.LFMPID] = "SOLVED"
					self.state2_comment[self.LFMPID] = solutionStatus
					
					
					
					
				except InsufficientSourceError as s:
					saveInformation("XS-INSUF2", s.load_AIES, s.gen_AIES, s.loss_total_AIES, s.comment)
					pass
				except solutionError as s:
					saveInformation("XS-UNSOL2", s.load_AIES, s.gen_AIES, s.loss_total_AIES, s.solvedMsg)
					pass
				except iterationLimitError as s:
					comment = "Iteration Limit Exceeded; Mismatch = %s, #Iteration = %s" %(s.mismatch, s.iterationNumber)
					saveInformation("XS-UNSOL2", s.load_AIES, s.gen_AIES, s.loss_total_AIES, comment)
					pass
				except HvdcSolutionError as s:
					saveInformation("XS-UNSOL2", s.load_AIES, s.gen_AIES, s.loss_total_AIES, "UNSOLVED HVDC")
					pass
				except tieFlowMismatchError as s:
					saveInformation("XS-UNSOL2", s.load_AIES, s.gen_AIES, s.loss_total_AIES, "TIE MISMATCH")
					pass	
			####################################Except Statements###
			##########################################################
			else:
				saveInformation("XS-NODISP")
		
		
		except InsufficientSourceError as s:
			saveInformation("XS-INSUF2", s.load_AIES, s.gen_AIES, s.loss_total_AIES, s.comment)
			pass
		
		
		state1_data = [self.LFMPID, self.state1_initialVolumeDict[self.LFMPID], 
		self.state1_deductibleNetLoadDict[self.LFMPID], self.state1_reducedNetLoadDict[self.LFMPID],
		self.state1_totalAiesLoss, self.state1_totalCustomerLoss, self.state1_systemLoss, self.state1_munitInfo["assetName"], self.state1_munitInfo["serial"], self.state1_munitInfo["blockNumber"], self.state1_munitInfo["offerPrice"], self.state1_munitInfo["availablePower"], self.state1_munitInfo["MarginalUnitReserve"], self.state1_owsp, self.state1_oesp, self.state1_watlflow, self.state1_eatlflow, self.state1_totalInfo["total_load"], self.state1_totalInfo["total_gen"], self.state1_totalInfo["NetEMMO_GrossLoad_SS_btfGen"], self.state1_IE_flows[bc_imp], self.state1_IE_flows[bc_exp], self.state1_IE_flows[sk_imp], self.state1_IE_flows[sk_exp], self.state1_IE_flows[mt_imp], self.state1_IE_flows[mt_exp], self.Total_currentHourExports_MW] 
				
		state2_data = [self.state2_RedispVolume[self.LFMPID], 
		self.state2_readjustedNetLoadDict[self.LFMPID],
		self.state2_totalAiesLoss[self.LFMPID], self.state2_totalCustomerLoss[self.LFMPID], self.state2_systemLoss[self.LFMPID], self.state2_MarginalUnit[self.LFMPID].assetName, self.state2_MarginalUnit[self.LFMPID].serial, self.state2_MarginalUnit[self.LFMPID].blockNumber, self.state2_MarginalUnit[self.LFMPID].offerPrice, self.state2_MarginalUnit[self.LFMPID].availablePower, self.state2_MarginalUnitReserve[self.LFMPID], self.state2_owsp[self.LFMPID], self.state2_oesp[self.LFMPID], self.state2_watlflow[self.LFMPID], self.state2_eatlflow[self.LFMPID], self.state2_total_load[self.LFMPID], self.state2_total_gen[self.LFMPID], self.state2_IE_flows[self.LFMPID][bc_imp], self.state2_IE_flows[self.LFMPID][bc_exp], self.state2_IE_flows[self.LFMPID][sk_imp], self.state2_IE_flows[self.LFMPID][sk_exp], self.state2_IE_flows[self.LFMPID][mt_imp], self.state2_IE_flows[self.LFMPID][mt_exp], self.state2_marginalUnitMismatch[self.LFMPID], self.state2_rlf[self.LFMPID], self.state2_status[self.LFMPID], self.state2_comment[self.LFMPID], self.bcTieFlow[self.LFMPID], self.skTieFlow[self.LFMPID], self.mtTieFlow[self.LFMPID], self.bcTieMismatch[self.LFMPID], self.skTieMismatch[self.LFMPID], self.mtTieMismatch[self.LFMPID]]
				
		extractedInformation = state1_data + state2_data
		
		return extractedInformation

def getLoadMWData(mpidName, loadData):
	loadValue = 0
	# print mpidName
	for eachloadmpidData in loadData:
		# print eachloadmpidData.mpidName
		if eachloadmpidData.mpidName == mpidName:
			loadValue = eachloadmpidData.mwData
			# print loadValue
		# raw_input()
	return loadValue

def getLoadPfData(mpidName, PfData):
	pfValue = 0
	tag = ""
	# print mpidName
	for eachloadmpidData in PfData:
		# print eachloadmpidData.mpidName
		if eachloadmpidData.mpidName == mpidName:
			tag = "Found"
			pfValue = eachloadmpidData.pfData
			break
			# print pfValue
	if tag != "Found":
		print "PF Data not found"
		print "PF Data not found"
		print "PF Data not found"
		raise 
	return pfValue


def write_hourlyEMMOlogfile(hourlyEMMOlogfilename, MOList):
	# global hourlyEMMOlogfile
	hourlyEMMOlogfile = open(hourlyEMMOlogfilename, "w")
	
	# fileName = "Log_EMMO_Adjusted - " + tag + ".txt"
	# EMMO_Log_Modified = open(fileName, "w")
	hourlyEMMOlogfile.write("time	serial	assetName	relatedImportAsset	assetShortName	Import_Export	blockNumber	flexibility	offerPrice	blockSize	availablePower	dispatchedPower	capabilityMW	totalDisp_eachMPID	P_export	P_import	P_netImportExport	emmoOffer	loadOffer	CriteriaCheckDecision	deductibleNTGLoad	reduceLoadTag	finalNTGLoad	P_export_dict[bc]	P_import_dict[bc]	P_netImportExport_dict[bc]	P_prev_netImportExport_dict[bc]	P_export_dict[sk]	P_import_dict[sk]	P_netImportExport_dict[sk]	P_prev_netImportExport_dict[sk]	P_export_dict[mt]	P_import_dict[mt]	P_netImportExport_dict[mt]	P_prev_netImportExport_dict[mt]")
	for mUnit in MOList:
		# print mUnit.time, mUnit.serial, mUnit.assetName, mUnit.relatedImportAsset, mUnit.assetShortName, mUnit.Import_Export, mUnit.blockNumber, mUnit.flexibility, mUnit.offerPrice, mUnit.blockSize, mUnit.availablePower, mUnit.dispatchedPower, mUnit.capabilityMW, mUnit.totalDisp_eachMPID, mUnit.P_export, mUnit.P_import, mUnit.P_netImportExport
		
		hourlyEMMOlogfile.write("\n")
		hourlyEMMOlogfile.write("%s\t"*35 %(mUnit.time, mUnit.serial, mUnit.assetName, mUnit.relatedImportAsset, mUnit.assetShortName, mUnit.Import_Export, mUnit.blockNumber, mUnit.flexibility, mUnit.offerPrice, mUnit.blockSize, mUnit.availablePower, mUnit.dispatchedPower, mUnit.capabilityMW, mUnit.totalDisp_eachMPID, mUnit.P_export, mUnit.P_import, mUnit.P_netImportExport, mUnit.emmoOffer, mUnit.loadOffer, mUnit.CriteriaCheckDecision, mUnit.deductibleNTGLoad, mUnit.reduceLoadTag, mUnit.finalNTGLoad, 
		mUnit.P_export_dict[bc], mUnit.P_import_dict[bc], mUnit.P_netImportExport_dict[bc], mUnit.P_prev_netImportExport_dict[bc], 
		mUnit.P_export_dict[sk], mUnit.P_import_dict[sk], mUnit.P_netImportExport_dict[sk], mUnit.P_prev_netImportExport_dict[sk], 
		mUnit.P_export_dict[mt], mUnit.P_import_dict[mt], mUnit.P_netImportExport_dict[mt], mUnit.P_prev_netImportExport_dict[mt]))
		# EMMO_Log_Modified.write("\n")
					
	hourlyEMMOlogfile.close()

def setSk_Tie_rev0(netTieFlow):
	# netTieFlow = importMW - exportMW
	# skTie_bus = 1473
	# skTie_loadId = '34'
	print "Set SK Tie Flow with netFlow : ", netTieFlow, "MW .... "
	# if netTieFlow !=0:
		# status =  1
	# else:
		# status = 0
	status = 1
	err = psspy.load_chng_4(skTie_bus, skTie_loadId, (status,_i,_i,_i,_i,_i), (-netTieFlow, _f, _f,_f,_f,_f)  )

def setSk_Tie(netTieFlow):
	# Updated  - 30 Apr 2020
	# netTieFlow = importMW - exportMW
	print "Set SK Tie Flow with netFlow : ", netTieFlow, "MW .... "
	if skTie_bus != "N/A" and skTie_loadId != "N/A":
		status = 1
		err = psspy.load_chng_4(skTie_bus, skTie_loadId, (status, _i, _i, _i, _i, _i),
								(-netTieFlow, _f, _f, _f, _f, _f))
	else:
		if netTieFlow != 0:
			print "Error - SK Tie Mapping not Correct "
			print "Check SK Topology/ SK Mapping and Existence of SK in EMMO"
			print "==================================="
			raise ValueError("Error - SK Tie Mapping not Correct ")
	
def setBC_Tie(netTieFlow):
	print "===="

def setMT_Tie(netTieFlow ):
	# Updated  - 30 Apr 2020
	# netTieFlow = importMW - exportMW
	print "Set MT Tie Flow with netFlow : ", netTieFlow, "MW .... "
	if mtTie_genbus != "N/A" and mtTie_genId != "N/A":
		status = 1
		UpdateGen(mtTie_genbus, mtTie_genId, netTieFlow, status)
	else:
		if netTieFlow != 0:
			print "Error - MT Tie Mapping not Correct "
			print "Check MT Topology/ MT Mapping and Existence of MT in EMMO"
			print "==================================="
			raise ValueError("Error - MT Tie Mapping not Correct ")

def setMT_Tie_rev0(netTieFlow ):
	# netTieFlow = importMW - exportMW
	print "Set MT Tie Flow with netFlow : ", netTieFlow, "MW .... "
	status = 1
	UpdateGen(mtTie_genbus, mtTie_genId, netTieFlow, status)



def determine_mpidInternalLoss__(MPIDs):
	# enable_print()
	totalMPIDLosses = 0
	for MPID in MPIDs:
		print MPID.mpidName
		initmpidInternalLoss = 0
		mpidsubsystem = MPID.MPID_buses
		print mpidsubsystem
		# mpidsubsystem.append(MPID.interfaceBus)
		# print mpidsubsystem
		if mpidsubsystem != []:
			sid = psspy.bsys(0,0,[ 0.4, 500.],0,[],len(mpidsubsystem),mpidsubsystem,0,[],0,[])
			ties = 1   ######## For each end of interior subsystem buses only
			flag = 2
			busesFrom, busesTo, statuses, ids, pflows, plosses = FindAllFlowData(sid, ties, flag)
			totalLoss = 0
			if busesFrom != [] and busesTo != [] and ids != []:
				for (frombus, tobus, id, status, pflow, ploss) in zip(busesFrom, busesTo, ids, statuses, pflows, plosses):
					print frombus, tobus, id, status, pflow, ploss
					totalLoss += ploss
					initmpidInternalLoss = (totalLoss/2)
			else:
				initmpidInternalLoss = 0
		else:
			initmpidInternalLoss = 0
		totalMPIDLosses += initmpidInternalLoss
	return totalMPIDLosses
		
def determine_mpidInternalLoss(MPIDs):
	
	totalMPIDLosses = 0
	for MPID in MPIDs:
		initmpidInternalLoss = 0
		mpidsubsystem = MPID.MPID_buses
		# mpidsubsystem.append(MPID.interfaceBus)
		# print mpidsubsystem
		if mpidsubsystem != []:
			sid = psspy.bsys(0,0,[ 0.4, 500.],0,[],len(mpidsubsystem),mpidsubsystem,0,[],0,[])
			ties = 1   ######## For each end of interior subsystem buses only
			flag = 2
			busesFrom, busesTo, statuses, ids, pflows, plosses = FindAllFlowData(sid, ties, flag)
			# print busesFrom, busesTo, statuses, ids, pflows, plosses
			
			
			totalLoss = 0
			if busesFrom != [] and busesTo != [] and ids != []:
				for (frombus, tobus, id, status, pflow, ploss) in zip(busesFrom, busesTo, ids, statuses, pflows, plosses):
					# print frombus, tobus, id, status, pflow, ploss
					totalLoss += ploss
					initmpidInternalLoss = (totalLoss/2)
			else:
				initmpidInternalLoss = 0
		else:
			initmpidInternalLoss = 0
		totalMPIDLosses += initmpidInternalLoss
	return totalMPIDLosses
		
	
		
class MPID(object):  ## Updated by SDR 20 Mar 2019
	# def __init__(self, mpidName, facilityName, loadmpid, tag, lfTaG, generators, loads, interfaceBus, MPID_buses, netFlow ):
	def __init__(self, mpidName=None, facilityName=None, lfTag=None, loadmpids=None, emmoOffer=None, loadOffer=None, locationType=None, generators=None, onsiteLoads=None, loadDistributionFactor=None, interfaceBus=None, MPID_buses=None, netFlow=None ):
		self.mpidName = mpidName
		self.facilityName = facilityName
		self.lfTag = lfTag
		self.loadmpids = loadmpids
		self.emmoOffer = emmoOffer
		self.loadOffer = loadOffer 
		
		self.locationType = locationType
		
		self.generators = generators
		self.onsiteLoads = onsiteLoads
		self.loadDistributionFactor = loadDistributionFactor
		
		self.interfaceBus = interfaceBus
		self.MPID_buses = MPID_buses
		self.netFlow = netFlow

class loadObject(object):
	def __init__(self, bus, id):
		self.bus = bus
		self.id = id
		# self.pload = pload
		# self.qload = qload

class generatorObject(object):
	def __init__(self, bus, id):
		self.bus = bus
		self.id = id
		# self.pgen = pgen
		# self.pmax = pmax
		# self.pmin = pmin
		# self.qmax = qmax
		# self.qmin = qmin
		# self.mbase = mbase


def findSwingBus():
	err, [buses, types] = psspy.abusint(-1, 1, ("NUMBER", "TYPE"))
	for bus, type in zip(buses, types):
		if type == 3:
			return bus
			# print "Prev. Swing Bus - ", bus
			# psspy.bus_chng_3(bus, (2, ))
			break

def InitGen(bus, id, pgen):
	psspy.progress("Initializing Gen : %s-%s, %s MW" %(bus, id, pgen))
	status = 0
	err = psspy.machine_chng_2(bus, id, (status,_i,_i,_i,_i,_i), (pgen, ))
	
	
	
def UpdateGen(bus, id, pgen, status):
	# print "Gen Dispatch Updates: ", bus, id, pgen, status
	# if pgen == 0:
		# status = 0
	# else:
	
	status = 1
	err = psspy.machine_chng_2(bus, id, (status,_i,_i,_i,_i,_i), (pgen, ))
	swingBus = findSwingBus()
	# busType = _i
	
	if bus == swingBus:	
		busType = 3
		psspy.bus_chng_3(bus,[busType,_i,_i,_i],[_f,_f,_f,_f,_f,_f,_f],_s)
	else:
		busType = 2
		psspy.bus_chng_3(bus,[busType,_i,_i,_i],[_f,_f,_f,_f,_f,_f,_f],_s)
		# else:
			# busType = _i
			# psspy.bus_chng_3(bus,[busType,_i,_i,_i],[_f,_f,_f,_f,_f,_f,_f],_s)
	print "Gen Dispatch Updates: ", bus, id, pgen, "status : ", status, "Bus Type :", busType
	# psspy.save("saved_case.sav")
	
def UpdateGen_Max(bus, id, pgen, pmax, status):
	# if pgen == 0:
		# status = 0
	# else:
		# status = 1
	
	status = 1
	err = psspy.machine_chng_2(bus, id, (status,_i,_i,_i,_i,_i), (pgen,_f,_f,_f,pmax, ))
	swingBus = findSwingBus()
	# busType = _i
	
	if bus == swingBus:	
		busType = 3
		psspy.bus_chng_3(bus,[busType,_i,_i,_i],[_f,_f,_f,_f,_f,_f,_f],_s)
	else:
		busType = 2
		psspy.bus_chng_3(bus,[busType,_i,_i,_i],[_f,_f,_f,_f,_f,_f,_f],_s)
	
		# if status == 1:
			# busType = 2
			# psspy.bus_chng_3(bus,[busType,_i,_i,_i],[_f,_f,_f,_f,_f,_f,_f],_s)
		# else:
			# busType = _i
			# psspy.bus_chng_3(bus,[busType,_i,_i,_i],[_f,_f,_f,_f,_f,_f,_f],_s)
	print "Gen Dispatch Updates: ", bus, id, pgen, "status : ", status, "Bus Type :", busType
	# temp_sum += pgen
	# print temp_sum
			
			
def UpdateLF_Gen(bus, id, pgen, status):
	# print "Gen Dispatch Updates: ", bus, id, pgen, status
	if pgen == 0:
		status = 0
		err = psspy.machine_chng_2(bus, id, (_i,_i,_i,_i,_i,_i), (pgen, ))
	else:
		status = 1
		err = psspy.machine_chng_2(bus, id, (status,_i,_i,_i,_i,_i), (pgen, ))
	swingBus = findSwingBus()
	busType = _i
	
	if bus == swingBus:	
		busType == 3
		psspy.bus_chng_3(bus,[busType,_i,_i,_i],[_f,_f,_f,_f,_f,_f,_f],_s)
	else:
		if status == 1:
			busType = 2
			psspy.bus_chng_3(bus,[busType,_i,_i,_i],[_f,_f,_f,_f,_f,_f,_f],_s)
		else:
			busType = _i
			psspy.bus_chng_3(bus,[busType,_i,_i,_i],[_f,_f,_f,_f,_f,_f,_f],_s)
	print "Gen Dispatch Updates: ", bus, id, pgen, "status : ", status, "Bus Type :", busType
	# psspy.save("saved_case.sav")
	
def UpdateLF_Gen_Max(bus, id, pgen, pmax, status):
	if pgen == 0:
		err = psspy.machine_chng_2(bus, id, (_i,_i,_i,_i,_i,_i), (pgen,_f,_f,_f,pmax, ))
	else:
		status = 1
		err = psspy.machine_chng_2(bus, id, (status,_i,_i,_i,_i,_i), (pgen,_f,_f,_f,pmax, ))
	swingBus = findSwingBus()
	busType = _i
	if bus == swingBus:	
		busType == 3
		psspy.bus_chng_3(bus,[busType,_i,_i,_i],[_f,_f,_f,_f,_f,_f,_f],_s)
	else:
		if status == 1:
			busType = 2
			psspy.bus_chng_3(bus,[busType,_i,_i,_i],[_f,_f,_f,_f,_f,_f,_f],_s)
		else:
			busType = _i
			psspy.bus_chng_3(bus,[busType,_i,_i,_i],[_f,_f,_f,_f,_f,_f,_f],_s)
	print "Gen Dispatch Updates: ", bus, id, pgen, "status : ", status, "Bus Type :", busType
	# temp_sum += pgen
	# print temp_sum
			
#################### ----- MPIDs from excel sheet are stored in MPIDs -----------------------
## MPIDs [mpid  bus generators]


###################### Merit Order ###################
class meritorderData_____(object):  ## Updated by SDR
	def __init__(self, serial, assetName, Import_Export, blockNumber, flexibility, offerPrice, blockSize, availablePower, dispatchedPower, capabilityMW, totalDisp_eachMPID):
		self.serial = serial
		self.assetName = assetName
		self.Import_Export = Import_Export
		self.blockNumber = blockNumber
		self.flexibility = flexibility
		self.offerPrice = offerPrice
		self.blockSize = blockSize
		self.availablePower = availablePower
		self.dispatchedPower = dispatchedPower
		self.capabilityMW = capabilityMW
		self.totalDisp_eachMPID = totalDisp_eachMPID

def createMOList(excelFile): ## Updated by SDR
	wb = xlrd.open_workbook(excelFile)
	ws = wb.sheet_by_name('EMMO_Dec01_HH1400')
	MOList = []
	for row in range(1, ws.nrows):
		# print "VAL :", col2num('A')
		assetName = str(ws.cell(row, col2num('E')).value)
		#### here assetName means MPID Name in Mapping File
		# print assetName
		# raw_input()
		if assetName != 'N/A':
			serial = ws.cell(row, col2num('C')).value
			Import_Export = ws.cell(row, col2num('F')).value
			blockNumber = ws.cell(row, col2num('G')).value
			flexibility = ws.cell(row, col2num('H')).value
			offerPrice = ws.cell(row, col2num('I')).value 
			blockSize = ws.cell(row, col2num('J')).value
			availablePower = ws.cell(row, col2num('K')).value
			dispatchedPower = ws.cell(row, col2num('L')).value
			capabilityMW = ws.cell(row, col2num('M')).value
			totalDisp_eachMPID = ws.cell(row, col2num('N')).value
			
			
			# print serial
			# print assetName
			# print Import_Export
			# print blockNumber
			# print flexibility
			# print offerPrice
			# print blockSize
			# print availablePower
			# print dispatchedPower
			# print capabilityMW
			# print totalDisp_eachMPID
			# raw_input()

			MOList.append(meritorderData(serial, assetName, Import_Export, blockNumber, flexibility, offerPrice, blockSize, availablePower, dispatchedPower, capabilityMW, totalDisp_eachMPID))
	return MOList
	
############## Determining Gen Data
def FindAllMachineData(sid = -1, flag = 4):  ## ## Updated by SDR
	# sid = -1  ### by Default
	# flag = 4 ### for All machines
	err, [buses, statuses] = psspy.amachint(sid, flag, ("NUMBER", "STATUS"))
	err, [ids] = psspy.amachchar(sid, flag, ("ID",))
	err, [pgens, pmaxes, pmins, qmaxes, qmins, mbases] = psspy.amachreal(sid, flag, ("PGEN", "PMAX", "PMIN", "QMAX", "QMIN", "MBASE"))
	
	
	
	return buses, ids, statuses, pgens, pmaxes, pmins, qmaxes, qmins, mbases

def GetGenData(getbus, getid): ## Updated by SDR
	#### status, pgen, pmax, pmin, qmax, qmin, mbase = GetGenData(getbus, getid)
	# print "---", getbus, getid
	buses, ids, statuses, pgens, pmaxes, pmins, qmaxes, qmins, mbases = FindAllMachineData(sid = -1, flag = 4)
	# print ids
	
	# raw_input()
	for (bus, id, status, pgen, pmax, pmin, qmax, qmin, mbase) in zip(buses, ids, statuses, pgens, pmaxes, pmins, qmaxes, qmins, mbases):
		# print bus, id 
		if bus == getbus and id.strip(" ") == getid:
			# if id == '3':
			# print "FOUND"
			
			return status, pgen, pmax, pmin, qmax, qmin, mbase
	# raw_input("-------")
	print "Generator Not Found"
	raise ValueError
			
	# return status, pgen, pmax, pmin, qmax, qmin, mbase

	

	
def determineMPID_Load(MPID):
	### Updated by sdr - 20-Mar-2019
	# print MPID.mpidName
	totalPload = 0
	totalQload = 0
	
	if MPID.mpidName not in Import_Export_Services:
		for loadmpid in MPID.loadmpids:
			loads = MPID.onsiteLoads[loadmpid]
			for load in loads:
				# loadbus = load.split('-')[0] 
				# loadid = load.split('-')[1]
				loadbus = int(load.split("-")[0])
				loadid = load.split("-")[1]
				status, pload, qload = getLoadData(loadbus, loadid)
				totalPload = totalPload + pload
				totalQload = totalQload + qload
				# print loadbus, loadid, totalPload, totalQload
				# raw_input()
	print totalPload, totalQload
	return totalPload, totalQload
############### Find Bus Data
	
def determineMPID_Gen(MPID):
	### Updated - 25-Apr-2020
	# print MPID.mpidName
	totalPgen = 0
	totalPmax = 0
	
	print MPID.mpidName
	# raw_input()
	if MPID.mpidName == bc_imp or MPID.mpidName == bc_exp:
		totalPgen = TieMeasure()
		totalPmax = totalPgen
	
	elif MPID.mpidName == sk_imp or MPID.mpidName == sk_exp:
		if skTie_bus != "N/A" and skTie_loadId != "N/A":
			status, pload, qload = getLoadData(skTie_bus, skTie_loadId)
			if status != 0:
				totalPgen = - pload
			totalPmax = totalPgen
	elif MPID.mpidName == mt_imp or MPID.mpidName == mt_exp:
		if mtTie_genbus != "N/A" and mtTie_genId != "N/A":
			status, pgen, pmax, pmin, qmax, qmin, mbase = GetGenData(mtTie_genbus, mtTie_genId)
			if status != 0:
				totalPgen = pgen
			totalPmax = pmax
	else:
		if MPID.generators != '':
			for gen in MPID.generators:
				status, pgen, pmax, pmin, qmax, qmin, mbase = GetGenData(gen.bus, gen.id)
				if status != 0:
					totalPgen += pgen
				totalPmax += pmax
	# print totalPgen, totalPmax
	return totalPgen, totalPmax

def determineMPID_Gen_v0(MPID):
	### Updated by sdr - 20-Mar-2019
	# print MPID.mpidName
	totalPgen = 0
	totalPmax = 0
	# if MPID.mpidName == 'BCHIMP':
	if MPID.mpidName == bc_imp or MPID.mpidName == bc_exp:
		totalPgen = TieMeasure()
		totalPmax = totalPgen
	# elif MPID.mpidName == 'SPCIMP':
	elif MPID.mpidName == sk_imp or MPID.mpidName == sk_exp:
		status, pload, qload = getLoadData(skTie_bus, skTie_loadId)
		totalPgen = - pload
		totalPmax = totalPgen
	else:
		if MPID.generators != '':
			for gen in MPID.generators:
				status, pgen, pmax, pmin, qmax, qmin, mbase = GetGenData(gen.bus, gen.id)
				if status != 0:
					totalPgen += pgen
				totalPmax += pmax
	print totalPgen, totalPmax
	return totalPgen, totalPmax




############### Determining Load Data ###
def FindAllLoadData(sid = -1, flag = 4):
	err, [buses, statuses] = psspy.aloadint(sid, flag, ("NUMBER", "STATUS"))
	err, [ids] = psspy.aloadchar(sid, flag, ("ID", ))
	err, [loads] = psspy.aloadcplx(sid, flag, ("TOTALACT", ))
	return buses, ids, statuses, loads
	
def checkLoadExistence(loadbus, loadid):
	# # # # print "Load Element Checking in Topology Case..."
	##########################################################
	checkResult = 'NO'
	buses, ids, statuses, loads = FindAllLoadData()
	
	for bus, id, status, load in zip(buses, ids, statuses, loads):
		if bus == loadbus and id.strip(" ") == loadid:
			checkResult = "YES"
			 
	return checkResult

def getLoadData(loadbus, loadid):
	buses, ids, statuses, loads = FindAllLoadData()
	# print buses, ids, statuses, loads
	# raw_input()
	# print ids
	for bus, id, status, load in zip(buses, ids, statuses, loads):
		# print bus, id
		# raw_input()
		if bus == loadbus and id.strip(" ") == loadid:
			# print bus , id, status, load.real
			# raw_input()
			return status, load.real, load.imag
			# return 0, 0, 0
	
	print loadbus, loadid, "Loadbus/id Not Found"
	raise 
	return 0, 0, 0

def UpdateLoad(loadbus, loadid, status, pload, qload):
	 
	if pload == 0:
		loadStatus = checkLoadExistence(loadbus, loadid)
		if loadStatus == "YES":
			psspy.progress ("\n %s, %s, %s, %s, %s\n" %(loadbus, loadid, status, pload, qload))
			err = psspy.load_chng_4(loadbus, loadid, [status, _i,_i,_i,_i,_i], [pload, qload, _f, _f,_f,_f])
			# UpdateLoad(loadbus, loadid, status, pload, qload)
		else:
			print "Load ", loadbus, "-", loadid, " NOT FOUND in case... but Pload=0 so ignored"
			# raw_input()
			psspy.progress("\n %s-%s Load not found in case... but Pload=0 so ignored" %(loadbus, loadid))
	else:
		loadStatus = checkLoadExistence(loadbus, loadid)
		if loadStatus == "YES":
			psspy.progress ("\n %s, %s, %s, %s, %s\n" %(loadbus, loadid, status, pload, qload))
			err = psspy.load_chng_4(loadbus, loadid, [status, _i,_i,_i,_i,_i], [pload, qload, _f, _f,_f,_f])
			# UpdateLoad(loadbus, loadid, status, pload, qload)
		else:
			print "Load ", loadbus, "-", loadid, " NOT FOUND in case...RAISE ERROR"
			print "Load not found in case... Raise Error"
			psspy.progress("\n %s-%s Load not found in case... Raise Error" %(loadbus, loadid))
			# raise ValueError
			raise MissingElementError(" -- Load Not Found in Topology")
	
	# if loadbus != skTie_bus:
		# if pload == 0:
			# status = 0
		# else:
			# status = 1
		
	
	


###### Determining MPID Net Flow
def FindAllFlowData(sid = -1, ties = 1, flag = 2):
	err, [busesFrom, busesTo, statuses] = psspy.aflowint(sid, 1, ties, flag, ("FROMNUMBER", "TONUMBER", "STATUS"))
	err, [ids] = psspy.aflowchar(sid, 1, ties, flag, ("ID",))
	err, [pflows, plosses] = psspy.aflowreal(sid, 1, ties, flag, ("P", "PLOSS"))
	
	return busesFrom, busesTo, statuses, ids, pflows, plosses

def getBranchFlow(fromBus, toBus, ID, direction="positive"):
	busesFrom, busesTo, statuses, ids, pflows, plosses = FindAllFlowData()
	for (busFrom, busTo, status, id, pflow, ploss) in zip(busesFrom, busesTo, statuses, ids, pflows, plosses):
		temp = []
		# if busFrom == fromBus and busTo == toBus:
		if busFrom == fromBus and busTo == toBus and id.strip(" ") == ID:
			# temp.append(id)
			# temp.append(ID)
			# print temp
			# raw_input()
		
			if direction == "positive":
				print status, pflow, ploss
				# raw_input()
				return  status, pflow, ploss
			else:
				print status, pflow, ploss
				# raw_input()
				return  status, -pflow, ploss
	
	print "Branch Not Found"
	raise ValueError

def get3WBranchFlow(fromBus, toBus, ID, direction="positive"):
	busesFrom, busesTo, statuses, ids, pflows, plosses = FindAllFlowData()
	for (busFrom, busTo, status, id, pflow, ploss) in zip(busesFrom, busesTo, statuses, ids, pflows, plosses):
		temp = []
		# if busFrom == fromBus and busTo == toBus:
		if busFrom == fromBus and busTo > toBus and id.strip(" ") == ID:
		# if busFrom == fromBus and id.strip(" ") == ID:
			if direction == "positive":
				print status, pflow, ploss
				# raw_input()
				return  status, pflow, ploss
			else:
				print status, pflow, ploss
				# raw_input()
				return  status, -pflow, ploss
	
	print "Branch Not Found"
	raise ValueError
	
	

def remove_duplicates(values):
    output = []
    seen = set()
    for value in values:
        # If value has not been encountered yet,
        # ... add it to both list and set.
        if value not in seen:
            output.append(value)
            seen.add(value)
    return output
	
def findDates(caseFiles):
	
	dates = dict()
	date_months = []
	
	for caseFile in caseFiles:
		# print caseFile
		caseName = os.path.basename(caseFile)
		tempName = caseName.split(".sav")[0]
		tempName = tempName.split("_")
		
		day = tempName[0]
		month = tempName[1].upper()
		year = tempName[2]
		hour = tempName[4]
		
		date = year + "-" + month + "-" + day + "-" + hour + "-" + "00"
		# print date
		dates[caseName] = date
		date_months.append(month)
		
		# raw_input()
	
	months = remove_duplicates(date_months)
	# print months
	# sys.exit()
	return dates, months

	
#####################
#############################
def selectMonthlyMPIDMapping(GenMappingFiles, month):
	desiredFile = ''
	for excelFile in GenMappingFiles:
		filename = os.path.splitext(os.path.split(excelFile)[1])[0].lower()
		filename = filename.split("_")[2]
		if month.lower() in filename:
			desiredFile = excelFile
		# if month.lower() in os.path.splitext(os.path.split(excelFile)[1])[0].lower():
			# desiredFile = excelFile
	return desiredFile	


def Createintertielst(excelFile, month):
	# Updated - 26 Apr 2020
	print("Reading Intertie Mapping.....")
	wb = xlrd.open_workbook(excelFile)
	ws = wb.sheet_by_name('Intertie Mapping')
	from_bus = []
	to_bus = []
	tie_id = []
	for col_idx in range(1, ws.ncols):
		for row_idx in range(2, ws.nrows):
			tempVal = ws.cell(row_idx, col_idx).value
			if tempVal == "N/A" or tempVal == "" or tempVal == "n/a":
				tempVal = "N/A"
				if col_idx == 1:
					from_bus.append(tempVal)
				elif col_idx == 2:
					# if ws.cell(row_idx,col_idx).value != 'N/A':
					to_bus.append(tempVal)
				else:
					tie_id.append(str(tempVal))
			else:
				if col_idx == 1:
					from_bus.append(int(tempVal))
				elif col_idx == 2:
					# if ws.cell(row_idx,col_idx).value != 'N/A':
					to_bus.append(int(tempVal))
				else:
					tie_id.append(str(tempVal))
	
	ab_bc_intertie_info = [[from_bus[idx], to_bus[idx], tie_id[idx]] for idx in range(0, 3)]
	sk_intertie_bus = from_bus[4]
	sk_intertie_id = tie_id[4]
	mt_intertie_bus = from_bus[3]
	mt_intertie_id = tie_id[3]
	return ab_bc_intertie_info, mt_intertie_bus, mt_intertie_id, sk_intertie_bus, sk_intertie_id


def Createintertielst_v0(excelFile, month):
	print("Reading Intertie Mapping.....")
	wb = xlrd.open_workbook(excelFile)
	ws = wb.sheet_by_name('Intertie Mapping')
	from_bus = []
	to_bus = []
	tie_id = []
	for col_idx in range(1,ws.ncols):
		for row_idx in range(2,ws.nrows):
			if col_idx == 1:
				from_bus.append(int(ws.cell(row_idx,col_idx).value))
			elif col_idx == 2:
				if ws.cell(row_idx,col_idx).value != 'N/A':
					to_bus.append(int(ws.cell(row_idx,col_idx).value))
			else:
				tie_id.append(str(ws.cell(row_idx,col_idx).value))
	ab_bc_intertie_info = [[from_bus[idx], to_bus[idx], tie_id[idx]] for idx in range(0,3)]
	sk_intertie_bus = from_bus[4]
	sk_intertie_id = tie_id[4]
	mt_intertie_bus = from_bus[3]
	mt_intertie_id = tie_id[3]
	return ab_bc_intertie_info, mt_intertie_bus, mt_intertie_id, sk_intertie_bus, sk_intertie_id


def CreateMPIDs(excelFile, month): ## Updated by SDR
	print ("Reading Gen Mapping .....")
	wb = xlrd.open_workbook(excelFile)
	ws = wb.sheet_by_name('Gen MPID Mapping') ## Updated
	MPIDs = []
	#absent = []
	MPIDs_dict = dict()
	for row in range(1, ws.nrows):
		# tag = ws.cell(row, 2).value   ### Clumn C
		lfTag = str(ws.cell(row, col2num("C")).value)   ### Clumn C
		if lfTag != 'SKIP': #or lfTag == 'SKIP-LF':
		# if tag == 'LF MPID' or tag == 'LF MPID-SKIP' or tag == 'SKIP':
		# if tag == 'LF' or tag == 'SKIP-LF':
		
			mpidName = str(ws.cell(row, col2num("A")).value)   ### Clumn B
		# print mpidName
			facilityName = str(ws.cell(row, col2num("B")).value)   ### Clumn B
			lfTag = str(ws.cell(row, col2num("C")).value)   ### Clumn B
			loadmpidNames  = str(ws.cell(row, col2num("D")).value)   ### Clumn B
		
			emmoOffer  = str(ws.cell(row, col2num("E")).value)   ### Clumn E
			loadOffer  = str(ws.cell(row, col2num("F")).value)   ### Clumn F
		
			locationType  = str(ws.cell(row, col2num("G")).value)   ### Clumn G
		# dosTag  = str(ws.cell(row, col2num("H")).value)   ### Clumn H
		
		# ISDtag = ws.cell(row, col2num("F")).value   ### Clumn C
		
		# associatedGens = [str(ws.cell(row, col).value) for col in range(6, 17)]
			associatedGens = [str(ws.cell(row, col).value) for col in range(col2num("H"), col2num("R")+1)]
		# associatedLoads = [str(ws.cell(row, col).value) for col in range(17, 20)]
			associatedLoads = [str(ws.cell(row, col).value) for col in range(col2num("S"), col2num("U")+1)]
		
			loadDistributionFactor  = ws.cell(row, col2num("V")).value
		
			listedLoadElements = []
		# if associatedLoads != []:
			for loads in associatedLoads:
				if loads != "":
					temploads = loads.split(";")
					for tempload in temploads:
						tempload = tempload.strip("[")
						tempload = tempload.strip("]")
						listedLoadElements.append(tempload)
		# print listedLoadElements	
		
			loadmpids = []
			if loadmpidNames != '':
			# print loadmpidNames
				loadmpidNames = loadmpidNames.replace(" ", "")
			# print loadmpidNames
				loadmpids = loadmpidNames.split(",")
			# print loadmpids
			onsiteLoads = dict()
			for (loadmpid, loadElement)  in zip(loadmpids, listedLoadElements):
				if loadmpid != "":
					onsiteLoads[loadmpid] = loadElement.split(",")
			
		# print onsiteLoads
		# enable_print()
		# print loadmpids
		# raw_input()

		
			interfaceBus = (ws.cell(row, col2num("W")).value)
			if interfaceBus != '':
				interfaceBus = int(interfaceBus)
			mpid_subsystem = str((ws.cell(row, col2num("X")).value))
			buses = mpid_subsystem.split(",")
			netFlow = str((ws.cell(row, col2num("Y")).value))
		
			generators = []
		# if associatedGens != []:
			for gen in associatedGens:
				if gen != '':
					[bus, id] = gen.split("-")
					bus = int(bus)
					generators.append(generatorObject(bus, str(id)))
		
		
			MPID_buses = []
			for bus in buses:
				if bus != '':
					MPID_buses.append(int(bus.strip(" ")))
			if interfaceBus != '':
				MPID_buses.append(interfaceBus)
		# print mpidName, tag, ISDtag
		# print associatedGens
		# print associatedLoads 
		# print interfaceBus
		# print MPID_buses
		# print netFlow 
		# raw_input()
			temp = MPID(mpidName, facilityName, lfTag, loadmpids, emmoOffer, loadOffer, locationType, generators, onsiteLoads, loadDistributionFactor, interfaceBus, MPID_buses, netFlow )
			MPIDs.append(temp)
		# MPIDs_dict[mpidName] = temp
	# sys.exit()    
		#else:
			#print (str(ws.cell(row, col2num("A")).value))
			#absent.append(str(ws.cell(row, col2num("A")).value))
		#print 'The MPIDs with SKIP tag are: '
		#print absent
	return MPIDs
	


###################################################
#####################################
###########
def selectMonthlyCase(caseFiles, month):
	desiredMonthlyCase = ''
	for caseFile in caseFiles:
		if month.lower() in os.path.splitext(os.path.split(caseFile)[1])[0].lower():
			desiredMonthlyCase = caseFile
			
	return desiredMonthlyCase	


########################################################
####################################################
def SelectMonthlyLoadMapping(loadMappingFiles, month):
	desiredFile = ''
	for excelFile in loadMappingFiles:
		if month.lower() in os.path.splitext(os.path.split(excelFile)[1])[0].lower():
			desiredFile = excelFile
			
	return desiredFile
class loadmapdata(object):
	def __init__(self, genMPID, loadMPID, bus, id, isdtag):
		self.genMPID = genMPID
		self.loadMPID = loadMPID
		self.bus = bus
		self.id = id
		self.isdtag = isdtag
def readLoadMapping(excelFile):
	wb = xlrd.open_workbook(excelFile)
	ws = wb.sheet_by_name("Load Mapping")
	loadMappingList = []
	for row in range(1, ws.nrows):
		genMPID = str(ws.cell(row, 0).value)
		loadMPID = str(ws.cell(row, 1).value)
		# print assetName
		# raw_input()
		if loadMPID != '':
			
			bus = int(ws.cell(row, 2).value)
			id = (ws.cell(row, 4).value)
			# print id, type(id)
			if type(id) is  float:
				id = str(int(id))
			elif type(id) is  int:
				id = str(id)
			else: ## type(id) is  unicode:
				id = str(id)
			isdtag = (ws.cell(row, col2num("S")).value)
			# print loadMPID, bus, id
			# raw_input()
			loadMappingList.append(loadmapdata(genMPID, loadMPID, bus, id, isdtag))
	# raw_input()
	return loadMappingList
######################################
####################################
		


################################################
################################################
###################


#############################
#############################
class meritorderData_v0(object):  ## Updated by SDR
	def __init__(self, time, serial, assetName, Import_Export, blockNumber, flexibility, offerPrice, blockSize, availablePower, dispatchedPower, capabilityMW, totalDisp_eachMPID):
		self.time = time
		self.serial = serial
		self.assetName = assetName
		self.Import_Export = Import_Export
		self.blockNumber = blockNumber
		self.flexibility = flexibility
		self.offerPrice = offerPrice
		self.blockSize = blockSize
		self.availablePower = availablePower
		self.dispatchedPower = dispatchedPower
		self.capabilityMW = capabilityMW
		self.totalDisp_eachMPID = totalDisp_eachMPID
		
		
class meritorderData_v1(object):  ## Updated by SDR
	def __init__(self, time, serial, assetName, assetShortName, Import_Export, blockNumber, flexibility, offerPrice, blockSize, availablePower, dispatchedPower, capabilityMW, totalDisp_eachMPID):
		self.time = time
		self.serial = serial
		self.assetName = assetName
		self.assetShortName = assetShortName
		self.Import_Export = Import_Export
		self.blockNumber = blockNumber
		self.flexibility = flexibility
		self.offerPrice = offerPrice
		self.blockSize = blockSize
		self.availablePower = availablePower
		self.dispatchedPower = dispatchedPower
		self.capabilityMW = capabilityMW
		self.totalDisp_eachMPID = totalDisp_eachMPID
		
class meritorderData(object):  ## Updated by SDR
	def __init__(self, time=None, serial=None, assetName=None, relatedImportAsset=None, assetShortName=None, Import_Export=None, blockNumber=None, flexibility=None, offerPrice=None, blockSize=None, availablePower=None, dispatchedPower=None, capabilityMW=None, totalDisp_eachMPID=None, P_export=None, P_import=None, P_netImportExport=None, emmoOffer=None, loadOffer=None, CriteriaCheckDecision=None, deductibleNTGLoad=None, reduceLoadTag=None, finalNTGLoad=None, P_export_dict=None, P_import_dict=None, P_netImportExport_dict=None, P_prev_netImportExport_dict=None):
		self.time = time
		self.serial = serial
		self.assetName = assetName
		self.relatedImportAsset = relatedImportAsset
		self.assetShortName = assetShortName
		self.Import_Export = Import_Export
		self.blockNumber = blockNumber
		self.flexibility = flexibility
		self.offerPrice = offerPrice
		self.blockSize = blockSize
		self.availablePower = availablePower
		self.dispatchedPower = dispatchedPower
		self.capabilityMW = capabilityMW
		self.totalDisp_eachMPID = totalDisp_eachMPID
		self.P_export = P_export
		self.P_import = P_import
		self.P_netImportExport = P_netImportExport
		self.emmoOffer = emmoOffer
		self.loadOffer = loadOffer
		self.CriteriaCheckDecision = CriteriaCheckDecision
		self.deductibleNTGLoad = deductibleNTGLoad
		self.reduceLoadTag = reduceLoadTag
		self.finalNTGLoad = finalNTGLoad
		
		self.P_export_dict = P_export_dict
		self.P_import_dict = P_import_dict
		self.P_netImportExport_dict = P_netImportExport_dict
		self.P_prev_netImportExport_dict = P_prev_netImportExport_dict		
		
		
class emmocorrection(object):
	def __init__(self, time, assetName, blockNumber, availablePower, totalDisp_eachMPID):
		self.time = time
		self.assetName = assetName
		self.blockNumber = blockNumber
		self.availablePower = availablePower
		self.totalDisp_eachMPID = totalDisp_eachMPID
	
	
	
	
def SelectMonthlyEMMO(EMMOFiles, month):
	desiredFile = ''
	for excelFile in EMMOFiles:
		if month.lower() in os.path.splitext(os.path.split(excelFile)[1])[0].lower():
			desiredFile = excelFile
			
	return desiredFile
	
# def createHourlyEMMO(monthlyEMMO, time, monthlyEMMOcorrection):
def createHourlyEMMO(monthlyEMMO, time):
	currentHourEMMO = []
	serial = 0
	for row in monthlyEMMO:
		if row.time == time:
			currentHourEMMO.append(row)
			serial += 1
			row.serial = serial
	def determineMPIDTotalDispatch(currentHourEMMO):
		for row in currentHourEMMO:
			currentSerial = row.serial
			currentAssetName = row.assetName
			totalDispatch = 0
			for eachrow in currentHourEMMO:
				if eachrow.serial <= currentSerial and eachrow.assetName == currentAssetName:
					totalDispatch = totalDispatch + eachrow.availablePower
				
			row.totalDisp_eachMPID = totalDispatch
			
		return currentHourEMMO
	
	def correctEMMO__(currentHourEMMO, time, monthlyEMMOcorrection):
		# print time
		### NOt Required###########
		# raw_input()
		for eachRecord in monthlyEMMOcorrection:
			# print eachRecord.time, time
			if eachRecord.time == time:
				for row in currentHourEMMO:
					# print row.assetName, eachRecord.assetName
					# print row.blockNumber, eachRecord.blockNumber
					if row.assetName == eachRecord.assetName and row.blockNumber == eachRecord.blockNumber:
						row.availablePower = eachRecord.availablePower
						row.totalDisp_eachMPID = eachRecord.totalDisp_eachMPID
						print time, row.assetName, row.blockNumber, row.availablePower, row.totalDisp_eachMPID
						# raw_input()
		# sys.exit()
		return currentHourEMMO
	currentHourEMMO = determineMPIDTotalDispatch(currentHourEMMO)
	# currentHourEMMO_corrected = correctEMMO__(currentHourEMMO, time, monthlyEMMOcorrection)
			
	# return currentHourEMMO_corrected
	return currentHourEMMO
			
def readMonthlyEMMO_v0(excelFile): ## Updated by SDR
	wb = xlrd.open_workbook(excelFile)
	sheetName = "EMMO"
	ws = wb.sheet_by_name(sheetName)
	monthlyEMMOList = []
	for row in range(1, ws.nrows):
		# print "VAL :", col2num('A')
		assetName = str(ws.cell(row, col2num('E')).value)
		#### here assetName means MPID Name in Mapping File
		# print assetName
		# raw_input()
		if assetName != 'N/A':
			time = ws.cell(row, col2num('B')).value
			# # t1 = time.split(":")[0]
			# # t2 = time.split(":")[1]
			# # t3 = time.split(":")[2]
			# # t4 = time.split(":")[3]
			
			# # t2 = str(int(t2) + 1)
			# # t2 = t2.zfill(2)
			
			# # time = t1 + ":" + t2 + ":" + t3 +":" + t4
			# serial = ws.cell(row, col2num('C')).value
			serial = ''
			Import_Export = ws.cell(row, col2num('F')).value
			blockNumber = int(ws.cell(row, col2num('G')).value)
			flexibility = ws.cell(row, col2num('H')).value
			offerPrice = ws.cell(row, col2num('I')).value 
			blockSize = ws.cell(row, col2num('J')).value
			availablePower = ws.cell(row, col2num('K')).value
			dispatchedPower = ws.cell(row, col2num('L')).value
			capabilityMW = ws.cell(row, col2num('M')).value
			# totalDisp_eachMPID = ws.cell(row, col2num('N')).value
			totalDisp_eachMPID = 0
			
			monthlyEMMOList.append(meritorderData(time, serial, assetName, Import_Export, blockNumber, flexibility, offerPrice, blockSize, availablePower, dispatchedPower, capabilityMW, totalDisp_eachMPID))
	return monthlyEMMOList

def readMonthlyEMMO_v1(excelFile): ## Updated by SDR
	wb = xlrd.open_workbook(excelFile)
	sheetName = "EMMO"
	ws = wb.sheet_by_name(sheetName)
	monthlyEMMOList = []
	for row in range(1, ws.nrows):
		# print "VAL :", col2num('A')
		assetName = str(ws.cell(row, col2num('E')).value)
		# print assetName
		# raw_input()
		#### here assetName means MPID Name in Mapping File
		# print assetName
		# raw_input()
		if assetName != 'N/A':
			time = ws.cell(row, col2num('B')).value
			# # t1 = time.split(":")[0]
			# # t2 = time.split(":")[1]
			# # t3 = time.split(":")[2]
			# # t4 = time.split(":")[3]
			
			# # t2 = str(int(t2) + 1)
			# # t2 = t2.zfill(2)
			
			# # time = t1 + ":" + t2 + ":" + t3 +":" + t4
			# serial = ws.cell(row, col2num('C')).value
			serial = ''
			Import_Export = ws.cell(row, col2num('F')).value
			blockNumber = ws.cell(row, col2num('G')).value
			flexibility = ws.cell(row, col2num('H')).value
			offerPrice = ws.cell(row, col2num('I')).value 
			blockSize = ws.cell(row, col2num('J')).value
			
			availablePower = ws.cell(row, col2num('K')).value
			dispatchedPower = ws.cell(row, col2num('L')).value
			capabilityMW = ws.cell(row, col2num('M')).value
			
			if Import_Export == "E":
				availablePower = -availablePower
				dispatchedPower = -dispatchedPower
			
			# totalDisp_eachMPID = ws.cell(row, col2num('N')).value
			totalDisp_eachMPID = 0
			# print time, serial, assetName, Import_Export, blockNumber, flexibility, offerPrice, blockSize, availablePower, dispatchedPower, capabilityMW, totalDisp_eachMPID
			# raw_input()
			monthlyEMMOList.append(meritorderData(time, serial, assetName, Import_Export, blockNumber, flexibility, offerPrice, blockSize, availablePower, dispatchedPower, capabilityMW, totalDisp_eachMPID))
	return monthlyEMMOList

def readMonthlyEMMO(excelFile): ## Updated by SDR
	wb = xlrd.open_workbook(excelFile)
	sheetName = "EMMO"
	ws = wb.sheet_by_name(sheetName)
	monthlyEMMOList = []
	for row in range(1, ws.nrows):
		# print "VAL :", col2num('A')
		assetName = str(ws.cell(row, col2num('E')).value)
		# print assetName
		# raw_input()
		#### here assetName means MPID Name in Mapping File
		# print assetName
		# raw_input()
		if assetName != 'N/A':
			time = ws.cell(row, col2num('B')).value
			# # t1 = time.split(":")[0]
			# # t2 = time.split(":")[1]
			# # t3 = time.split(":")[2]
			# # t4 = time.split(":")[3]
			
			# # t2 = str(int(t2) + 1)
			# # t2 = t2.zfill(2)
			
			# # time = t1 + ":" + t2 + ":" + t3 +":" + t4
			# serial = ws.cell(row, col2num('C')).value
			serial = ''
			assetShortName = str(ws.cell(row, col2num('D')).value)
			Import_Export = ws.cell(row, col2num('F')).value
			blockNumber = ws.cell(row, col2num('G')).value
			flexibility = ws.cell(row, col2num('H')).value
			offerPrice = ws.cell(row, col2num('I')).value 
			blockSize = ws.cell(row, col2num('J')).value
			
			availablePower = ws.cell(row, col2num('K')).value
			dispatchedPower = ws.cell(row, col2num('L')).value
			capabilityMW = ws.cell(row, col2num('M')).value
			
			if Import_Export == "E":
				availablePower = -availablePower
				dispatchedPower = -dispatchedPower
			
			# totalDisp_eachMPID = ws.cell(row, col2num('N')).value
			totalDisp_eachMPID = 0
			# print time, serial, assetName, Import_Export, blockNumber, flexibility, offerPrice, blockSize, availablePower, dispatchedPower, capabilityMW, totalDisp_eachMPID
			# raw_input()
			monthlyEMMOList.append(meritorderData(time, serial, assetName, assetShortName, Import_Export, blockNumber, flexibility, offerPrice, blockSize, availablePower, dispatchedPower, capabilityMW, totalDisp_eachMPID))
	return monthlyEMMOList
	
	
	
def readMonthlyEMMOcorrection(EMMOcorrectionFile):
	wb = openpyxl.load_workbook(EMMOcorrectionFile, data_only = True)
	ws = wb.get_sheet_by_name("Update EMMO")
	emmocorrectionList = []
	for row in range(2, ws.max_row+1):
		time = ws["A" + str(row)].value
		assetName = ws["B" + str(row)].value
		blockNumber = ws["C" + str(row)].value
		availablePower = ws["D" + str(row)].value
		totalDisp_eachMPID = ws["E" + str(row)].value
		emmocorrectionList.append(emmocorrection(time, assetName, blockNumber, availablePower, totalDisp_eachMPID))
	return emmocorrectionList
	######################################
#######################################
def SelectMonthlyLoad(loadDataFiles, month):
	desiredFile = ''
	for excelFile in loadDataFiles:
		filename = os.path.splitext(os.path.split(excelFile)[1])[0].lower()
		filename = filename.split("_")[2]
		if month.lower() in filename:
			desiredFile = excelFile
		# if month.lower() in os.path.splitext(os.path.split(excelFile)[1])[0].lower():
			# desiredFile = excelFile
			
	return desiredFile

class loadData(object):  ## Updated by SDR
	def __init__(self, mpidName, mwData):
		self.mpidName = mpidName
		self.mwData = mwData
	
def readMonthlyLoad(excelFile):
	wb = xlrd.open_workbook(excelFile)
	ws = wb.sheet_by_name("Load Data")
	monthlyLoadData = []
	
	times = []
	for col in range(col2num('B'), ws.ncols):
		date = (ws.cell(0, col).value)
		temp = xlrd.xldate.xldate_as_datetime(date, wb.datemode)
		dt = datetime.timedelta(hours=1)
		time = temp - dt
		time = time.strftime("%d%b%Y:%H:%M:%S")
		time = time.upper()
		print time
		# raw_input(time)
		# year = temp[0]
		# month = temp[1]
		# day = temp[2]
		
		# hour = str(ws.cell(2, col).value)
		# time = year+month+day+":"+hour
		times.append(time)
	# raw_input("END")
	for row in range(4, ws.nrows):
		mpidName = str(ws.cell(row, 0).value)
		mpidName = mpidName.replace('MP_', '')
		
		mwData = dict()
		# raw_input()
		if mpidName != '':
			for col in range(col2num('B'), ws.ncols):
				k = col2num('B')
				# print row, col, [col-k]
				# print times[col-k]
				mwData[times[col-k]] = ws.cell(row, col).value
			# print mpidName, mwData
			monthlyLoadData.append(loadData(mpidName, mwData))
	# raw_input()		
	return monthlyLoadData

def createHourlyLoad(monthlyLoad, time):
	currentHourLoad = []
	
	for row in monthlyLoad:
		mpidName = row.mpidName
		mwData = row.mwData[time]
		
		currentHourLoad.append(loadData(mpidName, mwData))
	
	return currentHourLoad
#############################################
###############################################

def SelectMonthlyTSS(tssDataFiles, month):
	desiredFile = ''
	for excelFile in tssDataFiles:
		if month.lower() in os.path.splitext(os.path.split(excelFile)[1])[0].lower():
			desiredFile = excelFile
			
	return desiredFile

class tssData(object):  ## Updated by SDR
	def __init__(self, mpidName, mwData):
		self.mpidName = mpidName
		self.mwData = mwData

def readMonthlyTSS(excelFile):
	wb = xlrd.open_workbook(excelFile)
	ws = wb.sheet_by_name("TSS")
	monthlyTSSData = []
	
	times = []
	for col in range(col2num('C'), ws.ncols):
	# for col in range(col2num('C'), col2num('AB')):
		date = str(ws.cell(0, col).value)
		if date != "":
			date = (ws.cell(0, col).value)
			temp = xlrd.xldate.xldate_as_datetime(date, wb.datemode)
			time = temp.strftime("%d%b%Y:%H:%M:%S")
			time = time.upper()
			
			# print time
			# hour = int(ws.cell(1, col).value)
			# hour = str(hour)
			# hour = hour.zfill(2)
			
			# print date, hour
			# raw_input()
			# # # hour = (ws.cell(1, col).value).strip(" ")
			# temp = date.split("-")
			# yr = temp[0]
			# month = temp[1]
			# day = temp[2]
			# dt = yr+"-"+month+"-"+day+"-"+hour
			
			
			# date_time = datetime.datetime.strptime(dt, "%Y-%m-%d-%H")
			# # temp = xlrd.xldate.xldate_as_datetime(date, wb.datemode)
			# time = date_time.strftime("%d%b%Y:%H:%M:%S")
			# time = time.upper()
			# print time
			# # raw_input(time)
			times.append(time)
	
	# raw_input("END-----")
	
	for row in range(2, ws.nrows):
		mpidName = str(ws.cell(row, 1).value)
		isdtag = str(ws.cell(row, 0).value)
		# mpidName = mpidName.replace('MP_', '')
		mwData = dict()
		if mpidName != '' and (isdtag == 'ISD' or isdtag == 'ISD-New'):
			for col in range(col2num('C'), ws.ncols):
				k = col2num('C')
				# print row, col, [col-k]
				# print mpidName, times[col-k], ws.cell(row, col).value
				mwValue = ws.cell(row, col).value
				if mwValue != '':
					mwData[times[col-k]] = ws.cell(row, col).value
				else:
					mwData[times[col-k]] = 0
				
			# print mpidName, mwData
				monthlyTSSData.append(tssData(mpidName, mwData))
	# raw_input()		
	return monthlyTSSData

def SelectMonthlyEMMOcorrection(emmoCorrectionFiles, month):
	desiredFile = ''
	for excelFile in emmoCorrectionFiles:
		if month.lower() in os.path.splitext(os.path.split(excelFile)[1])[0].lower():
			desiredFile = excelFile
			
	return desiredFile
	

def createHourlyTSS(monthlyTSS, time):
	currentHourLoad = []
	
	for row in monthlyTSS:
		mpidName = row.mpidName
		mwData = row.mwData[time]
		currentHourLoad.append(tssData(mpidName, mwData))
	
	return currentHourLoad


class munitObject(object):
	def __init__(self, filename, munit):
		self.filename = filename
		self.munit = munit


def determine_max_availablePower_EMMO(currentHourEMMO, mpidName):
	total_available_power=0
	for eachrow in currentHourEMMO:
		if eachrow.assetName == mpidName:
			total_available_power += eachrow.availablePower
	return total_available_power
	
	
def correctEMMO(currentHourEMMO, caseFile, MPIDs):
	# novalod1_mwData=0
	# novalod2_mwData=0
	# cnr5lod_mwData=0
	# fnlod_mwData =0 
	# ior1lod_mwData=0
	psspy.case(caseFile)
	
	
	def get_mpid_load_objects(mpidName, MPIDs):
		for eachMPID in MPIDs:
			if eachMPID.mpidName == mpidName:
				return eachMPID.loads
	
	# isdExceptionList = ["NOVAGEN15M", "IOR1", "CNR5", "FNG1"]
	isdExceptionList = ["NOVAGEN15M", "DOWGEN15M"]
	exceptionalBlockNumber=-10
	for eachException in isdExceptionList:
		lod_mwData =0
		loads = get_mpid_load_objects(eachException, MPIDs)
		for load in loads:
			status, pload, qload = getLoadData(load.bus, load.id)
			lod_mwData += pload
		
		for eachrow in currentHourEMMO:
		# if eachrow.assetName == eachException:
			newrow = _copy.copy(eachrow)
			break
		currentHourEMMO.insert(0,newrow)
		newrow.assetName = eachException
		newrow.blockNumber = exceptionalBlockNumber
		# self.offerPrice = offerPrice
		# self.blockSize = blockSize
		newrow.availablePower = lod_mwData
		newrow.dispatchedPower = lod_mwData
		newrow.capabilityMW = lod_mwData
		newrow.totalDisp_eachMPID = lod_mwData
		
		# maxAvailableP = determine_max_availablePower_EMMO(currentHourEMMO, eachException)
		# if maxAvailableP > 0:
		for eachrow in currentHourEMMO:
			if eachrow.assetName == eachException and eachrow.blockNumber != exceptionalBlockNumber:
				eachrow.totalDisp_eachMPID = eachrow.totalDisp_eachMPID + lod_mwData
				# if eachrow.blockNumber == 0:
					# eachrow.availablePower = eachrow.availablePower + lod_mwData
	index=1
	for eachrow in currentHourEMMO:
		eachrow.serial = index
		index += 1
	
	emmolog = open("EMMO_Modified", "w")
	
	for eachrow in currentHourEMMO:
		emmolog.write("\n" + "\t%s\t%s\t%s\t%s\t%s\t%s" %(eachrow.time, eachrow.assetName, eachrow.serial,eachrow.blockNumber, eachrow.availablePower,eachrow.totalDisp_eachMPID))
	
	emmolog.close()

	return currentHourEMMO
	
def SelectMonthlyLoad(loadDataFiles, month):
	print "Selecting Monthly Load File ... "
	desiredFile = ''
	for excelFile in loadDataFiles:
		if month.lower() in os.path.splitext(os.path.split(excelFile)[1])[0].lower():
			desiredFile = excelFile
			
	return desiredFile
	
def readMonthlyLoad(excelFile):
	print "Reading Monthly Load File ... "
	wb = xlrd.open_workbook(excelFile)
	ws = wb.sheet_by_name("Load (MW)")
	monthlyLoadData = []
	
	times = []
	# enable_print()
	# print ws.ncols
	# raw_input()
	for col in range(col2num('B'), ws.ncols):
		date = (ws.cell(0, col).value)
		# print date
		# raw_input()
		temp = xlrd.xldate.xldate_as_datetime(date, wb.datemode)
		# print temp.strftime("%d%b%Y:%H:%M:%S")
		
		dt = datetime.timedelta(hours=1)
		time = temp - dt
		time = time.strftime("%d%b%Y:%H:%M:%S")
		time = time.upper()
		# print time
		# raw_input(time)
		# year = temp[0]
		# month = temp[1]
		# day = temp[2]
		
		# hour = str(ws.cell(2, col).value)
		# time = year+month+day+":"+hour
		times.append(time)
	# raw_input("END")
	for row in range(3, ws.nrows):
		mpidName = str(ws.cell(row, 0).value)
		if type(mpidName) is float or type(mpidName) is int:
			mpidName = str(int(mpidName))
		else:
			mpidName = str(mpidName)
		# if type(mpidName) is int:
			# mpidName = str(int(mpidName))
			
		mpidName = mpidName.replace('MP_', '')
		# enable_print()
		# print mpidName
		# raw_input()
		mwData = dict()
		# raw_input()
		if mpidName != '':
			for col in range(col2num('B'), ws.ncols):
				k = col2num('B')
				# print row, col, [col-k]
				# print times[col-k]
				mwValue = ws.cell(row, col).value
				if mwValue != '':
					mwData[times[col-k]] = mwValue
				else:
					mwData[times[col-k]] = 0
			# print mpidName, mwData
			monthlyLoadData.append(loadData(mpidName, mwData))
	# raw_input()		
	return monthlyLoadData
	
def createHourlyLoad(monthlyLoad, time):
	print "Creating Hourly Load (MW) Data ... "
	currentHourLoad = []
	if len(monthlyLoad) == 0:
		raise MissingDataError("Load (MW) Data - In createHourlyLoad Phase")
	for row in monthlyLoad:
		mpidName = row.mpidName
		# print row.mpidName
		# # raw_input()
		# print row.mwData.keys()
		# raw_input()
		if time in row.mwData.keys():
			mwData = row.mwData[time]
			
		else:
			raise MissingDataError("Load (MW) Data - In createHourlyLoad Phase")
		# print mpidName, mwData
		# raw_input()
		currentHourLoad.append(loadData(mpidName, mwData))
	
	# if len(currentHourLoad) == 0:
		# raise MissingDataError("Load Data")
	
	
	return currentHourLoad
#############################################


class loadMvarData(object):  ## Updated by SDR
	def __init__(self, mpidName, mvarDataTag, mvarData):
		self.mpidName = mpidName
		self.mvarDataTag = mvarDataTag
		self.mvarData = mvarData
		self.pfData = mvarData ### 
		### self.pfData and self.mvarData both refers to PF data (In past revisions, MVAR data was saved instead of PF data, but it was changed later... now pf data is provided in the load data (PF sheeT) but the variables remains same. Hence, self.pfData => self.mvarData

def readMonthly_MvarLoad_v0(excelFile):
	wb = xlrd.open_workbook(excelFile)
	# ws = wb.sheet_by_name("Load MVAR")
	ws = wb.sheet_by_name("PF")
	monthlyLoadData = []
	
	times = []
	for col in range(col2num('C'), ws.ncols):
		date = (ws.cell(0, col).value)
		temp = xlrd.xldate.xldate_as_datetime(date, wb.datemode)
		dt = datetime.timedelta(hours=1)
		time = temp - dt
		time = time.strftime("%d%b%Y:%H:%M:%S")
		time = time.upper()
		# print time
		# raw_input(time)
		# year = temp[0]
		# month = temp[1]
		# day = temp[2]
		# hour = str(ws.cell(2, col).value)
		# time = year+month+day+":"+hour
		times.append(time)
	# raw_input("END")
	for row in range(3, ws.nrows):
		mpidName = (ws.cell(row, 0).value)
		if type(mpidName) is float or type(mpidName) is int:
			mpidName = str(int(mpidName))
		else:
			mpidName = str(mpidName)
		mpidName = mpidName.replace('MP_', '')
		# enable_print()
		# print mpidName
		# raw_input()
		mvarDataTag = str(ws.cell(row, col2num('B')).value)
		mvarData = dict()
		# raw_input()
		if mpidName != '':
			for col in range(col2num('C'), ws.ncols):
				k = col2num('C')
				# print row, col, [col-k]
				# print times[col-k]
				mvarValue = float(ws.cell(row, col).value)
				if mvarValue != '' and mvarValue != 0.0:
					mvarData[times[col-k]] = mvarValue
				else:
					# mvarData[times[col-k]] = 0
					###### Power Factor Value should not be zero/blank.. raise error if it is zero in data 
					print  "Power Factor Value should not be zero/blank.. ERROR" 
					print  "Power Factor Value should not be zero/blank.. ERROR" 
					print  "====================================================" 
					raise
			# print mpidName, mwData
			monthlyLoadData.append(loadMvarData(mpidName, mvarDataTag, mvarData))
	# raw_input()		
	return monthlyLoadData

def readMonthly_MvarLoad(excelFile):
	############### Updated 07 Apr 2020
	wb = xlrd.open_workbook(excelFile)
	# ws = wb.sheet_by_name("Load MVAR")
	ws = wb.sheet_by_name("PF")
	monthlyLoadData = []
	
	times = []
	for col in range(col2num('C'), ws.ncols):
		date = (ws.cell(0, col).value)
		temp = xlrd.xldate.xldate_as_datetime(date, wb.datemode)
		dt = datetime.timedelta(hours=1)
		time = temp - dt
		time = time.strftime("%d%b%Y:%H:%M:%S")
		time = time.upper()
		# print time
		# raw_input(time)
		# year = temp[0]
		# month = temp[1]
		# day = temp[2]
		# hour = str(ws.cell(2, col).value)
		# time = year+month+day+":"+hour
		times.append(time)
	# raw_input("END")
	for row in range(3, ws.nrows):
		mpidName = (ws.cell(row, 0).value)
		if type(mpidName) is float or type(mpidName) is int:
			mpidName = str(int(mpidName))
		else:
			mpidName = str(mpidName)
		mpidName = mpidName.replace('MP_', '')
		# enable_print()
		# print mpidName
		# raw_input()
		mvarDataTag = str(ws.cell(row, col2num('B')).value)
		mvarData = dict()
		# raw_input()
		if mpidName != '':
			for col in range(col2num('C'), ws.ncols):
				k = col2num('C')
				# print row, col, [col-k]
				# print times[col-k]
				mvarValue = float(ws.cell(row, col).value)
				if mvarValue != '':
					if mvarValue >= 0.75:
						mvarData[times[col-k]] = mvarValue
					else:
						mvarData[times[col-k]] = 0.9
				else:
					# mvarData[times[col-k]] = 0
					###### Power Factor Value should not be zero/blank.. raise error if it is zero in data 
					print  "Power Factor Value should not be blank.. ERROR" 
					print  "Power Factor Value should not be blank.. ERROR" 
					print  "====================================================" 
					raise
			# print mpidName, mwData
			monthlyLoadData.append(loadMvarData(mpidName, mvarDataTag, mvarData))
	# raw_input()		
	return monthlyLoadData


def createHourlyMvarLoad(monthlyMvarLoad, time):
	currentHourMvarLoad = []
	# enable_print()
	if len(monthlyMvarLoad) == 0:
		raise MissingDataError("P.F. Data")
	
	for row in monthlyMvarLoad:
		mpidName = row.mpidName
		mvarDataTag = row.mvarDataTag
		
		if time in row.mvarData.keys():
			mvarData = row.mvarData[time]
		else:
			raise MissingDataError("P.F. Data")
		
		currentHourMvarLoad.append(loadMvarData(mpidName, mvarDataTag, mvarData))
		
	return currentHourMvarLoad





################################
def ProcessFiles(caseFiles, GenMappingFiles, EMMOFiles, outputWB, munitlogfiles, s1EmmoLogfiles, loadDataFiles):
	# intertie = [[329, 819, '87'], [232, 1501, '86'], [456, 90000, '01']]
	#intertie = ab_bc
	
	##voltageLimits = ReadVoltageLimits(voltageFilename)
	wb = xlwt.Workbook()
	monthlyMPIDMapping = dict()
	monthlyLoad = dict()
	monthlyMvarLoad = dict()
	# monthlyCases = dict()
	# monthlyLoadMapping = dict()
	monthlyEMMO = dict()
	monthlyEMMOcorrection = dict()
	intertiedefn_ab_bc = dict()
	intertiedefn_mt_bus = dict()
	intertiedefn_mt_busid = dict()
	intertiedefn_sk_bus = dict()
	intertiedefn_sk_busid = dict()
	# monthlyLoad = dict()
	# monthlyTSS = dict()
	timeNow = datetime.datetime.now()
	timeNow = timeNow.strftime("%d%b%Y-%H-%M")
	print "Simulation Start Time : ", timeNow
	
	errorlogfilename = os.path.join(os.getcwd(), "State-2_Error_%s.log" %timeNow)
	# errorlog = open(errorlogfilename, "w")
	# errorlog.write("\tStart Time = %s\n" %timeNow)
	
	dates, months = findDates(caseFiles)
	# sys.exit()
	psspy.psseinit(100000)
	
	logfilename = os.path.join(os.getcwd(), "initLog.log")
	log_init = open(logfilename, "w")
	log_print(log_init)
	
	hourlyEMMOLogs = readEMMOLogfiles(s1EmmoLogfiles)
	state1_munitInfo, state1_hvdcInfo, state1_totalInfo, state1_IE_flows = readMULogfiles(munitlogfiles)
	# sys.exit()
	for month in months:
		# logfilename = os.path.join(os.getcwd(), month+ "-%s.log" %timeNow)
		logfilename = os.path.join(os.getcwd(), month+".log")
		log_month = open(logfilename, "w")
		log_print(log_month)
		################ Monthly MPID Mapping ############
		GenMappingFile = selectMonthlyMPIDMapping(GenMappingFiles, month)
		monthlyMPIDMapping[month] = CreateMPIDs(GenMappingFile, month)
		intertiedefn_ab_bc[month],intertiedefn_mt_bus[month], intertiedefn_mt_busid[month], intertiedefn_sk_bus[month], intertiedefn_sk_busid[month] = Createintertielst(GenMappingFile, month)
		################ Monthly Cases ############
		# monthlyCases[month] = selectMonthlyCase(caseFiles, month)
		#### Select EMMO ####
		# EMMOFile = SelectMonthlyEMMO(EMMOFiles, month)
		# monthlyEMMO[month] = readMonthlyEMMO(EMMOFile)
		# EMMOcorrectionFile = SelectMonthlyEMMOcorrection(emmoCorrectionFiles, month)
		# monthlyEMMOcorrection[month] = readMonthlyEMMOcorrection(EMMOcorrectionFile)
		loadDataFile = SelectMonthlyLoad(loadDataFiles, month)
		monthlyLoad[month] = readMonthlyLoad(loadDataFile)
		monthlyMvarLoad[month] = readMonthly_MvarLoad(loadDataFile)
	
	
	
	############### Output Directory
	outputDir = "State-2 - %s" %timeNow
	ensure_dir(outputDir)
	output = os.path.join(outputDir, "Final Result " + timeNow + ".xls")
	output_Final = os.path.join(outputDir, "Final LF Calculation - " + timeNow + ".xlsx")
	
	
	nextDate = 1
	nextrow = 0
	writeStart = 0
	newCase = 0
	
	# outResults = dict()
	
	for caseFile in caseFiles:
		# print caseFile
		caseName = os.path.basename(caseFile)
		# print caseName
		# dates = ["2015-DEC-01-14-00", "2015-DEC-01-03-00"]
		# date = dt.strftime("%Y-%b-%d-%H-%M")
		date = dates[caseName]
		# print  date
		year = date.split("-")[0]
		month = date.split("-")[1].upper()
		day = date.split("-")[2]
		hour = date.split("-")[3]
		min = date.split("-")[4]
		
		dt = datetime.datetime.strptime(date, "%Y-%b-%d-%H-%M")
		date = dt.strftime("%Y/%m/%d %H:%M")
		enable_print()
		timeNow = datetime.datetime.now()
		timeNow = timeNow.strftime("%d%b%Y-%H-%M")
		print "Processing : ... " , date, "\t\t", timeNow
		caseFilename = day+"_"+month+"_"+year+"_Hour_"+hour+".sav" 

		###### Create Output Directory ##########
		hourly_output_dirName = "Output_" + day+"_"+month+"_"+year+"_Hour_"+hour
		state2results_dir = os.path.join(outputDir, "State-2 Results")
		hourly_output_dir = os.path.join(outputDir, hourly_output_dirName)
		ensure_dir(hourly_output_dir)
		ensure_dir(state2results_dir)
		##################### Reports ########## Print files
		reportName = "State2_PrintLog_" + day+"_"+month+"_"+year+"_Hour_"+hour + ".log"
		reportfilename = os.path.join(hourly_output_dir, reportName)
		reportlog = open(reportfilename, "w")
		
		log_print(reportlog)
		
		
		year_2 = str(int(year)-2)
		time = day+month+year_2+":"+hour+":00:00"
		# year_2_emmo = year_2.split('20')[1]
		year_emmo = year.split('20')[1]
		# time_emmo = day+month+year_2_emmo+":"+hour+":00:00"
		# time_emmo = day+month+year+":"+hour+":00:00"
		time_emmo = day+month+year_emmo+":"+hour+":00:00"
		time_load = day+month+year+":"+hour+":00:00"
		
		
		filename = caseName.split(".sav")[0]
		print "filename :", filename
		print hourlyEMMOLogs.keys()
		#### Read hourly EMMO......
		# # currentHourEMMO = createHourlyEMMO(monthlyEMMO[month], time_emmo)
		# # currentHourEMMO = createHourlyEMMO(monthlyEMMO[month], time_emmo)
		currentHourEMMO = hourlyEMMOLogs[filename]
		# write_hourlyEMMOlogfile("EMMO_Log_0.log", currentHourEMMO)
		## Read Hourly Load Data::::
		currentHourLoad = createHourlyLoad(monthlyLoad[month], time_load)
		currentHourMvarLoad = createHourlyMvarLoad(monthlyMvarLoad[month], time_load)
		###### Read Motnhyl Mapping...............
		MPIDs = monthlyMPIDMapping[month]
		global ab_bc
		global mtTie_genbus
		global mtTie_genId
		global skTie_bus
		global skTie_loadId

		ab_bc = intertiedefn_ab_bc[month]
		mtTie_genId = intertiedefn_mt_busid[month]
		mtTie_genbus = intertiedefn_mt_bus[month]
		skTie_bus = intertiedefn_sk_bus[month]
		skTie_loadId = intertiedefn_sk_busid[month]
		intertie = ab_bc
		# case = Case(caseFile, intertie, MPIDs, currentHourEMMO, hourly_output_dir, month, year, munit, s1_hvdcParameters)
		case = Case(caseFile, intertie, MPIDs, currentHourEMMO, currentHourLoad, currentHourMvarLoad, hourly_output_dir, month, year, state1_munitInfo[filename], state1_hvdcInfo[filename], state1_totalInfo[filename], state1_IE_flows[filename])
		
		# ############ Process State-2 and write results ######
		# #######################################################
		extractedInformation = dict()
		
		
		# # caseName = os.path.splitext(os.path.split(caseFilename)[1])[0].lower()
		# # print caseName
		# # sheetName = caseFilename.split(".sav")[0]
		
		outputResult = os.path.join(state2results_dir, caseName.split(".sav")[0] + ".xls")
		wb = xlwt.Workbook()
		ws = wb.add_sheet("Results")
		MPIDs = sorted(MPIDs, key=attrgetter('mpidName'), reverse = False)
		
		enable_print()
		wantedMPIDs = ['BCHIMP', 'SPCIMP','120SIMP']
		wantedMPIDs = ['KH3',]
		# input = raw_input("Enter MPID : ")
		# # input = "0000012111"
		# if input == "all":
			# for mpid in MPIDs:
				# wantedMPIDs.append(mpid.mpidName)
		# else:
			# wantedMPIDs.append(input)
		
		
		# screenControl = raw_input("0 - Disable, 1 - Enable")
		screenControl = 0
		if screenControl != 0:
			enable_print()
		else:
			# print "Screen Disabled ... "
			log_print(reportlog)
		
		newCase = 0
		for mpid in MPIDs:
			
			if mpid.lfTag == "LF":
			# if mpid.mpidName in wantedMPIDs and mpid.lfTag == "LF":
				print " =========================================================="
				print " ============Processing MPID========== %s:" % mpid.mpidName 
				
				if mpid.mpidName == "CES2":
					print "-------------"
					print "Same as CES1 .... "
					print "-------------"
					continue
				elif mpid.mpidName in [bc_exp, sk_exp, mt_exp]:
					print "-------------"
					print "No LF Process for XOS ...."
					print "-------------"
					continue
					
				else:
					# enable_print()
					# print " =========================================================="
					# print " ============Processing MPID========== %s:" % mpid.mpidName 
					# try:
					extractedInformation[mpid.mpidName] = case.ProcessMPID(mpid)
					Write(outputResult, mpid.mpidName, extractedInformation[mpid.mpidName], wb, ws, newCase)
					newCase += 1
					# nextrow = writeFinal(output, mpid.mpidName, writedata2, wb_result, ws1, ws2, ws3, ws4, ws5, date, writeStart, nextrow, nextDate)
					writeStart += 1
					# print "===State2 Case Created for MPID : %s ======" %mpid.mpidName
					# raw_input()
					
					
					# except:
						# print("\tError in Handling Case = %s for \nMPID%s\n" %(caseFile, mpid.mpidName))
						# errorlog.write("\tError in Handling Case = %s for \nMPID%s\n" %(caseFile, mpid.mpidName))
						# pass
				
				print "=========================######=================================="
		nextDate += 1
		nextrow = 0
		# raw_input()
		
		# outResults[date] = results
	
	# write_hourlyEMMOlogfile("EMMO_Log.log", currentHourEMMO)
	enable_print()
	# writeResults(outResults, outputWB, output_Final)
	
	timeNow = datetime.datetime.now()
	timeNow = timeNow.strftime("%d%b%Y-%H-%M")
	print "End of Simulation : ", timeNow
	# errorlog.write("\tStop Time = %s\n" %timeNow)
	# errorlog.close()

def readEMMOLogfiles(s1EmmoLogfiles):
	# enable_print()
	hourlyEMMOLogs = dict()
	
	
	for logfile in s1EmmoLogfiles:
		
		hourlyEMMOLog = []
		
		
		
		
		logfileBasename = os.path.basename(logfile)
		time_logEMMO = logfileBasename.split('S1_EMMOLog_')[1].split('.log')[0]
		print time_logEMMO
		# raw_input()
		# time_emmo = day+month+year_emmo+":"+hour+":00:00"
		
		with open(logfile) as f: 
			data = f.readlines() 
		index = 0
		for line in data:
			index += 1
			if index > 1:
				# print line
				# raw_input()
				words = line.split('\t')
				# print words
				# print len(words)
				P_export_dict = dict() 
				P_import_dict = dict()
				P_netImportExport_dict= dict() 
				P_prev_netImportExport_dict = dict()
				
				time	=	str(words[0])
				serial	=	int(words[1])
				assetName	=	str(words[2])
				relatedImportAsset	=	str(words[3])
				assetShortName	=	str(words[4])
				Import_Export	=	str(words[5])
				blockNumber	=	int(words[6])
				flexibility	=	int(words[7])
				offerPrice	=	float(words[8])
				blockSize	=	float(words[9])
				availablePower	=	float(words[10])
				dispatchedPower	=	float(words[11])
				capabilityMW	=	(words[12])
				totalDisp_eachMPID	=	float(words[13])
				
				if words[14] != '':
					P_export	=	float(words[14])
				else:
					P_export	=	(words[14])
				
				if words[15] != '':
					P_import	=	float(words[15])
				else:
					P_import	=	(words[15])

				if words[16] != '':
					P_netImportExport	=	float(words[16])
				else:
					P_netImportExport	=	(words[16])
				
				emmoOffer	=	str(words[17])
				loadOffer	=	str(words[18])
				CriteriaCheckDecision	=	str(words[19])
				
				if words[20] != '':
					deductibleNTGLoad	=	float(words[20])
				else:
					deductibleNTGLoad	=	(words[20])
				
				reduceLoadTag	=	str(words[21])
				
				if words[22] != '':
					finalNTGLoad	=	float(words[22])
				else:
					finalNTGLoad	=	(words[22])
				
				P_export_dict[bc]	=	float(words[23])
				P_import_dict[bc]	=	float(words[24])
				P_netImportExport_dict[bc]	=	float(words[25])
				P_prev_netImportExport_dict[bc]	=	float(words[26])
				P_export_dict[sk]	=	float(words[27])
				P_import_dict[sk]	=	float(words[28])
				P_netImportExport_dict[sk]	=	float(words[29])
				P_prev_netImportExport_dict[sk]	=	float(words[30])
				P_export_dict[mt]	=	float(words[31])
				P_import_dict[mt]	=	float(words[32])
				P_netImportExport_dict[mt]	=	float(words[33])
				P_prev_netImportExport_dict[mt]	=	float(words[34])
				
				# print time, serial, assetName, relatedImportAsset, assetShortName, Import_Export, blockNumber, flexibility, offerPrice, blockSize, availablePower, dispatchedPower, capabilityMW, totalDisp_eachMPID, P_export, P_import, P_netImportExport, emmoOffer, loadOffer, CriteriaCheckDecision, deductibleNTGLoad, reduceLoadTag, finalNTGLoad, P_export_dict, P_import_dict, P_netImportExport_dict, P_prev_netImportExport_dict
				# print time, serial, assetName, P_export_dict, P_import_dict, 
				
				
				# sys.exit()
				
				emmo_object = meritorderData(time, serial, assetName, relatedImportAsset, assetShortName, Import_Export, blockNumber, flexibility, offerPrice, blockSize, availablePower, dispatchedPower, capabilityMW, totalDisp_eachMPID, P_export, P_import, P_netImportExport, emmoOffer, loadOffer, CriteriaCheckDecision, deductibleNTGLoad, reduceLoadTag, finalNTGLoad, P_export_dict, P_import_dict, P_netImportExport_dict, P_prev_netImportExport_dict)
				hourlyEMMOLog.append(emmo_object)

		hourlyEMMOLogs[time_logEMMO] = hourlyEMMOLog
	
	return hourlyEMMOLogs
	
# state1_munits, state1_OWSP, state1_OESP, state1_watlFlow, state1_eatlFlow = readMULogfiles(munitlogfiles)
def readMULogfiles(logfiles):
	
	state1_IE_flows = dict()
	state1_munitInfo = dict()
	state1_hvdcInfo = dict()
	state1_totalInfo = dict()
	
	for logfile in logfiles:
		with open(logfile) as f: 
			data = f.readlines() 
		index = 0
		for line in data:
			index += 1
			if index > 3:
				# print line
				# raw_input()
				words = line.split('\t')
				# print len(words)
				# for word in words:
					# print word
				
				filename = words[0].split(".sav")[0]
				# print filename
				
				state1_munitInfo[filename] = dict()
				state1_hvdcInfo[filename] = dict()
				state1_totalInfo[filename] = dict()
				state1_IE_flows[filename] = dict()
				
				
				state1_munitInfo[filename]["assetName"] = str(words[1])
				state1_munitInfo[filename]["serial"] = int(words[2])
				state1_munitInfo[filename]["blockNumber"] = int(words[3])
				state1_munitInfo[filename]["offerPrice"] = float(words[4])
				state1_munitInfo[filename]["availablePower"] = float(words[5])
				state1_munitInfo[filename]["MarginalUnitReserve"] = float(words[6])
				
				state1_hvdcInfo[filename]["OWSP"] = float(words[7])
				state1_hvdcInfo[filename]["OESP"] = float(words[8])
				state1_hvdcInfo[filename]["watlFlow"] = float(words[9])
				state1_hvdcInfo[filename]["eatlFlow"] = float(words[10])
				
				state1_totalInfo[filename]["total_load"] = float(words[11])
				state1_totalInfo[filename]["total_gen"] = float(words[12])
				state1_totalInfo[filename]["NetEMMO_GrossLoad_SS_btfGen"] = float(words[13])
				state1_totalInfo[filename]["total_aies_loss"] = float(words[14])
				
				state1_IE_flows[filename][bc_imp] = float(words[15])
				state1_IE_flows[filename][bc_exp] = float(words[16])
				state1_IE_flows[filename][sk_imp] = float(words[17])
				state1_IE_flows[filename][sk_exp] = float(words[18])
				state1_IE_flows[filename][mt_imp] = float(words[19])
				state1_IE_flows[filename][mt_exp] = float(words[20])
				state1_totalInfo[filename]["Total_currentHourExports_MW"] = float(words[21])
	
	# sys.exit()
	print state1_IE_flows
	# sys.exit()
	return state1_munitInfo, state1_hvdcInfo, state1_totalInfo, state1_IE_flows
			



	
def roundTime(dt=None, roundTo=60):
   # """Round a datetime object to any time laps in seconds
   # dt : datetime.datetime object, default now.
   # roundTo : Closest number of seconds to round to, default 1 minute.
   # Author: Thierry Husson 2012 - Use it as you want but don't blame me.
   # """
	# if dt == None : 
		# dt = datetime.datetime.now()
	seconds = (dt.replace(tzinfo=None) - dt.min).seconds
	rounding = (seconds+roundTo/2) // roundTo * roundTo
		
	return dt + datetime.timedelta(0,rounding-seconds,-dt.microsecond)
 
def Write(output, mpid, data, wb, ws, writeStart): ### Currently in use
	# wb = xlwt.Workbook()
	# ws = wb.add_sheet("Loss Factors")
	row = writeStart+1
	
	Header = ["MPID Name",	"NTG Flow (State-1)",	"Deductible Net Load (State-1)",	"Reduced Net Load (State-1)",	"Total AIES Loss (State-1)",	"Total MPID Internal Loss (State-1)",	"Loss (State-1)",	"Marginal Unit MPID (State-1)",	"Marginal Unit Serial (State-1)",	"Marginal Unit Block  (State-1)",	"Marginal Unit Price (State-1)",	"Marginal Unit Available Power MW (State-1)",	"Marginal Unit Reserve (State-1)",	"S1-OWSP (State-1)",	"S1-OESP (State-1)",	"WATL (State-1)",	"EATL (State-1)",	"Total Load (State-1)",	"Total Gen (State-1)",	"BTF Gen (To be excluded)",	"BC Import (State-1)",	"BC Export (State-1)",	"SK Import (State-1)",	"SK Export (State-1)",	"MT Import (State-1)",	"MT Export (State-1)",	"Maximum Export (MW)",	"NTG Flow (State-2)",	"Readjusted Net Load (State-2)",	"Total AIES Loss (State-2)",	"Total MPID Internal Loss (state-2)",	"Loss (State-2)",	"Marginal Unit MPID (State-2)",	"Marginal Unit Serial (State-2)",	"Marginal Unit Block  (State-2)",	"Marginal Unit Price (State-2)",	"Marginal Unit Available Power MW (State-2)",	"Marginal Unit Reserve (State-2)",	"S2-OWSP (State-2)",	"S2-OESP (State-2)",	"WATL (State-2)",	"EATL (State-2)",	"Total Load (State-2)",	"Total Gen (State-2)",	"BC Import (State-2)",	"BC Export (State-2)",	"SK Import (State-2)",	"SK Export (State-2)",	"MT Import (State-2)",	"MT Export (State-2)",	"Margina Unit Block Mismatch (MW)-(State-2)",	"Raw Loss Factor",	"Redispatched State Status",	"Comments", "bcTieFlow", "skTieFlow", "mtTieFlow", "BC Tie Mismatch", "SK Tie Mismatch", "MT Tie Mismatch"]

	if writeStart == 0:
		for col, value in enumerate(Header):
			ws.write(0, col, value)
			# col += col
	
	for col, value in enumerate(Header):
		# ws.write(row, col, 'Test')
		ws.write(row, col, data[col])
		
	
	wb.save(output)

######################################
####################
def file_list_(source_path, ext):
	eu = ext.upper()
	base_names = [s for s in os.listdir(source_path) if s.upper().endswith(eu)]
	abs_paths = [os.path.abspath(os.path.join(source_path, s)) for s in base_names]
	return base_names, abs_paths

def ensure_dir(f):
	try:
		os.makedirs(f)
	except OSError:
		if not os.path.isdir(f):
			raise
			
def log_print(log):
	sys.stdout = log
def enable_print():
	sys.stdout = sys.__stdout__

##################################### Main Function ###########
########################################################	
# def ilf_main(caseFiles, GenMappingFiles, EMMOFiles, outputWB, updateEMMO):
# def ilf_main(caseFiles):
def ilf_main(caseFiles, inputdir, s1logfiles, s1EmmoLogfiles):
# def main():
	enable_print()
	global flowTolerance
	global roundingdecimalpoint
	global iterationLimit
	iterationLimit = 50
	flowTolerance = 0.005
	roundingdecimalpoint = 2
	global ab_bc_swingbus #global ab_bc,
	# ab_bc = [[329, 819, '87'], [232, 1501, '86'], [456, 90000, '01']]
	#ab_bc = [[819, 329, '87'], [1501, 232, '86'], [90000, 456, '01']]
	ab_bc_swingbus = 1520
	
	# global skTie_bus
	# global skTie_loadId
	# skTie_bus = 1473
	# skTie_loadId = '34'
	#
	# global mtTie_genbus
	# global mtTie_genId
	# mtTie_genbus = 80000
	# mtTie_genId = "1"
	
	global sk_exp
	global bc_exp
	global mt_exp
	global sk_imp
	global bc_imp
	global mt_imp
	global sk
	global bc
	global mt
	global Import_Export_Services
	global exportServices
	
	sk_exp = "SPCEXP"
	bc_exp = "BCHEXP"
	mt_exp = "MTEXP"
	sk_imp = "SPCIMP"
	bc_imp = "BCHIMP"
	mt_imp = "120SIMP"
	sk = 'SK'
	bc = 'AB-BC'
	mt = 'MT'
	
	Import_Export_Services = [bc_imp, mt_imp, sk_imp, bc_exp, mt_exp, sk_exp]
	exportServices = [bc_exp, sk_exp, mt_exp]
	global sheetName_GrossLoadMW
	sheetName_GrossLoadMW = "Gross Load MW"
	
	# dir_emmo = os.path.join(os.getcwd(), 'Input Files\\EMMO')
	# dir_genMapping = os.path.join(os.getcwd(), 'Input Files\\Gen Mapping')
	# dir_emmoCorrection = os.path.join(os.getcwd(), 'Input Files\\EMMO Corrections')
	
	# inputdir = r"C:\Users\sdr\Desktop\ilf\Input Files"
	# print inputdir
	dir_emmo = os.path.join(inputdir, 'EMMO')
	dir_genMapping = os.path.join(inputdir, 'Mapping Information')
	dir_load = os.path.join(inputdir, 'Load Data')
	# dir_emmoCorrection = os.path.join(inputdir, 'EMMO Corrections')
	# dir_mulogfiles = os.path.join(os.getcwd(), 'Logfiles')
	
	print "============"
	print "Input Folders :"
	print dir_emmo
	print dir_genMapping
	print dir_load
	# print dir_emmoCorrection
	# print dir_mulogfiles

	outputWB = ''
	
	
	filesnames_GenMappingFiles, GenMappingFiles = file_list_(dir_genMapping, ".xlsx")
	filesnames_EMMOFiles, EMMOFiles = file_list_(dir_emmo, ".xlsx")
	filesnames_loadDataFiles, loadDataFiles = file_list_(dir_load, ".xlsx")
	# fnames, munitlogfiles = file_list_(dir_mulogfiles, ".log")
	# filesnames, updateEMMO = file_list_(dir_emmoCorrection, ".xlsx")
	
	
	
	
	
	# for file in filesnames1:
		# print file
		# raw_input()
	for (file, GenMappingFile) in zip(filesnames_GenMappingFiles, GenMappingFiles):
		if "~$" in file:
			GenMappingFiles.remove(GenMappingFile)
		
	for (file, EMMOFile) in zip(filesnames_EMMOFiles, EMMOFiles):
		if "~$" in file:
			EMMOFiles.remove(EMMOFile)
	for (file, loadDataFile) in zip(filesnames_loadDataFiles, loadDataFiles):
		if "~$" in file:
			loadDataFiles.remove(loadDataFile)
	
	# print GenMappingFiles
	# print EMMOFiles
	# sys.exit()
	
	
	ProcessFiles(caseFiles, GenMappingFiles, EMMOFiles, outputWB, s1logfiles, s1EmmoLogfiles, loadDataFiles)
	enable_print()
	
	print "\n++++++++++++++++++++++++++++++++++++ END OF PROGRAM +++++++++++++++++++++++++++++++++++"
	print "++++++++++++++++++++++++++++++++++++ END OF PROGRAM +++++++++++++++++++++++++++++++++++"
	print "++++++++++++++++++++++++++++++++++++ END OF PROGRAM +++++++++++++++++++++++++++++++++++"
	print "++++++++++++++++++++++++++++++++++++ END OF PROGRAM +++++++++++++++++++++++++++++++++++"


# main()
# if __name__ == "__main__":
    # main()