package org.ieee.odm.adapter.pwd.impl; import org.ieee.odm.adapter.pwd.InputLineStringParser; import org.ieee.odm.adapter.pwd.PWDAdapterForContingency.ContingencyType; import org.ieee.odm.common.ODMException; import org.ieee.odm.common.ODMLogger; import org.ieee.odm.model.IODMModelParser; import org.ieee.odm.model.aclf.AclfModelParser; import org.ieee.odm.model.base.ODMModelStringUtil; import org.ieee.odm.model.modify.NetModificationHelper; import org.ieee.odm.schema.BranchChangeRecSetXmlType; import org.ieee.odm.schema.BranchChangeRecXmlType; import org.ieee.odm.schema.BranchOutageEnumType; import org.ieee.odm.schema.NetModificationXmlType; /** * PWD contingency file data processor * * @version 0.2 09/30/2012 * @author Tony Huang * ======History====== * 09/30/12 Change from NVPair list to PWDDataParser * custom string for outage is saved in bus/branch description * */ public class ContingencyDataProcessor extends InputLineStringParser{ private NetModificationXmlType netModList=null; private NetModificationHelper helper=null; private BranchChangeRecSetXmlType branchTypeCtg=null; boolean skipCtg=false; boolean isCTGSubDataSection=false; private AclfModelParser parser = null; public ContingencyDataProcessor(AclfModelParser parser) { this.parser = parser; // initialization // create empty base network parser.getNet(); // create net modification helper. A contingency is corresponding to a modification record // The helper save the contingencies to a modification record list. helper = new NetModificationHelper(parser); // create a container for bus/branch-change type contingency records netModList = helper.createNetModificationList("ContingencyList", "Created from PWD contingency file"); } public void processContingencyData(String ctgStr){ /* * DATA (CONTINGENCY,[CTGLabel,CTGSkip,CTGProc,CTGSolved,LoadMW,CustomString]) { "005A" "NO " "NO" "NO" 0.0 "88005A-1-2/8804A/88006A-1/1780" <SUBDATA CTGElement> "BRANCH 7514 7512 1 OPEN" "" CHECK //WOODMONT CB 29Y-1T-2 * "BRANCH 7750 7752 1 OPEN" "" CHECK //DEVON_T CB 16P-1T-2 * "BRANCH 7750 7756 1 OPEN" "" CHECK //DEVON_T CB 16P-4T-2 * "BRANCH 7536 7535 1 OPEN" "" CHECK //MILVON CB 6850A * "BRANCH 7522 7524 1 OPEN" "" CHECK //WOODMONT CB 6840A * </SUBDATA> */ // First need to check whether or not the data input is CTGElement Data if(ctgStr.trim().startsWith("<SUBDATA")){ isCTGSubDataSection=true; return; } else if(ctgStr.trim().startsWith("</SUBDATA>")){ isCTGSubDataSection=false; return; } // if(!isCTGSubDataSection){ parseData(ctgStr); //process basic contingency definition data, including Table, ModelCriteria processBasicCTGData(); } else processCTGElementData(ctgStr); } private void processBasicCTGData() { String ctgId=""; String ctgInfo=""; // create a branch change set object to represent a contingency try { if(exist("CTGSkip")) skipCtg=getString("CTGSkip").trim().equalsIgnoreCase("NO")?false:true; ctgId =getString("CTGLabel"); if(exist("CustomString")) ctgInfo=getString("CustomString"); //Only for this project } catch (ODMException e) { ODMLogger.getLogger().severe(e.toString()); } if(!skipCtg){ branchTypeCtg = helper.createBranchChangeRecSetXmlType(netModList); branchTypeCtg.setId(ctgId); branchTypeCtg.setDesc(ctgInfo); } } private void processCTGElementData(String str) { String action=""; String comment=""; //TODO process the following CTGElement Data if skipCtg=false if(!skipCtg){ //first process the comment int cmtIndex=str.indexOf("//"); if(cmtIndex!=-1){ comment=str.substring(cmtIndex+1); str=str.substring(0, cmtIndex); } //parse CTGElement Data /* * return format[Action,ModelCriteria,status], since the comment has been subtracted; */ String[] ctgElement= parseDataFields(str); action=ctgElement[0]; //get Branch info, format[branchId, status,fromId, toId, cirId] String[] braInfo=getNetModelChangeInfo(action,ContingencyType.BRANCH); if (braInfo != null) { // for each contingency, one to many branch change could be defined BranchChangeRecXmlType branchChange = helper.createBranchChangeRecXmlType(branchTypeCtg); branchChange.setBranchId(braInfo[0]); branchChange.setOutage(braInfo[1].equalsIgnoreCase("OPEN")?BranchOutageEnumType.OPEN:BranchOutageEnumType.CLOSE); branchChange.setFromBusId(braInfo[2]); branchChange.setToBusId(braInfo[3]); branchChange.setCircuitId(braInfo[4]); //comment if(comment.length()>1)branchChange.setDesc(comment); } } } private void isCTGElementData(String str, boolean isCTGSubDataSection) { if(str.trim().startsWith("<SUBDATA")){ isCTGSubDataSection=true; return; } else if(str.trim().startsWith("</SUBDATA>")){ isCTGSubDataSection=false; return; } } private String[] getNetModelChangeInfo(String actionStr,ContingencyType type) { String[] info=null; if(actionStr!=null&&!actionStr.trim().isEmpty()){ if(type==ContingencyType.BRANCH){ String[] temp=actionStr.split(" "); if(!temp[0].equals("BRANCH")){ ODMLogger.getLogger().severe("Input data is not BRANCH type contingency!"); return null; } long fromBusNum=Long.valueOf(temp[1]); long toBusNum=Long.valueOf(temp[2]); String cirId=temp[3]; String fromId=IODMModelParser.BusIdPreFix+fromBusNum; String toId=IODMModelParser.BusIdPreFix+toBusNum; String branchId=ODMModelStringUtil.formBranchId(fromId, toId,cirId ); String status=temp[4]; info=new String[5]; info[0]=branchId; info[1]=status; info[2]=fromId; info[3]=toId; info[4]=cirId; } else ODMLogger.getLogger().severe("Error: wrong contingency type"); } return info; } }