/*
* spiceParsers.java
*Copyright (C) 2006 Kurt M Peters
* Ver 0.10
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* Created on July 29, 2005, 1:09 PM
*
Change Log
* =================================================
* Created on February 10, 2006, 2:57 PM - first revision Ver. 0.6
*
* 13 Feb 2006 - fixed error where it was throwing out first line in
* loadparseCIRFile line 772.
* Added a line to write to the CIR StyleDocument
* 04 Mar 2006 - Added variable type parser to give int for type of variable
* found. Should make useable for SPICE2 eventually as well.
* 07 Mar 2006 - Changed loop determining the header to look for "Variables"
* name to leave loop in ASCII header
* 22 Oct 2006 - Removed code to import the whole data file initially
* Added getRawDataSelected and addAnalysistoScreen
* allowing completion of these changes
* 30 Dec 2006 - Refined graph display function to allow displaying results
*
* 03 Dec 2007 - Added GnuCap support
*
*/
package spicefe;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Stroke;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.AxisLocation;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.StandardXYItemRenderer;
import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;
import org.w3c.dom.Document;
import org.w3c.dom.DOMException;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.w3c.dom.Node;
import org.w3c.dom.NamedNodeMap;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.FactoryConfigurationError;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParserFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import org.xml.sax.*;
import org.xml.sax.helpers.AttributesImpl;
import java.util.*;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.tree.*;
import javax.swing.JOptionPane;
import org.xml.sax.*;
import org.xml.sax.helpers.DefaultHandler;
import org.xml.sax.helpers.AttributesImpl;
import java.io.*;
import java.util.regex.*;
import javax.swing.SwingWorker;
import javax.swing.text.*;
//import DeviceSet.*;
/**
* This is a Utility Class to parse
* various possible Spice Files
* @author Kurt M Peters
* @version 0.7
*
* ChangeLog
* 13 Feb 2006 - fixed
* 04 Mar 2006 - additional parser
* 12 Nov 2010 - made this threaded to return back to the control screen and have busy cursor
*/
public class SpiceParsers extends SwingWorker<ArrayList<WholeAnalysisSet>, Void>{
static int ALLPORTS= 0;
static int FIRSTLETTER= 0;
static int ELEMENT= 1;
static int NUMBEROFTERMINALS= 1;
static int TERMINALNAMES= 2;
static int ACTION= 3;
static int COMMANDS= 6;
static int RAWCOMMAND= 7;
static int WRITELENGTH= 8;
static int READLENGTH = 9;
static int LEADCHARACTER = 3;
static int FULLDESCRIPTION= 4;
final static int TIME = 1;
final static int FREQUENCY= 2;
final static int VOLTAGE= 3;
final static int CURRENT= 4;
final static int SPICERAWFILE =0;
final static int GNUCAPRAWFILE = 1;
/**
* These are "Actions" that will be taken for
* for each possible component being read in.
* These have the attribute "Action" in the XML
* file.
* This is the Regular Device with a constant number of terminals
*/
public final static int REGULARDEVICE= 0; //essentially all others
/**
* This is the command card, or the period prefix "."
*/
public final static int COMMANDCARD= 1; // .
/**
* This is the "X" prefix and is special because it can have any number
* of terminals followed by the SUBCKT name
*/
public final static int SUBCIRCUIT= 2; // X
/**
* This is the comment line "*"
*/
public final static int COMMENT= 3; // *
private static int internalsubckt = 0;
static final String[] typeName = {
"none",
"Element",
"Attr",
"Text",
"CDATA",
"EntityRef",
"Entity",
"ProcInstr",
"Comment",
"Document",
"DocType",
"DocFragment",
"Notation"
};
static final String[] leafsNodes = {
"Device",
"NumberofTerminals",
"TerminalNames",
"Action",
"parity",
"stopbits",
"Commands",
"RawCommand",
"Writelength",
"Readlength"
};
static final String[] attributeDevice = {
"FirstLetter",
"Element",
"InterExt",
"LeadCharacter",
"FullDescription"
};
private File RAWFile =null;
private int typeOfLoad = SPICERAWFILE;
/** Creates a new instance of GetConfigItems */
public SpiceParsers(File RAWFile, int typeOfLoad) {
this.RAWFile = RAWFile;
this.typeOfLoad = typeOfLoad;
}
/**
* This parses the possible SPICE devices stored in a XML file:
* <?xml version='1.0' encoding='US-ASCII' standalone="yes"?>
* <AllDevices>
* <Device FirstLetter="C" Element="Capacitor">
* <NumberofTerminals>2</NumberofTerminals>
* <TerminalNames>+ -</TerminalNames>
* <Action>0</Action>
* </Device>
* </AllDevices>
* @param configfile File - file name of the XML config file
* @return java.util.TreeMap<String, DevicesSet> A Map consisting of the
* first letter as the Key and DeviceSet as the value.
*/
public static java.util.TreeMap<String, DevicesSet> parseConfigFile(File configfile) { // throws IOException, SAXException
Document document = null;
NodeList portsDefined =null;
DevicesSet tempDH =null;
int jj=1;
java.util.TreeMap<String, DevicesSet> SpiceDevices = new java.util.TreeMap<String, DevicesSet>();
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
//factory.setValidating(true);
factory.setCoalescing(false);
factory.setNamespaceAware(true);
int ii = 0;
try {
DocumentBuilder builder = factory.newDocumentBuilder();
document = builder.parse( configfile );
} catch (SAXException sxe) {
// Error generated during parsing)
Exception x = sxe;
if (sxe.getException() != null)
x = sxe.getException();
x.printStackTrace();
} catch (ParserConfigurationException pce) {
// Parser with specified options can't be built
pce.printStackTrace();
} catch (IOException ioe) {
// I/O error
ioe.printStackTrace();
}
document.normalize();
if (document.hasChildNodes()) {
//writeNode(document); ///document
Node AllDevices = document.getFirstChild();
//System.out.println("AllDevices Child.");
//writeNode(AllDevices); //AllPorts
//System.out.println("||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||\n");
if (AllDevices.hasChildNodes()) {
NodeList devicesBroughtIn = AllDevices.getChildNodes();
for (ii=0;ii<devicesBroughtIn.getLength();ii++) {
if (devicesBroughtIn.item(ii).getNodeType()==Node.ELEMENT_NODE) {
// These are successful ports
//writeNode(portsBroughtIn.item(ii));
//followNode(devicesBroughtIn.item(ii));
if (devicesBroughtIn.item(ii).hasAttributes()) {
NamedNodeMap moreAttr = devicesBroughtIn.item(ii).getAttributes();
//Now that we've gotten to actual data in node this can be used to get attributes at Constant locations
//System.out.println("picked out has attribute: " + moreAttr.getNamedItem(attributeDevice[ELEMENT]).getNodeName() + " with value: "+moreAttr.getNamedItem(attributeDevice[ELEMENT]).getNodeValue()+"\n");
//System.out.println("picked out has attribute: " + moreAttr.getNamedItem(attributeDevice[FIRSTLETTER]).getNodeName() + " with value: "+moreAttr.getNamedItem(attributeDevice[FIRSTLETTER]).getNodeValue()+"\n");
tempDH = new DevicesSet( moreAttr.getNamedItem(attributeDevice[FIRSTLETTER]).getNodeValue().trim(),
moreAttr.getNamedItem(attributeDevice[ELEMENT]).getNodeValue().trim(),
Integer.valueOf(getNamedValue(devicesBroughtIn.item(ii), leafsNodes[NUMBEROFTERMINALS]).trim()),
getNamedValue(devicesBroughtIn.item(ii),leafsNodes[TERMINALNAMES]).trim(),
Integer.valueOf(getNamedValue(devicesBroughtIn.item(ii), leafsNodes[ACTION]).trim()));
//for (int jj = 0;jj< moreAttr.getLength();jj++) {
//writeNode(getNamedNode(devicesBroughtIn.item(ii), leafsNodes[COMMANDS]));
//fillInCommands(getNamedNode(devicesBroughtIn.item(ii), leafsNodes[COMMANDS]), leafsNodes[RAWCOMMAND], tempDH);
//System.out.println(" has attribute: " + moreAttr.item(jj).getNodeName() + " with value: "+moreAttr.item(jj).getNodeValue()+"\n");
//}
}
SpiceDevices.put(tempDH.toString(),tempDH);
}
}
}
}
//Node nextNode = node.getNextSibling();
/*
try {
followNode(document);
} catch (NullPointerException e) {
}
*/
return SpiceDevices;
}
/**
* This is a legacy to help debug
* @param node Node
* @param name String: Name
* @param devHandler Not used deprectated
* @throws java.lang.NullPointerException NullPointerException
*/
public void fillInCommands(Node node, String name, DevicesSet devHandler) throws NullPointerException {
int ii =0;
NodeList listOfChildren = node.getChildNodes();
NodeList finalChild = null;
//writeNode(node);
for (ii=0;ii<listOfChildren.getLength();ii++){
if (listOfChildren.item(ii).getNodeType()==Node.ELEMENT_NODE && listOfChildren.item(ii).getNodeName().equals(name)){
//System.out.println("got here");
NamedNodeMap moreAttr = listOfChildren.item(ii).getAttributes();
finalChild = listOfChildren.item(ii).getChildNodes();
//System.out.println( finalChild.item(0).getNodeValue().trim());
//System.out.println( getNamedValue(listOfChildren.item(ii), leafsNodes[WRITELENGTH]));
//System.out.println( getNamedValue(listOfChildren.item(ii), leafsNodes[READLENGTH]));
//System.out.println(moreAttr.getNamedItem(attributePort[FULLDESCRIPTION]).getNodeValue());
devHandler.addDevice(finalChild.item(0).getNodeValue().trim(),
moreAttr.getNamedItem(attributeDevice[ELEMENT]).getNodeValue().trim(),
Integer.valueOf(getNamedValue(listOfChildren.item(ii), leafsNodes[NUMBEROFTERMINALS]).trim()),
getNamedValue(listOfChildren.item(ii), leafsNodes[TERMINALNAMES]).trim(),
Integer.valueOf(getNamedValue(listOfChildren.item(ii), leafsNodes[ACTION]).trim()));
}
}
}
/**
* This helps debug the XML file.
* @param node Node
* @param name String
* @return String
* @throws java.lang.NullPointerException Throws NullpointerException
*/
public static String getNamedValue(Node node, String name) throws NullPointerException {
int ii =0;
NodeList listOfChildren = node.getChildNodes();
NodeList finalChild = null;
//writeNode(node);
for (ii=0;ii<listOfChildren.getLength();ii++){
if (listOfChildren.item(ii).getNodeType()==Node.ELEMENT_NODE && listOfChildren.item(ii).getNodeName().equals(name)){
//System.out.println("got here");
finalChild = listOfChildren.item(ii).getChildNodes();
return finalChild.item(0).getNodeValue();
}
}
return (String) null;
}
/**
* Returns the node with a name "name"
* @param node Node
* @param name String
* @return Node
* @throws java.lang.NullPointerException Throws NullPointerException
*/
public Node getNamedNode(Node node, String name) throws NullPointerException {
int ii =0;
NodeList listOfChildren = node.getChildNodes();
NodeList finalChild = null;
//writeNode(node);
for (ii=0;ii<listOfChildren.getLength();ii++){
if (listOfChildren.item(ii).getNodeType()==Node.ELEMENT_NODE && listOfChildren.item(ii).getNodeName().equals(name)){
return listOfChildren.item(ii);
}
}
return (Node) null;
}
/**
* Returns the Java type of the node.
* @param node Node
* @return String
*/
public static String getTypeName(Node node) {
int type = node.getNodeType();
/* Yes, getNodeType() returns a short, but Java will
almost always upcast this short to an int before
using it in any operation, so we might as well just go
ahead and use the int in the first place. */
if (type<13)
return typeName[type];
else
return "Unknown";
}
/**
* Helps debug by printing information about a Node
* @param node node
* @throws java.lang.NullPointerException Throws NullPointerException if the input node is null
*/
public void writeNode(Node node) throws NullPointerException {
if (node == null) {
throw new NullPointerException("Node must be non-null.");
}
if (node.getNodeType() == Node.DOCUMENT_NODE
|| node.getNodeType() == Node.DOCUMENT_FRAGMENT_NODE) {
// starting a new document, reset the node count
}
String name = node.getNodeName(); // never null
String type = getTypeName(node); // never null
String localName = node.getLocalName();
String uri = node.getNamespaceURI();
String prefix = node.getPrefix();
String value = node.getNodeValue();
StringBuffer result = new StringBuffer();
result.append(" Type: " + type + "\r\n");
result.append(" Name: " + name + "\r\n");
if (localName != null) {
result.append(" Local Name: " + localName + "\r\n");
}
if (prefix != null) {
result.append(" Prefix: " + prefix + "\r\n");
}
if (uri != null) {
result.append(" Namespace URI: " + uri + "\r\n");
}
if (value != null) {
result.append(" Value: " + value + "\r\n");
}
if (node.hasAttributes()) {
NamedNodeMap moreAttr = node.getAttributes();
for (int ii = 0;ii< moreAttr.getLength();ii++) {
result.append(" has attribute: " + moreAttr.item(ii).getNodeName() + " with value: "+moreAttr.item(ii).getNodeValue()+"\n");
}
}
if (node.hasChildNodes()) {
result.append(node.getChildNodes().getLength()+ " is number of children.\n");
}
System.out.println(result.toString());
}
/**
* Recursive routine to follow the nodes all the way down.
* Uses writeNode to output the information.
* @param node Node
* @throws java.lang.NullPointerException NullPointerException if input is null
*/
public void followNode(Node node) throws NullPointerException {
if (node == null) {
throw new NullPointerException("Node must be non-null.");
}
writeNode(node);
if (node.hasChildNodes()) {
Node firstChild = node.getFirstChild();
System.out.println("Child of "+node.getNodeName());
followNode(firstChild);
}
Node nextNode = node.getNextSibling();
if (nextNode != null) followNode(nextNode);
}
/**
* Node used
* @param configfile File
* @param jCBCommandList A ComboBox that you want the confile file's contents to be placed in
*/
public void readcommandfile(File configfile, javax.swing.JComboBox jCBCommandList) {
StringBuffer readBuffer = new StringBuffer(1024);
String str;
AttributesImpl atts = null;
Matcher m;
java.util.regex.Pattern p = java.util.regex.Pattern.compile("\\[Commands\\]([^\\[]+)\\[");
StringBuffer sbtemp = new StringBuffer();
boolean b;
int ii=0;
int k;
int wafer;
float value;
String widefield = null;
String nsu = ""; // NamespaceURI
String indent1 = "\n "; // for readability!
String indent2 = "\n "; // for readability!
String indent3 = "\n "; // for readability!
ContentHandler handler = null;
/** Read the file from the directory specified
* currently c:\workpspace
*/
System.out.print("\n\n* Continuing PROGRAM OUTPUT *\nConfig file "+configfile.canRead()+" can be read again.\n");
try {
BufferedReader in = new BufferedReader(new FileReader(configfile));
while ((str = in.readLine()) != null) {
readBuffer.append(str);
readBuffer.append("\n");
}
in.close();
} catch (IOException e) {
}
//System.out.print(readBuffer.toString()+"\n");
/** Now to find the [PORTS] section and store all of that
* in a stringbuffer for another search of each parameter
*/
m = p.matcher(readBuffer);
if (m.find()) {
//k = m.start();
sbtemp.append(m.group(1));
//System.out.print("Configure items for ports is:\n"+m.group(1)+"\n:::::::\n");
//System.out.print("Total match is:\n"+m.group(0)+"\n:::::::\n");
}
try {
atts.addAttribute( nsu, "PortName", "PortName", "Name", "COM1");
handler.ignorableWhitespace(indent2.toCharArray(),
0, // start index
2
);
handler.startElement(nsu, "Port", "Port", atts);
handler.ignorableWhitespace(indent1.toCharArray(),
0, // start index
indent1.length()
);
atts.clear();
handler.startElement(nsu, "bitrate","bitrate" /*"qName"*/, atts);
handler.characters("9600".toCharArray(),
0,
"9600".length());
handler.endElement(nsu, "bitrate","bitrate");
handler.ignorableWhitespace(indent1.toCharArray(),
0, // start index
indent1.length()
);
handler.startElement(nsu, "bits","bits" /*"qName"*/, atts);
handler.characters("7".toCharArray(),
0,
"7".length());
handler.endElement(nsu, "bits","bits");
handler.ignorableWhitespace(indent1.toCharArray(),
0, // start index
indent1.length()
);
handler.startElement(nsu, "parity","parity" /*"qName"*/, atts);
handler.characters("O".toCharArray(),
0,
"O".length());
handler.endElement(nsu, "parity","parity");
handler.ignorableWhitespace(indent1.toCharArray(),
0, // start index
indent1.length()
);
handler.startElement(nsu, "stopbits","stopbits" /*"qName"*/, atts);
handler.characters("1".toCharArray(),
0,
"1".length());
handler.endElement(nsu, "stopbits","stopbits");
atts.addAttribute( nsu, "LeadCharacter", "LeadCharacter", "LeadCharacter", "*");
atts.addAttribute( nsu, "Address", "Address", "Address", "null");
handler.ignorableWhitespace(indent1.toCharArray(),
0, // start index
indent1.length()
);
handler.startElement(nsu, "Commands", "Commands", atts);
atts.clear();
} catch (Exception e) {
System.out.println("problem writing");
}
p = java.util.regex.Pattern.compile("\\s*([^,]*)\\s*,\\s*([^,]*)\\s*,\\s*([^,]*)\\s*,\\s*([0-9]*)\\s*\\n");
//System.out.println(p.pattern());
m = p.matcher(sbtemp);
/** Fill up combobox and decoder with appropriate information
*/
ii=0;
while (m.find()) {
//for (ii=1;ii<=m.groupCount();ii++) {
//portConfigItems(String name, int rate, int numbits, char par, int sb )
//cmds.put(m.group(1).toUpperCase(), new CommandSet(m.group(2),Integer.parseInt(m.group(3)),Integer.parseInt(m.group(4))));
try {
handler.ignorableWhitespace(indent2.toCharArray(),
0, // start index
indent2.length()
);
atts.addAttribute( nsu, "FullDescription", "FullDescription", "FullDescription", m.group(2));
handler.startElement(nsu, "ThreeLetter","ThreeLetter" /*"qName"*/, atts);
handler.characters(m.group(1).toUpperCase().toCharArray(),
0,
m.group(1).length());
//handler.ignorableWhitespace(indent2.toCharArray(),
// 0, // start index
// indent2.length()
// );
//handler.startElement(nsu, "FullDescription","FullDescription" /*"qName"*/, atts);
//handler.characters(m.group(2).toCharArray(),
// 0,
// m.group(2).length());
//handler.endElement(nsu, "FullDescription","FullDescription");
atts.clear();
handler.ignorableWhitespace(indent3.toCharArray(),
0, // start index
indent3.length()
);
handler.startElement(nsu, "Writelength","Writelength" /*"qName"*/, atts);
handler.characters(m.group(3).toCharArray(),
0,
m.group(3).length());
handler.endElement(nsu, "Writelength","Writelength");
handler.ignorableWhitespace(indent3.toCharArray(),
0, // start index
indent3.length()
);
handler.startElement(nsu, "Readlength","Readlength" /*"qName"*/, atts);
handler.characters(m.group(4).toCharArray(),
0,
m.group(4).length());
handler.endElement(nsu, "Readlength","Readlength");
handler.ignorableWhitespace(indent2.toCharArray(),
0, // start index
indent2.length()
);
handler.endElement(nsu, "ThreeLetter","ThreeLetter");
} catch (Exception e) {
System.out.println("problem parsing.");
}
jCBCommandList.addItem(m.group(2)+" - "+m.group(1).toUpperCase());
//System.out.print("Configure item "+ii+" for command is:\n"+m.group(2)+" - "+m.group(1).toUpperCase()+"\n:::::::\n");
ii++;
//}
//System.out.print("Total group count is:\n"+m.groupCount() +"\n:::::::\n");
//System.out.print("Total match is:\n"+m.group(0)+"\n:::::::\n");
}
//for (String key : cmds.keySet())
// System.out.println(key);
//for (CommandSet O : cmds.values())
// jCBCommandList.addItem(O.getCommandText());
//System.out.println(O.getCommandText());
//The idiom for iterating over values is analogous. Here's the idiom for iterating over key-value pairs:
//for (MapEntry <String, CommandSet> e : cmds.entrySet())
// System.out.println(e.getKey() + ": " + e.getValue());
/*
try{
if (sfile.substring(k-33,k-20).trim().length()!=0)
value = Float.parseFloat(sfile.substring(k-33,k-20).trim());
else
value = 0.0f;
wafer = Integer.parseInt(sfile.substring(k-41,k-39).trim());
lot.addValue(ii, wafer, value);
}
catch(NumberFormatException nfe)
{
System.out.println(nfe);
}
*/
//ports.put(pId.getName(),new portConfigItems(pId.getName()));
m.reset();
try {
handler.ignorableWhitespace(indent1.toCharArray(),
0, // start index
indent1.length()
);
handler.endElement(nsu, "Commands", "Commands");
handler.ignorableWhitespace(indent2.toCharArray(),
0, // start index
2
);
handler.endElement(nsu, "Port", "Port");
handler.ignorableWhitespace(indent2.toCharArray(),
0, // start index
2
);
} catch (Exception e) {
}
}
/**
* Reads a config file
* Deprecated
* @param configfile File
* @throws java.io.IOException Thrown when file error occurs
*/
public void readconfigfile(File configfile) throws IOException {//java.util.TreeMap<String, portConfigItems> ports
StringBuffer readBuffer = new StringBuffer(1024);
String str;
Matcher m;
java.util.regex.Pattern p = java.util.regex.Pattern.compile("\\[Ports\\]([^\\[]+)\\[");
StringBuffer sbtemp = new StringBuffer();
boolean b;
int ii=0;
int k;
int wafer;
float value;
String widefield = null;
/** Read the file from the directory specified
* currently c:\workpspace
*/
if (!configfile.canRead()){
System.out.print("\n\n* START OF PROGRAM OUTPUT *\nConfig file "+configfile.canRead()+" can be read.\n");
throw new IOException("Cannot Read Configuration File.");
} else {
try {
BufferedReader in = new BufferedReader(new FileReader(configfile));
while ((str = in.readLine()) != null) {
readBuffer.append(str);
readBuffer.append("\n");
}
in.close();
} catch (IOException e) {
throw e;
}
//System.out.print(readBuffer.toString()+"\n");
/** Now to find the [PORTS] section and store all of that
* in a stringbuffer for another search of each parameter
*/
m = p.matcher(readBuffer);
if (m.find()) {
//k = m.start();
sbtemp.append(m.group(1));
//System.out.print("Configure items for ports is:\n"+m.group(1)+"\n:::::::\n");
//System.out.print("Total match is:\n"+m.group(0)+"\n:::::::\n");
}
//for (portConfigItems o : ports)
//System.out.println(o.getComPort());
/** Now to find the each port definition and store all of that
* in a portConfigItems for another search of each parameter
*/
p = java.util.regex.Pattern.compile("port\\s*=\\s*([\\w]*)(\\s*bitrate\\s*=\\s*([\\w]*))?(\\s*bits\\s*=\\s*([\\w]*))?(\\s*parity\\s*=\\s*([\\w]*))?(\\s*stopbits\\s*=\\s*([\\w]*))?");
//System.out.println(p.pattern());
m = p.matcher(sbtemp);
//try{
// m.find();
//} catch (IndexOutOfBoundsException e){
//}m.groupCount()>0
//while (m.find()) {
//for (ii=1;ii<=m.groupCount();ii++) {
//portConfigItems(String name, int rate, int numbits, char par, int sb )
//ports.put(m.group(1).toUpperCase(), new portConfigItems(m.group(1),m.group(3),m.group(5),m.group(7),m.group(9)));
//System.out.print("Configure item "+ii+" for port is:\n"+m.group(ii)+"\n:::::::\n");
//}
//System.out.print("Total group count is:\n"+m.groupCount() +"\n:::::::\n");
//System.out.print("Total match is:\n"+m.group(0)+"\n:::::::\n");
//}
/*
try{
if (sfile.substring(k-33,k-20).trim().length()!=0)
value = Float.parseFloat(sfile.substring(k-33,k-20).trim());
else
value = 0.0f;
wafer = Integer.parseInt(sfile.substring(k-41,k-39).trim());
lot.addValue(ii, wafer, value);
}
catch(NumberFormatException nfe)
{
System.out.println(nfe);
}
*/
//ports.put(pId.getName(),new portConfigItems(pId.getName()));
m.reset();
}
}
/**
* Parses a circuit file
* Calls fillInNodes
* @param CIRFile File - SPICE Circuit file
* @param nodeSet Set: (Usually a TreeSet) containing the list of nodes (usually input as empty).
* Will contain the Top-level terminal names found
* @param devicesSet Set: (Usually a TreeSet) containing the list of devices (usually input as empty).
* Will contain the Top-level device names found.
* @param CircuitDoc Styledocument: Styled document that will be written to and will contain
* the raw SPICE file input.
* @param SPICEDevices TreeMap: the Map of the possible devices and actions.
* Usually gotten from parseConfigFile.
*/
public static void loadparseCIRFile(File CIRFile, Set<String> nodeSet, Set<String> devicesSet, StyledDocument CircuitDoc, java.util.TreeMap<String, DevicesSet> SPICEDevices){
// Buffered reader to read CIR file
BufferedReader br;
String bufString =null;
Pattern p = Pattern.compile(";");
// Open the file and display error window if there's an error
try {
br = new BufferedReader(new FileReader(CIRFile));
} catch (FileNotFoundException fnfe) {
JOptionPane.showMessageDialog(null, "Can't read CIR File.\n"+fnfe.toString(),fnfe.toString(),JOptionPane.WARNING_MESSAGE);
System.out.println("Cannot locate input file! "+fnfe.getMessage());
return;
}
nodeSet.clear();
devicesSet.clear();
try {
CircuitDoc.remove(0,CircuitDoc.getLength());
} catch (BadLocationException ble) {
System.err.println("Couldn't insert initial text into text pane.");
}
javax.swing.text.DefaultEditorKit dek = new javax.swing.text.DefaultEditorKit();
//A non-whitespace character: [^\s]
//Get the First Line
try {
bufString = br.readLine(); //Throw out the first line which should be the title
if (bufString!=null)
CircuitDoc.insertString(CircuitDoc.getLength(),bufString + "\n", CircuitDoc.getStyle("Courier New"));
bufString = br.readLine(); //This is the first line of usable circuitry
} catch (IOException ioe) {} catch (BadLocationException ble) {
System.err.println("Couldn't insert initial text into text pane.");
}
//Go into a loop to get the rest
internalsubckt = 0;
while (bufString!=null) {
try {
CircuitDoc.insertString(CircuitDoc.getLength(),bufString + "\n", CircuitDoc.getStyle("Courier New"));
} catch (BadLocationException ble) {
System.err.println("Couldn't insert initial text into text pane.");
}
/**
* Now do something with the line we just read
* First remove any comments at the end of the line
*/
String[] removeComments = p.split(bufString);
fillInNodes(removeComments[0], nodeSet, devicesSet, SPICEDevices);
//read the next line from the file and test for null
try {
bufString = br.readLine();
} catch (IOException ioe) {}
}
// to move to the end of the line
// textArea.setCaretPosition(textArea.getDocument().getLength());
/*
try {
dek.read(br, CircuitDoc, 0);
} catch (IOException e) {}
catch (BadLocationException ble) {}
*/
try{
br.close();
} catch(IOException ioe){}
}
/**
* This function actually parses most of the SPICE
* circuit file to find the nodes and component names
* and place them into the JList components
* @param OneLine A single line from the SPICE file
* @param nodeSet Set: (Usually a TreeSet) containing the list of nodes (usually input as empty).
* Will contain the Top-level terminal names found
* @param devicesSet Set: (Usually a TreeSet) containing the list of devices (usually input as empty).
* Will contain the Top-level device names found.
* @param SPICEDevices TreeMap: the Map of the possible devices and actions.
* Usually gotten from parseConfigFile.
*/
public static void fillInNodes(String OneLine, Set <String> nodeSet, Set <String> devicesSet, java.util.TreeMap<String, DevicesSet> SPICEDevices) {
int ii =0;
Matcher m;
/* This stringbuilder will contain the number of groups necessary
* note: there is no need to account for spaces at the beginning
because the input is trimmed.
**/
StringBuilder regexPattern = new StringBuilder("([^\\s]*)");
java.util.regex.Pattern p = java.util.regex.Pattern.compile("\\s*([^,]*)\\s*,\\s*([^,]*)\\s*,\\s*([^,]*)\\s*,\\s*([0-9]*)\\s*\\n");
//get rid of leading and trailing spaces
OneLine = OneLine.trim();
//return if there was nothing on the line
if (OneLine.length()<1) return;
// get the first character
String FirstLetter = OneLine.substring(0,1).toUpperCase();
//System.out.println(FirstLetter);
if (SPICEDevices.containsKey(FirstLetter)) {
DevicesSet Device = (DevicesSet) SPICEDevices.get(FirstLetter);
switch (Device.getActiontoTake()) {
case REGULARDEVICE: //essentially all "real devices"
/*
* create the regular expression to match to
* it should have numberofterminals+1 groups
*/
if (internalsubckt<1) {
for (ii=1; ii<=Device.getNumberofTerminals(); ii++) {
regexPattern.append("\\s*([^\\s]*)");
// any group 1 group 2
// the pattern is: beginning spaces - no spaces - spaces - no spaces - spaces- group 3
// Name of device node
}
p = java.util.regex.Pattern.compile(regexPattern.toString());
m = p.matcher(OneLine);
if (m.find()) {
//k = m.start();
devicesSet.add(m.group(1));
//System.out.print("Device name: "+m.group(1));
for (ii=2; ii<=Device.getNumberofTerminals()+1; ii++) {
//System.out.print(" | node "+ ii +": " + m.group(ii));
//System.out.print("Configure items for ports is:\n"+m.group(1)+"\n:::::::\n");
// Add to the set (duplicates won't be accepted)
nodeSet.add(m.group(ii));
//System.out.print("Total match is:\n"+m.group(0)+"\n:::::::\n");
}
//System.out.println(" found.");
}
}
//System.out.println("Regular Device");
break;
case COMMANDCARD: // . -- ignore all of these but subckt
p = java.util.regex.Pattern.compile(".SUBCKT");
m = p.matcher(OneLine.toUpperCase());
if (m.find()) {
internalsubckt++;
}
p = java.util.regex.Pattern.compile(".ENDS");
m = p.matcher(OneLine.toUpperCase());
if (m.find()) {
internalsubckt--;
//System.out.println("Found end of a subckt.");
if (internalsubckt<0) {
internalsubckt = 0;
JOptionPane.showMessageDialog(null, "Possibly too many SUBCKT with no ENDS.","Subcircuit Error",JOptionPane.WARNING_MESSAGE);
}
}
break;
case SUBCIRCUIT: // X
if (internalsubckt<1) {
int kk=0;
p = java.util.regex.Pattern.compile("([\\w]*)\\s+");
m = p.matcher(OneLine);
while (m.find()) {
kk++;
//System.out.println("I found the text \"" + m.group() +
// "\" starting at index " + m.start() +
// " and ending at index " + m.end() + ".");
if (kk==1)
devicesSet.add(m.group().trim());
else
nodeSet.add(m.group().trim());
}
//System.out.print("Total terminals found for X: "+kk );
}
//System.out.println(" Subcircuit");
break;
case COMMENT: // *
//System.out.println("Comment");
break;
default:
//System.out.println("Unknown");
break;
}
}
}
/**
* Attempt to read in SPICE3 file
* try to detect whether SPICE3 or not
* and go to SPICE2 if not
* @param in DataInputStream
* @return Result code
*/
public static int setASCIILocation(RandomAccessFile in) {
int ii=0;
StringBuilder desc = new StringBuilder(20);
/*
* Now to try to find the word: Binary:\n
* I really only look for the last letter
* followed by a : and \n
*/
ii=-1;
desc.append("...");
byte[] tempHolder = {0};// new byte[0];
try {
do {
ii++;
tempHolder[0] = in.readByte();
desc.append(new String(tempHolder));
} while(desc.substring(ii).compareTo("ry:\n")!=0);
} catch (IOException e) {
System.out.println(e.toString());
}
//System.out.println("This is as far as we got: "+desc+"........"+ii);
return ii;
}
/**
* Gets the GnuCap file and places it in a WholeAnalysisSet
* This is the main file called by an outside program
* to retrieve all the data
* @param RAWFile File RAW File
* @param wholeDataSet WholeAnalysisSet
* @return ArrayList<WholeDataSet>
*/
public static ArrayList<WholeAnalysisSet> getGnuCapFile(File RAWFile, ArrayList<WholeAnalysisSet> wholeDataSet) {
// The stored values are supposedly 8 bytes per value
// which is Double Little Endian (Java is Big Endian)
RandomAccessFile in = null;
int numberOfAnalysisTypes = 0;
try {
//in = new DataInputStream(new FileInputStream(RAWFile));
in = new RandomAccessFile(RAWFile,"r");
} catch (FileNotFoundException ex) {
ex.printStackTrace();
System.out.println("File not found. "+ex.toString());
return null;
}
// add the zero'th Analysis set since read-in was successful
wholeDataSet.add(new WholeAnalysisSet());
/* Since the data in the file starts with a "#" we
* need to find that. All the data follows that list
* of column headers.
*/
while (getGnuCapColumnHeaders( in, wholeDataSet, numberOfAnalysisTypes)==88) {
/* Now that we're successful in retrieving the header
* we now need to get the RAW binary data.
* Note: in the new version, we do not get the
* raw data but, instead store pointers to the start
* of the data.
*/
numberOfAnalysisTypes++;
/* Add another wholedataset for the
* next read-in
*/
wholeDataSet.add(new WholeAnalysisSet());
try {
in.close();
} catch (IOException ex) {
ex.printStackTrace();
}
try {
//in = new DataInputStream(new FileInputStream(RAWFile));
in = new RandomAccessFile(RAWFile,"r");
} catch (FileNotFoundException ex) {
ex.printStackTrace();
System.out.println("File not found. "+ex.toString());
return null;
}
}
// This algorithm creates one extra, so we need to remove it.
//wholeDataSet.remove(wholeDataSet.size()-1);
//TO DO else - add ability to divert to binary header
//
try {
in.close();
} catch (IOException ex) {
ex.printStackTrace();
}
return wholeDataSet;
}
/**
* Get get GnuCap Column Headers
*
* * GnuCap format
* #Time v(in) v(out) (Newline (\n) terminated string)
* 0. 0. 1.8 (Newline (\n) terminated string)
*
* Return int: file read problem = -1
* read ok =0
* not SPICE3 = 1
* @param in DataInputStream
* @param WDS WholeAnalysisSet
* @param numberOfAnalysis int the analysis currently being read
* @return int file read problem = -1
* read ok =0
* not SPICE3 = 1
*/
public static int getGnuCapColumnHeaders( RandomAccessFile in, ArrayList<WholeAnalysisSet> WDS, int numberOfAnalysis) {
//InputStreamReader isr = new InputStreamReader(in);
RandomAccessFile isr = in;
Matcher m;
java.util.regex.Pattern p = java.util.regex.Pattern.compile("^#(.*)$");
int ii=0;
int jj=0;
char chr = 'c';
StringBuilder desc = new StringBuilder(64);
StringBuilder columnHeads = new StringBuilder(64);
// This is the line separator in the SPICE3 specification
char lineSep = '\n'; //System.getProperty("line.separator").charAt(0); //
boolean continueLoop = true;
int returncodeMORE = 0;
/*
* First read in the ASCII text above, which is the setup info
* in the HEADER
* ii is the line number used
*/
//for (ii=0;ii<8;ii++)
while (continueLoop) {
try {
chr = (char) isr.read();
while (chr != lineSep) {
desc.append(chr);
chr = (char) isr.read();
}
} catch (IOException e) {
System.out.println(e.toString());
return -1;
}
//System.out.println(desc);
m = p.matcher(desc);
// Found a line starting with #
if (m.find()) {
// if we need analysis 2 instead of 0, skip this one until we get to the right one
if (jj==numberOfAnalysis) {
WDS.get(numberOfAnalysis).getAnalysisDescription().setPlotName("GnuCap Analysis #"+numberOfAnalysis);
WDS.get(numberOfAnalysis).getAnalysisDescription().setFlags("Real");
try {
WDS.get(numberOfAnalysis).getAnalysisDescription().setFileLocation(in.getFilePointer());
} catch (IOException ex) {
ex.printStackTrace();
System.out.println("Could not read file pointer location.");
return -1;
}
//k = m.start();
continueLoop = false;
System.out.println(m.group(1));
columnHeads.append(m.group(1));
/**
* Use the line number (ii) to parse
* the header
**/
p = java.util.regex.Pattern.compile("([\\S]+)[\\s*]");
m = p.matcher(columnHeads);
while (m.find()) {
//System.out.println(m.group(1));
WDS.get(numberOfAnalysis).getInternalVID().add(new SpiceVariableInfoData(ii, m.group(1), "GC Unknown" ));
ii++;
}
} else {
jj++;
}
}
// clear out the StringBuilder so we can use REGEX again
desc.delete(0,desc.length());
columnHeads.delete(0,columnHeads.length());
}
WDS.get(numberOfAnalysis).getAnalysisDescription().setNumberOfVariables(ii);
/**
* This section reads in the data to
* figure out the number of points
* We assume the data ends at
* the end of file,
* a blank line, or
* line beginning with a first non-white character not in [0-9+-] .
*
*/
//if (WDS.get(numberOfAnalysis).getAnalysisDescription().getNumberOfPoints() >0) {
continueLoop = true;
ii = 0;
while (continueLoop) {
// clear out the StringBuilder so we can use REGEX again
chr = 'c';
jj =0;
desc.delete(0,desc.length());
p = java.util.regex.Pattern.compile("^#(.*)$");
// Read a single line
try {
while ((chr != lineSep) && (jj!=-1)) {
jj = isr.read();
if (jj!=-1) {
chr = (char) jj;
desc.append(chr);
} else {
continueLoop = false;
}
}
} catch (IOException e) {
System.out.println(e.toString());
}
if (continueLoop) {
// determine if there's another analysis set there
m = p.matcher(desc);
if (m.find()) {
returncodeMORE = 88;
continueLoop = false;
}
//System.out.println(desc);
//see if there's an empty line
p = java.util.regex.Pattern.compile("^(\\s*)$");
m = p.matcher(desc);
if (m.find()) {
continueLoop = false;
}
}
ii++;
}
WDS.get(numberOfAnalysis).getAnalysisDescription().setNumberOfPoints(ii-1);
return returncodeMORE;
}
/**
* Get's only the data points required for display
* data stored in the RAW file in binary format
* @param in DataInputStream
* @param WDS WholeDataSet
* @param numberOfAnalysis index of the number of analysis
* @return int file read problem = -1
* read ok =0
* not SPICE3 = 1
*/
public static int getGnuCapDataSelected(File RAWFile, ArrayList<WholeAnalysisSet> WDS, int numberOfAnalysis, boolean changeEndian) {
RandomAccessFile in = null;
int numberOfAnalysisTypes = 0;
Matcher m;
char chr = 'c';
java.util.regex.Pattern p = java.util.regex.Pattern.compile("([\\S]+)[\\s*]");
try {
in = new RandomAccessFile(RAWFile,"r");
} catch (FileNotFoundException ex) {
ex.printStackTrace();
System.out.println("File not found. "+ex.toString());
return -1;
}
int ii, jj, kk;
StringBuilder desc = new StringBuilder(256);
double real = 0.0D;
double imag = 0.0D;
/*This section sets the location of the file location where the
*data resides. This will be used to read in much larger files
*/
try {
in.seek(WDS.get(numberOfAnalysis).getAnalysisDescription().getFileLocation());
} catch (IOException ex) {
ex.printStackTrace();
System.out.println("Problem attempting to set seek location.");
return -1;
}
/*
* Repeat reading in bytes until we get the
* right thing.
*/
imag = 0.0D;
for (kk=0;kk<WDS.get(numberOfAnalysis).getAnalysisDescription().getNumberOfPoints();kk++) {
// clear out the StringBuilder so we can use REGEX again
desc.delete(0,desc.length());
try {
desc.append(in.readLine());
} catch(EOFException e){
System.out.println("End of file.");
return -1;
} catch (IOException e) {
System.out.println(e.toString());
return -1;
}
System.out.println(desc);
m = p.matcher(desc);
for (jj=0;jj<WDS.get(numberOfAnalysis).getAnalysisDescription().getNumberOfVariables();jj++) {
if (m.find()) {
//k = m.start();
try {
real=Double.valueOf(m.group(1)) ;
} catch(NumberFormatException e) {
real = 0.0D;
}
WDS.get(numberOfAnalysis).getInternalVID().get(jj).getAssociatedData().add(new jComplexNumber(real,imag));
}
}
}
return 0;
}
/**
* Gets the Raw file and places it in a WholeAnalysisSet
* This is the main file called by an outside program
* to retrieve all the data
* @param RAWFile File RAW File
* @param wholeDataSet WholeAnalysisSet
* @return ArrayList<WholeDataSet>
*/
public static ArrayList<WholeAnalysisSet> getSPICE3RawFile(File RAWFile, ArrayList<WholeAnalysisSet> wholeDataSet) {
// The stored values are supposedly 8 bytes per value
// which is Double Little Endian (Java is Big Endian)
RandomAccessFile in = null;
int numberOfAnalysisTypes = 0;
int result;
try {
//in = new DataInputStream(new FileInputStream(RAWFile));
in = new RandomAccessFile(RAWFile,"r");
} catch (FileNotFoundException ex) {
ex.printStackTrace();
System.out.println("File not found. "+ex.toString());
return null;
}
// add the zero'th Analysis set since read-in was successful
wholeDataSet.add(new WholeAnalysisSet());
/* Since the Raw file first has an ASCII header we
* need to read that in first. All the rest of the headers
* are binary.
*/
result=getASCIIHeaderFile( in, wholeDataSet, numberOfAnalysisTypes);
if (result==0) {
/* Now that we're successful in retrieving the header
* we now need to get the RAW binary data.
* Note: in the new version, we do not get the
* raw data but, instead store pointers to the start
* of the data.
*/
getData3RawFile( in, wholeDataSet, numberOfAnalysisTypes);
numberOfAnalysisTypes++;
/* Add another wholedataset for the
* next read-in
*/
wholeDataSet.add(new WholeAnalysisSet());
/* This time the header is binary and all the
* rest of the headers will be binary, so we can
* do a loop until we've read in all possible data
* sets.
*/
while (getBinaryHeaderFile( in, wholeDataSet, numberOfAnalysisTypes)==0) {
getData3RawFile( in, wholeDataSet, numberOfAnalysisTypes);
numberOfAnalysisTypes++;
wholeDataSet.add(new WholeAnalysisSet());
}
}
// This algorithm creates one extra, so we need to remove it.
wholeDataSet.remove(wholeDataSet.size()-1);
//TO DO else - add ability to divert to binary header
//
try {
in.close();
} catch (IOException ex) {
ex.printStackTrace();
}
if (result == 1) {
return null;
} else {
return wholeDataSet;
}
}
/**
* Get SPICE3 ASCII header file
*
* * SPICE3 format
* Title Card (Newline (\n) terminated string)
* Date and Time (Newline (\n) terminated string)
* Plot Title (Newline (\n) terminated string)
* Flags (Newline (\n) terminated string)
* Number of Variables (No. Variables: [an integer])
* Number of Points (No. Points: [an integer])
* Version (Newline (\n) terminated string)
*
* Return int: file read problem = -1
* read ok =0
* not SPICE3 = 1
* @param in DataInputStream
* @param WDS WholeAnalysisSet
* @param numberOfAnalysis int the analysis currently being read
* @return int file read problem = -1
* read ok =0
* not SPICE3 = 1
*/
public static int getASCIIHeaderFile( RandomAccessFile in, ArrayList<WholeAnalysisSet> WDS, int numberOfAnalysis) {
//InputStreamReader isr = new InputStreamReader(in);
RandomAccessFile isr = in;
Matcher m;
java.util.regex.Pattern p = java.util.regex.Pattern.compile("\\s*([^,]*)\\s*,\\s*([^,]*)\\s*,\\s*([^,]*)\\s*,\\s*([0-9]*)\\s*\\n");
int ii=0;
int jj=0;
char chr = 'c';
StringBuilder desc = new StringBuilder(20);
// This is the line separator in the SPICE3 specification
char lineSep = '\n'; //System.getProperty("line.separator").charAt(0); //
boolean continueLoop = true;
/*
* First read in the ASCII text above, which is the setup info
* in the HEADER
* ii is the line number used
*/
//for (ii=0;ii<8;ii++)
while (continueLoop) {
try {
chr = (char) isr.read();
while (chr != lineSep) {
desc.append(chr);
chr = (char) isr.read();
}
} catch (IOException e) {
System.out.println(e.toString());
return -1;
}
//System.out.println(desc);
/**
* Use the line number (ii) to parse
* the header
*/
switch (ii) {
case (0): //Check to ensure the first line is Title:
p = java.util.regex.Pattern.compile("([\\w]*):\\s*");
m = p.matcher(desc);
if (m.find()) {
//k = m.start();
if (m.group(1).compareTo("Title")!=0)
return 1;
} else {
return 1;
}
break;
case (2): // This is the Plotname
p = java.util.regex.Pattern.compile(":\\s*([\\w\\s]*)");
m = p.matcher(desc);
if (m.find()) {
//k = m.start();
//System.out.println("This is the returned plotname: "+m.group(1));
WDS.get(numberOfAnalysis).getAnalysisDescription().setPlotName(m.group(1).trim());
}
break;
case (3): // This is the flags section
p = java.util.regex.Pattern.compile(":\\s*([\\w\\s]*)");
m = p.matcher(desc);
if (m.find()) {
//k = m.start();
//System.out.println("This is the returned flag: "+m.group(1));
WDS.get(numberOfAnalysis).getAnalysisDescription().setFlags(m.group(1).trim());
}
break;
case (4): // This returns the number of Variables
p = java.util.regex.Pattern.compile(":\\s*([\\d]*)");
m = p.matcher(desc);
if (m.find()) {
//k = m.start();
//System.out.println("This is the returned no.of variables: "+m.group(1));
WDS.get(numberOfAnalysis).getAnalysisDescription().setNumberOfVariables(Integer.valueOf(m.group(1)));
}
break;
case (5): //This returns the number of points
p = java.util.regex.Pattern.compile(":\\s*([\\d]*)");
m = p.matcher(desc);
if (m.find()) {
//k = m.start();
//System.out.println("This is the returned no.of points: "+m.group(1));
WDS.get(numberOfAnalysis).getAnalysisDescription().setNumberOfPoints(Integer.valueOf(m.group(1)));
}
break;
default: //Find the "Variables:" section
p = java.util.regex.Pattern.compile("([\\w]*):\\s*");
m = p.matcher(desc);
if (m.find()) {
//k = m.start();
if (m.group(1).compareTo("Variables")==0)
continueLoop=false;
}
break;
}
ii++;
// clear out the StringBuilder so we can use REGEX again
desc.delete(0,desc.length());
}
/**
* This section reads in the variables names
* and type (voltage, current, etc) and assigns
* Them to a useful class for later processing
*0 = no type
* 1 = time
* 2 = frequency
* 3 = voltage
* 4 = current
* 5 = output noise
* 6 = input noise
* 7 = HD2
* 8 = HD3
* 9 = DIM2
* 10 = SIM2
* 11 = DIM3
*/
// If there are no points, don't read anything else
if (WDS.get(numberOfAnalysis).getAnalysisDescription().getNumberOfPoints() >0) {
for (ii=0;ii<WDS.get(numberOfAnalysis).getAnalysisDescription().getNumberOfVariables();ii++) {
try {
chr = (char) isr.read();
while (chr != lineSep) {
desc.append(chr);
chr = (char) isr.read();
}
} catch (IOException e) {
System.out.println(e.toString());
}
//System.out.println(desc);
//[tab] (index) [tab] (name) [tab] (type)
p = java.util.regex.Pattern.compile("\\s*([\\d]*)\\s*([\\S]*)\\s*([\\S]*)");
m = p.matcher(desc);
if (m.find()) {
//System.out.println("This is the variable set: "+m.group(1)+" | "+m.group(2)+" | "+m.group(3));
/*
* Fill up the array list with each variable and its
* associated information
*/
//if (!m.group(2).contains("#")) {
WDS.get(numberOfAnalysis).getInternalVID().add(new SpiceVariableInfoData(Integer.valueOf(m.group(1)), m.group(2), m.group(3) ));
//realNumberOfVariables++;
//}
desc.delete(0,desc.length());
}
}
/*
* Read the last line which should say
* Binary: This is to put the stream at the start of the binary data
*/
try {
chr = (char) isr.read();
while (chr != lineSep) {
desc.append(chr);
chr = (char) isr.read();
}
} catch (IOException e) {
System.out.println(e.toString());
}
}
//System.out.println(desc);
/*
* Here I close and reopen
* so I can use the DataInputStream
instead of the StreamReader
(Byte vs Character)
try {
isr.close();
} catch (IOException ex) {
ex.printStackTrace();
}
*/
//desc.delete(0,desc.length());
return 0;
}
/**
* get SPICE3 Binary header (
* @param in DataInputStream
* @param WDS WholeDataSet
* @param numberOfAnalysis index of the analysis in progress
* @return int file read problem = -1
* read ok =0
* not SPICE3 = 1
* end of File Most likely reached = 2
*/
public static int getBinaryHeaderFile(RandomAccessFile in, ArrayList<WholeAnalysisSet> WDS, int numberOfAnalysis) {
Matcher m;
java.util.regex.Pattern p = java.util.regex.Pattern.compile("\\s*([^,]*)\\s*,\\s*([^,]*)\\s*,\\s*([^,]*)\\s*,\\s*([0-9]*)\\s*\\n");
int ii=0;
int jj=0;
String chr = "c";
StringBuilder desc = new StringBuilder(20);
byte[] tempHolder = {0};// new byte[0];
// This is the line separator in the SPICE3 specification
String lineSep = "\n"; //System.getProperty("line.separator").charAt(0); //
boolean continueLoop = true;
/*
* Just in case there's more data, keep reading
* try to get more and see what it is
*/
//for (ii=0;ii<8;ii++)
while (continueLoop) {
try {
do {
tempHolder[0] = in.readByte();
chr = new String(tempHolder);
desc.append(chr);
} while (chr.compareTo(lineSep)!=0);
} catch (IOException e) {
System.out.println(e.toString()+". File end reached succesfully.");
return 2;
}
//System.out.println(desc);
/**
* Use the line number (ii) to parse
* the header
*/
switch (ii) {
case (0): //Check to ensure the first line is Title:
p = java.util.regex.Pattern.compile("([\\w]*):\\s*");
m = p.matcher(desc);
if (m.find()) {
//k = m.start();
if (m.group(1).compareTo("Title")!=0)
return 1;
}
break;
case (2): // This is the Plotname
p = java.util.regex.Pattern.compile(":\\s*([\\w\\s]*)");
m = p.matcher(desc);
if (m.find()) {
//k = m.start();
//System.out.println("This is the returned plotname: "+m.group(1));
WDS.get(numberOfAnalysis).getAnalysisDescription().setPlotName(m.group(1).trim());
}
break;
case (3): // This is the flags section
p = java.util.regex.Pattern.compile(":\\s*([\\w\\s]*)");
m = p.matcher(desc);
if (m.find()) {
//k = m.start();
//System.out.println("This is the returned flag: "+m.group(1));
WDS.get(numberOfAnalysis).getAnalysisDescription().setFlags(m.group(1).trim());
}
break;
case (4): // This returns the number of Variables
p = java.util.regex.Pattern.compile(":\\s*([\\d]*)");
m = p.matcher(desc);
if (m.find()) {
//k = m.start();
//System.out.println("This is the returned no.of variables: "+m.group(1));
WDS.get(numberOfAnalysis).getAnalysisDescription().setNumberOfVariables(Integer.valueOf(m.group(1)));
}
break;
case (5): //This returns the number of points
p = java.util.regex.Pattern.compile(":\\s*([\\d]*)");
m = p.matcher(desc);
if (m.find()) {
//k = m.start();
//System.out.println("This is the returned no.of points: "+m.group(1));
WDS.get(numberOfAnalysis).getAnalysisDescription().setNumberOfPoints(Integer.valueOf(m.group(1)));
}
break;
default: //Find the "Variables:" section
p = java.util.regex.Pattern.compile("([\\w]*):\\s*");
m = p.matcher(desc);
if (m.find()) {
//k = m.start();
if (m.group(1).compareTo("Variables")==0)
continueLoop=false;
}
break;
}
ii++;
// clear out the StringBuilder so we can use REGEX again
desc.delete(0,desc.length());
}
/**
* This section reads in the variables names
* and type (voltage, current, etc) and assigns
* Them to a useful class for later processing
*0 = no type
* 1 = time
* 2 = frequency
* 3 = voltage
* 4 = current
* 5 = output noise
* 6 = input noise
* 7 = HD2
* 8 = HD3
* 9 = DIM2
* 10 = SIM2
* 11 = DIM3
*/
// If there are no points, don't read anything else
if (WDS.get(numberOfAnalysis).getAnalysisDescription().getNumberOfPoints() >0) {
for (ii=0;ii<WDS.get(numberOfAnalysis).getAnalysisDescription().getNumberOfVariables();ii++) {
try {
do {
tempHolder[0] = in.readByte();
chr = new String(tempHolder);
desc.append(chr);
} while (chr.compareTo(lineSep)!=0);
} catch (IOException e) {
System.out.println(e.toString());
}
//System.out.println(desc);
//[tab] (index) [tab] (name) [tab] (type)
p = java.util.regex.Pattern.compile("\\s*([\\d]*)\\s*([\\S]*)\\s*([\\S]*)");
m = p.matcher(desc);
if (m.find()) {
//System.out.println("This is the variable set: "+m.group(1)+" | "+m.group(2)+" | "+m.group(3));
/*
* Fill up the array list with each variable and its
* associated information
*/
//if (!m.group(2).contains("#")) {
WDS.get(numberOfAnalysis).getInternalVID().add(new SpiceVariableInfoData(Integer.valueOf(m.group(1)), m.group(2), m.group(3) ));
//realNumberOfVariables++;
//}
desc.delete(0,desc.length());
}
}
/*
* Read the last line which should say
* Binary: This is to put the stream at the start of the binary data
*/
try {
do {
tempHolder[0] = in.readByte();
chr = new String(tempHolder);
desc.append(chr);
} while (chr.compareTo(lineSep)!=0);
} catch (IOException e) {
System.out.println(e.toString());
}
}
//System.out.println(desc);
return 0;
}
/**
* Get's data stored in the RAW file in binary format
* @param in DataInputStream
* @param WDS WholeDataSet
* @param numberOfAnalysis index of the number of analysis
* @return int file read problem = -1
* read ok =0
* not SPICE3 = 1
*/
public static int getData3RawFile(RandomAccessFile in, ArrayList<WholeAnalysisSet> WDS, int numberOfAnalysis) {
int ii, jj, kk;
StringBuilder desc = new StringBuilder(256);
double real = 0.0D;
double imag = 0.0D;
byte[] tempByte = new byte[8];
/*This section sets the location of the file location where the
*data resides. This will be used to read in much larger files
*/
try {
WDS.get(numberOfAnalysis).getAnalysisDescription().setFileLocation(in.getFilePointer());
} catch (IOException ex) {
ex.printStackTrace();
System.out.println("Could not read file pointer location.");
return -1;
}
/*
* Repeat reading in bytes until we get the
* right thing. Note the use of ByteBuffer to handle
* Little Endian storage from the C code
*/
try {
for (kk=0;kk<WDS.get(numberOfAnalysis).getAnalysisDescription().getNumberOfPoints();kk++) {
for (jj=0;jj<WDS.get(numberOfAnalysis).getAnalysisDescription().getNumberOfVariables();jj++) {
for (ii=0;ii<8;ii++){
tempByte[ii] = in.readByte();
}
real = ByteBuffer.wrap( tempByte ).order( ByteOrder.LITTLE_ENDIAN ).getDouble();
if (WDS.get(numberOfAnalysis).getAnalysisDescription().isComplex()){
for (ii=0;ii<8;ii++){
tempByte[ii] = in.readByte();
}
imag = ByteBuffer.wrap( tempByte ).order( ByteOrder.LITTLE_ENDIAN ).getDouble();
} else
imag = 0.0D;
/*
* This line is commented out. As of Version 1.0.9;
* data is no longer stored in memory
*/
//WDS.get(numberOfAnalysis).getInternalVID().get(jj).getAssociatedData().add(new jComplexNumber(real,imag));
}
// This line is solely for diagnostics
//for (ii=0;ii<WDS.get(numberOfAnalysis).getAnalysisDescription().getNumberOfVariables();ii++)
//System.out.println(WDS.get(numberOfAnalysis).getInternalVID().get(ii).getVariableName()+" : "+ii+" = "+ WDS.get(numberOfAnalysis).getInternalVID().get(ii).getAssociatedData().get(kk).toString());
}
} catch(EOFException e){
System.out.println("End of file.");
return -1;
} catch (IOException ex) {
ex.printStackTrace();
System.out.println("End of file. Read Whole File.");
return -1;
}
return 0;
}
/**
* Get's only the data points required for display
* data stored in the RAW file in binary format
* @param in DataInputStream
* @param WDS WholeDataSet
* @param numberOfAnalysis index of the number of analysis
* @return int file read problem = -1
* read ok =0
* not SPICE3 = 1
*/
public static int getRawDataSelected(File RAWFile, ArrayList<WholeAnalysisSet> WDS, int numberOfAnalysis, boolean changeEndian) {
RandomAccessFile in = null;
int numberOfAnalysisTypes = 0;
try {
in = new RandomAccessFile(RAWFile,"r");
} catch (FileNotFoundException ex) {
ex.printStackTrace();
System.out.println("File not found. "+ex.toString());
return -1;
}
int ii, jj, kk;
StringBuilder desc = new StringBuilder(256);
double real = 0.0D;
double imag = 0.0D;
byte[] tempByte = new byte[8];
/*This section sets the location of the file location where the
*data resides. This will be used to read in much larger files
*/
try {
in.seek(WDS.get(numberOfAnalysis).getAnalysisDescription().getFileLocation());
} catch (IOException ex) {
ex.printStackTrace();
System.out.println("Problem attempting to set seek location.");
return -1;
}
/*
* Repeat reading in bytes until we get the
* right thing. Note the use of ByteBuffer to handle
* Little Endian storage from the C code
*/
try {
for (kk=0;kk<WDS.get(numberOfAnalysis).getAnalysisDescription().getNumberOfPoints();kk++) {
for (jj=0;jj<WDS.get(numberOfAnalysis).getAnalysisDescription().getNumberOfVariables();jj++) {
for (ii=0;ii<8;ii++){
tempByte[ii] = in.readByte();
}
if (changeEndian) {
real = ByteBuffer.wrap( tempByte ).order( ByteOrder.BIG_ENDIAN ).getDouble();
} else {
real = ByteBuffer.wrap( tempByte ).order( ByteOrder.LITTLE_ENDIAN ).getDouble();
}
if (WDS.get(numberOfAnalysis).getAnalysisDescription().isComplex()){
for (ii=0;ii<8;ii++){
tempByte[ii] = in.readByte();
}
if (changeEndian) {
imag = ByteBuffer.wrap( tempByte ).order( ByteOrder.BIG_ENDIAN ).getDouble();
} else {
imag = ByteBuffer.wrap( tempByte ).order( ByteOrder.LITTLE_ENDIAN ).getDouble();
}
} else
imag = 0.0D;
//WholeAnalysisSet.VariableInfo.dataset.data.number
WDS.get(numberOfAnalysis).getInternalVID().get(jj).getAssociatedData().add(new jComplexNumber(real,imag));
}
//for (ii=0;ii<WDS.get(numberOfAnalysis).getAnalysisDescription().getNumberOfVariables();ii++)
//System.out.println(WDS.get(numberOfAnalysis).getInternalVID().get(ii).getVariableName()+" : "+ii+" = "+ WDS.get(numberOfAnalysis).getInternalVID().get(ii).getAssociatedData().get(kk).toString());
}
} catch(EOFException e){
System.out.println("End of file.");
return -1;
} catch (IOException ex) {
ex.printStackTrace();
System.out.println("End of file. Read Whole File.");
return -1;
}
return 0;
}
/**
* This function returns an
* integer for use in a switch statement
* based on the type of variable found
* 0 = no type
* 1 = time
* 2 = frequency
* 3 = voltage
* 4 = current
* 5 = output noise
* 6 = input noise
* 7 = HD2
* 8 = HD3
* 9 = DIM2
* 10 = SIM2
* 11 = DIM3
* @param typeVariable String: From the WAS - the type of variable
* @return int
* 0 = no type
* 1 = time
* 2 = frequency
* 3 = voltage
* 4 = current
* NOT Implemented:
* 5 = output noise
* 6 = input noise
* 7 = HD2
* 8 = HD3
* 9 = DIM2
* 10 = SIM2
* 11 = DIM3
*/
public static int parseTypeVariable(String typeVariable) {
/* 0 = no type
1 = time
2 = frequency
3 = voltage
4 = current
5 = output noise
6 = input noise
7 = HD2
8 = HD3
9 = DIM2
10 = SIM2
11 = DIM3
*/
if (typeVariable.compareToIgnoreCase("time")==0)
return 1;
if (typeVariable.compareToIgnoreCase("frequency")==0)
return 2;
if (typeVariable.compareToIgnoreCase("voltage")==0)
return 3;
if (typeVariable.compareToIgnoreCase("current")==0)
return 4;
return 0;
}
/*
* This Display routine is an attempt to move from the JFSpiceFE
* class. I'm not sure if this is a great idea, but the
* file is really large because of this routine
*/
public static void addAnalysistoScreen(int timesThrough, int selectedSetting, ArrayList<WholeAnalysisSet> WAS, JFSpiceFE theprogram) {
// ArrayList<WholeAnalysisSet> WAS) { ,
// javax.swing.JTabbedPane jTBOutputGraphs, int timesThrough, int YGraphingChoices, JButtonGroup BGCalculator, int[] analysisSelections, boolean includeCalculator, int dataSet, int XAxis, int[] YAxis, int indexToYScale, int indexToXScale, int selectedSetting, boolean LogXAxisSelected, boolean LogYAxisSelected, boolean addToAlreadySelectedGraph, ArrayList<WholeAnalysisSet> WAS) {
javax.swing.JTabbedPane jTBOutputGraphs = theprogram.getjTBOutputGraphs();
int YGraphingChoices = theprogram.getYGraphingChoices();
JButtonGroup BGCalculator = theprogram.getBGCalculator();
int[] analysisSelections = theprogram.getAnalysisSelections();
boolean includeCalculator =theprogram.getIncludeCalculator();
int dataSet = theprogram.getDataSet();
int XAxis = theprogram.getXAxis();
int[] YAxis = theprogram.getYAxis();
int indexToYScale = theprogram.getindexToYScale();
int indexToXScale = theprogram.getindexToXScale();
boolean LogXAxisSelected = theprogram.getLogXAxis();
boolean LogYAxisSelected = theprogram.getLogYAxis();
boolean addToAlreadySelectedGraph = theprogram.getAddtoGraph();
// ArrayList<WholeAnalysisSet> WAS = theprogram.getWAS();
float[] MagValues = {1,1e15f,1e12f,1e9f,1e6f,1e3f,1e-3f,1e-6f,1e-9f,1e-12f};
// create a dataset...
Boolean gotASeries = true;
// Get the dataset
// Number of traces the user requested to plot
int numberOfTraces = YAxis.length;
// This will contain the total number of points
int npts = WAS.get(dataSet).getAnalysisDescription().getNumberOfPoints();
// Get the future chart title
String chartTitle = WAS.get(dataSet).getAnalysisDescription().getPlotName();
// Create a new DataSet (Collection)
XYSeriesCollection dataset = new XYSeriesCollection();
// There should be only one X variable, so we can just use this
SpiceVariableInfoData tempVIDX = WAS.get(dataSet).getInternalVID().get(XAxis);
// Temporary SpiceVariableInfoData to store each of the Y- information
SpiceVariableInfoData tempVIDY = null;
// each series will be added here
XYSeries series = null;
if (numberOfTraces > 0) {
for (int traces=0;traces<numberOfTraces;traces++){
tempVIDY=WAS.get(dataSet).getInternalVID().get(YAxis[traces]);
series = new XYSeries(tempVIDY.getVariableName(),false);
/*
* "Mag ","Phase", "Real", "Imag" - X choices
* "Mag/Phase","dB/Phase", "Phase Only", "Mag Only", "dB Only","Real", "Imag" - Y Choices
*/
// This creates a single variable to decode all the possible choices to
// allow the use of a single switch statement
// Note: the dual axis is handled below
switch (selectedSetting) {
case (0):// Mag x - Mag/Phase Y
case (3): // Mag x - Mag - only y
for (int y=0;y<npts;y++){
series.add(tempVIDX.getAssociatedData().get(y).mag()*MagValues[indexToXScale], tempVIDY.getAssociatedData().get(y).mag()*MagValues[indexToYScale]);
}
gotASeries = true;
break;
case (1):// Mag x - dB/Phase Y
case (4):// Mag x - dB only y
for (int y=0;y<npts;y++){
series.add(tempVIDX.getAssociatedData().get(y).mag()*MagValues[indexToXScale], 20.0D*Math.log10(tempVIDY.getAssociatedData().get(y).mag()));
}
gotASeries = true;
break;
case (2)://Phase Only
gotASeries = false;
break;
case (5):// Mag x - Real Y
for (int y=0;y<npts;y++){
series.add(tempVIDX.getAssociatedData().get(y).mag()*MagValues[indexToXScale], tempVIDY.getAssociatedData().get(y).real()*MagValues[indexToYScale]);
}
gotASeries = true;
break;
case(6):// Mag x - Imag Y
for (int y=0;y<npts;y++){
series.add(tempVIDX.getAssociatedData().get(y).mag()*MagValues[indexToXScale], tempVIDY.getAssociatedData().get(y).imag()*MagValues[indexToYScale]);
}
gotASeries = true;
break;
case (10):// Phase x - Mag/Phase Y
case (13):
for (int y=0;y<npts;y++){
series.add(tempVIDX.getAssociatedData().get(y).arg(jComplexNumber.DEGREES), tempVIDY.getAssociatedData().get(y).mag()*MagValues[indexToYScale]);
}
gotASeries = true;
break;
case (11):// Phase x - dB/Phase Y
case (14):
for (int y=0;y<npts;y++){
series.add(tempVIDX.getAssociatedData().get(y).arg(jComplexNumber.DEGREES), 20.0D*Math.log10(tempVIDY.getAssociatedData().get(y).mag()));
}
gotASeries = true;
break;
case (12): //Phase Only
gotASeries = false;
break;
case(15):// Phase x - Real Y
for (int y=0;y<npts;y++){
series.add(tempVIDX.getAssociatedData().get(y).arg(jComplexNumber.DEGREES), tempVIDY.getAssociatedData().get(y).real()*MagValues[indexToYScale]);
}
gotASeries = true;
break;
case (16):// Phase x - Imag Y
for (int y=0;y<npts;y++){
series.add(tempVIDX.getAssociatedData().get(y).arg(jComplexNumber.DEGREES), tempVIDY.getAssociatedData().get(y).imag()*MagValues[indexToYScale]);
}
gotASeries = true;
break;
case (20): //Real - Mag/Phase Y
case (23):
for (int y=0;y<npts;y++){
series.add(tempVIDX.getAssociatedData().get(y).real()*MagValues[indexToXScale], tempVIDY.getAssociatedData().get(y).mag()*MagValues[indexToYScale]);
}
gotASeries = true;
break;
case (21): //Real - dB/Phase Y
case (24):
for (int y=0;y<npts;y++){
series.add(tempVIDX.getAssociatedData().get(y).real()*MagValues[indexToXScale], 20.0D*Math.log10(tempVIDY.getAssociatedData().get(y).mag()));
}
gotASeries = true;
break;
case (22)://Phase Only
gotASeries = false;
break;
case (25)://Real X - Real Y
for (int y=0;y<npts;y++){
series.add(tempVIDX.getAssociatedData().get(y).real()*MagValues[indexToXScale], tempVIDY.getAssociatedData().get(y).real()*MagValues[indexToYScale]);
}
gotASeries = true;
break;
case (26): //Real X - Image Y
for (int y=0;y<npts;y++){
series.add(tempVIDX.getAssociatedData().get(y).real()*MagValues[indexToXScale], tempVIDY.getAssociatedData().get(y).imag()*MagValues[indexToYScale]);
}
gotASeries = true;
break;
case (30): //Imag X - Mag/Phase Y
case (33):
for (int y=0;y<npts;y++){
series.add(tempVIDX.getAssociatedData().get(y).imag()*MagValues[indexToXScale], tempVIDY.getAssociatedData().get(y).mag()*MagValues[indexToYScale]);
}
gotASeries = true;
break;
case (31)://Imag X - dB/Phase Y
case (34):
for (int y=0;y<npts;y++){
series.add(tempVIDX.getAssociatedData().get(y).imag()*MagValues[indexToXScale], 20.0D*Math.log10(tempVIDY.getAssociatedData().get(y).mag()));
}
gotASeries = true;
break;
case (32):
gotASeries = false;
break;
case (35)://Imag X - Real Y
for (int y=0;y<npts;y++){
series.add(tempVIDX.getAssociatedData().get(y).imag()*MagValues[indexToXScale], tempVIDY.getAssociatedData().get(y).real()*MagValues[indexToYScale]);
}
gotASeries = true;
break;
case (36)://Imag X - Imag Y
for (int y=0;y<npts;y++){
series.add(tempVIDX.getAssociatedData().get(y).imag()*MagValues[indexToXScale], tempVIDY.getAssociatedData().get(y).imag()*MagValues[indexToYScale]);
}
gotASeries = true;
break;
}
if (gotASeries)
dataset.addSeries(series);
}
}
// See if the "Calculator" dataset needs to be added
// - jCBIncludeCalculator.isSelected()
if (includeCalculator) {
tempVIDY=WAS.get(dataSet).getInternalVID().get(analysisSelections[0]);
// Get the selected button which should have function stored into it
JToggleButtonwithFunction ButtonSelected = (JToggleButtonwithFunction) ((JButtonGroup) BGCalculator).getSelected();
//Create a brand-new series for the calculator set
series = new XYSeries("Calculation "+ButtonSelected.getText(),false);
switch (selectedSetting) {
case (0):// Mag x - Mag/Phase Y
case (3): // Mag x - Mag - only y
for (int y=0;y<npts;y++){
series.add(tempVIDX.getAssociatedData().get(y).mag()*MagValues[indexToXScale],
ButtonSelected.calculate(y, false, dataSet, analysisSelections, WAS).mag()*MagValues[indexToYScale]);
}
gotASeries = true;
break;
case (1):// Mag x - dB/Phase Y
case (4):// Mag x - dB only y
for (int y=0;y<npts;y++){
series.add(tempVIDX.getAssociatedData().get(y).mag()*MagValues[indexToXScale],
10.0D*Math.log10(ButtonSelected.calculate(y, false, dataSet, analysisSelections, WAS).mag()));
}
gotASeries = true;
break;
case (2)://Phase Only
for (int y=0;y<npts;y++){
series.add(tempVIDX.getAssociatedData().get(y).mag()*MagValues[indexToXScale],
ButtonSelected.calculate(y, true, dataSet, analysisSelections, WAS).real());
}
gotASeries = true;
break;
case (5):// Mag x - Real Y
for (int y=0;y<npts;y++){
series.add(tempVIDX.getAssociatedData().get(y).mag()*MagValues[indexToXScale],
ButtonSelected.calculate(y, false, dataSet, analysisSelections, WAS).real()*MagValues[indexToYScale]);
}
gotASeries = true;
break;
case(6):// Mag x - Imag Y
for (int y=0;y<npts;y++){
series.add(tempVIDX.getAssociatedData().get(y).mag()*MagValues[indexToXScale],
ButtonSelected.calculate(y, false, dataSet, analysisSelections, WAS).imag()*MagValues[indexToYScale]);
}
gotASeries = true;
break;
case (10):// Phase x - Mag/Phase Y
case (13):
for (int y=0;y<npts;y++){
series.add(tempVIDX.getAssociatedData().get(y).arg(jComplexNumber.DEGREES),
ButtonSelected.calculate(y, false, dataSet, analysisSelections, WAS).mag()*MagValues[indexToYScale]);
}
gotASeries = true;
break;
case (11):// Phase x - dB/Phase Y
case (14):
for (int y=0;y<npts;y++){
series.add(tempVIDX.getAssociatedData().get(y).arg(jComplexNumber.DEGREES),
10.0D*Math.log10(ButtonSelected.calculate(y, false, dataSet, analysisSelections, WAS).mag()));
}
gotASeries = true;
break;
case (12): //Phase Only
for (int y=0;y<npts;y++){
series.add(tempVIDX.getAssociatedData().get(y).arg(jComplexNumber.DEGREES),
ButtonSelected.calculate(y, true, dataSet, analysisSelections, WAS).real());
}
gotASeries = true;
break;
case(15):// Phase x - Real Y
for (int y=0;y<npts;y++){
series.add(tempVIDX.getAssociatedData().get(y).arg(jComplexNumber.DEGREES),
ButtonSelected.calculate(y, false, dataSet, analysisSelections, WAS).real()*MagValues[indexToYScale]);
}
gotASeries = true;
break;
case (16):// Phase x - Imag Y
for (int y=0;y<npts;y++){
series.add(tempVIDX.getAssociatedData().get(y).arg(jComplexNumber.DEGREES),
ButtonSelected.calculate(y, false, dataSet, analysisSelections, WAS).imag()*MagValues[indexToYScale]);
}
gotASeries = true;
break;
case (20): //Real - Mag/Phase Y
case (23):
for (int y=0;y<npts;y++){
series.add(tempVIDX.getAssociatedData().get(y).real()*MagValues[indexToXScale],
ButtonSelected.calculate(y, false, dataSet, analysisSelections, WAS).mag()*MagValues[indexToYScale]);
}
gotASeries = true;
break;
case (21): //Real - dB/Phase Y
case (24):
for (int y=0;y<npts;y++){
series.add(tempVIDX.getAssociatedData().get(y).real()*MagValues[indexToXScale],
10.0D*Math.log10(ButtonSelected.calculate(y, false, dataSet, analysisSelections, WAS).mag()));
}
gotASeries = true;
break;
case (22)://Phase Only
for (int y=0;y<npts;y++){
series.add(tempVIDX.getAssociatedData().get(y).real()*MagValues[indexToXScale],
ButtonSelected.calculate(y, true, dataSet, analysisSelections, WAS).real());
}
gotASeries = true;
break;
case (25)://Real X - Real Y
for (int y=0;y<npts;y++){
series.add(tempVIDX.getAssociatedData().get(y).real()*MagValues[indexToXScale],
ButtonSelected.calculate(y, false, dataSet, analysisSelections, WAS).real()*MagValues[indexToYScale]);
}
gotASeries = true;
break;
case (26): //Real X - Image Y
for (int y=0;y<npts;y++){
series.add(tempVIDX.getAssociatedData().get(y).real()*MagValues[indexToXScale],
ButtonSelected.calculate(y, false, dataSet, analysisSelections, WAS).imag()*MagValues[indexToYScale]);
}
gotASeries = true;
break;
case (30): //Imag X - Mag/Phase Y
case (33):
for (int y=0;y<npts;y++){
series.add(tempVIDX.getAssociatedData().get(y).imag()*MagValues[indexToXScale],
ButtonSelected.calculate(y, false, dataSet, analysisSelections, WAS).mag()*MagValues[indexToYScale]);
}
gotASeries = true;
break;
case (31)://Imag X - dB/Phase Y
case (34):
for (int y=0;y<npts;y++){
series.add(tempVIDX.getAssociatedData().get(y).imag()*MagValues[indexToXScale],
10.0D*Math.log10(ButtonSelected.calculate(y, false, dataSet, analysisSelections, WAS).mag()));
}
gotASeries = true;
break;
case (32):
for (int y=0;y<npts;y++){
series.add(tempVIDX.getAssociatedData().get(y).imag()*MagValues[indexToXScale],
ButtonSelected.calculate(y, true, dataSet, analysisSelections, WAS).real());
}
gotASeries = true;
break;
case (35)://Imag X - Real Y
for (int y=0;y<npts;y++){
series.add(tempVIDX.getAssociatedData().get(y).imag()*MagValues[indexToXScale],
ButtonSelected.calculate(y, false, dataSet, analysisSelections, WAS).real()*MagValues[indexToYScale]);
}
gotASeries = true;
break;
case (36)://Imag X - Imag Y
for (int y=0;y<npts;y++){
series.add(tempVIDX.getAssociatedData().get(y).imag()*MagValues[indexToXScale],
ButtonSelected.calculate(y, false, dataSet, analysisSelections, WAS).imag()*MagValues[indexToYScale]);
}
gotASeries = true;
break;
}
if (gotASeries)
dataset.addSeries(series);
}
/* Label the axes properly based on the new
* scaling
*/
StringBuilder xLabel = new StringBuilder(10);
StringBuilder yLabel = new StringBuilder(10);
switch (SpiceParsers.parseTypeVariable(tempVIDX.getTypeVariable())) {
case (SpiceParsers.TIME):
xLabel.append(JFSpiceFE.EngStrings[indexToXScale]+"sec");
break;
case(SpiceParsers.FREQUENCY):
xLabel.append(JFSpiceFE.EngStrings[indexToXScale]+"hertz");
break;
case(SpiceParsers.VOLTAGE):
xLabel.append(JFSpiceFE.EngStrings[indexToXScale]+"volt");
break;
case(SpiceParsers.CURRENT):
xLabel.append(JFSpiceFE.EngStrings[indexToXScale]+"amp");
break;
default:
xLabel.append(JFSpiceFE.EngStrings[indexToXScale]);
break;
}
switch (SpiceParsers.parseTypeVariable(tempVIDY.getTypeVariable())) {
case (SpiceParsers.TIME):
yLabel.append(JFSpiceFE.EngStrings[indexToYScale]+"sec");
break;
case(SpiceParsers.FREQUENCY):
yLabel.append(JFSpiceFE.EngStrings[indexToYScale]+"hertz");
break;
case(SpiceParsers.VOLTAGE):
yLabel.append(JFSpiceFE.EngStrings[indexToYScale]+"volt");
break;
case(SpiceParsers.CURRENT):
yLabel.append(JFSpiceFE.EngStrings[indexToYScale]+"amp");
break;
default:
yLabel.append(JFSpiceFE.EngStrings[indexToYScale]);
break;
}
JFreeChart chart = null;
int nextDataSetIndex = 1;
float dash[] = {4.0f, 4.0f, 2.0f, 4.0f};
Stroke phaseLineStroke = new BasicStroke(1.5f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 2.0f, dash, 0.0f);
/*
* Now to handle dual Y-axis
* jLYGraphingChoices.getSelectedIndex()
*/
switch (YGraphingChoices) {
case (0): // These add a second axis of phase
case (1):
if (addToAlreadySelectedGraph) {
CrossHairPanel tempCHP = (CrossHairPanel) jTBOutputGraphs.getSelectedComponent();
chart = tempCHP.getChartPanel().getChart();
//ensure we are not overwriting a previous dataset
nextDataSetIndex = chart.getXYPlot().getDatasetCount()+1;
//add the dataset instead of creating a new chart.
chart.getXYPlot().setDataset(nextDataSetIndex,dataset);
StandardXYItemRenderer renderera = new StandardXYItemRenderer();
renderera.setSeriesPaint(0, Color.blue);
for (int traces=0;traces<numberOfTraces;traces++){
renderera.setSeriesStroke(traces,phaseLineStroke);
}
renderera.setDrawSeriesLineAsPath(true);
chart.getXYPlot().setRenderer(nextDataSetIndex, renderera);
} else {
chart = ChartFactory.createXYLineChart(
chartTitle, // chart title
xLabel.toString(), // x axis label
yLabel.toString(), // y axis label
dataset, // data
PlotOrientation.VERTICAL,
true, // include legend
true, // tooltips
false // urls
);
}
XYSeriesCollection datasetPhase = new XYSeriesCollection();
for (int traces=0;traces<numberOfTraces;traces++){
tempVIDY=WAS.get(dataSet).getInternalVID().get(YAxis[traces]);
series = new XYSeries(tempVIDY.getVariableName()+" Phase",false);
for (int y=0;y<npts;y++){
series.add(tempVIDX.getAssociatedData().get(y).real()*MagValues[indexToXScale], tempVIDY.getAssociatedData().get(y).arg(jComplexNumber.DEGREES));
}
datasetPhase.addSeries(series);
}
XYPlot plot = (XYPlot) chart.getXYPlot();
NumberAxis axis2 = new NumberAxis("Phase (Deg)");
plot.setRangeAxis(1, axis2);
plot.setRangeAxisLocation(1, AxisLocation.BOTTOM_OR_RIGHT);
plot.setDataset(1, datasetPhase);
plot.mapDatasetToRangeAxis(1, 1);
StandardXYItemRenderer renderer2 = new StandardXYItemRenderer();
renderer2.setSeriesPaint(0, Color.red);
for (int traces=0;traces<numberOfTraces;traces++){
renderer2.setSeriesStroke(traces,phaseLineStroke);
}
renderer2.setDrawSeriesLineAsPath(true);
plot.setRenderer(1, renderer2);
plot.setBackgroundPaint(Color.white);
plot.setRangeGridlinePaint(Color.black);
plot.setDomainGridlinePaint(Color.black);
break;
case (2): // This makes a single Phase axis
for (int traces=0;traces<numberOfTraces;traces++){
tempVIDY=WAS.get(dataSet).getInternalVID().get(YAxis[traces]);
series = new XYSeries(tempVIDY.getVariableName(),false);
for (int y=0;y<npts;y++){
series.add(tempVIDX.getAssociatedData().get(y).real()*MagValues[indexToXScale], tempVIDY.getAssociatedData().get(y).arg(jComplexNumber.DEGREES));
}
dataset.addSeries(series);
}
if (addToAlreadySelectedGraph) {
CrossHairPanel tempCHP = (CrossHairPanel) jTBOutputGraphs.getSelectedComponent();
chart = tempCHP.getChartPanel().getChart();
//ensure we are not overwriting a previous dataset
nextDataSetIndex = chart.getXYPlot().getDatasetCount()+1;
//add the dataset instead of creating a new chart.
chart.getXYPlot().setDataset(nextDataSetIndex,dataset);
StandardXYItemRenderer renderera = new StandardXYItemRenderer();
renderera.setSeriesPaint(0, Color.blue);
for (int traces=0;traces<numberOfTraces;traces++){
renderera.setSeriesStroke(traces,phaseLineStroke);
}
renderera.setDrawSeriesLineAsPath(true);
chart.getXYPlot().setRenderer(nextDataSetIndex, renderera);
chart.getXYPlot().setBackgroundPaint(Color.white);
chart.getXYPlot().setRangeGridlinePaint(Color.black);
chart.getXYPlot().setDomainGridlinePaint(Color.black);
} else {
chart = ChartFactory.createXYLineChart(
chartTitle, // chart title
xLabel.toString(), // x axis label
yLabel.toString(), // y axis label
dataset, // data
PlotOrientation.VERTICAL,
true, // include legend
true, // tooltips
false // urls
);
chart.getXYPlot().setBackgroundPaint(Color.white);
chart.getXYPlot().setRangeGridlinePaint(Color.black);
chart.getXYPlot().setDomainGridlinePaint(Color.black);
}
break;
default: //Make sure a chart is made for all other cases
if (addToAlreadySelectedGraph) {
CrossHairPanel tempCHP = (CrossHairPanel) jTBOutputGraphs.getSelectedComponent();
chart = tempCHP.getChartPanel().getChart();
//ensure we are not overwriting a previous dataset
nextDataSetIndex = chart.getXYPlot().getDatasetCount()+1;
//add the dataset instead of creating a new chart.
chart.getXYPlot().setDataset(nextDataSetIndex,dataset);
StandardXYItemRenderer renderera = new StandardXYItemRenderer();
renderera.setSeriesPaint(0, Color.blue);
for (int traces=0;traces<numberOfTraces;traces++){
renderera.setSeriesStroke(traces,phaseLineStroke);
}
renderera.setDrawSeriesLineAsPath(true);
chart.getXYPlot().setRenderer(nextDataSetIndex, renderera);
chart.getXYPlot().setBackgroundPaint(Color.white);
chart.getXYPlot().setRangeGridlinePaint(Color.black);
chart.getXYPlot().setDomainGridlinePaint(Color.black);
} else {
chart = ChartFactory.createXYLineChart(
chartTitle, // chart title
xLabel.toString(), // x axis label
yLabel.toString(), // y axis label
dataset, // data
PlotOrientation.VERTICAL,
true, // include legend
true, // tooltips
false // urls
);
chart.getXYPlot().setBackgroundPaint(Color.white);
chart.getXYPlot().setRangeGridlinePaint(Color.black);
chart.getXYPlot().setDomainGridlinePaint(Color.black);
}
break;
}
//temppanel.setChart(chart);
//jCBILogXAxis.isSelected()
if (LogXAxisSelected) {
LogarithmicAxisZoomPatched xLogAxis = new LogarithmicAxisZoomPatched(xLabel.toString());
xLogAxis.setAllowNegativesFlag(true);
xLogAxis.setStrictValuesFlag(true);
XYPlot plotX = (XYPlot) chart.getPlot();
//try {
plotX.setBackgroundPaint(Color.white);
plotX.setRangeGridlinePaint(Color.black);
plotX.setDomainGridlinePaint(Color.black);
plotX.setDomainAxis(xLogAxis);
//} catch (Exception e){
//}
}
//jCBILogYAxis.isSelected()
if (LogYAxisSelected) {
LogarithmicAxisZoomPatched yLogAxis = new LogarithmicAxisZoomPatched(yLabel.toString());
yLogAxis.setAllowNegativesFlag(true);
yLogAxis.setStrictValuesFlag(true);
XYPlot plotY = (XYPlot) chart.getPlot();
//try {
plotY.setBackgroundPaint(Color.white);
plotY.setRangeGridlinePaint(Color.black);
plotY.setDomainGridlinePaint(Color.black);
plotY.setRangeAxis(yLogAxis);
//} catch (Exception e) {
//}
}
// No need to add a tab since we're using one already
if (!addToAlreadySelectedGraph) {
jTBOutputGraphs.addTab(chartTitle+" "+timesThrough, new CrossHairPanel(chart));
jTBOutputGraphs.setSelectedIndex(jTBOutputGraphs.getTabCount()-1);
}
/*
* Clear the internal VIDs for reading the next time
* This really get's the data sets and clears them
*/
for (int traces=0;traces<numberOfTraces;traces++){
tempVIDY=WAS.get(dataSet).getInternalVID().get(traces);
tempVIDY.getAssociatedData().clear();
}
// No need to do the X since that should be included
//tempVIDX.getAssociatedData().clear();
//ImageIcon ad = new javax.swing.ImageIcon(getClass().getResource("/spicefe/resources/jkspicead.png"));
//jFDisplayOutput.setVisible(true);
//Graphics2D fg2d = (Graphics2D) jPAddPanel.getGraphics();
//AffineTransform toScaleAT = new AffineTransform();
//toScaleAT.scale(2.0,2.0);
//fg2d.drawImage(ad.getImage(),toScaleAT,ad.getImageObserver());
}
@Override
protected ArrayList<WholeAnalysisSet> doInBackground() throws Exception {
ArrayList<WholeAnalysisSet> WAS = new ArrayList<WholeAnalysisSet>(3);
if (this.typeOfLoad == SpiceParsers.SPICERAWFILE) {
WAS = getSPICE3RawFile(this.RAWFile, WAS);
} else {
WAS = getGnuCapFile(this.RAWFile, WAS);
}
return WAS;
}
/**
* Some extra code
*
* desc.delete(0,desc.length());
* ii=-1;
* try {
* do {
* ii++;
* tempHolder[0] = in.readByte();
* desc.append(new String(tempHolder));
* } while(desc.substring(ii).compareTo("\n")!=0);
* } catch (IOException e) {
* System.out.println(e.toString());
* }
* System.out.println("This is as far as we got: "+desc+"........"+ii);
* desc.delete(0,desc.length());
*/
}