Example #1
0
        /// <summary>
        /// Equals(object)
        /// overrides Equals comparing ComponentInfo with an object
        /// </summary>
        /// <param name="obj"> The object to compare.</param>
        /// <returns>true if the values are equal.</returns>
        public override bool Equals(object obj)
        {
            // If parameter is null return false.
            if (obj == null)
            {
                return(false);
            }

            // If parameter cannot be cast to ComponentInfo return false.
            ComponentInfo p = obj as ComponentInfo;

            if ((System.Object)p == null)
            {
                return(false);
            }

            // Return true if the fields match:
            return(Equals(p));
        }
 public void missing()
 {
     Parse myParser = new Parse();
     string filename = Path.Combine(Path_TestModels, "missing.cir");
     ComponentInfo result = new ComponentInfo();
     var exception = Assert.Throws<Exception>(delegate
     {
         result = myParser.ParseFile(filename);
     });
     Assert.True(exception.Message.Contains("does not exist"));
 }
        public void nameCharsTestPass()
        {
            Parse myParser = new Parse();
            string filename = Path.Combine(Path_TestModels, "nameCharsTestPass.cir");
            ComponentInfo result = myParser.ParseFile(filename);

            ComponentInfo expected = new ComponentInfo()
            {
                name = "AaBbCXxYyZz!#$%[0189]_",
                elementType = 'X',
                parameters = new Dictionary<String, String>()
                {
                },
                pins = new List<string>()
                {
                    "1",
                    "2"
                }
            };

            Assert.True(result.Equals(expected));
        }
        public void firstLineCommentTest()
        {
            Parse myParser = new Parse();
            string filename = Path.Combine(Path_TestModels, "firstLineCommentTest.cir");
            ComponentInfo result = myParser.ParseFile(filename);

            ComponentInfo expected = new ComponentInfo()
            {
                name = "RES_2ndLineComponent",
                elementType = 'X',
                parameters = new Dictionary<String, String>()
                {
                },
                pins = new List<string>()
                {
                    "1",
                    "2"
                }
            };

            Assert.True(result.Equals(expected));
        }
        public void q2n222a()
        {
            Parse myParser = new Parse();
            string filename = Path.Combine(Path_TestModels, "q2n222a.cir");
            ComponentInfo result = myParser.ParseFile(filename);

            ComponentInfo expected = new ComponentInfo()
            {
                name = "Q2N222A",
                elementType = 'Q',
                parameters = new Dictionary<String, String>()
                {
                },
                pins = new List<string>()
                {
                    "COLLECTOR",
                    "BASE",
                    "EMITTER"
                }
            };

            Assert.True(result.Equals(expected));
        }
        /// <summary>
        /// Arrange SPICE-model pins into rows and columns.
        /// </summary>
        /// <param name="ci">The parsed SPICE subcircuit or model info.</param>
        /// <param name="spicePinNameDictionary">Maps SPICE pin names to SPICE pins.</param>
        /// <returns>A dictionary mapping spice pin names to an array containing their row number and column number.</returns>
        private Dictionary<string, int[]> ArrangeSpiceModelPinsIntoRowsAndCols(ComponentInfo ci, Dictionary<string, CyPhy.SchematicModelPort> spicePinNameDictionary)
        {
            List<string> spicePinNames = new List<string>(ci.pins);
            spicePinNames.Sort(ComparePinsUsingNaturalNumericOrder);
            // If more than 5 pins, arrange in two columns.
            int numberOfPinColumns = (spicePinNames.Count() > 5 ? 2 : 1);
            m_numberOfPinsPerColumn = spicePinNames.Count() / numberOfPinColumns;
            // Keep track of the rows and columns associated with the SPICE pins, for later schematic pin positioning.
            Dictionary<string, int[]> spicePinRowColDictionary = new Dictionary<string, int[]>();
            int pinIndex = 0;
            foreach (string pinName in spicePinNames)
            {
                var pinPort = spicePinNameDictionary[pinName];

                // Figure out what row and column this pin is in.
                int pinCol = pinIndex / m_numberOfPinsPerColumn;
                int pinRow = pinIndex % m_numberOfPinsPerColumn;
                pinIndex += 1;

                // Figure out the visual positioning of this pin within the SPICE model window.
                int pinX = PIN_X_OFFSET + (pinCol * PIN_X_SPACING);
                int pinY = PIN_Y_OFFSET + (pinRow * PIN_Y_SPACING);

                // Set the pin's GUI coordinates in all aspects.
                setFCOPosition(pinPort.Impl as MgaFCO, pinX, pinY);

                // Keep track of the row and column for later schematic pin positioning.
                int[] rowCol = { pinRow, pinCol };
                try
                {
                    spicePinRowColDictionary.Add(pinName, rowCol);
                }
                catch (Exception e)
                {
                    Logger.WriteWarning("WARNING! Exception adding pin '{0}' to spicePinRowColDictionary: {1}",
                        GetHyperlinkStringFromComponent(pinName, pinPort.Impl as IMgaFCO),
                        e.Message);
                }
            }

            // Show the rows and columns of the pins
            Logger.WriteDebug("Spice pin names (row,col):");
            foreach (var entry in spicePinRowColDictionary)
            {
                Logger.WriteDebug("   '{0}' ({1}, {2})",
                    GetHyperlinkStringFromComponent(entry.Key, spicePinNameDictionary[entry.Key].Impl as IMgaFCO),
                    entry.Value[0],
                    entry.Value[1]);
            }
            return spicePinRowColDictionary;
        }
        public void test00()
        {
            // Create a ComponentInfo class and set initial values.
            ComponentInfo ci = new ComponentInfo()
            {
                name = "RES_0603",
                elementType = 'X',
                parameters = new Dictionary<String, String>()
                {
                    {"RVAL", "1.0k"},
                    {"Bogus", "Yeah"}
                },
                pins = new List<string>()
                {
                    "PinOne",
                    "PinTwo"
                }
            };

            Assert.False(ci.Equals(null));
            Assert.True(ci.Equals(ci));

            // Create a ComponentInfo class and set initial values the same as before.
            ComponentInfo ci2 = new ComponentInfo()
            {
                name = "RES_0603",
                elementType = 'X',
                parameters = new Dictionary<String, String>()
                {
                    {"RVAL", "1.0k"},
                    {"Bogus", "Yeah"}
                },
                pins = new List<string>()
                {
                    "PinOne",
                    "PinTwo"
                }
            };
            Assert.True(ci.Equals(ci2));
            Assert.True(ci2.Equals(ci2));
            Assert.True(ci2.Equals(ci));

            // Create a ComponentInfo class but don't set initial values.
            ComponentInfo ci3 = new ComponentInfo();
            Assert.True(ci3.Equals(ci3));
            Assert.False(ci2.Equals(ci3));
            Assert.False(ci3.Equals(ci));

            // Create a ComponentInfo class and set initial values slightly differently.
            ComponentInfo ci4 = new ComponentInfo()
            {
                name = "RES_0603",
                elementType = 'X',
                parameters = new Dictionary<String, String>()
                {
                    {"RVAL", "1.0k"}
                },
                pins = new List<string>()
                {
                    "PinOne",
                    "PinTwo"
                }
            };

            Assert.True(ci4.Equals(ci4));
            Assert.False(ci2.Equals(ci4));

            // Create a ComponentInfo class with the pins in a different order.
            ComponentInfo ci5 = new ComponentInfo()
            {
                name = "RES_0603",
                elementType = 'X',
                parameters = new Dictionary<String, String>()
                {
                    {"RVAL", "1.0k"}
                },
                pins = new List<string>()
                {
                     "PinTwo",
                     "PinOne",
                }
            };


            Assert.True(ci5.Equals(ci5));
            Assert.False(ci5.Equals(ci4));

        }
 public void bogusparams1()
 {
     Parse myParser = new Parse();
     string filename = Path.Combine(Path_TestModels, "bogusparams1.cir");
     ComponentInfo result = new ComponentInfo();
     var exception = Assert.Throws<Exception>(delegate
     {
         result = myParser.ParseFile(filename);
     });
     Assert.True(exception.Message.Contains("needs an equals sign"));
 }
        public void test01()
        {
            Parse myParser = new Parse();
            string filename = Path.Combine(Path_TestModels, "L_LINEAR.cir");
            ComponentInfo result = myParser.ParseFile(filename);

            ComponentInfo expected = new ComponentInfo()
            {
                name = "L_LINEAR",
                elementType = 'X',
                parameters = new Dictionary<String, String>()
                {
                    {"Inductance", "10e-6"},
                    {"Rs", "0.01"},
                    {"Cp", "2e-12"},
                    {"Rp", "300e3"},
                },
                pins = new List<string>()
                {
                    "1",
                    "2"
                }
            };

            Assert.True(result.Equals(expected));
        }
Example #10
0
        /// <summary>
        /// Equals( ComponentInfo )
        /// overrides Equals with comparing ComponentInfo with another ComponentInfo
        /// </summary>
        /// <param name="ci"> The ComponentInfo to compare.</param>
        /// <returns>true if the values are equal.</returns>
        public bool Equals(ComponentInfo ci)
        {
            // If parameter is null return false.
            if (ci == null)
            {
                //Console.WriteLine("Null param found.");
                return(false);
            }

            if (elementType != ci.elementType)
            {
                //Console.WriteLine("elementType != ci.elementType.");
                return(false);
            }

            if (!name.Equals(ci.name))
            {
                //Console.WriteLine("name.Equals(ci.name).");
                return(false);
            }

            /***********************************
             * if (!(pins.Count == ci.pins.Count))
             * {
             *  //Console.WriteLine("!(pins.Count == ci.pins.Count).");
             *  return false;
             * }
             *
             * foreach (string pinname in pins)
             * {
             *  if (!ci.pins.Contains(pinname))
             *  {
             *      //Console.WriteLine("!ci.pins.Contains(pinname).");
             *      return false;
             *  }
             * }
             ******************************/


            if (!pins.SequenceEqual(ci.pins))
            {
                return(false);
            }


            if (!(parameters.Count == ci.parameters.Count))
            {
                //Console.WriteLine("!(parameters.Count == ci.parameters.Count).");
                return(false);
            }
            foreach (KeyValuePair <string, string> entry in parameters)
            {
                if (!ci.parameters.ContainsKey(entry.Key))
                {
                    //Console.WriteLine("!ci.parameters.ContainsKey( entry.Key ).");
                    return(false);
                }
                else if (!(ci.parameters[entry.Key] == entry.Value))
                {
                    //Console.WriteLine("!(ci.parameters[entry.Key] == entry.Value).");
                    return(false);
                }
            }
            //Console.WriteLine("OK.");
            // Return true if the fields match:
            return(true);
        }
        /// <summary>
        /// Create and connect schematic properties for unconnected SPICE parameters
        /// </summary>
        /// <param name="component">The component that will have property elements added.</param>
        /// <param name="ci">Parsed info about the subcircuit/model.</param>
        /// <param name="spiceParameterNameDictionary">A mapping of parameter names to SPICEModelParameters.</param>
        /// <param name="schematicPropertyNameDictionary">A mapping of property names to schematic properties.  Updated if properties are created.</param>
        /// <param name="unconnectedSpiceParameterNames">A list of the unconnected SPICE property names.</param>
        /// <remarks>The new properties will be placed in the component's window below the pins on the left of the SPICE model.</remarks>
        private void CreateAndConnectSchematicPropertiesForUnconnectedSpiceParameters(
            CyPhy.Component component, 
            ComponentInfo ci, 
            Dictionary<string, CyPhy.SPICEModelParameter> spiceParameterNameDictionary, 
            Dictionary<string, CyPhy.Property> schematicPropertyNameDictionary,
            List<string> unconnectedSpiceParameterNames)
        {
            unconnectedSpiceParameterNames.Sort(ComparePinsUsingNaturalNumericOrder);    // Sort the unconnected SPICE parameters so there is a chance of them being placed in order.
            int propertyRow = 0;
            // int propertyOffsetY = 200 + 15 * numberOfPinsPerColumn;
            foreach (string spiceParameterName in unconnectedSpiceParameterNames)
            {
 
                // Get the spice parameter
                var spiceParameter = spiceParameterNameDictionary[spiceParameterName];

                // Create the schematic property
                CyPhy.Property schematicProperty = CyPhyClasses.Property.Create(component);
                schematicProperty.Name = spiceParameterName;
                string valueWithOptionalNgspiceScaleFactors = ci.parameters[spiceParameterName];
                // See MOT-398 and section 2.1.3 of the Ngspice User's Manual Version 26plus.
                schematicProperty.Attributes.Value = GetNumericStringFromNgspiceNumberField( valueWithOptionalNgspiceScaleFactors );

                try
                {
                    schematicPropertyNameDictionary.Add(schematicProperty.Name, schematicProperty);
                    Logger.WriteInfo("Created a new property called \"{0}\".",
                        GetHyperlinkStringFromComponent(schematicProperty.Name, schematicProperty.Impl as IMgaFCO));
                }
                catch (Exception e)
                {
                    Logger.WriteWarning("Exception adding schematicProperty '{0}' to schematicPropertyNameDictionary: {1}",
                        GetHyperlinkStringFromComponent(schematicProperty.Name, schematicProperty.Impl as IMgaFCO),
                        e.Message);
                }


                // Compute the position of the newly-created property.
                int propertyX = SCHEMATIC_PIN_X_OFFSET;  // Position the parameters below the left pins
                int propertyY = m_startY + SCHEMATIC_PIN_Y_OFFSET + ((++propertyRow + m_numberOfPinsPerColumn) * SCHEMATIC_PIN_Y_SPACING);

                // Set the property's GUI coordinates in all aspects.
                setFCOPosition(schematicProperty.Impl as MgaFCO, propertyX, propertyY);

                // Create a connection between the schematic property and spice parameter.
                CyPhyClasses.SPICEModelParameterMap.Connect(
                    schematicProperty,
                    spiceParameter,
                    null,
                    null,
                    component);
            }
        }
        /// <summary>
        /// Creates new parameters within the SPICE model element, and also populates a parameter-name-to-SPICEModelParameter dictionary.
        /// </summary>
        /// <param name="ci">The parsed SPICE subcircuit or model info.</param>
        /// <param name="myModel">The SPICE model element that will have parameters added.</param>
        /// <param name="spiceParameterNameDictionary">A mapping between parameter names and SPICEModelParameters that gets populated.</param>
        private void CreateNewParametersWithinSpiceModelAndPopulateDictionary(
            ComponentInfo ci, 
            CyPhy.SPICEModel myModel, 
            out Dictionary<string, CyPhy.SPICEModelParameter> spiceParameterNameDictionary)
        {
            int paramRow = 0;
            spiceParameterNameDictionary = new Dictionary<string, CyPhy.SPICEModelParameter>();

            foreach (var param in ci.parameters)
            {
                // Create parameters within the Spice model
                CyPhy.SPICEModelParameter newParam = CyPhyClasses.SPICEModelParameter.Create(myModel);
                newParam.Name = param.Key;
                newParam.Attributes.Value = param.Value;

                // Place the parameter at the bottom left of the component, so even numbers of pins remain symmetric.
                int paramX = PIN_X_OFFSET;  // use the same X offset as the left pins.
                int paramY = PIN_Y_OFFSET + ((++paramRow + m_numberOfPinsPerColumn) * PIN_Y_SPACING);

                // Set the parameter's GUI coordinates in all aspects.
                setFCOPosition(newParam.Impl as MgaFCO, paramX, paramY);

                try
                {
                    // Add the new parameter to the SPICE parameter-name dictionary.
                    spiceParameterNameDictionary.Add(newParam.Name, newParam);
                }
                catch (Exception e)
                {
                    Logger.WriteWarning("Exception adding parameter '{0}' to spiceParameterNameDictionary: {1}",
                        GetHyperlinkStringFromComponent(newParam.Name, newParam.Impl as IMgaFCO),
                        e.Message);
                }
            }
        }
        public void ImportSpiceModel(CyPhy.Component component, String path_SpiceFile = null)
        {
            ComponentInfo ci = new ComponentInfo();

            Boolean ownLogger = false;
            if (Logger == null)
            {
                ownLogger = true;
                Logger = new CyPhyGUIs.GMELogger(component.Impl.Project, "SpiceModelImport");
            }

            if (path_SpiceFile == null)
            {
                using (OpenFileDialog ofd = new OpenFileDialog())
                {
                    ofd.CheckFileExists = true;
                    ofd.DefaultExt = "*.cir";
                    ofd.Multiselect = false;
                    ofd.Filter = "CIR (*.cir)|*.cir|All files (*.*)|*.*";
                    DialogResult dr = ofd.ShowDialog();
                    if (dr == DialogResult.OK)
                    {
                        path_SpiceFile = ofd.FileName;
                    }
                    else
                    {
                        Logger.WriteError("No file was selected. SPICE Model Import will not complete.");

                        if (ownLogger)
                        {
                            Logger.Dispose();
                            Logger = null;
                        }

                        return;
                    }
                }
                if (String.IsNullOrWhiteSpace(path_SpiceFile))
                {
                    Logger.WriteError("SPICE Model Path of \"{0}\" isn't valid.", path_SpiceFile);

                    if (ownLogger)
                    {
                        Logger.Dispose();
                        Logger = null;
                    }

                    return;
                }
            }

            try
            {
                Parse myParse = new Parse();
                ci = myParse.ParseFile(path_SpiceFile);
            }
            catch( Exception e )
            {
                Logger.WriteError("Error parsing '{0}': {1}", path_SpiceFile, e.Message);

                if (ownLogger)
                {
                    Logger.Dispose();
                    Logger = null;
                }

                return;
            }

            //-----------------------------------------------------------------------------------
            //
            //  At this point, the SPICE model file has been parsed and component info extracted.
            //
            //  'ci' has the SPICE component information.
            //  'component' is the GME component that the SPICE info will be added to.
            //  'path_SpiceFile' is the complete path and filename of the ".CIR" file.
            //
            //------------------------------------------------------------------------------------

            //// Clean up the classifications.
            //// This doesn't really belong here; it's just temporary to fix components on 4/1/2014.
            //string[] sArray = component.Attributes.Classifications.Replace( "/", ".").Split( '.' );
            //int sArrayLength = sArray.GetLength(0);
            //string s = "";
            //for (int i = 0; i < sArrayLength; i++)
            //{
            //    string ss = sArray[i].ToLower().Trim().Replace( ' ', '_');
            //    ss = ss.Replace("(", "").Replace(")", "");
            //    s += ss.Replace( "_&_", "_and_" );
            //    if (i + 1 < sArrayLength)
            //    {
            //        s += ".";
            //    }
            //}
            //component.Attributes.Classifications = s;



            // Find the visual coordinates of where the new SPICE model should be placed.
            getNewModelInitialCoordinates(component, out m_startX, out m_startY);

            //------------- Setup the pins
            // Make a list of the preexisting schematic pins (ports) in the component, if any,
            // as well as a dictionary mapping pin names to the ports,
            // for future use when creating SPICE pins that may need to connect to the
            // schematic pins.
            List<string> schematicPins = new List<string>();
            Dictionary<string, CyPhy.Port> schematicPinNameDictionary = new Dictionary<string, CyPhy.Port>();

            // Iterate over child (schematic) ports of the component, to fill in the pin list and dictionary.
            foreach (CyPhy.Port port in component.Children.PortCollection)
            {
                Logger.WriteDebug("Child Port: {0}", GetHyperlinkStringFromComponent(port.Name, port.Impl as IMgaFCO));    // MOT-228
                schematicPins.Add(port.Name);
                try
                {
                    schematicPinNameDictionary.Add( port.Name, port );
                }
                catch( Exception e )
                {
                    // Logger.WriteDebug("Exception adding pin '{0}' to schematicPinNameDictionary: {1}", port.Name, e.Message);
                    // Include GME hyperlink in the debug message for MOT-228:
                    
                    Logger.WriteDebug("Exception adding pin '{0}' to schematicPinNameDictionary: {1}",
                        GetHyperlinkStringFromComponent(port.Name, port.Impl as IMgaFCO),
                        e.Message);
                    // Cleanup
                    Logger.WriteWarning("Unable to match any schematic pins with SPICE pins; new pins will be created.");
                    schematicPins = new List<string>();
                    schematicPinNameDictionary = new Dictionary<string, CyPhy.Port>();
                    break;
                }
            }

            // Find a mapping between the schematic pins and the SPICE pins
            string[,] matchedPins = PinMatcher.PinMatcher.GetPinMatches( schematicPins, ci.pins);

            // Show the pin matches
            if (matchedPins.GetLength(0) > 0)
            {
                Logger.WriteDebug("Pin Matches:");

                for (int row = 0; row < matchedPins.GetLength(0); row++)
                {
                    // Print out the schematic pin name and the SPICE-model pin name, for each pin match.
                    string p0 = matchedPins[row, 0];
                    string p1 = matchedPins[row, 1];

                    // Substitute hyperlinks for the schematic pin names, for MOT-228.
                    if (schematicPinNameDictionary.ContainsKey(p0))
                    {
                        p0 = GetHyperlinkStringFromComponent(p0, schematicPinNameDictionary[p0].Impl as IMgaFCO);
                    }

                    Logger.WriteDebug(@"  {0} [{1}, {2}]", row + 1, p0, p1 );
                }
            }


            //------------------ Setup the Properties
            // Make a list of the preexisting schematic properties in the component, if any,
            // as well as a dictionary mapping property names to the properties,
            // for future use when creating SPICE parameters that may need to connect to the
            // properties.
            List<string> schematicProperties = new List<string>();
            Dictionary<string, CyPhy.Property> schematicPropertyNameDictionary = new Dictionary<string, CyPhy.Property>();

            // Iterate over child (schematic) properties of the component, to fill in the schematicProperties list and dictionary.
            foreach (CyPhy.Property property in component.Children.PropertyCollection)
            {
                Logger.WriteDebug("Child Property: {0} = {1}",
                    GetHyperlinkStringFromComponent(property.Name, property.Impl as IMgaFCO),
                    property.Attributes.Value);

                schematicProperties.Add(property.Name);

                try
                {
                    schematicPropertyNameDictionary.Add(property.Name, property);
                }
                catch (Exception e)
                {
                    Logger.WriteDebug("Exception adding property '{0}' to schematicPropertyNameDictionary: {1}",
                        GetHyperlinkStringFromComponent(property.Name, property.Impl as IMgaFCO),
                        e.Message);
                    // Cleanup
                    Logger.WriteWarning("Unable to match any schematic properties with SPICE parameters; new properties will be created.");
                    schematicProperties = new List<string>();
                    schematicPropertyNameDictionary = new Dictionary<string, CyPhy.Property>();
                    break;
                }
            }

            // Get a list of the SPICE parameter names
            List<string> spiceParameters = new List<string>( ci.parameters.Keys );

            // Find a mapping between the schematic properties and the SPICE parameters
            string[,] matchedProperties = PinMatcher.PinMatcher.GetPinMatches(schematicProperties, spiceParameters);

            // Show the property matches
            if (matchedProperties.GetLength(0) > 0)
            {
                Logger.WriteDebug("Property Matches:");

                for (int row = 0; row < matchedProperties.GetLength(0); row++)
                {
                    // Print out the schematic property name and the SPICE parameter name, for each mapping.
                    string p0 = matchedProperties[row, 0];
                    string p1 = matchedProperties[row, 1];

                    // Substitute hyperlinks for the schematic property names, for MOT-228.
                    if (schematicPropertyNameDictionary.ContainsKey(p0))
                    {
                        p0 = GetHyperlinkStringFromComponent(p0, schematicPropertyNameDictionary[p0].Impl as IMgaFCO);
                    }

                    Logger.WriteDebug(@"  {0} [{1}, {2}]", row + 1, p0, p1);
                }
            }


            //------------------------------------------------------------
            // Create a SPICEModel child
            CyPhy.SPICEModel newModel = CyPhyClasses.SPICEModel.Create(component);
            newModel.Name = ci.name +"_SPICEModel";
            newModel.Attributes.Notes = "Created using SPICE Model CAT Module";
            newModel.Attributes.Class = string.Format("{0}:{1}", ci.elementType, ci.name);

            Logger.WriteInfo("Created a new SPICEModel: \"{0}\"", GetHyperlinkStringFromComponent(newModel.Name, newModel.Impl as IMgaFCO));

            // Adjust the SpiceLib model's label length to allow complete pin and property names to be seen.
            newModel.Preferences.PortLabelLength = 0;

            // Set the SPICE model's visual position.
            setFCOPosition(newModel.Impl as MgaFCO, m_startX, m_startY);

            // Create new ports within the SPICEModel, and add them to a SPICE-pin dictionary
            Dictionary<string, CyPhy.SchematicModelPort> spicePinNameDictionary = CreatePortsWithinTheSpiceModelForEachSpicePin(ci, newModel);

            // Arrange the SPICE model's pins into columns.
            Dictionary<string, int[]> spicePinRowColDictionary = ArrangeSpiceModelPinsIntoRowsAndCols(ci, spicePinNameDictionary);

            // Now the SPICE-model pins (ports) have been added to the SPICE model.
            // We need to connect them to existing schematic pins, if possible,
            // based on how the SPICE pin names matched with the schematic pin names.
            m_unconnectedSpicePinNames = new List<string>();  // Keep track of any SPICE pins that don't get connected.

            ConnectSpiceModelPortsToExistingSchematicPinsIfPossible(component, schematicPinNameDictionary, matchedPins, spicePinNameDictionary);

            CreateAndConnectSchematicPinsForUnconnectedSpicePins(component, spicePinNameDictionary, spicePinRowColDictionary, schematicPinNameDictionary);

            // Create new parameters within the SPICEModel, and add them to a SPICE parameter-name dictionary
            Dictionary<string, CyPhy.SPICEModelParameter> spiceParameterNameDictionary;
            CreateNewParametersWithinSpiceModelAndPopulateDictionary(ci, newModel, out spiceParameterNameDictionary);

            // Now the SPICE-model parameters (properties) have been added to the SPICE model.
            // We need to connect them to existing properties, if possible,
            // based on how the SPICE parameter names matched with the schematic property names.
            List<string> unconnectedSpiceParameterNames;  // Keeps track of any SPICE parameters that don't get connected.
            ConnectSpiceModelParametersToExistingPropertiesIfPossible(
                component, 
                schematicPropertyNameDictionary, 
                matchedProperties, 
                spiceParameterNameDictionary, 
                out unconnectedSpiceParameterNames);


            // Now we need to create and connect schematic properties for any SPICE parameters that are still unconnected.
            CreateAndConnectSchematicPropertiesForUnconnectedSpiceParameters(
                component, 
                ci, 
                spiceParameterNameDictionary, 
                schematicPropertyNameDictionary,
                unconnectedSpiceParameterNames);

            // Get the visual location to place the SPICE-model-file resource.
            int spiceModelfileResourceX = m_startX + 200;
            int spiceModelFileResourceY = m_startY - 100;

            string subdirectory = "Spice";  // The subdirectory where the SPICE file will be copied.

            //  - Copy the SPICE Model files into the component's back-end folder

            string verbose = "";    // String used for exception debugging.
            string destFileName = "";   // Name of the destination SPICE file after possible modification during copying.
            try
            {
                CopySpiceFile(component, path_SpiceFile, subdirectory, out destFileName, out verbose);

            }
            catch (Exception e)
            {
                Logger.WriteError("{1}Exception copying SPICE file: {0}", e.Message, verbose);
                return;
            }

            // Create the SPICE-model-file resource
            CreateSpiceModelFileResource(
                component,
                subdirectory,
                destFileName,
                path_SpiceFile,
                spiceModelfileResourceX,
                spiceModelFileResourceY,
                newModel);


            if (ownLogger)
            {
                Logger.Dispose();
                Logger = null;
            }
        }
 public void shortSubcircuit()
 {
     Parse myParser = new Parse();
     string filename = Path.Combine(Path_TestModels, "shortSubcircuit.cir");
     ComponentInfo result = new ComponentInfo();
     var exception = Assert.Throws<Exception>(delegate
     {
         result = myParser.ParseFile(filename);
     });
     Assert.True(exception.Message.Contains("Not enough fields"));
 }
        public void test2()
        {
            Parse myParser = new Parse();
            string filename = Path.Combine(Path_TestModels, "test2.cir");
            ComponentInfo result = myParser.ParseFile(filename);

            ComponentInfo expected = new ComponentInfo()
            {
                name = "DB9",
                elementType = 'X',
                parameters = new Dictionary<String, String>()
                {
                },
                pins = new List<string>()
                {
                    "PIN1",
                    "PIN2",
                    "PIN3",
                    "PIN4",
                    "PIN5",
                    "PIN6",
                    "PIN7",
                    "PIN8",
                    "PIN9"
                }
            };

            Assert.True(result.Equals(expected));
        }
 public void bogusName()
 {
     Parse myParser = new Parse();
     string filename = Path.Combine(Path_TestModels, "bogusName.cir");
     ComponentInfo result = new ComponentInfo();
     var exception = Assert.Throws<Exception>(delegate
     {
         result = myParser.ParseFile(filename);
     });
     Assert.True(exception.Message.Contains("not a valid model name"));
 }
        public void test3()
        {
            Parse myParser = new Parse();
            string filename = Path.Combine(Path_TestModels, "test3.cir");
            ComponentInfo result = myParser.ParseFile(filename);

            ComponentInfo expected = new ComponentInfo()
            {
                name = "RES_0603_330",
                elementType = 'R',
                parameters = new Dictionary<String, String>()
                {
                },
                pins = new List<string>()
                {
                    "PIN1",
                    "PIN2"
                }
            };

            Assert.True(result.Equals(expected));
        }
 public void braceTest()
 {
     Parse myParser = new Parse();
     string filename = Path.Combine(Path_TestModels, "braceTest.cir");
     ComponentInfo result = new ComponentInfo();
     var exception = Assert.Throws<Exception>(delegate
     {
         result = myParser.ParseFile(filename);
     });
     Assert.True(exception.Message.Contains("brace-expression parameter"));
 }
        public void multiparams()
        {
            Parse myParser = new Parse();
            string filename = Path.Combine(Path_TestModels, "multiparams.cir");
            ComponentInfo result = myParser.ParseFile(filename);

            ComponentInfo expected = new ComponentInfo()
            {
                name = "RES_MP",
                elementType = 'X',
                parameters = new Dictionary<String, String>()
                {
                    {"RVAL", "1.0k"},
                    {"LVAL", "800pH"}
                },
                pins = new List<string>()
                {
                    "1",
                    "2"
                }
            };

            Assert.True(result.Equals(expected));
        }
        /// <summary>
        /// Equals( ComponentInfo )
        /// overrides Equals with comparing ComponentInfo with another ComponentInfo
        /// </summary>
        /// <param name="ci"> The ComponentInfo to compare.</param>
        /// <returns>true if the values are equal.</returns>
        public bool Equals(ComponentInfo ci)
        {
            // If parameter is null return false.
            if (ci == null)
            {
                //Console.WriteLine("Null param found.");
                return false;
            }

            if (elementType != ci.elementType)
            {
                //Console.WriteLine("elementType != ci.elementType.");
                return false;
            }

            if (!name.Equals(ci.name))
            {
                //Console.WriteLine("name.Equals(ci.name).");
                return false;
            }

            /***********************************
            if (!(pins.Count == ci.pins.Count))
            {
                //Console.WriteLine("!(pins.Count == ci.pins.Count).");
                return false;
            }

            foreach (string pinname in pins)
            {
                if (!ci.pins.Contains(pinname))
                {
                    //Console.WriteLine("!ci.pins.Contains(pinname).");
                    return false;
                }
            }
             ******************************/


            if (!pins.SequenceEqual(ci.pins))
            {
                return false;
            }


            if (!(parameters.Count == ci.parameters.Count))
            {
                //Console.WriteLine("!(parameters.Count == ci.parameters.Count).");
                return false;
            }
            foreach (KeyValuePair<string, string> entry in parameters)
            {
                if (!ci.parameters.ContainsKey( entry.Key ) )
                {
                    //Console.WriteLine("!ci.parameters.ContainsKey( entry.Key ).");
                    return false;
                }
                else if (!(ci.parameters[entry.Key] == entry.Value))
                {
                    //Console.WriteLine("!(ci.parameters[entry.Key] == entry.Value).");
                    return false;
                }
            }
            //Console.WriteLine("OK.");
            // Return true if the fields match:
            return true;
        }
        /// <summary>
        /// Creates a SchematicModelPort (pin) within the SPICE-model element for each SPICE pin.
        /// </summary>
        /// <param name="ci">Parsed SPICE-file info about the SPICE subcircuit or model.</param>
        /// <param name="newModel">The SPICE-model element.</param>
        /// <returns>A mapping of SPICE pin names to SchematicModelPorts internal to the SPICE-model element.</returns>
        private Dictionary<string, CyPhy.SchematicModelPort> CreatePortsWithinTheSpiceModelForEachSpicePin(ComponentInfo ci, CyPhy.SPICEModel newModel)
        {
            Dictionary<string, CyPhy.SchematicModelPort> spicePinNameDictionary = new Dictionary<string, CyPhy.SchematicModelPort>();

            int spicePinNumber = 0;
            foreach (string portName in ci.pins)
            {
                // Create a new port within the SPICEModel.
                CyPhy.SchematicModelPort newPort = CyPhyClasses.SchematicModelPort.Create(newModel);
                newPort.Name = portName;
                newPort.Attributes.SPICEPortNumber = spicePinNumber++;

                try
                {
                    // Add the new port to the SPICE pin-name dictionary.
                    spicePinNameDictionary.Add(newPort.Name, newPort);
                }
                catch (Exception e)
                {
                    Logger.WriteWarning("WARNING! Exception adding pin '{0}' to spicePinNameDictionary: {1}",
                        GetHyperlinkStringFromComponent(newPort.Name, newPort.Impl as IMgaFCO),
                        e.Message);
                }
            }
            return spicePinNameDictionary;
        }