def generate345PathList(Raw,startBusList): # Function to generate the list of paths print 'Compiling the neighbour data from the Raw file. May take some time. Please wait.' print '\n' CAPENeighbourDict = getNeighbours(Raw) # key: any bus in the raw file, value: set of all neighbours (line and tf) BusDataDict = getBusData(Raw) # Dict whose values are all the relevant info about any bus, key is the bus itself print 'Ok, done!' ImpPathDict = {} # Use CAPENeighbourDict and BFS to find path from one bus to another. Use the concept given in getNeighboursAtCertainDepthFn for startBus in startBusList: PathDict = {} explored = set() #startBus = raw_input('Enter start bus: ') #endBus = raw_input('Enter end bus: ') frontier = Queue(maxsize=0) frontier.put(startBus) while not frontier.empty(): currentBus = frontier.get() frontier.task_done() #if currentBus == endBus: # break BusVolt = float(BusDataDict[currentBus].NominalVolt) BusName = BusDataDict[currentBus].name BusArea = BusDataDict[currentBus].area if BusVolt >= 345.0 and not BusName.startswith('T3W') and not BusName.endswith('M') and BusArea == '222': # see if the bus is a legit 345 kV bus endBus = currentBus break NeighBourList = list(CAPENeighbourDict[currentBus]) explored.add(currentBus) for neighbour in NeighBourList: try: NeighBourArea = BusDataDict[neighbour].area except: # probably type 4 bus continue if NeighBourArea != '222': # go to next neighbour if continue if neighbour in explored: continue if currentBus in PathDict.keys(): PathDict[neighbour] = PathDict[currentBus] + '->' + neighbour else: # if currentBus is the start bus PathDict[neighbour] = currentBus + '->' + neighbour frontier.put(neighbour) #print PathDict[endBus] ImpPathDict[startBus] = PathDict[endBus] return ImpPathDict
GenBusMapLog = 'GenBusMap.log' # gen map used later on isolatedCAPEBusList = 'isolatedCAPEBusList_All.txt' # list of buses which are isolated in cape verifiedGenData = 'verifiedGenData.txt' # this file contains the verified gen data busMappingConfirmedFile = 'mapping_confirmed_old_numbers.txt' # bus mapping provided by hemanth (includes old bus numbers and tf midpoints) PSSEMap = 'PSSE345Mapverified.txt' # verified 345 kV bus map data manualMapFile = 'mapped_buses_cleaned0407.csv' # manual map file changeLogPrevious = 'changeBusNoLogPrevious.txt' # log of all bus number changes carried out previously angleChangeFile = 'logAngleChange.txt' changeLog = 'changeBusNoLog.txt' AllMappedBusData = 'AllMappedBusData.txt' # output file which contains all the CAPE bus data, with voltages mapped from planning AllMappedLog = 'AllMappedLog.txt' # the log of which bus maps to what newMidPointList = 'MidPointBusesAdded.txt' # list of all planning midpoint maps added # variables MappedPSSEGenBusSet = set() # set of PSSE Comed gen bus which has been mapped noNeedtoMapSet = set() # set of non-comed and isolated CAPE buses CAPEBusDataDict = getBusData(CAPERaw) planningBusDataDict = getBusData(PSSE_Raw) GenBusSet = set() # set of all Comed gen buses in planning MapAllExceptGenDict = {} # contains all the mappings MapAllExceptGenSet = set() # set of buses which have been except for gen buses stillUnmappedSet = set( ) # dynamically keep track of the buses which are still to be mapped GenMapDict = {} # key: CAPEBus, value: planningBus AllCAPEBuses = set( ) # set of all CAPE buses which are needed (except outside comed and isolated) verifiedGenLines = [] CAPENeighbourDict = getNeighbours(CAPERaw) MappedCAPEGenBusSet = set() changeNameDictNewToOld = { } # key: changed bus numbers, value: original bus numbers AngleChangeDict = {} # key: original bus numbers, value: phase shifts in float
+ os.environ['PATH']) # get the list of raw files to be considered for the simulation fileList = os.listdir('.') RawFileList = [] for file in fileList: if file.endswith('.raw') and 'savnw_conp' in file: #print file RawFileList.append(file) # generate the HV bus set refRaw = 'savnw_conp.raw' BusDataDict = getBusData(refRaw) HVBusSet = set() for Bus in BusDataDict: BusVolt = float(BusDataDict[Bus].NominalVolt) BusType = BusDataDict[Bus].type if BusVolt >= 34.5: # no need to consider type 4 buses since they are already filtered out in the get Bus Data function HVBusSet.add(Bus) topology_inconsistency_file = 'topology_inconsistency_cases_savnw.txt' # get the N-2 events which cause topology inconsistencies topology_inconsistent_set = set() with open(topology_inconsistency_file, 'r') as f: fileLines = f.read().split('\n') for line in fileLines: if line == '':
sys.path.insert(0,'C:/Users/Bikiran/Google Drive/Bus Mapping Project Original/Donut Hole Approach/Donut Hole v2') from generateNeighbourImpedanceData import getBranchTFData # helps get organized branch (and tf) impedance data from updatedMaps import MapDictNew, MapDictOld # needed to scan mappings and compare branch data (between CAPE and planning) from getBusDataFn import getBusData # function to all relevant bus data given the raw file from getBranchGroupFn import makeBranchGroups # to help with identifying all the fringe buses causing mismatch flowReport = 'BusReports_RAW0509.txt' sortedMismatchData = 'sortedMismatchData0509.txt' CAPERaw = 'RAW0509.raw' planningRaw = 'hls18v1dyn_1219.raw' getMaxFlowBranches = 'mismatchAnalysisv2.txt' # contains the mismatch info as well as some info about the branch which causes max mismatch flowDict = {} mismatchSet = set() areaList = [] exploredBranchSet = set() # set of branches already identified as the main cause behind mismatches mismatchAnalysis = [] # lines which will contain the max mismatch branch data as well as the total mismatch at the bus BusDataCAPE = getBusData(CAPERaw) # contains all the bus data for all in-service buses in CAPE BusDataPlanning = getBusData(planningRaw) # contains all the bus data for all in-service buses in planning BusGroupData = makeBranchGroups(CAPERaw) # contains dict for every bus which has ties class mismatchReport(object): def __init__(self): self.toBus = [] self.MWList = [] self.MVARList = [] self.MVAList = [] self.cktID = [] self.MismatchMVA = 0.0 self.MismatchMW = 0.0 self.MismatchMVAR = 0.0
from getBusDataFn import getBusData from runSimFn import runSim import csv import numpy as np ## define the raw, dyr path and the events list file rawFile = 'test_cases/PSSE/pf_ornl0823conz.raw' dyrFile = 'test_cases/PSSE/pf_ornl_all.dyr' eventListFile = 'N_2FEvents.txt' BusDataDict = getBusData(rawFile) outdir = 'PFORNLSimSeq' #### get the events list eventsList = [] with open(eventListFile,'r') as f: fileLines = f.read().split('\n') for line in fileLines: if line == '': continue eventsList.append(line.strip()) ##### # dump the arrays into csv files simList = eventsList[3300:3400] i = 34 k=0 TS3phOutFile = 'TS3phoutput{}.out'.format(k) # calculation of the start and end indices of the steady state and transient part timestep = 1/120.0 transientEnd = int(1.5/timestep) # get roughly 1.5 seconds of initial data
def MapChange(planningRaw, changeFile, CAPERaw, newRawFile, originalCase): # function to change bus mapping in raw file # originalCase: defines whether we are using planning or CAPE raw file to get bus info angleChangeFile = 'C:/Users/Bikiran/Google Drive/Bus Mapping Project Original/Donut Hole Approach/Donut Hole v2/Raw with only 2 winders/' + 'logAngleChange.txt' mapping_priority1 = 'C:/Users/Bikiran/Google Drive/Bus Mapping Project Original/Donut Hole Approach/Donut Hole v2/' + 'mapping_priority1.txt' from splitTapVoltAngleFn import splitTapVoltAngles # function which reads tap split data, performs the tap splits and generates the new raw file from tfMapFnv2 import doTFMaps # only do tf mapping, bus data is not changed from getBusDataFn import getBusData planningBusDataDict = getBusData(planningRaw) CAPENewVoltDict = { } # key: CAPEBus whose bus volt and angle will be substituted, value: new volt and angle data ManualMapDict = { } # key: the bus whose data is being used, value: the bus where we superimpose bus data currentBusSet = set() CAPEBusVoltSet = set( ) # set of all CAPE buses whose bus data will be substituted planningBusSet = set() newRawLines = [] AngleChangeDict = {} # dictionary of bus angle changes due to phase shift BranchImpedanceDictPlanning = {} BranchImpedanceDictCAPE = {} tapSplitLines = [] # lines containing tap split info ManualMapDictCAPE = { } # keys are CAPE buses according to new numbering system, values are planning buses newMapLines = [] mappedLinesSet = set() # set to prevent any duplicate mappings tfMapLines = [] # map the tf data def makeBranchImpedanceDict(Raw): # generates a branch impedance dict from the given raw file # key: Bus1 + ',' + Bus2 + ',' + cktID, value = [R,X] where R and X are both strings with open(Raw, 'r') as f: BranchImpedanceDict = {} filecontent = f.read() fileLines = filecontent.split('\n') branchStartIndex = fileLines.index( '0 / END OF GENERATOR DATA, BEGIN BRANCH DATA') + 1 branchEndIndex = fileLines.index( '0 / END OF BRANCH DATA, BEGIN TRANSFORMER DATA') for i in range(branchStartIndex, branchEndIndex): line = fileLines[i] words = line.split(',') Bus1 = words[0].strip() Bus2 = words[1].strip() cktID = words[2].strip("'").strip() key = Bus1 + ',' + Bus2 + ',' + cktID R = words[3] X = words[4] BranchImpedanceDict[key] = [R, X] return BranchImpedanceDict ##################### def reconstructLine2(words): currentLine = '' for word in words: currentLine += word currentLine += ',' return currentLine[:-1] ######## BranchImpedanceDictPlanning = makeBranchImpedanceDict( planningRaw) # generate the impedance dict for planning # Read the angle change values and generate a dict with open(angleChangeFile, 'r') as f: filecontent = f.read() fileLines = filecontent.split('\n') for line in fileLines: if 'Bus' in line: continue if line == '': continue words = line.split('->') Bus = words[0].strip() Angle = float(words[1].strip()) if Angle == 0.0: # Add to dictionary only if there is a phase shift #print Bus continue AngleChangeDict[Bus] = Angle # open the file which contains the list of manual changes necessary with open(changeFile, 'r') as f: filecontent = f.read() fileLines = filecontent.split('\n') branchImpedanceChangeStart = fileLines.index( "List of branch impedance changes:") + 1 tfMapStart = fileLines.index( "List of transformer (and corresponding bus maps):") + 1 tapSplitStart = fileLines.index( "List of split tap angles (start, end, tap):") + 1 tapSplitEnd = fileLines.index("Other miscellaneous manual changes:") # get the bus substitution data for i in range(branchImpedanceChangeStart): line = fileLines[i] if line == '': continue if '->' not in line: continue words = line.split('->') if len(words) < 2: continue planningBus = words[0].strip() CAPEBus = words[1].strip() # generate mapping info, can handle one to many mappings ManualMapDictCAPE[CAPEBus] = planningBus if planningBus not in ManualMapDict.keys(): ManualMapDict[planningBus] = [CAPEBus] else: ManualMapDict[planningBus].append(CAPEBus) planningBusSet.add(planningBus) CAPEBusVoltSet.add(CAPEBus) # get the branch substitution data for i in range(branchImpedanceChangeStart, tfMapStart): line = fileLines[i] if line == '': continue if '->' not in line: continue words = line.split('->') if len(words) < 2: continue planningPart = words[0].strip() CAPEPart = words[1].strip() BranchImpedanceDictCAPE[CAPEPart] = BranchImpedanceDictPlanning[ planningPart] # get the tf map data for i in range(tfMapStart, tapSplitStart): line = fileLines[i].strip() tfMapLines.append(line) # get tap split data for i in range(tapSplitStart, tapSplitEnd): line = fileLines[i] if line == '': continue words = line.split(',') if len(words) < 3: continue tapSplitLines.append(line.strip()) # determine which raw file to use for bus info if originalCase.strip() == 'CAPE': originalRaw = CAPERaw elif originalCase.strip() == 'planning': originalRaw = planningRaw else: print 'Please select proper originalCase argument' # get the bus data to be substituted with open(originalRaw, 'r') as f: filecontent = f.read() fileLines = filecontent.split("\n") for line in fileLines: if ('PSS' in line) or ('COMED' in line) or ('DYNAMICS' in line): continue if 'END OF BUS DATA' in line: break words = line.split(',') if len( words ) < 2: # continue to next iteration of loop if its a blank line continue Bus = words[0].strip() if Bus in planningBusSet: BusName = planningBusDataDict[Bus].name if BusName.startswith('T3W') or BusName.endswith('M'): NominalVolt = 0 else: NominalVolt = words[2] Vmag = words[7] Vang = words[8] #if originalCase.strip() == 'planning': for bus in ManualMapDict[ Bus]: # done this way so that one to many mappings can be handled #CAPEBus = ManualMapDict[Bus] #else: # CAPEBus = Bus CAPENewVoltDict[bus] = [NominalVolt, Vmag, Vang] # generate the new raw file data with open(CAPERaw, 'r') as f: filecontent = f.read() fileLines = filecontent.split('\n') # reconstruct bus status for line in fileLines: if ('PSS' in line) or ('COMED' in line) or ('DYNAMICS' in line): continue if 'END OF BUS DATA' in line: break words = line.split(',') if len(words) < 2: continue Bus = words[0].strip() if Bus in currentBusSet: # in CAPERaw, there are several buses which appear twice. This gets rid of that problem continue else: currentBusSet.add(Bus) if Bus in CAPEBusVoltSet: NewVoltageData = CAPENewVoltDict[Bus] if NewVoltageData[ 0] != 0: # only change nominal voltage when the planning bus was not a midpoint words[2] = NewVoltageData[0] # change the nominal voltage words[7] = NewVoltageData[1] # pu volt substitution # Apply any phase shifts if Bus in AngleChangeDict.keys(): PS = AngleChangeDict[Bus] OldAngle = float(NewVoltageData[2].strip()) NewAngle = OldAngle + PS NewAngleStr = '%.4f' % NewAngle NewAngleStr = ' ' * (9 - len(NewAngleStr)) + NewAngleStr words[8] = NewAngleStr else: words[8] = NewVoltageData[2] # angle substitution # reconstruct line and add newline = reconstructLine2(words) newRawLines.append(newline) else: newRawLines.append(line) # add these two bus lines, for some reason they were missing newRawLines.append( "243083,'05CAMPSS ', 138.0000,1, 205,1251, 1,1.01145, -55.0773") newRawLines.append( "658082,'MPSSE 7 ', 115.0000,1, 652,1624, 658,1.02055, -45.2697") busEndIndex = fileLines.index('0 / END OF BUS DATA, BEGIN LOAD DATA') branchStartIndex = fileLines.index( '0 / END OF GENERATOR DATA, BEGIN BRANCH DATA') + 1 branchEndIndex = fileLines.index( '0 / END OF BRANCH DATA, BEGIN TRANSFORMER DATA') # append everything between end of bus and start of branch for i in range(busEndIndex, branchStartIndex): line = fileLines[i] newRawLines.append(line) # change any branch data for i in range(branchStartIndex, branchEndIndex): line = fileLines[i] words = line.split(',') Bus1 = words[0].strip() Bus2 = words[1].strip() cktID = words[2].strip("'").strip() key = Bus1 + ',' + Bus2 + ',' + cktID # change branch data if instructed to if key in BranchImpedanceDictCAPE.keys(): print key R = BranchImpedanceDictCAPE[key][0] X = BranchImpedanceDictCAPE[key][1] words[3] = R words[4] = X line = reconstructLine2(words) newRawLines.append(line) # append everything else for i in range(branchEndIndex, len(fileLines)): line = fileLines[i] newRawLines.append(line) # output the new raw data with open(newRawFile, 'w') as f: f.write( '0, 100.00, 33, 1, 1, 60.00 / PSS(R)E-33.3 TUE, DEC 13 2016 22:08' ) f.write('\n') f.write('COMED 2018, HLS18V1, N18S OUTSIDE AND 18 INTCHNG') f.write('\n') f.write('DYNAMICS REVSION 01') f.write('\n') for line in newRawLines: f.write(line) f.write('\n') CAPEBusDataDict = getBusData(newRawFile) ManualMapDictCAPE = doTFMaps( tfMapLines, newRawFile, newRawFile, planningBusDataDict, CAPEBusDataDict, ManualMapDictCAPE ) # do tf mapping on the new raw file, should be done before any angle splitting splitTapVoltAngles( newRawFile, newRawFile, tapSplitLines ) # split angles only after the bus mapping has been completed, and use the latest raw file # get the previous manual mappings with open(mapping_priority1, 'r') as f: filecontent = f.read() fileLines = filecontent.split('\n') for line in fileLines: if line == '': continue if line in mappedLinesSet: # prevent the same mapping appearing multiple times continue if '->' not in line: # skip header continue words = line.split('->') LHSBus = words[0].strip() # planning bus RHSBus = words[1].strip() # CAPE bus (new numbering system) # check for mapping conflicts if RHSBus in ManualMapDictCAPE.keys(): if LHSBus != ManualMapDictCAPE[RHSBus]: print RHSBus + ' has two different manual maps.' newMapLines.append(line) mappedLinesSet.add(line) # append the new manual maps with open(mapping_priority1, 'w') as f: f.write( 'Highest priority maps (This file should be consulted first before any other for mapping purposes):' ) f.write('\n') for line in newMapLines: f.write(line) f.write('\n') for CAPEBus in ManualMapDictCAPE.keys(): string = ManualMapDictCAPE[CAPEBus] + '->' + CAPEBus if string not in mappedLinesSet: f.write(string) f.write('\n') mappedLinesSet.add(string)
rawPath = rawFile TS3phOutFile = 'TS3phoutput.out' rawFlag = '-ts_raw_dir' rawPath = rawFile dyrFlag = '-ts_dyr_dir' dyrPath = dyrFile state_varFlag = '-state_var_out_file' state_varFile = TS3phOutFile # convert raw file crlf to lf (needed for linux) convertFileLinux(rawPath, currentOS) rawBusDataDict = getBusData(rawPath) """ # specify the event event1Flag = '-event01' event1Param = '0.1,OUT,TRANSFORMER,151,101,,1,7,,,,,' #event2Flag = '-event02' #event2Param = '0.1,OUT,LINE,151,152,,2,7,,,,,' exitFlag = '-event03' exitParam = '0.2,EXIT,,,,,,,,,,,' #EventList = [event1Flag,event1Param,event2Flag,event2Param,exitFlag,exitParam] EventList = [event1Flag,event1Param,exitFlag,exitParam] """ """
Script to do the substitution of CAPE 3 winders to planning 2 winders Done after all the 3 winders are converted to 2 winders Update: Import the off nominal tap ratio from planning as well """ from getBusDataFn import getBusData from getTFDataFnv2 import getTFData import math input_file = 'Winder3To2SubInputs.txt' CAPERaw = 'new_Raw0706.raw' planningRaw = 'hls18v1dyn_1219.raw' changeLog = 'changeBusNoLog.txt' tMapFile = 'tmap_Raw0706.raw' newRawFile = 'new_Raw0706_3wconv.raw' # output file where all the 3w->2w subs are done TapInput = 'tap_split_changes.txt' # original file containing tap split info TapInput_new = 'tap_split_changes_new.txt' # updated with all the new midpoint tap split info CAPEBusDataDict = getBusData(CAPERaw) planningBusDataDict = getBusData(planningRaw) changeDict = {} # old to new dict tMapDict = { } # key: original 3 winder, value: new 2 winders, without the tertiary planningTFDataDict = getTFData(planningRaw) CAPETFDataDict = getTFData(CAPERaw) NewTFImpedanceData = { } # key: all tf whose impedances are being subbed, values: new impedance and sbase data newRawLines = [] MidptDict = {} # key: 3 winder, value: corresponding tf originaltapSplitLines = [] midptTapSplitLines = [] # list of new tap split lines def reconstructLine2(words):
################################# savnw_raw = 'savnw_dy_sol_0905.raw' # get the total load (MVA) in the raw file LoadDataDict = getLoadData(savnw_raw) NeighbourDict = getNeighbours(savnw_raw) totalConstZMVA = 0.0 # total constant impedance load in the raw file for Bus in LoadDataDict: constZP = LoadDataDict[Bus].constZP constZQ = LoadDataDict[Bus].constZQ constZS = math.sqrt(constZP**2 + constZQ**2) totalConstZMVA += constZS # organize the distance between any two buses in the system BusDataDict = getBusData(savnw_raw) depthDict = { } # stores the distance of all the other buses to the bus provided as key for Bus in BusDataDict: depthDict[Bus] = PathStruct() for n in BusDataDict: if n != Bus: depthDict[Bus].restOfBuses.append(n) Path = getPath(savnw_raw, Bus, n) d = len(Path.split( '->')) - 1 # since the starting bus is the bus itself depthDict[Bus].depth.append(d) # load voltage data VoltageDataDict = load_obj( 'VoltageData'
# append all data from the end of tf data for i in range(tfEndIndex,len(fileLines)): line = fileLines[i] newRawLines.append(line) # generate new raw file with open(newRAW,'w') as f: f.write('0, 100.00, 33, 1, 1, 60.00 / PSS(R)E-33.3 TUE, DEC 13 2016 22:08') f.write('\n') f.write('COMED 2018, HLS18V1, N18S OUTSIDE AND 18 INTCHNG') f.write('\n') f.write('DYNAMICS REVSION 01') f.write('\n') for line in newRawLines: f.write(line) f.write('\n') return ManualMapDictCAPE if __name__ == '__main__': from getBusDataFn import getBusData # test the fn planningRAW = 'hls18v1dyn_1219.raw' OldRAW = 'RAW0509.raw' newRAW = 'RAW0509_tmp.raw' changeLines = ['270797,274650,1-> 274650,5286,1'] planningBusDataDict = getBusData(planningRAW) CAPEBusDataDict = getBusData(OldRAW) doTFMaps(changeLines,OldRAW,newRAW,planningBusDataDict,CAPEBusDataDict)
""" Output all the 3 winder substitutions in proper format from oldGenAndMidPtSubFile Output all the midpoint data from the same file """ from getTFDataFn import getTFData from getBusDataFn import getBusData planningRaw = 'hls18v1dyn_new.raw' newMidPointList = 'MidPointBusesAdded.txt' MidpointSet = set() MidPtTMap = {} # key: Midpoint, value: set of its connections MidPtIDMap = {} # key: Midpoint, value: csv of its tf IDs oldGenAndMidPtSubFile = 'genAndMidpoint3wMaps.txt' Comed3WinderPlanningDict = {} planningBusDataDict = getBusData(planningRaw) planningTFDataDict = getTFData(planningRaw) # get the set of planning midpoint buses imported into the merged raw file with open(newMidPointList,'r') as f: filecontent = f.read() fileLines = filecontent.split('\n') for line in fileLines: if line == '': continue words = line.split(',') Bus = words[0].strip() MidpointSet.add(Bus)
# carries out the normal 2w->2w transformer substitutions specified in tf2tfmaps_2winder_cleaned.txt from tfMapFnv3 import doTFMaps from getBusDataFn import getBusData planningRaw = 'hls18v1dyn_1219.raw' newRawFile = 'RAW0620.raw' oldTFData = 'TFSubManualDone.txt' newTFData = 'TFSubGenTFFixRemaining.txt' #BusDataDicts are needed for nominal voltage info only planningBusDataDict = getBusData(planningRaw) CAPEBusDataDict = getBusData(newRawFile) input_file = 'tf2tfmaps_2winder_cleaned.txt' tfSubLines = [] with open(input_file, 'r') as f: filecontent = f.read() fileLines = filecontent.split('\n') # get the relevant inputs startIndex = fileLines.index( 'Normal two winder substitutions from mapping_confirmed_0606:') + 1 for i in range(startIndex, len(fileLines)): line = fileLines[i] tfSubLines.append(line) # do the tf subs on the old tf data to get new tf data doTFMaps(tfSubLines, oldTFData, newTFData, planningBusDataDict, CAPEBusDataDict)
#old_input = 'CAPEToCAPEMappingInput.txt' new_input = 'CAPEToCAPEMappingInput.txt' tmap_file = 'tmap_Raw0706.raw' RawFile = 'new_Raw0706_TapDone.raw' # the raw file output by TapLogChange angleChangeFile = 'logAngleChange.txt' NewRawFile = 'new_Raw0706_CCMapsApplied.raw' tMapDict = {} tMapDictReverse = {} VoltageDict = {} AngleChangeDict = {} newRawLines = [] from getBusDataFn import getBusData CAPEBusDataDict = getBusData(RawFile) def reconstructLine2(words): currentLine = '' for word in words: currentLine += word currentLine += ',' return currentLine[:-1] # Read the angle change values and generate a dict with open(angleChangeFile,'r') as f: filecontent = f.read() fileLines = filecontent.split('\n') for line in fileLines: if 'Bus' in line: continue
#from changetfDatav4 import BusVoltageDict from getBusDataFn import getBusData PSSErawFile = 'hls18v1dyn_1219.raw' AllMapFile = 'AllMappedLog.txt' manualMapFile = 'mapped_buses_cleaned_for_load_shunt.csv' newShuntData = 'newShuntData.txt' # output of this file ssBusNoChangeLog = 'ssBusNoChangeLog.txt' # log of changes made in this file changeLog = 'changeBusNoLog.txt' BusData = 'PSSE_bus_data.txt' outsideComedFile = 'outsideComedBusesv4.txt' isolatedCAPEBusList = 'isolatedCAPEBusList_All.txt' # list of buses which are isolated in cape GenBusChangeLog = 'GenBusChange.log' # log file of CAPE buses which have been renumbered to PSSE gen bus numbers NeighbourDict = getNeighbours(PSSErawFile) # dict of neighbours in planning #PSSEGenFile = 'PSSEGenFile.txt' BusDataDict = getBusData(PSSErawFile) genLines = [] ComedBusSet = set() MapDict = {} ManualMapDict = {} ssBusNoChangeDict = {} changeBusNoLogList = [] OldBusSet = set() changeNameDict = {} #BusVoltageDict = {} noNeedtoMapSet = set() TrueGenBusSet = set() # set of all gen buses, numbered according to planning """ with open(BusData,'r') as f: filecontent = f.read() fileLines = filecontent.split('\n')
# get the bus list with open(buslistfile,'r') as f: filecontent = f.read().strip() buslist = filecontent.split(',') # get a buswise list buswiselist = [] for event in eventwiseList: for bus in buslist: currentstr = '{}/{}'.format(event,bus) buswiselist.append(currentstr) refRaw = 'savnw.raw' busdatadict = getBusData(refRaw) # get the inputs print('Getting the inputs...') originalColumnSize = 23*120 adfT = pd.read_csv(aFileInput,header = None) inputArrayEventWise = adfT.values[:-1] # the last row is incomplete, so take it out inputArrayA = inputArrayEventWise.reshape(-1,120) inputArrayA = inputArrayA[:,:60] inputArrayEventWiseNew = inputArrayA.reshape(-1,originalColumnSize/2) # #### get the target voltage array print('Getting the steady state angles and generate targets...')
def changeLoad(raw, start, end, step, newdir): """ New raw files are created for each percentage step in [start,end]. The current step defines the percentage scaling up (or down) factor for load and generation """ # convert the raw file to another one where all the load is constant power raw_conp = raw.replace('.raw', '') + '_conp.raw' redirect.psse2py() psspy.psseinit(buses=80000) # ignore the output psspy.report_output(6, '', [0, 0]) psspy.progress_output(6, '', [0, 0]) psspy.alert_output(6, '', [0, 0]) psspy.prompt_output(6, '', [0, 0]) # read the raw file and convert all the loads to constant power ierr = psspy.read(0, raw) # multi-line command to convert the loads to 100% constant power psspy.conl(0, 1, 1, [1, 0], [0.0, 0.0, 0.0, 0.0]) psspy.conl(0, 1, 2, [1, 0], [0.0, 0.0, 0.0, 0.0]) psspy.conl(0, 1, 3, [1, 0], [0.0, 0.0, 0.0, 0.0]) ierr = psspy.rawd_2(0, 1, [1, 1, 1, 0, 0, 0, 0], 0, raw_conp) # run change Load on the constant power load raw file rawBusDataDict = getBusData(raw_conp) # create a new directory to put the files in currentdir = os.getcwd() if not os.path.exists(newdir): os.mkdir(newdir) output_dir = currentdir + '/' + newdir #genDiscount = 0.90 # ratio of the actual increase in generation genDiscount = 1.0 lossRatio = 0.0 # gen scale-up factor: (scalePercent + (scalePercent-100)*lossRatio)/100 ############################################ # create new raw files with scaled up loads and generation for scalePercent in range(start, end + step, step): scalePercent = float( scalePercent) # float is needed, otherwise 101/100 returns 1 scalePercentInt = int( scalePercent) # integer value needed to append to filename scalePercentStr = str(scalePercentInt) # variables to store load data loadBusList = [] # list of load buses (string) loadPList = [] # list of Pload values (string) loadQList = [] # list of Qload values (string) loadPListInt = [] # list of Pload values (float) loadQListInt = [] # list of Qload values (float) #loadBusListInt = [] # list of load buses (int) # variables to store gen data genBusList = [] #genBusListInt = [] genPList = [] genMVAList = [] genMVAListInt = [] genPListInt = [] raw_name = raw_conp.replace('.raw', '') out_file = raw_name + scalePercentStr + '.raw' # output file out_path = output_dir + '/' + out_file impLoadBuses = [ ] # enter specified load buses to scale, if empty all loads are scaled incLoss = ( scalePercent - 100 ) * lossRatio # Additional percentage increase in Pgen (to account for losses) ############################################# #Read raw file with open(raw_conp, 'r') as f: filecontent = f.read() filelines = filecontent.split('\n') ## Get start and end indices of load and gen info ######################################### loadStartIndex = filelines.index( '0 / END OF BUS DATA, BEGIN LOAD DATA') + 1 loadEndIndex = filelines.index( '0 / END OF LOAD DATA, BEGIN FIXED SHUNT DATA') genStartIndex = filelines.index( '0 / END OF FIXED SHUNT DATA, BEGIN GENERATOR DATA') + 1 genEndIndex = filelines.index( '0 / END OF GENERATOR DATA, BEGIN BRANCH DATA') ############################################################################## totalPincr = 0.0 totalQincr = 0.0 percentIncr = (scalePercent - 100.0) / 100 # increment in percentage newPConList = [] newQConList = [] newIPList = [] newIQList = [] newZPList = [] newZQList = [] # Extract load info for i in range(loadStartIndex, loadEndIndex): words = filelines[i].split(',') loadBus = words[0].strip() #loadBusList.append(words[0].strip()) loadPCon = float(words[5].strip()) loadQCon = float(words[6].strip()) loadIP = float(words[7].strip()) loadIQ = float(words[8].strip()) loadZP = float(words[9].strip()) loadZQ = float(words[10].strip()) # calculate the total MW (MVAr) increase in load loadBusVolt = float(rawBusDataDict[loadBus].voltpu) Pincr = percentIncr * ( loadPCon + loadIP * loadBusVolt + loadZP * loadBusVolt**2 ) # this equation is provided in PAGV1 page 293 Qincr = percentIncr * (loadQCon + loadIQ * loadBusVolt + loadZQ * loadBusVolt**2) totalPincr += Pincr totalQincr += Qincr ### # new load values newPConList.append(loadPCon * scalePercent / 100) newQConList.append(loadQCon * scalePercent / 100) newIPList.append(loadIP * scalePercent / 100) newIQList.append(loadIQ * scalePercent / 100) newZPList.append(loadZP * scalePercent / 100) newZQList.append(loadZQ * scalePercent / 100) """ loadPList.append(words[5].strip()) # adding P value (constant power) loadQList.append(words[6].strip()) # adding Q value (constant power) loadIPList.append(words[7].strip()) # constant current P loadIQList.append(words[7].strip()) # constant current Q loadZPList.append(words[9].strip()) # adding P value (constant admittance) loadZQList.append(words[10].strip()) # adding Q value (constant admittance) """ # get total MW gen totalGenMW = 0.0 # total generation excluding the swing bus for i in range(genStartIndex, genEndIndex): words = filelines[i].split(',') GenBus = words[0].strip() if rawBusDataDict[GenBus].type == '3': continue PGen = float(words[2].strip()) totalGenMW += PGen # get new MW Gen GenMWDict = {} # dictionary to hold new PGen values for i in range(genStartIndex, genEndIndex): words = filelines[i].split(',') Bus = words[0].strip() if rawBusDataDict[Bus].type == '3': continue macID = words[1].strip() key = Bus + macID PGen = float(words[2].strip()) genIncr = PGen / totalGenMW * totalPincr newPGen = (PGen + genIncr) * genDiscount GenMVA = float(words[8].strip()) if newPGen < GenMVA: GenMWDict[key] = newPGen else: GenMWDict[key] = GenMVA # generate the new raw file with open(out_path, 'w') as f: # copy everything before load data for i in range(loadStartIndex): f.write(filelines[i]) f.write('\n') # modify the load data j = 0 for i in range(loadStartIndex, loadEndIndex): words = filelines[i].split(',') # change the constant MVA values words[5] = '%.3f' % newPConList[j] words[6] = '%.3f' % newQConList[j] words[5] = words[5].rjust(10) words[6] = words[6].rjust(10) # change the constant current values words[7] = '%.3f' % newIPList[j] words[8] = '%.3f' % newIQList[j] words[7] = words[7].rjust(10) words[8] = words[8].rjust(10) # change the constant impedance values words[9] = '%.3f' % newZPList[j] words[10] = '%.3f' % newZQList[j] words[9] = words[9].rjust(10) words[10] = words[10].rjust(10) # construct a whole string by inserting commas between the words list filelines[i] = reconstructLine2(words) f.write(filelines[i]) f.write('\n') # increment the load list index j += 1 # copy the shunt data, which is in between the load and gen data for i in range(loadEndIndex, genStartIndex): f.write(filelines[i]) f.write('\n') # update and write the gen data for i in range(genStartIndex, genEndIndex): words = filelines[i].split(',') Bus = words[0].strip() if rawBusDataDict[Bus].type == '3': f.write(filelines[i]) f.write('\n') continue macID = words[1].strip() key = Bus + macID newPGen = GenMWDict[key] words[2] = '%.3f' % newPGen words[2] = words[2].rjust(10) # construct a whole string by inserting commas between the words list filelines[i] = reconstructLine2(words) f.write(filelines[i]) f.write('\n') # copy the rest of the raw data for i in range(genEndIndex, len(filelines)): f.write(filelines[i]) f.write('\n') # solves each of the newly generated raw files and saves them output_dir = currentdir + '/' + newdir NewRawFiles = os.listdir(output_dir) PathList = [(output_dir + '/' + f) for f in NewRawFiles] redirect.psse2py() psspy.psseinit(buses=80000) _i = psspy.getdefaultint() _f = psspy.getdefaultreal() _s = psspy.getdefaultchar() for i in range(len(PathList)): #Settings. CONFIGURE THIS settings = { # use the same raw data in PSS/E and TS3ph ##################################### 'filename': PathList[i], #use the same raw data in PSS/E and TS3ph ################################################################################ 'dyr_file': '', 'out_file': 'output2.out', 'pf_options': [ 0, #disable taps 0, #disable area exchange 0, #disable phase-shift 0, #disable dc-tap 0, #disable switched shunts 0, #do not flat start 0, #apply var limits immediately 0, #disable non-div solution ] } psse_log = output_dir + '/' + 'log' + NewRawFiles[i].replace( '.raw', '.txt') psspy.report_output(2, psse_log, [0, 0]) psspy.progress_output(2, psse_log, [0, 0]) psspy.alert_output(2, psse_log, [0, 0]) psspy.prompt_output(2, psse_log, [0, 0]) print "\n Reading raw file:", settings['filename'] ierr = psspy.read(0, settings['filename']) ierr = psspy.fnsl(settings['pf_options']) converge = psspy.solved() if converge == 0: ierr = psspy.rawd_2(0, 1, [1, 1, 1, 0, 0, 0, 0], 0, PathList[i]) else: # file does not converge, remove raw file, keep log file os.remove(PathList[i]) """
#### classes class Features(object): def __init__(self, inputV): self.max_ratio = 0.0 self.genRatioF = 0.0 self.similarityCL0 = 0.0 self.similarityCL1 = 0.0 self.t_max = 0.0 self.osc = 0.0 # one if sample belongs to oscillatory class, otherwise 0 self.inputV = inputV raw = 'savnw.raw' BusDataDict = getBusData(raw) GenDataDict = getGenData(raw) NeighbourDict = getNeighbours(raw) FeatureDict = {} ############## Functions def load_obj(name): # load pickle object with open('obj/' + name + '.pkl', 'rb') as f: return pickle.load(f) def GenRatioDepth1(Bus, totalGen): # function which returns the total generation in a depth of one of the bus # as a ratio of the total gen in the system
# get the branch and tf flows from the bus report in descending order from analyzeBusReportFnv2 import BusReport from getBusDataFn import getBusData import math rawfile = 'savnw_dy_sol_0905.raw' BusFlowReport = 'BusReportsavnw_dy_sol_0905.txt' ReportDict = BusReport(BusFlowReport, rawfile) rawBusDataDict = getBusData(rawfile) HVBusSet =set() FlowDict = {} for Bus in rawBusDataDict: BusVolt = float(rawBusDataDict[Bus].NominalVolt) BusType = rawBusDataDict[Bus].type if BusVolt >= 34.5: # no need to consider type 4 buses since they are already filtered out in the get Bus Data function HVBusSet.add(Bus) # generate the HV bus set for Bus in rawBusDataDict: BusVolt = float(rawBusDataDict[Bus].NominalVolt) BusType = rawBusDataDict[Bus].type if BusVolt >= 34.5: # no need to consider type 4 buses since they are already filtered out in the get Bus Data function HVBusSet.add(Bus) for Bus in ReportDict: if Bus not in HVBusSet: continue neighbours = ReportDict[Bus].toBusList for i in range(len(neighbours)): nBus = neighbours[i] if nBus not in HVBusSet:
# write a script which organizes all the generator angle data during (apparent) steady state # this will help with determining the type of oscillation (none, poorly damped oscillation, angle separation) from getBusDataFn import getBusData import csv class EventGenAngles(): def __init__(self): self.GenDict = {} organizedEventDict = {} BusDataDict = getBusData('savnw.raw') genbustypes = ['2', '3'] ### # gather angles for all the simulations (before any gen trip was applied) # for i in range(1,10): # #print('Loop {} out of 9'.format(i)) # # get the event list # currentEventFile = 'obj/eventKeys_{}.csv'.format(i) # currentEventList = [] # with open(currentEventFile,'r') as f: # fileLines = f.read().split('\n') # for line in fileLines: # if line == '': # continue # currentEventList.append(line) # # start reading the angle data
def runPSSESimBatches(simList, dyrFile, objName): import sys, os # add psspy to the system path sys.path.append(r"C:\Program Files (x86)\PTI\PSSE33\PSSBIN") os.environ['PATH'] = (r"C:\Program Files (x86)\PTI\PSSE33\PSSBIN;" + os.environ['PATH']) from contextlib import contextmanager import StringIO from getBusDataFn import getBusData @contextmanager def silence(file_object=None): #Discard stdout (i.e. write to null device) or #optionally write to given file-like object. if file_object is None: file_object = open(os.devnull, 'w') old_stdout = sys.stdout try: sys.stdout = file_object yield finally: sys.stdout = old_stdout if file_object is None: file_object.close() # Local imports import redirect import psspy import dyntools # getting the raw file ##### Get everything set up on the PSSE side redirect.psse2py() #output = StringIO.StringIO() with silence(): psspy.psseinit(buses=80000) _i = psspy.getdefaultint() _f = psspy.getdefaultreal() _s = psspy.getdefaultchar() # some important parameters FaultRpu = 1e-06 Sbase = 100.0 EventsDict = {} for event in simList: eventWords = event.split('/') RawFileIndicator = eventWords[0].strip() linesOutage = eventWords[1].strip() FaultBus = eventWords[2].strip()[ 1:] # exclude the 'F' at the beginning # get the raw file if RawFileIndicator == '100': rawFile = 'savnw_conp.raw' else: rawFile = 'savnw_conp{}.raw'.format(RawFileIndicator) #Parameters. CONFIGURE THIS settings = { # use the same raw data in PSS/E and TS3ph ##################################### 'filename': rawFile, #use the same raw data in PSS/E and TS3ph ################################################################################ 'dyr_file': dyrFile, 'out_file': 'output2.out', 'pf_options': [ 0, #disable taps 0, #disable area exchange 0, #disable phase-shift 0, #disable dc-tap 0, #disable switched shunts 0, #do not flat start 0, #apply var limits immediately 0, #disable non-div solution ] } output = StringIO.StringIO() with silence(output): ierr = psspy.read(0, settings['filename']) #This is for the power flow. I'll use the solved case instead ierr = psspy.fnsl(settings['pf_options']) ##### Prepare case for dynamic simulation # Load conversion (multiple-step) psspy.conl(_i, _i, 1, [0, _i], [_f, _f, _f, _f]) # all constant power load to constant current, constant reactive power load to constant admittance # standard practice for dynamic simulations, constant MVA load is not acceptable psspy.conl(1, 1, 2, [_i, _i], [100.0, 0.0, 0.0, 100.0]) psspy.conl(_i, _i, 3, [_i, _i], [_f, _f, _f, _f]) ierr = psspy.cong(0) #converting generators ierr = psspy.ordr(0) #order the network nodes to maintain sparsity ierr = psspy.fact() #factorise the network admittance matrix ierr = psspy.tysl(0) #solving the converted case ierr = psspy.dynamicsmode(0) #enter dynamics mode print "\n Reading dyr file:", settings['dyr_file'] ierr = psspy.dyre_new([1, 1, 1, 1], settings['dyr_file']) ierr = psspy.docu( 0, 1, [0, 3, 1]) #print the starting point of state variables # select time step ############################################################## ierr = psspy.dynamics_solution_params( [_i, _i, _i, _i, _i, _i, _i, _i], [_f, _f, 0.00833333333333333, _f, _f, _f, _f, _f], 'out_file') # the number here is the time step ################################################################################ ##### select channels ierr = psspy.delete_all_plot_channels() # clear channels BusDataDict = getBusData(rawFile) # get all the bus voltages, angles and frequencies for bus in BusDataDict: bus = int(bus) ierr = psspy.voltage_and_angle_channel([-1, -1, -1, bus]) ierr = psspy.bus_frequency_channel([-1, bus]) print 'Event: {}'.format(event) # get the nominal voltages as well as the fault impedance in ohms FaultBusNomVolt = float(BusDataDict[str(FaultBus)].NominalVolt) Zbase = FaultBusNomVolt**2 / Sbase # float since Sbase is a float Rohm = FaultRpu * Zbase # fault impedance in ohms # run simulation till just before the fault ResultsDict = {} # get the line params line1Elements = linesOutage.split(';')[0].strip() line2Elements = linesOutage.split(';')[1].strip() # Line 1 params line1 = line1Elements.split(',') L1Bus1 = int(line1[0].strip()) L1Bus2 = int(line1[1].strip()) L1cktID = line1[2].strip("'").strip() #print L1Bus1 #print L1Bus2 #print L1cktID # Line 2 params line2 = line2Elements.split(',') L2Bus1 = int(line2[0].strip()) L2Bus2 = int(line2[1].strip()) L2cktID = line2[2].strip("'").strip() #print L2Bus1 #print L2Bus2 #print L2cktID #output = StringIO.StringIO() with silence(output): ierr = psspy.strt(0, settings['out_file']) ierr = psspy.run(0, 0.1, 1, 1, 1) ierr = psspy.dist_branch_trip(L1Bus1, L1Bus2, L1cktID) #output = StringIO.StringIO() with silence(output): ierr = psspy.run(0, 0.2, 1, 1, 1) #fault on time outputStr = output.getvalue() if "Network not converged" in outputStr: print 'For ' + event + ':' print 'Network did not converge between branch 1 trip and fault application, skipping...' continue ####### # check for convergence during fault #output = StringIO.StringIO() with silence(output): ierr = psspy.dist_bus_fault(int(FaultBus), 3, 0.0, [Rohm, 0.0]) ierr = psspy.run(0, 0.3, 1, 1, 1) #fault off time ierr = psspy.dist_clear_fault(1) outputStr = output.getvalue() if "Network not converged" in outputStr: print 'For ' + event + ':' print 'Network did not converge during fault, skipping...' continue # check for convergence between fault clearance and second branch trip #output = StringIO.StringIO() with silence(output): ierr = psspy.run(0, 0.31, 1, 1, 1) #fault off time ierr = psspy.dist_branch_trip(L2Bus1, L2Bus2, L2cktID) ierr = psspy.run(0, 0.35, 1, 1, 1) #fault off time # check for non-convergence #output = StringIO.StringIO() outputStr = output.getvalue() if "Network not converged" in outputStr: print 'For ' + event + ':' print 'Network did not converge between fault clearance and branch 2 trip, skipping...' continue # select run time ############################################################## #output = StringIO.StringIO() with silence(output): ierr = psspy.run(0, 10.0, 1, 1, 1) #exit time (second argument is the end time) ################################################################################ # check for non-convergence outputStr = output.getvalue() if "Network not converged" in outputStr: print 'For ' + event + ':' print 'Network did not converge sometime after 2nd branch trip, skipping...' continue # write to output file #with open('outputTmp.txt','w') as f: # f.write(outputStr) outputData = dyntools.CHNF(settings['out_file']) data = outputData.get_data() channelDict = data[ 1] # dictionary where the value is the channel description valueDict = data[ 2] # dictionary where the values are the signal values, keys match that of channelDict tme = valueDict['time'] # get time ResultsDict['time'] = tme for key in channelDict: if key == 'time': continue signalDescr = channelDict[key] words = signalDescr.split() signalType = words[0].strip() bus = words[1].strip() #print Bus + ' ' + signalType if bus not in ResultsDict: ResultsDict[bus] = Results() if signalType == 'VOLT': ResultsDict[bus].volt = valueDict[key] elif signalType == 'ANGL': ResultsDict[bus].angle = valueDict[key] elif signalType == 'FREQ': ResultsDict[bus].freq = valueDict[key] EventsDict[event] = ResultsDict return EventsDict
from getCAPESubstationDict import SubStationDictNew # key: substation name, value: list of all buses (new bus numbers) belonging to the substation from findPathTo345Fn import generate345PathList from getTFDataFn import getTFData from writeFileFn import writeToFile from generateNeighboursFn import getNeighbours from getBranchGroupFn import makeBranchGroups CAPERaw = 'RAW0602.raw' changeLog = 'changeBusNoLog.txt' Imp138PathFile = 'Imp138PathFile.txt' directTFConnFile = 'directTFConnFile.txt' AllToBeMappedFile = 'AllToBeMappedFile.txt' ArtificialLoadBusFile = 'ArtificialLoadBusFile.txt' Imp138PathSet = set() Imp138Depth1Set = set() CAPEBusDataDict = getBusData(CAPERaw) CAPENeighboursDict = getNeighbours(CAPERaw) ArtificialLoadBusSet = set() necessaryMidpointSet = set() # set of tf midpoints which need to be there ParentDict = {} AllToBeMappedSet = set() # All the non-345 comed buses to be mapped toGetPathSet = set( ) # set of 138 kV belonging to the 3 SVC substations, from which we need to get paths to 345 OldToNewBusDict = {} # key: new CAPE bus number, old: old CAPE bus number # get the path from the three 138 kV substations where the SVCs are at, to nearest 345 impSubStationList = [ 'TSS 135 ELMHURST', 'TSS 117 PROSPECT HEIGHTS', 'STA 13 CRAWFORD' ] AllToBeMappedLines = [] OldBusSet = set() directTFConnLines = []
# check to see if the sort idea to get correct nomv and windv values work. Good news, they do work from getBusDataFn import getBusData ThreeWToThreeWSubFile = 'All3wTo3wSubDataCleaned_Mod.txt' PSSErawFile = 'hls18v1dyn_new.raw' CAPERaw = 'RAW0620.raw' changeLog = 'changeBusNoLog.txt' planningBusDataDict = getBusData(PSSErawFile) CAPEBusDataDict = getBusData(CAPERaw) changeNameDictOldToNew = {} # look at log files which contains all the changed bus numbers in the previous iteration (first time i did this) with open(changeLog, 'r') as f: filecontent = f.read() fileLines = filecontent.split('\n') for line in fileLines: if 'CAPE' in line: continue words = line.split('->') if len(words) < 2: continue OldBus = words[0].strip() NewBus = words[1].strip() changeNameDictOldToNew[OldBus] = NewBus # get relevant data (no change and 3w->3w cases) from this file with open(ThreeWToThreeWSubFile, 'r') as f: filecontent = f.read() fileLines = filecontent.split('\n') for line in fileLines: if '->' not in line: continue
# write a function which will match up all the non-midpoint bus data in Raw_cropped and output before 3w -> 2w conversion # this function should be called after tap splits # also write a function which compares tf data from getBusDataFn import getBusData scriptOutputRaw = 'Raw0706.raw' croppedRaw = 'RAWCropped_latest.raw' AllToBeMappedFile = 'AllToBeMappedFile.txt' AllToBeMappedSet = set() scriptOutputBusDataDict = getBusData(scriptOutputRaw) croppedRawBusDataDict = getBusData(croppedRaw) #scriptOutputBusDataDict = {} #croppedRawBusDict = {} # get the necessary comed buses whose voltage value is less than 345 kV with open(AllToBeMappedFile, 'r') as f: filecontent = f.read() fileLines = filecontent.split('\n') # grab bus data for line in fileLines: if line == '': continue if 'List of buses' in line: # skip the header file continue words = line.split(',') Bus = words[0].strip() AllToBeMappedSet.add(Bus) for Bus in croppedRawBusDataDict: if Bus in AllToBeMappedSet:
# find all the 40 kV or lower buses which are causing significant mismatch ( > 500 MVA) and which have step up tf connections # also these tf cannot be mapped initially (by the CS guys) import sys sys.path.insert( 0, 'C:/Users/Bikiran/Google Drive/Bus Mapping Project Original/Donut Hole Approach/Donut Hole v2' ) from getTFDataFn import getTFData from getBusDataFn import getBusData CAPERaw = 'RAW0509.raw' manualMapFile = 'C:/Users/Bikiran/Google Drive/Bus Mapping Project Original/Donut Hole Approach/Donut Hole v2/' + 'mapped_buses_cleaned0407.csv' sortedMismatchData = 'sortedMismatchData0509.txt' TFDataDict = getTFData(CAPERaw) # get TF data BusDataDict = getBusData(CAPERaw) # get Bus data ManualMapDict = {} # get the manual maps with open(manualMapFile, 'r') as f: filecontent = f.read() fileLines = filecontent.split('\n') for line in fileLines: words = line.split(',') if len(words) < 2: continue PSSEBus = words[0].strip() CAPEBus = words[5].strip() PSSEBusCode = words[2].strip() if 'M' in PSSEBusCode: continue if PSSEBus in ['NA', '']: continue
from getBusDataFn import getBusData print 'Reading the csv files' vFileName = 'fault3ph/vData3phLI.csv' # csv file containing voltage data (different types of fault) tFileName = 'fault3ph/tData3ph.csv' # csv file containing the time data eventKeyFile = 'fault3ph/eventIDFileLI.txt' vFile = open(vFileName, 'rb') tFile = open(tFileName, 'rb') readerV = csv.reader(vFile, quoting=csv.QUOTE_NONNUMERIC ) # so that the entries are converted to floats readerT = csv.reader(tFile, quoting=csv.QUOTE_NONNUMERIC) tme = [row for idx, row in enumerate(readerT) if idx == 0][0] ##### get a random set of buses where to place the PMUs refRaw = 'savnw.raw' BusDataDict = getBusData(refRaw) tapbuslist = ['3007', '204'] buslist = [bus for bus in BusDataDict.keys() if bus not in tapbuslist] numBuses = len(buslist) PMUBuses = random.sample(buslist, 4) ##### # get the indices for fault on and fault off faultontime = 0.1 #timesteps = 40 #timesteps = 10 #timesteps = 20 timesteps = 30 numcyc = 6 shiftRange = 5
import sys sys.path.insert( 0, 'C:/Users/Bikiran/Google Drive/Bus Mapping Project Original/Donut Hole Approach/Donut Hole v2' ) from generateBranchNeighboursFn import generateNeighbours from getBusDataFn import getBusData planningRaw = 'hls18v1dyn_new.raw' _, BranchDataDictPlanning = generateNeighbours(planningRaw) BusDataDictPlanning = getBusData(planningRaw) branchGroupLines = [] TieDict = {} for key in BranchDataDictPlanning.keys(): #RList = BranchDataDictPlanning[key].R ZList = BranchDataDictPlanning[key].Z Bus1 = key Bus2List = BranchDataDictPlanning[key].toBus # Get pairs of buses which have same voltage and angles """ Bus1VoltAngle = [float(BusDataDictPlanning[Bus1].voltpu), float(BusDataDictPlanning[Bus1].angle)] for Bus2 in Bus2List: Bus2VoltAngle = [float(BusDataDictPlanning[Bus2].voltpu), float(BusDataDictPlanning[Bus2].angle)] if Bus1VoltAngle == Bus2VoltAngle: print Bus1 + ',' + Bus2 """