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 openpyxl

# psstools.ImportPSSE(33)
# psstools.EnableExceptions()
import psstools
import psspy
import datetime
import xlrd
import xlwt
temp_sum = 0
WSCCArea = 15
test_index = 0 

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

# Branch = namedtuple("Branch", 'bus1 bus2 id')

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 checkSolution():
    try:
        solved = psspy.solved()
        return {0: "Solved", 1: "Iteration limit exceeded", 2: "Blown up", 5: "Singular Jacobian or voltage of 0.0 detected"}[solved]
    except:
        return "Failed for reason %s" % solved
		
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()
	
	
		
def Solve():
	print "======================solving========================="
	psspy.progress("\n FDNS - Lock tap lock shunts\n")
	psspy.fdns([0,0,0,1,0,0,99,0])
	psspy.fdns([0,0,0,1,0,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])
	checkSol()
	# psspy.fdns([0,0,0,1,0,0,99,0])
	# psspy.fdns([0,0,0,1,2,0,99,0])
	# psspy.fdns([0,0,0,1,1,0,99,0])
	# psspy.fnsl([0,0,0,1,1,0,99,0])
	# psspy.fnsl([0,0,0,1,1,0,99,0])
	# psspy.progress("\n FDNS - Step  tap Enable all\n")
	# psspy.fdns([1,0,0,1,1,0,99,0])
	# checkSol()
	# psspy.progress("\n FNSL - Lock tap lock shunts\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,0,0,99,0])
	# checkSol()
	# psspy.progress("\n FNSL - Stepping tap Enable All \n")
	# psspy.fnsl([1,0,0,1,1,0,99,0])
	# checkSol()
	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])
	checkSol()
	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])
	checkSol()
	# psspy.progress("\n FNSL - Lock tap Enable SVC Only\n")
	# psspy.fnsl([0,0,0,1,2,0,99,0])
	# checkSol()
	# psspy.progress("\n FNSL - Lock tap Enable SVC Only\n")
	# psspy.fnsl([0,0,0,1,2,0,99,0])
	# checkSol()
	# 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.fdns([0,0,0,1,0,0,99,0]) #### FDNS_Lock tap_ Lock Swicthed shunt
	# psspy.fdns([0,0,0,1,0,0,99,0]) #### FDNS_Lock tap_ Lock Swicthed shunt
	# psspy.fnsl([0,0,0,1,0,0,99,0]) #### FNSL_Lock tap_ Lock Swicthed shunt
	# psspy.fnsl([0,0,0,1,0,0,99,0]) #### FNSL_Lock tap_ Lock Swicthed shunt
	# 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
	# psspy.fnsl([1,0,0,1,1,0,99,0]) #### FNSL_Stepping_ Enable all Swicthed shunt
	# psspy.fnsl([1,0,0,1,1,0,99,0]) #### FNSL_Stepping_ Enable all Swicthed shunt
def checkSol():
	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]
		psspy.progress("+++++++++++++++++++++++++ NOT SOLVED PROPERLY +++++++++++++++++ \n")
		psspy.progress("+++++++++++++++++++++++++ NOT SOLVED PROPERLY +++++++++++++++++ \n")
		psspy.progress("+++++++++++  %s ++++++++++++ \n" %solvedMsg)
		
		raise solutionError(solvedMsg)

def finalcheckSol():
	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]
		psspy.progress("+++++++++++++++++++++++++ NOT SOLVED PROPERLY +++++++++++++++++ \n")
		psspy.progress("+++++++++++++++++++++++++ NOT SOLVED PROPERLY +++++++++++++++++ \n")
		psspy.progress("+++++++++++  %s ++++++++++++ \n" %solvedMsg)
		
		raise solutionError(solvedMsg)

def defaultSolve():
	# 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.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,0,0,99,0])
	# psspy.fdns([0,0,0,1,0,0,99,0])
	solved = 0
	iterN = 0
	while (solved == 0 or solved == 1) and iterN < 5:
		psspy.fdns([0,0,0,1,0,0,99,0])
		iterN += 1
		solved = psspy.solved()
	if solved == 0:
		print "solved " 
		print iterN
		psspy.progress("+++++++++++++++++++++++++ SOLVED PROPERLY +++++++++++++++++ \n")
		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]
		psspy.progress("+++++++++++++++++++++++++ NOT SOLVED PROPERLY +++++++++++++++++ \n")
		psspy.progress("+++++++++++++++++++++++++ NOT SOLVED PROPERLY +++++++++++++++++ \n")
		psspy.progress("+++++++++++  %s ++++++++++++ \n" %solvedMsg)
		
		raise solutionError(solvedMsg)


	
def TieMeasure():
	Pm = 0
	
	for br in ab_bc:
		print br
		err, temp_flow = psspy.brnflo(br[0], br[1], br[2])
		Pm += temp_flow.real
	print "AB-BC :", Pm
	# sys.exit()
	# psstools.IgnoreErrorCodes = set()
	return -Pm.real

class Intertie(object):
	def __init__(self, branches=None):
		self.branches = branches
	
	def Measure(self):
		Pm = 0
		print Pm
		# psstools.IgnoreErrorCodes = set((3,))
		for br in ab_bc:
			print br
			err, temp_flow = psspy.brnflo(br[0], br[1], br[2])
			Pm += temp_flow.real
		print "AB-BC :", Pm
		# sys.exit()
		# psstools.IgnoreErrorCodes = set()
		return -Pm.real

class Case(object):
	flowEpsilon = 0.05
	scaleLoadsIterationLimit = 50
	includeMotors = True
	ignoreBaseCaseVoltageViolations = True
	ignoreBaseCaseBranchOverloads = True
	saskImport = 1473
	WSCCArea = 15
	marginalMW = 1
	minGenBeforeMarginal = 0.1
	ignorePmin = False
	ignorePmax = False
	swingBus = 1520
	# useIntertie = True  
	
	# def __init__(self, topologyCase, filename, intertie, MPIDs, MOList, loadData, loadMapping, tssData):
	def __init__(self, topologyCase, intertie, MPIDs, MOList, loadData, loadMvarData, loadMapping, tssData, outputCaseName, month):
		
		
		self.topologyCase = topologyCase
		self.outputCaseName = outputCaseName
		# self.filename = filename
		
		self.MOList = MOList
		self.MPIDs = MPIDs
		self.loadData = loadData
		self.loadMvarData = loadMvarData
		self.loadMapping = loadMapping
		self.tssData = tssData
		# self.emmoUpdateList = []
		self.emmoUpdateList = dict()
		self.month = month
		
		print len(self.MOList)
		for eachemmo in self.MOList:
			MPID = self.findMU_MPID_info(eachemmo)
			if MPID == []:
				self.MOList.remove(eachemmo)
			
		print len(self.MOList)
		
	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 GetSystemTotals(self, excludeWSCC):
		# 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, pload, qload = getLoadData(1473, '34')
			if pload < 0:
				totalLoad = load.real - pload
			else:
				totalLoad = load.real
				
			# return load.real, gen.real, loss.real, alshnt.real
			return totalLoad, gen.real, loss.real, alshnt.real
		
		
		load_AIES, gen_AIES, loss_AIES, loss_alshnt = self.GetSystemTotals(False)
		# 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()
		# load_AIES = load_AIES - load_wscc.real
		# gen_AIES = gen_AIES - gen_wscc.real
		loss_AIES = loss_AIES - loss_wscc.real
		loss_alshnt = loss_alshnt.real
		loss_total_AIES = loss_AIES
		return load_AIES, gen_AIES, loss_total_AIES, loss_alshnt
		

	def FindMarginalUnit(self, LFMPID):  ###### Updated by SDR
		# MOList = GSOUnits
		MOList = self.MOList
		TotalDispatch = 0.0 # Initialize
		Load, Gen, Loss, ShuntLoss = self.GetSystemTotals(True)
		print Gen.real, (Load.real+Loss.real+ShuntLoss.real)
		TotalDemand = (Load.real+Loss.real+ShuntLoss.real)
		print "Real Total Demand ", TotalDemand
		
		for eachMORecord in MOList:
			TotalDispatch += eachMORecord.availablePower
			
			if TotalDispatch > TotalDemand:
				MarginalUnit = eachMORecord
				MarginalUnitReserve = TotalDispatch-TotalDemand #GSOUnit.maxDispatchamount 
				break
				## What if MaxDispatch < Pgen(MPIDUnit)
				# UnitReserve = Pmax - Pgen
		# print "TotalDispatch:", TotalDispatch, "\nTotalDemand:", TotalDemand, "\nGSOUnit", GSOUnit.gsoNumber
		# sys.exit()
		if MarginalUnit.assetName == LFMPID or MarginalUnit.assetName == 'BCHIMP' or MarginalUnit.assetName == 'SPCIMP':
			MarginalUnit, MarginalUnitReserve = self.UpdateMarginalUnit(MarginalUnit, "NEXT", LFMPID)
		
		return MarginalUnit, MarginalUnitReserve
		
	def	 UpdateMarginalUnit(self, currentMarginalUnit, cntrl, LFMPID):
		# print "======UpdateMarginalUnit+++++++++ " , currentMarginalUnit.gsoMPID
		Match = False
		if cntrl == 'NEXT':
			for GSOUnit in self.MOList:      
				# print "Hello" , GSOUnit.gsoMPID, GSOUnit.gsoNumber
					
				if not Match:
					if GSOUnit.serial == currentMarginalUnit.serial:
						Match = True
					continue
				else :
					# if GSOUnit.assetName == 'BCHIMP' or GSOUnit.assetName == 'SPCIMP' or GSOUnit.availablePower == 0 or GSOUnit.assetName == LFMPID:
					if GSOUnit.availablePower == 0 or GSOUnit.assetName == LFMPID:
						continue
					
					# print "GSOUnit.gsoNumber - mpid", GSOUnit.gsoNumber , GSOUnit.gsoMPID
					
					return GSOUnit, GSOUnit.totalDisp_eachMPID
					break
				
		elif cntrl == 'PREV':
			for GSOUnit in reversed(self.MOList):    
				# print "Hello" , GSOUnit.gsoMPID, GSOUnit.gsoNumber
					
				if not Match:
					if GSOUnit.serial == currentMarginalUnit.serial:
						Match = True
					continue
				else :
					# if GSOUnit.assetName == 'BCHIMP' or GSOUnit.assetName == 'SPCIMP' or GSOUnit.availablePower == 0 or GSOUnit.assetName == LFMPID:
					if GSOUnit.availablePower == 0 or GSOUnit.assetName == LFMPID:
						continue
					
					# print "GSOUnit.gsoNumber - mpid", GSOUnit.gsoNumber , GSOUnit.gsoMPID
					
					return GSOUnit, 0
					break
	def	 UpdateMarginalUnit_caseprep(self, currentMarginalUnit, cntrl, LFMPID):
		# print "======UpdateMarginalUnit+++++++++ " , currentMarginalUnit.gsoMPID
		Match = False
		if cntrl == 'NEXT':
			for GSOUnit in self.MOList:      
				# print "Hello" , GSOUnit.gsoMPID, GSOUnit.gsoNumber
					
				if not Match:
					if GSOUnit.serial == currentMarginalUnit.serial:
						Match = True
					continue
				else :
					if GSOUnit.assetName == 'BCHIMP' or GSOUnit.assetName == 'SPCIMP' or GSOUnit.availablePower == 0 or GSOUnit.assetName == LFMPID:
					# if GSOUnit.availablePower == 0 or GSOUnit.assetName == LFMPID:
						continue
					
					# print "GSOUnit.gsoNumber - mpid", GSOUnit.gsoNumber , GSOUnit.gsoMPID
					
					return GSOUnit, GSOUnit.totalDisp_eachMPID
					break
				
		elif cntrl == 'PREV':
			for GSOUnit in reversed(self.MOList):    
				# print "Hello" , GSOUnit.gsoMPID, GSOUnit.gsoNumber
					
				if not Match:
					if GSOUnit.serial == currentMarginalUnit.serial:
						Match = True
					continue
				else :
					if GSOUnit.assetName == 'BCHIMP' or GSOUnit.assetName == 'SPCIMP' or GSOUnit.availablePower == 0 or GSOUnit.assetName == LFMPID:
					# if GSOUnit.availablePower == 0 or GSOUnit.assetName == LFMPID:
						continue
					
					# print "GSOUnit.gsoNumber - mpid", GSOUnit.gsoNumber , GSOUnit.gsoMPID
					
					return GSOUnit, 0
					break			
			
			
	
	def sask_imp_adjustment(control, MPID):
		if control == 'Initialize':
			saskbus = 1473
			# psspy.plant_data(saskbus,0,[ 1.0, 100.0])
			# psspy.machine_data_2(saskbus,r"""3""",[_i,2,_i,_i,_i,_i],[ 0.0398,-0.3269, 1605.6,-1170.3, 2641.0,-87991.2, 1870.9, 0.12, 0.24,_f,_f,_f,_f,_f,_f,_f,_f])
			# psspy.seq_machine_data_3(saskbus,r"""3""",_i,[ 0.12, 0.24, 0.12, 0.24, 0.12, 0.24, 0.24, 0.24,_f,_f])
			status = 1
			psspy.machine_chng_2(saskbus,r"""3""",[status,_i,_i,_i,_i,_i],[0.0,0.0,_f,_f,_f,_f,_f,_f,_f,_f,_f,_f,_f,_f,_f,_f,_f])
			err, busvoltage = psspy.busdat(saskbus, 'PU')
			psspy.plant_chng(saskbus,_i,[busvoltage,_f])
		elif control == 'Finalize':
			totalPgen = 0
			totalQgen = 0
			for gen in MPID.generators:
				err, [pgen, qgen] = psspy.macdat(gen.bus, gen.id, ['P', 'Q'])
				err, [status] = psspy.macdat(gen.bus, gen.id, ['STATUS'])
				if status != 0 :
					totalPgen += pgen 
					totalQgen += qgen
			mismatch = totalPgen - 0
			while abs(mismatch) > flowTolerance:
				totalPload, totalQload = determineMPID_Load()
				PL = totalPgen - totalPload
				QL = totalQgen - totalQload
				for load in MPID.loads:
					psspy.load_chng_4(load.bus,load.id,[1,_i,_i,_i,_i,_i],[PL,QL,_f,_f,_f,_f])
				for gen in MPID.generators:
					psspy.machine_chng_2(gen.bus,gen.id,[_i,_i,_i,_i,_i,_i],[0.0,0.0,_f,_f,_f,_f,_f,_f,_f,_f,_f,_f,_f,_f,_f,_f,_f])
				Solve()
				totalPgen = 0
				totalQgen = 0
				for gen in MPID.generators:
					err, [pgen, qgen] = psspy.macdat(gen.bus, gen.id, ['P', 'Q'])
					err, [status] = psspy.macdat(gen.bus, gen.id, ['STATUS'])
					if status != 0 :
						totalPgen += pgen 
						totalQgen += qgen
				mismatch = totalPgen - 0
					
					
	
	def ProcessMPID(self, setPGen=None):
		# 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 UpdateWorkingMPID(delta, workingMPID, control, fulldispatchamount=None):
			delta = abs(delta)
			MPID = workingMPID
			print MPID.mpidName
			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 :
						if delta>pgen:
							newpgen = 0
							newstatus = 0
							delta = delta - pgen
							UpdateGen(gen.bus, gen.id, newpgen, newstatus)
							# raw_input("=====")
							print "delta :", delta
						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 = 0
							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 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 == "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)
		

		def findMarginalUnit_MPID_info(MarginalUnit):
			MPID = []
			for eachMPID in self.MPIDs:
				if eachMPID.mpidName == MarginalUnit.assetName:
					MPID = eachMPID
					break
			# if MPID == []:
				# raise ValueError
			return MPID
			
		def UpdateSystem_old(deltaNetFlow, MarginalUnit, MarginalUnitReserve, MOList, control, LFMPID):
			
			for eachMPID in self.MPIDs:
				if eachMPID.mpidName == MarginalUnit.assetName:
					MPID = eachMPID
					break
			totalPgen, totalPmax = determineMPID_Gen(MPID)
			MarginalUnitReserve = MarginalUnit.totalDisp_eachMPID - totalPgen
			print "MarginalUnitReserve ", MarginalUnitReserve
			# raw_input()
			
			if control == "Increase":
			# if deltaNetFlow<0:  #### Working MPID Ges was reduced to nullify the netFlow - Increase Total Gen Dispatch
				delta = abs(deltaNetFlow)
				
				for workingMUnit in MOList:
					if workingMUnit.serial == MarginalUnit.serial:
						MU_MPID = findMarginalUnit_MPID_info(MarginalUnit)
						if delta > MarginalUnitReserve:
							print "delta ", delta
							# raw_input()
							UpdateWorkingMPID(MarginalUnitReserve, MU_MPID, "Increase")
							
							
							# raw_input("====Wait===")
							delta = delta - MarginalUnitReserve
							MarginalUnit, MarginalUnitReserve = self.UpdateMarginalUnit(MarginalUnit, "NEXT", LFMPID)
							MarginalUnitReserve = MarginalUnit.availablePower
							continue
						elif delta <= MarginalUnitReserve:
							print "delta ", delta
							# raw_input()
							UpdateWorkingMPID(delta, MU_MPID, "Increase")
							
							MarginalUnit = MarginalUnit
							MarginalUnitReserve = MarginalUnitReserve - delta
							delta = 0
							break
			
			elif control == "Reduce":
			# elif deltaNetFlow>0:  #### Working MPID Ges was reduced to nullify the netFlow - Increase Total Gen Dispatch
				delta = abs(deltaNetFlow)
				for workingMUnit in MOList:
					MU_MPID = findMarginalUnit_MPID_info(MarginalUnit)
					if workingMUnit.serial == MarginalUnit.serial:
						Pdisp = MarginalUnit.availablePower - MarginalUnitReserve
						if delta > Pdisp:
							UpdateWorkingMPID(Pdisp, MU_MPID, "Reduce")
							
							MarginalUnit, MarginalUnitReserve = self.UpdateMarginalUnit(MarginalUnit, "PREV", LFMPID)
							MarginalUnitReserve = 0
							delta = delta - Pdisp
							# raw_input("=====")
							print "delta :", delta
							continue
						elif delta <= Pdisp:
							UpdateWorkingMPID(delta, MU_MPID, "Reduce")
							
							MarginalUnit = MarginalUnit
							MarginalUnitReserve = MarginalUnitReserve + delta
							delta = 0
							# raw_input("=====")
							print "delta :", delta
							break
	
			return MarginalUnit, MarginalUnitReserve

		def UpdateSystem(deltaNetFlow, MarginalUnit, MarginalUnitReserve, MOList, control, LFMPID):
			
			for eachMPID in self.MPIDs:
				if eachMPID.mpidName == MarginalUnit.assetName:
					MPID = eachMPID
					break
			totalPgen, totalPmax = determineMPID_Gen(MPID)
			MarginalUnitReserve = MarginalUnit.totalDisp_eachMPID - totalPgen
			print "MarginalUnitReserve ", MarginalUnitReserve
			# raw_input()
			if MarginalUnit.assetName == 'BCHIMP':
				desiredSwingBus = assignSwingBus(MarginalUnit)
				# if control == "Increase":
				# delta = abs(deltaNetFlow)
				target_bctie = MarginalUnit.totalDisp_eachMPID
				minimum_bctie_blockValue = MarginalUnit.availablePower
				previous_target_bctie = target_bctie - minimum_bctie_blockValue
				Solve()
				current_bctie = TieMeasure()
				if current_bctie > target_bctie:
					mismatch = abs(current_bctie - target_bctie)
					while mismatch > flowTolerance:
						MarginalUnit, MarginalUnitReserve = self.UpdateMarginalUnit(MarginalUnit, "NEXT", "")
						MarginalUnit, MarginalUnitReserve = UpdateSystem(mismatch, MarginalUnit, MarginalUnitReserve, MOList, "Increase", LFMPID)
						Solve()
						current_bctie = TieMeasure()
						mismatch = abs(current_bctie - target_bctie)
				elif current_bctie <= previous_target_bctie:
					mismatch = abs(current_bctie - previous_target_bctie)
					while mismatch > flowTolerance:
						MarginalUnit, MarginalUnitReserve = self.UpdateMarginalUnit(MarginalUnit, "PREV", "")
						MarginalUnit, MarginalUnitReserve = UpdateSystem(mismatch, MarginalUnit, MarginalUnitReserve, MOList, "Reduce", LFMPID)
						Solve()
						current_bctie = TieMeasure()
						mismatch = abs(current_bctie - previous_target_bctie)
				if current_bctie <= target_bctie and current_bctie > previous_target_bctie:
					MarginalUnitReserve = findMarginalUnitReserve(MarginalUnit)
			elif MarginalUnit.assetName == 'SPCIMP':
				MPID = findMarginalUnit_MPID_info(MarginalUnit)
				sask_imp_adjustment("Initialize", MPID)
				desiredSwingBus = assignSwingBus(MarginalUnit)
				target_sasktie = MarginalUnit.totalDisp_eachMPID
				minimum_sasktie_blockValue = MarginalUnit.availablePower
				previous_target_sasktie = target_sasktie - minimum_sasktie_blockValue
				Solve()
				MPID = findMarginalUnit_MPID_info(MarginalUnit)
				current_sasktie = determineMPID_Gen(MPID)
				mismatch = abs(current_sasktie - target_sasktie)
				if current_sasktie > target_sasktie:
					mismatch = abs(current_sasktie - target_sasktie)
					while mismatch > flowTolerance:
						MarginalUnit, MarginalUnitReserve = self.UpdateMarginalUnit(MarginalUnit, "NEXT", "")
						MarginalUnit, MarginalUnitReserve = UpdateSystem(mismatch, MarginalUnit, MarginalUnitReserve, MOList, "Increase", LFMPID)
						Solve()
						current_sasktie = determineMPID_Gen(MPID)
						mismatch = abs(current_sasktie - target_sasktie)
				elif current_sasktie < previous_target_sasktie:
					mismatch = abs(current_sasktie - previous_target_sasktie)
					while mismatch > flowTolerance:
						MarginalUnit, MarginalUnitReserve = self.UpdateMarginalUnit(MarginalUnit, "PREV", "")
						MarginalUnit, MarginalUnitReserve = UpdateSystem(mismatch, MarginalUnit, MarginalUnitReserve, MOList, "Reduce", LFMPID)
						Solve()
						current_sasktie = determineMPID_Gen(MPID)
						mismatch = abs(current_sasktie - previous_target_sasktie)
				if current_sasktie <= target_sasktie and current_sasktie >= previous_target_sasktie:
					MarginalUnitReserve = findMarginalUnitReserve(MarginalUnit)
				sask_imp_adjustment("Finalize", MPID)
				
				
			else:
				if control == "Increase":
				# if deltaNetFlow<0:  #### Working MPID Ges was reduced to nullify the netFlow - Increase Total Gen Dispatch
					delta = abs(deltaNetFlow)
					
					for workingMUnit in MOList:
						if workingMUnit.serial == MarginalUnit.serial:
							MU_MPID = findMarginalUnit_MPID_info(MarginalUnit)
							if delta > MarginalUnitReserve:
								print "delta ", delta
								# raw_input()
								UpdateWorkingMPID(MarginalUnitReserve, MU_MPID, "Increase")
								
								
								# raw_input("====Wait===")
								delta = delta - MarginalUnitReserve
								MarginalUnit, MarginalUnitReserve = self.UpdateMarginalUnit(MarginalUnit, "NEXT", LFMPID)
								MarginalUnitReserve = MarginalUnit.availablePower
								continue
							elif delta <= MarginalUnitReserve:
								print "delta ", delta
								# raw_input()
								UpdateWorkingMPID(delta, MU_MPID, "Increase")
								
								MarginalUnit = MarginalUnit
								MarginalUnitReserve = MarginalUnitReserve - delta
								delta = 0
								break
				
				elif control == "Reduce":
				# elif deltaNetFlow>0:  #### Working MPID Ges was reduced to nullify the netFlow - Increase Total Gen Dispatch
					delta = abs(deltaNetFlow)
					for workingMUnit in MOList:
						MU_MPID = findMarginalUnit_MPID_info(MarginalUnit)
						if workingMUnit.serial == MarginalUnit.serial:
							Pdisp = MarginalUnit.availablePower - MarginalUnitReserve
							print "Pdisp :", Pdisp
							# raw_input()
							if delta > Pdisp:
								UpdateWorkingMPID(Pdisp, MU_MPID, "Reduce")
								
								MarginalUnit, MarginalUnitReserve = self.UpdateMarginalUnit(MarginalUnit, "PREV", LFMPID)
								MarginalUnitReserve = 0
								delta = delta - Pdisp
								# raw_input("=====")
								print "delta :", delta
								continue
							elif delta <= Pdisp:
								UpdateWorkingMPID(delta, MU_MPID, "Reduce")
								
								MarginalUnit = MarginalUnit
								MarginalUnitReserve = MarginalUnitReserve + delta
								delta = 0
								# raw_input("=====")
								print "delta :", delta
								break
		
			return MarginalUnit, MarginalUnitReserve
			
			
			
		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):
			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
			
			print Pdisp, Ptotal_uptoCurrentBlock, Ptotal_previousBlock
			mismatch = 0 
			if Pdisp > Ptotal_uptoCurrentBlock:
				mismatch = Pdisp - Ptotal_uptoCurrentBlock
			elif Pdisp <= Ptotal_uptoCurrentBlock and Pdisp >= Ptotal_previousBlock:
				mismatch = 0
			elif Pdisp < Ptotal_previousBlock:
				mismatch = Pdisp - Ptotal_previousBlock

			return mismatch
			

		def assignSwingBus(MarginalUnit):
			if MarginalUnit.assetName == 'BCHIMP':
				desiredSwingBus = 1520
			elif MarginalUnit.assetName == 'SPCIMP':
				desiredSwingBus = 1473
			else:
				MPID = findMarginalUnit_MPID_info(MarginalUnit)
				mpidgenerators = MPID.generators
				sortedmpidgenerators = sorted(mpidgenerators, key=attrgetter('id'), reverse = True)
				for gen in sortedmpidgenerators:
					print gen.bus, gen.id
					status, pgen, pmax, pmin, qmax, qmin, mbase = GetGenData(gen.bus, gen.id) ##(gen.bus, gen.id)
					if status != 0 :
						desiredSwingBus = gen.bus
						break
			# raw_input()
			############ Change the previous swing bus back tot 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)
			Solve()
			return desiredSwingBus
			
		def findMarginalUnitReserve(MarginalUnit):
			MPID = findMarginalUnit_MPID_info(MarginalUnit)
			totalPgen, totalPmax = determineMPID_Gen(MPID) 
			MarginalUnitReserve = MarginalUnit.totalDisp_eachMPID - totalPgen
			print "MarginalUnitReserve : ", MarginalUnitReserve
			return MarginalUnitReserve
		
		
		def bctiematch(deltaFlow, MarginalUnit, MarginalUnitReserve):
			mismatch = deltaFlow
			while abs(mismatch) > flowTolerance :   #### Reduced Gen in Working MPID - Dispatch Up Total Gen from Merit Order
				
				if mismatch > 0:
					control = "Increase"
				elif mismatch < 0:
					control = "Reduce"
				# print MarginalUnit.serial, MarginalUnit.assetName, MarginalUnitReserve
				# raw_input()
				MarginalUnit, MarginalUnitReserve = UpdateSystem(mismatch, MarginalUnit, MarginalUnitReserve, self.MOList, control, "")
				Solve()
				mismatch = TieMeasure()
			print mismatch
			MarginalUnitReserve = findMarginalUnitReserve(MarginalUnit)
			print MarginalUnit.serial, MarginalUnit.assetName, MarginalUnitReserve
			return MarginalUnit
		
		def casePrep():
			psspy.progress("\n\n===============================     Initializing GENS  ==================================\n")
			Load, Gen, Loss, ShuntLoss = self.GetSystemTotals(True)
			TotalDemand = Load + Loss + ShuntLoss
			print Load, Loss, TotalDemand
			# raw_input()
			TotalDispatch = 0
			bctie = 0 ### initial bctie
			# print 
			############ turnoff_all_gens()
			psspy.progress("\n\n====== TURNING OFF ALL MACHINES =========\n")
			buses, ids, statuses, pgens, pmaxes, pmins, qmaxes, qmins, mbases = FindAllMachineData(sid = -1, flag = 4)
			for bus, id, status, pgen, pmax, pmin, qmax, qmin, mbase in zip(buses, ids, statuses, pgens, pmaxes, pmins, qmaxes, qmins, mbases):
				if bus != 1520:
					UpdateGen(bus, id, 0, 0)
			UpdateLoad(1473, '34', 0, 0, 0)
			
			psspy.progress("\n\n======     DISPATCHING GENERATORS ===============\n")
			# while TotalDispatch < TotalDemand:
			
			for mUnit in self.MOList:
				# print mUnit.assetName
				# raw_input()
				if TotalDispatch < TotalDemand:
					MPID = findMarginalUnit_MPID_info(mUnit)
					if MPID != []:
						TotalDispatch += mUnit.availablePower
						print TotalDispatch 
						print int(mUnit.serial), " ----- ", mUnit.assetName,  mUnit.availablePower
						# raw_input()
						
						# raw_input("-----------")
						if mUnit.assetName == 'BCHIMP':
							bctie = mUnit.totalDisp_eachMPID
							MarginalUnit = mUnit
							continue
						elif mUnit.assetName == 'SPCIMP':
							bus = 1473
							id = '34'
							pload = -mUnit.totalDisp_eachMPID
							if pload !=0:
								status =  1
							else:
								status = 0
							err = psspy.load_chng_4(bus, id, (status,_i,_i,_i,_i,_i), (pload, _f, _f,_f,_f,_f)  )
							MarginalUnit = mUnit
						else:
							# if MPID != []:
							totalPgen, totalPmax = determineMPID_Gen(MPID)
							delta = totalPgen -  mUnit.totalDisp_eachMPID
							print delta
							MarginalUnit = mUnit
							# raw_input()
							if delta > 0:
								UpdateWorkingMPID(abs(delta), MPID, "Reduce", fulldispatchamount=None)
							elif delta < 0 :
								UpdateWorkingMPID(abs(delta), MPID, "Increase", fulldispatchamount=None)
							else:
								continue
						# psspy.save("2017LF_Dec01_HH1400_BaseCase.sav")
						# raw_input('=====Saved=====')
				else:
					break
			print "================================================"
			print "TotalDemand, TotalDispatch : ", TotalDemand, TotalDispatch
			# print temp_sum
			Load, Gen, Loss, ShuntLoss = self.GetSystemTotals(True)
			print Gen, Load+Loss+ShuntLoss
			
			
			tempname = self.outputCaseName.split(".sav")[0]
			
			psspy.save(tempname + "DispatchedGen_notSolved.sav")
			caseprep_Solve()
			# Solve()
			# defaultSolve()
			# psspy.save("2017LF_Dec01_HH1400_BaseCase.sav")
			Load, Gen, Loss, ShuntLoss = self.GetSystemTotals(True)
			print Gen.real, (Load.real+Loss.real+ShuntLoss.real)
			
			# MarginalUnit = mUnit
			MarginalUnitReserve = findMarginalUnitReserve(MarginalUnit)
			mismatch = (TieMeasure() - bctie)
			# MarginalUnit, MarginalUnitReserve = UpdateSystem(mismatch, MarginalUnit, MarginalUnitReserve, self.MOList, control, "")
			# mismatch = (TieMeasure() - bctie)
			print "mismatch = ", mismatch
			print "MarginalUnit : ", MarginalUnit.assetName, MarginalUnit.serial, MarginalUnitReserve
			# raw_input("=============================================")
			psspy.progress("\n\n======     TIE FLOW MATCHING ===============\n")
			print mismatch
			
			iterationNumber = 1
			while abs(mismatch) > flowTolerance and iterationNumber < iterationLimit:   #### Reduced Gen in Working MPID - Dispatch Up Total Gen from Merit Order
				if MarginalUnitReserve == 0 and mismatch >0 :
					MarginalUnit, MarginalUnitReserve = self.UpdateMarginalUnit_caseprep(MarginalUnit, "NEXT", "")
				elif MarginalUnitReserve == MarginalUnit.totalDisp_eachMPID and mismatch < 0:
					MarginalUnit, MarginalUnitReserve = self.UpdateMarginalUnit_caseprep(MarginalUnit, "PREV", "")
				if mismatch > 0:
					control = "Increase"
				elif mismatch < 0:
					control = "Reduce"
				print MarginalUnit.serial, MarginalUnit.assetName, MarginalUnitReserve
				# raw_input()
				MarginalUnit, MarginalUnitReserve = UpdateSystem(mismatch, MarginalUnit, MarginalUnitReserve, self.MOList, control, "")
				# Solve()
				# defaultSolve()
				caseprep_Solve()
				# Solve()
				mismatch = (TieMeasure() - bctie)
				print MarginalUnit.serial, MarginalUnit.assetName, MarginalUnitReserve
				MarginalUnitReserve = findMarginalUnitReserve(MarginalUnit)
				print "MarginalUnitReserve : ", MarginalUnitReserve
				print "\n Tie Mismatch : ", mismatch
				psspy.progress("\n Tie Mismatch : %s" %mismatch)
				iterationNumber += 1
				# psspy.save("2017LF_Dec01_HH1400_BaseCase.sav")
				# raw_input()
			
			if abs(mismatch) > flowTolerance and iterationNumber >= iterationLimit:
				raise iterationLimitError(mismatch, iterationNumber)
			else:
				print mismatch
				MarginalUnitReserve = findMarginalUnitReserve(MarginalUnit)
				print MarginalUnit.serial, MarginalUnit.assetName, MarginalUnitReserve
				# deltaNetFlow, MarginalUnit = checkMarginalUnit(MarginalUnit, self.MOList, self.MPIDs)
				return MarginalUnit.serial, MarginalUnit.assetName, MarginalUnit
		
		def initializeLoad():
			#################
			
			def isdLoadMapping(loadMapping):
				
				isdLoadList = []
				for eachload in loadMapping:
					if eachload.isdtag == "ISD" or eachload.isdtag == "ISD-New": 
						bus_id = str(eachload.bus) + "-" + str(eachload.id)
						isdLoadList.append(bus_id)
				
				# enable_print()
				for row in isdLoadList:
					print row
				# raw_input()
				
					
				return isdLoadList
				
			def TurnOffLoads(isdLoadList):
				# psspy.progress("\n\n======     TURNING OFF NON-ISD LOADS ===============\n")
				psspy.progress("\n\n======     TURNING OFF ALL LOADS ===============\n")
				
				buses, ids, statuses, loads = FindAllLoadData()
				# print buses, ids, statuses, loads
				# raw_input()
				for bus, id, status, load in zip(buses, ids, statuses, loads):
					bus_id = str(bus) + "-" + str(id)
					if bus_id not in isdLoadList:
						# print bus, id
						# raw_input()
						UpdateLoad(bus, id, 0, 0, 0)
					# UpdateLoad(bus, id, 0, 0, 0)
				
			def AssignLoads(loadData, loadMvarData, loadMapping):
				# loadMPID, bus, id
				psspy.progress("\n\n======     DISPATCHING NON-ISD LOADS ===============\n")
				loadmpids = [] 
				for eachloadMPID in loadMapping:
					loadmpids.append(eachloadMPID.loadMPID)
				
				loads_in_loadmpids = dict()
				for eachloadMPID in loadMapping:
					number_of_loads = loadmpids.count(eachloadMPID.loadMPID)
					loads_in_loadmpids[eachloadMPID.loadMPID] = number_of_loads
					print eachloadMPID.loadMPID, loads_in_loadmpids[eachloadMPID.loadMPID]
				
				for eachloadMPID in loadMapping:
					if eachloadMPID.isdtag == "ISD" or  eachloadMPID.isdtag == 'ISD-New': 
						###### SKIP ISD LOads
						continue
					else:
						workingloadmpid = eachloadMPID.loadMPID
						loadbus = eachloadMPID.bus
						loadid = eachloadMPID.id
						number_of_loads = loads_in_loadmpids[workingloadmpid]
						mwData = 0
						mvarData = 0
						mvarTag = ''
						for eachloadmpidData in loadData:
							#mpidName, mwData
							if eachloadmpidData.mpidName == workingloadmpid:
								mwData = eachloadmpidData.mwData
								break
						for eachloadmpidData in loadMvarData:
							#mpidName, mwData
							if eachloadmpidData.mpidName == workingloadmpid:
								mvarTag = eachloadmpidData.mvarDataTag
								pfData = eachloadmpidData.mvarData
								break
						# pf = 0.9
						# pload = mwData/number_of_loads
						# qload = pload * math.tan(math.acos(pf))
						if mvarTag == 'OK':
							pload = mwData/number_of_loads
							# if pfData != "" and pfData != 0.0:
								# qload = pload * math.tan(math.acos(pfData))
							if pfData != "" and abs(pfData) >= 0.75:
								qload = pload * math.tan(math.acos(pfData))
							else:
								pf = 0.9
								qload = pload * math.tan(math.acos(pf))
							# if mvarData == 'check':
								# pf = 0.9
								# pload = mwData/number_of_loads
								# qload = pload * math.tan(math.acos(pf))
							# else:
								# if mvarData < mwData:
									# pload = mwData/number_of_loads
									# if pload !=0:
										# qload = mvarData/number_of_loads
									# else:
										# qload = 0
								# else:
									# pf = 0.9
									# pload = mwData/number_of_loads
									# qload = pload * math.tan(math.acos(pf))
						elif (mvarTag == 'Review' or mvarTag == 'No Data'):
							pf = 0.9
							pload = mwData/number_of_loads
							qload = pload * math.tan(math.acos(pf))
						else:
							pf = 0.9
							pload = mwData/number_of_loads
							qload = pload * math.tan(math.acos(pf))
						
						print workingloadmpid, pload, qload, loadbus, loadid
						
						psspy.progress("\n ================= Updating LOAD MPID : %s  , BUS = %s,  ID = '%s \n" %(workingloadmpid, loadbus, loadid))
						psspy.progress("PLOAD = %s,  QLOAD = %s \n" %(pload, qload))
						if pload != 0:
							powerFactor = math.cos(math.atan(qload/pload))
						else:
							powerFactor = "INF ERROR"
						psspy.progress("\n Applied PF = %s \n" %powerFactor)
						psspy.progress("\n Number_of_loads = %s , MW DATA = %s, MVAR TAG : %s, MVAR DATA = %s \n" %(number_of_loads, mwData, mvarTag, pfData))
						
						if pload != 0:
							status = 1
						else:
							status = 0
						UpdateLoad(loadbus, loadid, status, pload, qload)
						# raw_input()
			
			
			isdLoadList = isdLoadMapping(self.loadMapping)
			TurnOffLoads(isdLoadList)
			# psspy.save("Test.sav")
			# psspy.stoprecording()
			# raw_input()
			AssignLoads(self.loadData, self.loadMvarData, self.loadMapping)
				
					# raw_input("=================")			
		def AssignISDLoads(loadData, tssData, loadMapping, MPIDs):
			psspy.progress("\n\n======     DISPATCHING ISD LOADS (EMMO - TSS) ===============\n")
			# loadMPID, bus, id
			loadmpids = [] 
			# isdExceptionList = ["NOVAGEN15M", "IOR1", "CNR5", "FNG1"]
			isdExceptionList = ["NOVAGEN15M", "DOWGEN15M"]
			# isdExceptionList2 = ["FNG1", "CNR5", "IOR1"]
			# isdExceptionList2 = ["SLP1", "AFG1TX", "BCRK", "BCR2", "DAI1", "MEG1", "SHCG", "SCL1", "WEY1", "CNR5", "IOR1"]
			isdExceptionList2 = ["SLP1", "AFG1TX", "DAI1", "MEG1", "SHCG", "SCL1", "CNR5", "IOR1"]

			for eachMPID in MPIDs:
				if (eachMPID.ISDtag == 'ISD'):
					loadmpids = eachMPID.loadmpid
					genMPID = eachMPID.mpidName
					loadmpid_busids = dict()
					
					if genMPID in isdExceptionList :
						if len(loadmpids) > 1:
							for loadmpid, load in zip(loadmpids, eachMPID.loads):
								loadmpid_busids[loadmpid] = load
							for eachloadmpidData in loadData:
								#mpidName, mwData
								for loadmpid in loadmpids:
									if eachloadmpidData.mpidName == loadmpid:
										pload = eachloadmpidData.mwData
										pf = 0.9
										qload = pload * math.tan(math.acos(pf)) 
										if pload != 0:
											status = 1
										else:
											status = 0
										# enable_print()
										# print loadmpid, loadmpid_busids[loadmpid].bus, loadmpid_busids[loadmpid].id, pload, qload
										UpdateLoad(loadmpid_busids[loadmpid].bus, loadmpid_busids[loadmpid].id, status, pload, qload)
						elif len(loadmpids) == 1:
							mwData = 0
							for eachloadmpidData in loadData:
								#mpidName, mwData
								for loadmpid in loadmpids:
									if eachloadmpidData.mpidName == loadmpid:
										mwData += eachloadmpidData.mwData
							pload = mwData/len(eachMPID.loads)
							pf=0.9
							qload = pload * math.tan(math.acos(pf))
							if pload != 0:
								status = 1
							else:
								status = 0
							for load in eachMPID.loads:
								UpdateLoad(load.bus, load.id, status, pload, qload)
					
					# elif genMPID in ["FNG1", "CNR5", "IOR1"]:
					elif genMPID in isdExceptionList2:
						for load in eachMPID.loads:
							UpdateLoad(load.bus, load.id, 0, 0, 0)
					else:					
						mwData = 0
						for eachloadmpidData in loadData:
							#mpidName, mwData
							for loadmpid in loadmpids:
								if eachloadmpidData.mpidName == loadmpid:
									mwData += eachloadmpidData.mwData
									# break
						
						if loadmpid == "TC04LOD":
							mwData = mwData/2
							
						emmo_pgen, pmax = determineMPID_Gen(eachMPID)
						if mwData > 0 :
							pf = 0.9
							if len(eachMPID.loads) != 0:
								pload = (mwData + emmo_pgen)/len(eachMPID.loads)
								qload = pload * math.tan(math.acos(pf))
								if pload != 0:
									status = 1
								else:
									status = 0
								for load in eachMPID.loads:
									UpdateLoad(load.bus, load.id, status, pload, qload)
						else:
							# emmo_pgen, pmax = determineMPID_Gen(eachMPID)
							mwData_tss = 0
							for eachloadmpidData in tssData:
								#mpidName, mwData
								if eachloadmpidData.mpidName == genMPID:
									mwData_tss = eachloadmpidData.mwData
									break
							if emmo_pgen >= mwData_tss:
								isd_load_mw = emmo_pgen - mwData_tss
							else:
								isd_load_mw = 0
								delta = mwData_tss - emmo_pgen
								# updateEMMO(eachMPID, mwData_tss, delta)
							print genMPID, "isd_load_mw : ", isd_load_mw
							pf = 0.9
							if len(eachMPID.loads) != 0:
								pload = isd_load_mw/len(eachMPID.loads)
								qload = pload * math.tan(math.acos(pf))
							
								if pload != 0:
									status = 1
								else:
									status = 0
								for load in eachMPID.loads:
									UpdateLoad(load.bus, load.id, status, pload, qload)
							# raw_input("=================")			
				
		def updateEMMO(eachMPID, mwData_tss, delta):
			
			for munit in self.MOList:
				if munit.assetName == eachMPID.mpidName and munit.blockNumber == 0:
					if munit.availablePower < mwData_tss:
						munit.availablePower = mwData_tss
						munit.totalDisp_eachMPID = mwData_tss
						# eachemmo = [munit.assetName, munit.blockNumber, munit.availablePower, munit.totalDisp_eachMPID]
						# self.emmoUpdateList.append(eachemmo)
						self.emmoUpdateList[munit.assetName] = [munit.serial, munit.blockNumber, munit.availablePower, munit.totalDisp_eachMPID]
				
				
			
			
			
		#########################################
		def basecaseprep():
			psspy.case(self.topologyCase)
			# psspy.startrecording(1, "InitializeLoads.py")
			# psspy.save("Test1.sav")
			# psspy.case("2017LF_Dec01_BaseCase_Ready.sav")
			psspy.solution_parameters_4((psspy._i, 50), (psspy._f,) *5 + (0.01, ))
			
			tempname = self.outputCaseName.split(".sav")[0]
			psspy.progress("\n\n======     INITIALIZING LOADS ===============\n")
			initializeLoad()
			# AssignISDLoads(self.tssData, self.loadMapping, self.MPIDs)
			psspy.save(tempname + "_initializedload.sav")
			# defaultSolve()
			# Solve()
			# raw_input("==========Initialized Loads=============")
			
			MUserial, MUassetName, MarginalUnit = casePrep()
			psspy.save(tempname + "_initializedload_genDispatch1.sav")
			# raw_input("==========Dispatched Gens=============")
			Load, Gen, Loss, ShuntLoss = self.GetSystemTotals(True)
			currentDemand = Load+Loss
			demandMismatch = currentDemand
			
			iterationNumber = 1
			while abs(demandMismatch) > 1 and iterationNumber < iterationLimit:
			# while abs(demandMismatch) > 10:
				AssignISDLoads(self.loadData, self.tssData, self.loadMapping, self.MPIDs)
				psspy.save(tempname + "_initializedload_genDispatch1_ISDLoad.sav")
				# raw_input("==========Assigned ISD Loads =============")
				MUserial, MUassetName, MarginalUnit = casePrep()
				# Solve()
				# defaultSolve()
				psspy.save(tempname + "_initializedload_genDispatch1_ISDLoad_Redispatch.sav")
				Load, Gen, Loss, ShuntLoss = self.GetSystemTotals(True)
				currentDemand_new = Load+Loss
				demandMismatch = currentDemand_new - currentDemand
				currentDemand = currentDemand_new
				
				print demandMismatch, currentDemand_new
				iterationNumber += 1
				# raw_input()
			Solve()
			psspy.save(tempname + "_Before_HVDC.sav")
			# enable_print()
			psspy.progress(" ===================  Month : %s ======= " %self.month)
			print "============================"
			print self.month
			# raw_input()
			try:
				import setHvdcDispatch
				savedOWSP, savedOESP, newWATL, newEATL = setHvdcDispatch.hvdcMain(self.month)
				print "===================HVDC Dispatch Done"
				psspy.progress("\n\n ==================== HVDC Dispatch Done =============== \n")
			except:
				raise HvdcError
			psspy.save(tempname + "_After_HVDC.sav")
			MUserial, MUassetName, MarginalUnit = casePrep()
			# psspy.save(tempname + "_initializedload_genDispatch1.sav")
			# raw_input("==========Dispatched Gens=============")
			Load, Gen, Loss, ShuntLoss = self.GetSystemTotals(True)
			currentDemand = Load+Loss
			demandMismatch = currentDemand
			# raw_input()
			
			iterationNumber = 1
			while abs(demandMismatch) > 1 and iterationNumber < iterationLimit:
				AssignISDLoads(self.loadData, self.tssData, self.loadMapping, self.MPIDs)
				psspy.save(tempname + "_initializedload_genDispatch1_ISDLoad.sav")
				# raw_input("==========Assigned ISD Loads =============")
				MUserial, MUassetName, MarginalUnit = casePrep()
				# Solve()
				# defaultSolve()
				psspy.save(tempname + "_initializedload_genDispatch1_ISDLoad_Redispatch.sav")
				Load, Gen, Loss, ShuntLoss = self.GetSystemTotals(True)
				currentDemand_new = Load+Loss
				demandMismatch = currentDemand_new - currentDemand
				currentDemand = currentDemand_new
				
				print "demandMismatch, currentDemand_new : " , demandMismatch, currentDemand_new
				iterationNumber += 1
				# raw_input()
			
			Solve()
			# if abs(demandMismatch) > 10 and iterationNumber >= iterationLimit:
				# raise iterationLimitError(demandMismatch, iterationNumber)
			# psspy.save(self.outputCaseName)
			Load, Gen, Loss, ShuntLoss = self.GetSystemTotals(True)
			print Gen.real, Load.real, Loss.real+ShuntLoss.real, (Load.real+Loss.real+ShuntLoss.real)
			print("======     BASE CASE PREP - DONE ===============")
			psspy.progress("\n\nGen = %s, Load = %s, Loss = %s, Total Demand = %s" %(Gen.real, Load.real, Loss.real+ShuntLoss.real, (Load.real+Loss.real+ShuntLoss.real)))
			psspy.progress("\n\n======     BASE CASE PREP - DONE ===============")
			
			
			return MUserial, MUassetName, MarginalUnit, savedOWSP, savedOESP, newWATL, newEATL
		
		
		psselogFile = self.outputCaseName + ".txt"
		psspy.progress_output(2,psselogFile,[0,0])
		MUserial, MUassetName, MarginalUnit, savedOWSP, savedOESP, newWATL, newEATL = basecaseprep()
		print MUserial, MUassetName, MarginalUnit.blockNumber, savedOWSP, savedOESP, newWATL, newEATL
		
		# Load, Gen, Loss, ShuntLoss = self.GetSystemTotals(True)
		# print "\n Gen , Load, Loss+ShuntLoss, Load+Loss+ShuntLoss : ", Gen.real, Load.real, Loss.real+ShuntLoss.real, (Load.real+Loss.real+ShuntLoss.real)
		# print("======     BASE CASE PREP with HVDC Dispatch - DONE ===============")
		# psspy.progress("\n\nGen = %s, Load = %s, Loss = %s, Total Demand = %s" %(Gen.real, Load.real, Loss.real+ShuntLoss.real, (Load.real+Loss.real+ShuntLoss.real)))
		# psspy.progress("\n\n======     BASE CASE PREP with HVDC Dispatch - DONE ===============\n")
		
		# try:
		# import setHvdcDispatch
		# setHvdcDispatch.hvdcMain()
		# hvdcMain()
		finalcheckSol()
		
		psspy.save(self.outputCaseName)
		
		Load, Gen, Loss, ShuntLoss = self.GetSystemTotals(True)
		print "\n Gen , Load, Loss+ShuntLoss, Load+Loss+ShuntLoss : ", Gen.real, Load.real, Loss.real+ShuntLoss.real, (Load.real+Loss.real+ShuntLoss.real)
		print("======     BASE CASE PREP with HVDC Dispatch - DONE ===============")
		psspy.progress("\n\nGen = %s, Load = %s, Loss = %s, Total Demand = %s" %(Gen.real, Load.real, Loss.real+ShuntLoss.real, (Load.real+Loss.real+ShuntLoss.real)))
		psspy.progress("\n\n======     BASE CASE PREP with HVDC Dispatch - DONE ===============\n")
		
		
		# sys.exit()
		# except:
			# raise HvdcError()
		return  self.outputCaseName, self.emmoUpdateList, MarginalUnit, savedOWSP, savedOESP, newWATL, newEATL
		# raw_input()
		# sys.exit()
		
		#############################
		########################################
		#######################################################
		
		# psspy.case("")
		# psspy.solution_parameters_4((psspy._i, 50), (psspy._f,) *5 + (0.01, ))
		# Solve()

		# MUserial, MUassetName, MarU = casePrep()
		# print MUserial, MUassetName
		# psspy.save("2017LF_Dec01_BaseCase_Ready-2.sav")






			
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)
			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
    def __init__(self, mpidName, loadmpid, tag, ISDtag, generators, loads, interfaceBus, MPID_buses, netFlow ):
		self.mpidName = mpidName
		self.loadmpid = loadmpid
		self.tag = tag
		self.ISDtag = ISDtag
		self.generators = generators
		self.loads = loads
		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 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:
		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 UpdateGen_Max(bus, id, pgen, pmax, status):
	if pgen == 0:
		status = 0
	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
			




	

############## 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
	# 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_Gen(MPID):
	# print MPID.mpidName
	totalPgen = 0
	totalPmax = 0
	if MPID.mpidName == 'BCHIMP':
		totalPgen = TieMeasure()
		totalPmax = totalPgen
	elif MPID.mpidName == 'SPCIMP':
		for load in MPID.loads:
			status, pload, qload = getLoadData(load.bus, load.id)
			totalgen = 0
			if MPID.generators != '':
				for gen in MPID.generators:
					status, pgen, pmax, pmin, qmax, qmin, mbase = GetGenData(gen.bus, gen.id)
					if status != 0:
						totalgen += pgen
					totalPmax += pmax
			totalPgen = totalgen - pload
	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
############### Find Bus Data




############### 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 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
	return 0, 0, 0

def UpdateLoad(loadbus, loadid, status, p, q):
	err = psspy.load_chng_4(loadbus, loadid, [status, _i,_i,_i,_i,_i], [p, q, _f, _f,_f,_f])
	
	
	
	
def determineMPID_Load(MPID):
	totalPload = 0
	totalQload = 0
	if MPID.loads != []:
		for load in MPID.loads:
			print "BUS_ID", load.bus, load.id
			# raw_input()
			status, pload, qload = getLoadData(load.bus, load.id)
			# print status, pload, qload
			
			if status != 0:
				totalPload += pload 
				totalQload += qload
	
	print totalPload, totalQload
	# raw_input("-----Load-----")
	return totalPload, totalQload

###### 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 determineMPID_netFlow__old(MPID):
	# MPID.netFlow = MPID.netFlow.upper()
	if MPID.netFlow != '':
		if MPID.mpidName == 'BCHIMP':
			totalFlow = TieMeasure()
		elif MPID.mpidName == 'SPCIMP':
			mpidLoad, mpidQ = determineMPID_Load(MPID)
			totalFlow = -mpidLoad
		else:
			
			totalFlow = 0
			if MPID.netFlow == "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):
						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):
						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:
						pload, qload = determineMPID_Load(MPID)
						if "-" in branch:
							flow = -pload
						else:
							flow = pload
					elif "DL" in branch:
						temp = branch.split("(")
						temp = temp[1].strip(")")
						[loadbus, loadid] = temp.split("-")
						status, pload, qload = getLoadData(loadbus, loadid)
						if "-" in branch:
							flow = -pload
						else:
							flow = pload
					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 totalFlow
	
	return totalFlow
		

def determineMPID_netFlow(MPID):
	print "\n========================= Determining NTG of MPID - ", MPID.mpidName, " ==========================\n" 
	print MPID.netFlow
	# raw_input()
	# MPID.netFlow = MPID.netFlow.upper()
	if MPID.netFlow != '':
		if MPID.mpidName == 'BCHIMP':
			totalFlow = TieMeasure()
		elif MPID.mpidName == 'SPCIMP':
			mpidLoad, mpidQ = determineMPID_Load(MPID)
			totalFlow = -mpidLoad
		else:
			if MPID.ISDtag == "DOS":
				mpidLoad, mpidQ = determineMPID_Load(MPID)
				totalFlow = mpidLoad
			else:
				totalFlow = 0
				if MPID.netFlow == "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):
							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):
							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:
							pload, qload = determineMPID_Load(MPID)
							if "-" in branch:
								flow = -pload
							else:
								flow = pload
						elif "DL" in branch:
							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
						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 "totalFlow : ", totalFlow
	print "================================================"
	# raw_input()
	return totalFlow
	
###############################
#############################################
##############################################################

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, loadData, MPIDs):
	novalod1_mwData=0
	novalod2_mwData=0
	cnr5lod_mwData=0
	fnlod_mwData =0 
	ior1lod_mwData=0
	
	def get_mpid_loadmpids(mpidName, MPIDs):
		for eachMPID in MPIDs:
			if eachMPID.mpidName == mpidName:
				return eachMPID.loadmpid
	
	# isdExceptionList = ["NOVAGEN15M", "IOR1", "CNR5", "FNG1"]
	isdExceptionList = ["NOVAGEN15M", "DOWGEN15M"]
	exceptionalBlockNumber=-10
	
	for eachException in isdExceptionList :
		lod_mwData=0
		loadmpids = get_mpid_loadmpids(eachException, MPIDs)
		for loadmpid in loadmpids:
			# enable_print()
			# print loadmpid
			# raw_input()
			for data in loadData:
				if data.mpidName == loadmpid:
					lod_mwData += data.mwData
		
		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
	
	
	
	
	
	
	
	
	# for data in loadData:
		# if data.mpidName == "APNC":
			# novalod1_mwData = data.mwData
		# if data.mpidName == "0000053502":
			# novalod2_mwData = data.mwData
		# if data.mpidName == "CNRL838S":
			# cnr5lod_mwData = data.mwData
		# if data.mpidName == "FNLOAD":
			# fnlod_mwData = data.mwData
		# if data.mpidName == "IOR1LOD":
			# ior1lod_mwData = data.mwData
			
	# novalod_mwData = novalod1_mwData + novalod2_mwData
	
	# novagen_maxAvailableP = determine_max_availablePower_EMMO(currentHourEMMO, "NOVAGEN15M")
	# ior1_maxAvailableP = determine_max_availablePower_EMMO(currentHourEMMO, "IOR1")
	# cnr5_maxAvailableP = determine_max_availablePower_EMMO(currentHourEMMO, "CNR5")
	# fng1_maxAvailableP = determine_max_availablePower_EMMO(currentHourEMMO, "FNG1")
	
	
	# if novagen_maxAvailableP > 0:
		# for eachrow in currentHourEMMO:
			# if eachrow.assetName == "NOVAGEN15M":
				# eachrow.totalDisp_eachMPID = eachrow.totalDisp_eachMPID + novalod_mwData
				# if eachrow.blockNumber == 0:
					# eachrow.availablePower = eachrow.availablePower + novalod_mwData
	# if ior1_maxAvailableP > 0:
		# for eachrow in currentHourEMMO:
			# if eachrow.assetName == "IOR1":
				# eachrow.totalDisp_eachMPID = eachrow.totalDisp_eachMPID + ior1lod_mwData
				# if eachrow.blockNumber == 0:
					# eachrow.availablePower = eachrow.availablePower + ior1lod_mwData
	# if cnr5_maxAvailableP > 0:
		# for eachrow in currentHourEMMO:
			# if eachrow.assetName == "CNR5":
				# eachrow.totalDisp_eachMPID = eachrow.totalDisp_eachMPID + cnr5lod_mwData
				# if eachrow.blockNumber == 0:
					# eachrow.availablePower = eachrow.availablePower + cnr5lod_mwData
	# if fng1_maxAvailableP > 0:
		# for eachrow in currentHourEMMO:
			# if eachrow.assetName == "FNG1":
				# eachrow.totalDisp_eachMPID = eachrow.totalDisp_eachMPID + fnlod_mwData
				# if eachrow.blockNumber == 0:
					# eachrow.availablePower = eachrow.availablePower + fnlod_mwData
	
	# return currentHourEMMO
	
	

def ProcessCases(caseFiles, GenMappingFiles, EMMOFiles, loadDataFiles, loadMappingFiles, tssDataFiles, dates, months):
	intertie = [[329, 819, '87'], [232, 1501, '86'], [456, 90000, '01']]
	
	##voltageLimits = ReadVoltageLimits(voltageFilename)

	wb = xlwt.Workbook()

	monthlyMPIDMapping = dict()
	monthlyCases = dict()
	monthlyLoadMapping = dict()
	
	monthlyEMMO = dict()
	monthlyLoad = dict()
	monthlyMvarLoad = dict()
	monthlyTSS = dict()
	timeNow = datetime.datetime.now()
	timeNow = timeNow.strftime("%d%b%Y-%H-%M")
	print "Simulation Start Time : ", timeNow
	
	preparedCaseDir = "State-1 -%s" %timeNow
	caseOutDir = "State-1 Cases -%s" %timeNow
	ensure_dir(preparedCaseDir)
	ensure_dir(caseOutDir)
	
	basecaseprepLogDir = "Logfiles"
	ensure_dir(basecaseprepLogDir)

	errorlogfilename = os.path.join(preparedCaseDir, "BasecasePrep-Error-%s.log" %timeNow)
	basecasepreplogname = os.path.join(basecaseprepLogDir, "BasecasePrep-Log-%s.log" %timeNow)
	
	# errorlogs = dict()
	# basecasepreplogs = dict()
	
	errorlog = open(errorlogfilename, "w")
	errorlog.write("\tStart Time = %s\n" %timeNow)
	basecasepreplog = open(basecasepreplogname, "w")
	# basecasepreplog.write("\tStart Time = %s\n" %timeNow)
	
	emmoUpdateWB = openpyxl.Workbook()
	emmoUpdateWS = emmoUpdateWB.create_sheet("Update EMMO")
	
	emmoupdateRow = 1
	
	for month in months:
		logfilename = os.path.join(os.getcwd(), month+ "-%s.log" %timeNow)
		log = open(logfilename, "w")
		
		
		
		
		enable_print()
		################ Monthly MPID Mapping ############
		GenMappingFile = selectMonthlyMPIDMapping(GenMappingFiles, month)
		log_print(log)
		monthlyMPIDMapping[month] = CreateMPIDs(GenMappingFile, month)
		################ Monthly Cases ############
		monthlyCases[month] = selectMonthlyCase(caseFiles, month)
		############ Monthly Load Mapping ##############
		loadMappingFile = SelectMonthlyLoadMapping(loadMappingFiles, month)
		monthlyLoadMapping[month] = readLoadMapping(loadMappingFile)
		#### Select EMMO ####
		EMMOFile = SelectMonthlyEMMO(EMMOFiles, month)
		monthlyEMMO[month] = readMonthlyEMMO(EMMOFile)
		###### Monthly load Data ##
		loadDataFile = SelectMonthlyLoad(loadDataFiles, month)
		monthlyLoad[month] = readMonthlyLoad(loadDataFile)
		###### Monthly load Mvar Data ##
		# loadMvarDataFile = SelectMonthlyLoad(loadDataFiles, month)
		monthlyMvarLoad[month] = readMonthly_MvarLoad(loadDataFile)
		### Monthly TSS Data ####
		tssDataFile = SelectMonthlyTSS(tssDataFiles, month)
		monthlyTSS[month] = readMonthlyTSS(tssDataFile)
	
	# # raw_input()
	count_success_s1 = 0
	count_attemptedCases = 0
	for dt in dates:
		# dates = ["2015-DEC-01-14-00", "2015-DEC-01-03-00"]
		date = dt.strftime("%Y-%b-%d-%H-%M")
		
		year = date.split("-")[0]
		month = date.split("-")[1].upper()
		day = date.split("-")[2]
		hour = date.split("-")[3]
		min = date.split("-")[4]
		
		
		# global output_dir
		# output_dir = 'Output Cases'
		output_dir = os.path.join(preparedCaseDir, day+"_"+month+"_"+year)
		ensure_dir(output_dir)
		enable_print()
		print "Processing : " , date, "  Attempted : ", count_attemptedCases, "  Success : ", count_success_s1 
		
		logfilename = os.path.join(output_dir, day+"_"+month+"_"+year+"_Hour_"+hour+".log")
		log = open(logfilename, "w")
		log_print(log)
		# global log
		
		year_2 = str(int(year)-2)
		time = day+month+year_2+":"+hour+":00:00"
		
		year_2_emmo = year_2.split('20')[1]
		time_emmo = day+month+year_2_emmo+":"+hour+":00:00"

		currentHourEMMO = createHourlyEMMO(monthlyEMMO[month], time_emmo)
		currentHourTSS = createHourlyTSS(monthlyTSS[month], time)
		
		time = day+month+year+":"+hour+":00:00"
		currentHourLoad = createHourlyLoad(monthlyLoad[month], time)
		currentHourMvarLoad = createHourlyMvarLoad(monthlyMvarLoad[month], time)
		
		caseFilename = monthlyCases[month]
		MPIDs = monthlyMPIDMapping[month]
		loadMapping = monthlyLoadMapping[month]
		
		
		loadData = currentHourLoad
		MOList = correctEMMO(currentHourEMMO, loadData, MPIDs)
		loadMvarData = currentHourMvarLoad
		tssData = currentHourTSS
		
		# print len(MOList)
		
		# for row in MOList:
			# print row.time
			# print row.serial
			# print row.assetName
			# print row.availablePower
			# print row.capabilityMW
			# print row.totalDisp_eachMPID
		
		
		# raw_input()
		
		tempcasename = day+"_"+month+"_"+year+"_Hour_"+hour+".sav"
		outputCaseName = os.path.join(output_dir, tempcasename)
		# raw_input(outputCaseName)
		print outputCaseName
		
		# enable_print()
		count_attemptedCases += 1
		if count_success_s1 == 0:
			previousCase = caseFilename
		# else:
			
		case = Case(previousCase, intertie, MPIDs, MOList, loadData, loadMvarData, loadMapping, tssData, outputCaseName, month)
		try:
			previousCase, emmoUpdateList, MarginalUnit, savedOWSP, savedOESP, newWATL, newEATL = case.ProcessMPID()
			# emmoupdateRow = writeEmmoUpdate(date, emmoUpdateList, emmoUpdateWB, emmoUpdateWS, emmoupdateRow, MarginalUnit)
			# basecasepreplog.write(tempcasename + "\tMarginal Unit : %s - %s\n" %(MarginalUnit.assetName, int(MarginalUnit.blockNumber)))
			basecasepreplog.write(tempcasename + "\t%s-%s\t%s\t%s\t%s\t%s\n" %(MarginalUnit.assetName, int(MarginalUnit.blockNumber), savedOWSP, savedOESP, newWATL, newEATL))
			count_success_s1 += 1
		except iterationLimitError as e:
			errorlog.write(tempcasename + "\tMismatch = %s\tIterations = %s\n" %(e.mismatch, e.iterationNumber))
			pass
		except solutionError as s:
			errorlog.write(tempcasename + "\tSolution Error = %s\n" %(s.solvedMsg))
			pass
		except HvdcError:
			errorlog.write(tempcasename + "\tHVDC Error\n")
		except:
			errorlog.write(tempcasename + " Unknown Error\n")
			pass
		
		
		
	enable_print()
	timeNow = datetime.datetime.now()
	timeNow = timeNow.strftime("%d%b%Y-%H-%M")
	errorlog.write("\tStop Time = %s\n" %timeNow)
	# basecasepreplog.write("\tStop Time = %s\n" %timeNow)
	# basecasepreplog.write("\tNo of Successful S1 Cases = %s\n" %count_success_s1)
	print " =============== No of Successful S1 Cases : ", count_success_s1
	errorlog.close()
	basecasepreplog.close()
	import CollectState1Files
	CollectState1Files.collectmain(preparedCaseDir, caseOutDir)
	
	
def writeEmmoUpdate(date, emmoUpdateList, emmoUpdateWB, emmoUpdateWS, emmoupdateRow, MarginalUnit):
	row = emmoupdateRow
	
	# date = dt.strftime("%d%b%Y:%H:%M")
	year = date.split("-")[0]
	# year_2 = str(int(year)-2)
	month = date.split("-")[1].upper()
	day = date.split("-")[2]
	hour = date.split("-")[3]
	min = date.split("-")[4] 
	# time = day+month+year_2+":"+hour+":00:00"
	
	year_2 = str(int(year)-2)
	# time = day+month+year_2+":"+hour+":00:00"
	year_2_emmo = year_2.split('20')[1]
	time_emmo = day+month+year_2_emmo+":"+hour+":00:00"
	for eachRecord in emmoUpdateList:
		if emmoUpdateList[eachRecord][0] <= MarginalUnit.serial:
			row += 1
			emmoUpdateWS["A"+str(row)] = time_emmo
			# emmoUpdateWS["B"+str(row)] = eachRecord[0]
			emmoUpdateWS["B"+str(row)] = eachRecord
			emmoUpdateWS["C"+str(row)] = emmoUpdateList[eachRecord][1]
			emmoUpdateWS["D"+str(row)] = emmoUpdateList[eachRecord][2]
			emmoUpdateWS["E"+str(row)] = emmoUpdateList[eachRecord][3]
	
	emmoUpdateWB.save("EMMO Correction %s.xlsx" %month)
	return row


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

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

class HvdcError(Exception):
	def __init__(self):
		print "HVDC ERROR"
#####################
#############################
def selectMonthlyMPIDMapping(GenMappingFiles, month):
	desiredFile = ''
	for excelFile in GenMappingFiles:
		# print os.path.splitext(os.path.split(excelFile)[1])[0].lower()
		# print month.lower()
		if month.lower() in os.path.splitext(os.path.split(excelFile)[1])[0].lower():
			desiredFile = excelFile
	# print desiredFile, month
	# raw_input()
	return desiredFile	

def CreateMPIDs(excelFile, month): ## Updated by SDR
	
	wb = xlrd.open_workbook(excelFile)
	ws = wb.sheet_by_name('Gen MPID Mapping') ## Updated
	MPIDs = []
	for row in range(1, ws.nrows):
		tag = ws.cell(row, 2).value   ### Clumn C
		# if tag == 'LF MPID' or tag == 'LF MPID-SKIP' or tag == 'SKIP':
		if tag == 'LF MPID' or tag == 'LF MPID-SKIP':
			mpidName = str(ws.cell(row, col2num("B")).value)   ### Clumn B
			loadmpidNames  = str(ws.cell(row, col2num("E")).value)   ### Clumn B
			ISDtag = ws.cell(row, col2num("F")).value   ### Clumn C
			associatedGens = [str(ws.cell(row, col).value) for col in range(6, 17)]
			associatedLoads = [str(ws.cell(row, col).value) for col in range(17, 20)]
			interfaceBus = (ws.cell(row, col2num("V")).value)
			if interfaceBus != '':
				interfaceBus = int(interfaceBus)
			mpid_subsystem = str((ws.cell(row, col2num("W")).value))
			buses = mpid_subsystem.split(",")
			netFlow = str((ws.cell(row, col2num("Y")).value))
			# print 
			# print mpidName, tag, ISDtag
			# print associatedGens
			# print associatedLoads 
			# print interfaceBus
			# print buses
			# print netFlow 
			# raw_input()
			
			generators = []
			# if associatedGens != []:
			for gen in associatedGens:
				if gen != '':
					[bus, id] = gen.split("-")
					bus = int(bus)
					generators.append(generatorObject(bus, str(id)))
			
			loads = []
			# if associatedLoads != []:
			for load in associatedLoads:
				if load != '':
					[bus, id] = load.split("-")
					bus = int(bus)
					loads.append(loadObject(bus, id))
			
			loadmpids = []
			loadmpidNames = loadmpidNames.strip(" ")
			loadmpids = loadmpidNames.split(", ")
			# enable_print()
			# print loadmpids
			# raw_input()
			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, loadmpids, tag, ISDtag, generators, loads, interfaceBus, MPID_buses, netFlow )
			MPIDs.append(temp)
	# sys.exit()    
			
	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 (Review)")
	ws = wb.sheet_by_name("Load Mapping")
	loadMappingList = []
	for row in range(1, ws.nrows):
		genMPID = (ws.cell(row, 0).value)
		if type(genMPID) is float or type(genMPID) is int:
			genMPID = str(int(genMPID))
		else:
			genMPID = str(genMPID)
		
		loadMPID = str(ws.cell(row, 1).value)
		if type(loadMPID) is float or type(loadMPID) is int:
			loadMPID = str(int(loadMPID))
		else:
			loadMPID = str(loadMPID)
		
		# if type(mpidName) is float or type(mpidName) is int:
			# mpidName = str(int(mpidName))
		# print assetName
		# raw_input()
		if loadMPID != '':
			
			bus = int(ws.cell(row, 2).value)
			id = (ws.cell(row, 3).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("E")).value)
			# print loadMPID, bus, id
			# raw_input()
			loadMappingList.append(loadmapdata(genMPID, loadMPID, bus, id, isdtag))
	# raw_input()
	return loadMappingList
######################################
####################################
		


	

 
def Write(output, mpid, data, caseName, wb, ws, writeStart):
	# wb = xlwt.Workbook()
	# ws = wb.add_sheet("Loss Factors")
	row = writeStart+1
	Header = "MPID Name,Initial Net Flow,Initial System Loss,Working MPID Internal Loss,Net system Loss,Marginal Unit,Final Net Flow,Final System Loss,Working MPID Internal Loss,Net system Loss,Marginal Unit,Loss Factor, MU Mismatch"

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


#############################
#############################
class meritorderData(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

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):
	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
	
	currentHourEMMO = determineMPIDTotalDispatch(currentHourEMMO)
			
	return currentHourEMMO
			
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 = ''
			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
			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 SelectMonthlyLoad(loadDataFiles, month):
	desiredFile = ''
	for excelFile in loadDataFiles:
		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 (MW)")
	monthlyLoadData = []
	
	times = []
	# enable_print()
	for col in range(col2num('B'), ws.ncols):
		date = (ws.cell(0, col).value)
		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 = (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]
				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
#############################################

class loadMvarData(object):  ## Updated by SDR
	def __init__(self, mpidName, mvarDataTag, mvarData):
		self.mpidName = mpidName
		self.mvarDataTag = mvarDataTag
		self.mvarData = mvarData
	
def readMonthly_MvarLoad(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]
				mvarData[times[col-k]] = ws.cell(row, col).value
			# print mpidName, mwData
			monthlyLoadData.append(loadMvarData(mpidName, mvarDataTag, mvarData))
	# raw_input()		
	return monthlyLoadData

def createHourlyMvarLoad(monthlyLoad, time):
	currentHourMvarLoad = []
	
	for row in monthlyLoad:
		mpidName = row.mpidName
		mvarDataTag = row.mvarDataTag
		mvarData = row.mvarData[time]
		
		currentHourMvarLoad.append(loadMvarData(mpidName, mvarDataTag, mvarData))
	
	return currentHourMvarLoad

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


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
				mwData[times[col-k]] = ws.cell(row, col).value
			# print mpidName, mwData
				monthlyTSSData.append(tssData(mpidName, mwData))
	# raw_input()		
	return monthlyTSSData

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

################################
######################################
####################
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__

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 ilf_main(caseFiles, GenMappingFiles, EMMOFiles, loadDataFiles, loadMappingFiles, tssDataFiles, dates, months):
# def ilf_main(dates, months):
def ilf_main(dates, months, inputdir):


	enable_print()
	psspy.psseinit(100000)

	global flowTolerance
	global roundingdecimalpoint
	global iterationLimit
	iterationLimit = 50
	flowTolerance = 0.005
	roundingdecimalpoint = 2
	global ab_bc
	ab_bc = [[329, 819, '87'], [232, 1501, '86'], [456, 90000, '01']]

	# inputdir = r"C:\Users\sdr\Desktop\ilf\Input Files"
	inputdir = str(inputdir)
	
	dir_case = os.path.join(inputdir, 'Cases')
	dir_emmo = os.path.join(inputdir, 'EMMO')
	dir_genMapping = os.path.join(inputdir, 'Gen Mapping')
	dir_loadMapping = os.path.join(inputdir, 'Load Mapping')
	dir_tssData = os.path.join(inputdir, 'TSS Data')
	dir_loadData = os.path.join(inputdir, 'Load Data')
	
	# dir_case = os.path.join(os.getcwd(), 'Input Files\\Cases')
	# dir_emmo = os.path.join(os.getcwd(), 'Input Files\\EMMO')
	# dir_genMapping = os.path.join(os.getcwd(), 'Input Files\\Gen Mapping')
	# dir_loadMapping = os.path.join(os.getcwd(), 'Input Files\\Load Mapping')
	# dir_tssData = os.path.join(os.getcwd(), 'Input Files\\TSS Data')
	# dir_loadData = os.path.join(os.getcwd(), 'Input Files\\Load Data')
	
	fullMonths = []
	for date in dates:
		fullMonths.append(date.strftime("%B"))
	fullMonths = remove_duplicates(fullMonths)
	# print fullMonths
	# raw_input()
	
	GenMappingFiles = []
	EMMOFiles = []
	caseFiles = []
	loadDataFiles = []
	loadMappingFiles = []
	tssDataFiles = []
	
	
	for each in fullMonths:
		GenMappingFiles.append(os.path.join(dir_genMapping, 'Gen_Mapping_%s.xlsx' %each))
		EMMOFiles.append(os.path.join(dir_emmo, 'EMMO_%s.xlsx' %each))
		
		caseFiles.append(os.path.join(dir_case,"2017LF_%s_R1_Final_Topology.sav" %each))
		loadDataFiles.append(os.path.join(dir_loadData, 'Load Data_%s.xlsx' %each))
		loadMappingFiles.append(os.path.join(dir_loadMapping, 'Load_Mapping_%s.xlsx' %each))
		tssDataFiles.append(os.path.join(dir_tssData, 'TSS Volumes_%s.xlsx' %each))
	
	# dates = [datetime.datetime(2017,8,10,14,00), datetime.datetime(2017,8,20,06,00)]
	# dates = [datetime.datetime(2017,8,10,06,00), datetime.datetime(2017,8,15,06,00), datetime.datetime(2017,8,05,06,00)]
	# months = [desiredMonth,]
	print "==========="
	print "Input Files : "
	print caseFiles
	print GenMappingFiles
	print EMMOFiles
	print loadDataFiles
	print loadMappingFiles
	print tssDataFiles
	
	ProcessCases(caseFiles, GenMappingFiles, EMMOFiles, loadDataFiles, loadMappingFiles, tssDataFiles, dates, months)
	enable_print()
	
	
	print "++++++++++++++++++++++++++++++++++++ END OF PROGRAM +++++++++++++++++++++++++++++++++++"
	# sys.exit()
    
     
# main()   
# if __name__ == "__main__":
    # main()