mph- / lcapy

Lcapy is a Python package for symbolic linear circuit analysis and signal processing. It uses SymPy for symbolic mathematics.
GNU Lesser General Public License v2.1
246 stars 47 forks source link

Netlist .include problem when pasing filepath #150

Open dzenki-byte opened 1 week ago

dzenki-byte commented 1 week ago

Hi, recently I have encountered a problem when defining a circuit using an subcircuit defined in an external file. Below is my code where I define a circuit using a link to a transistor model i have defined in a separate file.

   t_file = os.path.join(transistor_save_dir, t_sch)

    circuit_text = f'''
                    .include {t_file} as x1
                    .include {t_file} as x2

                    P1 1 0_1

                    R_1 1 x1._G
                    W 1 x1._D
                    W x1._S x2._S

                    W x2._G 0
                    W 0_1 0
                    W 0 0_2

                    R_2 x1._G 2
                    W x2._D 2

                    P2 2 0_2
                    '''

    circuit = lp.Circuit(circuit_text)

File path is contained in t_file variable of the form folder_a/folder with spaces/transistor_model.sch. Problem arises when there are spaces in the file path, namely _include(self, string) method in NetfileMixin uses parts = string.split(' ') to split the .include {t_file} as x1 into 4 parts but this also splits the file path leading to error. I have fixed this by using regular expressions:

    pattern = r'(\.include)\s+(.+?)\s+(as)\s+(\w+)'
    matches = re.match(pattern, string)
    if matches:
        parts = list(matches.groups())
    else:
        raise ValueError('Expecting include filename in %s' % string)

(\.include)matches .include. \s+ matches one or more whitespace characters. (.+?)lazily matches the file path (anything between .include and as). (as) matches the keyword as. (\w+) matches the name following as (e.g., x1).

Is there a better way of including subcircuits into the schematic?

mph- commented 1 week ago

Ah, I see the problem. I grew up in a world where you never put spaces in filenames but the world has changed.

Your regular expression seems fine. An alternative would be to require filenames with spaces to be enclosed in braces. Then we could use the split function in parser.py. Which do you think is best from a user's perspective?

dzenki-byte commented 3 days ago

Sorry for the slow answer. Braces seem more foolproof but i think that few more words on .include in package documentation would be more beneficial, so that users are more aware of this option.

On a similar topic i found an error in open_circuit() method of Cpt class. When calling circuit.open_circuit('OA1.C_in') I get the following error:

  File... in __init__
    circuit.open_circuit('OA1.C_in')

  File .../lcapy/netlist.py:878 in open_circuit
    return self.elements[cpt].open_circuit()

  File .../lcapy/mnacpts.py:853 in open_circuit
    net = self._netmake((dummy_node, ) + self.relnodes[1:])

TypeError: can only concatenate tuple (not "list") to tuple

I was able to fix the issue by implementing the following code.

  def open_circuit(self):
        """Apply open-circuit in series with component.  Returns name of
        open-circuit component."""

        dummy_node = self._dummy_node()
        net = self._netmake((dummy_node, ) + tuple(self.relnodes[1:]))
        self.cct.remove(self.name)
        self.cct.add(net)
        self.cct.add('O? %s %s' % (self.relnodes[0].name, dummy_node.name)) 
        return self.cct.last_added()

P. S. I really like Lcapy and I hope you continue developing it. One feature I think would be very useful is the graphical interface. I have seen that you have started development on that issue but what I would recommend is using something similar to SLiCAP_python package. What they did is use existing software such as KiCAD, LTspice and gSchem/Lepton-eda and defined custom elements that you download and place in appropriate folders (https://analog-electronics.tudelft.nl/slicap/html/userguide/circuit.html#ltspice). I have used this approach with Lepton-eda on Linux and was able to run some of the schematics in lcapy with some manual editing.