.. _schematics:

==========
Schematics
==========


Introduction
============

High quality schematics can be generated from a netlist using
Circuitikz for LaTeX diagrams.  This is much easier than writing
Circuitikz commands directly in LaTeX.

A semi-automatic component placement is used with hints required to
designate component orientation and explicit wires to link nodes of
the same potential but with different coordinates.

Here's an example:
   >>> from lcapy import Circuit
   >>> cct = Circuit("""
   ... V 1 0 {V(s)}; down
   ... R 1 2; right
   ... C 2 _0_2; down
   ... W 0 _0_2; right"")
   >>> cct.draw('schematic.pdf')

Note, the orientation hints are appended to the netlist strings with a
semicolon delimiter.  The drawing direction is with respect to the
first node.  The component W is a wire.  Node names starting with an underscore are not drawn.

The image generated by this netlist is:

.. image:: examples/schematics/schematic.png
   :width: 4cm


Here's another example, this time loading the netlist from a file:
   >>> from lcapy import Circuit
   >>> cct = Circuit('voltage-divider.sch')
   >>> cct.draw('voltage-divider.pdf')

Here are the contents of the file 'voltage-divider.sch'::

   Vi 1 0_1; down
   R1 1 2; right, size=1.5
   R2 2 0; down
   P1 2_2 0_2; down, v=V_o
   W 2 2_2; right
   W 0_1 0; right
   W 0 0_2; right

Here, P1 defines a port.  This is shown as a pair of open blobs.  The
wires do not need unique names.

.. image:: examples/schematics/voltage-divider.png
   :width: 5cm


Component orientation
---------------------

Lcapy uses a semi-automated component layout.  Each component requires
a specified orientation: up, down, left, or right.  In addition,
attributes can be added to override color, size, etc.

The drawing direction provides a constraint.  For example, the nodes
of components with a vertical orientation have the same x coordinate,
whereas nodes of horizontal components have the same y coordinate.

The component orientation is specified by a rotation angle.  This
angle is degrees anticlockwise with zero degrees being along the
positive x axis.  For example,

   >>> cct.add('D1 1 2; rotate=45')

The component orientation can also be specified by a direction keyword.  Note, this rotates the component:

- right (0 degrees)

- left  (180 degrees)

- up    (90 degrees)

- down  (-90 degrees)

For example:

.. literalinclude:: examples/schematics/Dright.sch

.. image:: examples/schematics/Dright.png
   :width: 2.5cm

.. literalinclude:: examples/schematics/Ddown.sch

.. image:: examples/schematics/Ddown.png
   :width: 1.5cm

Note, the drawing direction is from the positive node to the negative
node.

Here's an example of how to draw a diode bridge:

.. literalinclude:: examples/schematics/Dbridge.sch

.. image:: examples/schematics/Dbridge.png
   :width: 4cm


Most components can be mirrored about the x-axis using the `mirror` or
`flipud` attributes and mirrored about the y axis with the `invert` or
`fliplr` attribute.  For example, to switch the order of the inverting
and non-inverting inputs of an opamp use:

   >>> cct.add('E1 1 2 opamp 3 0; right, mirror')

Note, the mirroring is performed before rotations are applied.  Opamps also have a `mirrorinputs` option that switches the inverting and non-inverting inputs pwithout mirroring the entire component.

Here's an example of using `invert` to mirror a D flip-flop in the y-axis, compared to rotating the flip-flop:

.. literalinclude:: examples/schematics/fliplr1.sch

.. image:: examples/schematics/fliplr1.png
   :width: 12cm
   

Component size
--------------

By default each component has a minimum size of 1. This can be
stretched to satisfy a node constraint.  The minimum size is specified
using the size keyword, for example:

   >>> cct.add('R1 1 2; right, size=2')

The size argument is used as a scale factor for the component node
spacing.  The size can also be specified by adding a value to the
`left`, `right`, `up`, or `down` arguments.  For example:

   >>> cct.add('R1 1 2; right=2')

Here's a comparison of resistors of different sizes.

.. literalinclude:: examples/schematics/resistors1.sch

.. image:: examples/schematics/resistors1.png
   :width: 14cm

By default, a component with size 1 has its nodes spaced by 2 units.
This can be changed using the `node_spacing` option of the schematic.
For example,

.. literalinclude:: examples/schematics/resistors2.sch

.. image:: examples/schematics/resistors2.png
   :width: 10.5cm

Be default, a component has a length of 1.5 units.  This can be
changed using the `cpt_size` option of the schematic.  For example,

.. literalinclude:: examples/schematics/resistors3.sch

.. image:: examples/schematics/resistors3.png
   :width: 14cm

.. literalinclude:: examples/schematics/resistors4.sch

.. image:: examples/schematics/resistors4.png
   :width: 7cm

The size of components can scaled with the `scale` attribute:

.. literalinclude:: examples/schematics/resistors6.sch

.. image:: examples/schematics/resistors6.png
   :width: 14cm

The overall schematic can be scaled with the `scale` option of the schematic:

.. literalinclude:: examples/schematics/resistors5.sch

.. image:: examples/schematics/resistors5.png
   :width: 7cm


Nodes
-----

Nodes are shown by a blob.  By default, only the primary nodes (those
not starting with an underscore) are shown by default.  This is
equivalent to:

    >>> cct.draw(draw_nodes='primary')

All nodes can be drawn using:

    >>> cct.draw(draw_nodes='all')

Only the nodes where there are more than two branches can be drawn using:

    >>> cct.draw(draw_nodes='connections')

No nodes can be drawn using:

    >>> cct.draw(draw_nodes=False)

By default, only the primary nodes are labelled.  All nodes can be
labelled (this is useful for debugging) using:

    >>> cct.draw(label_nodes='all')

No nodes can be labelled using:

    >>> cct.draw(label_nodes=False)

Only nodes starting with a letter can be labelled using:

    >>> cct.draw(label_nodes='alpha')

In this case nodes with names such as `in` and `out` will be displayed
but not numeric node names.

These options can be stored with the schematic netlist, for example::

  C1 1 0 100e-12; down, size=1.5, v={5\,kV}
  R1 1 6 1500; right
  R2 2 4 1e12; down
  C2 3 5 5e-9; down
  W 2 3; right
  W 0 4; right
  W 4 5; right
  SW 6 2 no; right, l=, size=1.5
  ; draw_nodes=connections, label_nodes=False, label_ids=False


Node names
----------

Circuit nodes are usually identified by a number.  They can be given arbitrary names provided they do not contain a period (.).  By default, nodes with names starting with an underscore are not drawn.  The name can contain an underscore to denote a subscript or a caret to denote a superscript.  For example, `T_123`.

Node names starting with a period are a short-hand notation.  For
example::

  R1 1 .2; right
  C1 R1.2 3; right

is short-hand for::

  R1 1 R1.2; right
  C1 R1.2 3; right

Node names not starting with an underscore are considered primary nodes.
Node names starting with an underscore are considered secondary nodes (usually they are at the same potential as a primary node and do not need to be
labelled).  For backward compatibility, nodes with names that contain an underscore and start with a digit are considered secondary.

Node names can also refer to pins of shape and chip components.  For example::

  U1 regulator; right
  W  1 U1.in; right
  W  U1.gnd 0; down
  

Components
==========

Only linear, time-invariant, components can be analyzed by Lcapy.   However, many others can be drawn.


Batteries
---------

.. literalinclude:: examples/schematics/batteries.sch

.. image:: examples/schematics/batteries.png
   :width: 3cm


Crystals
--------

.. literalinclude:: examples/schematics/XT1.sch

.. image:: examples/schematics/XT1.png
   :width: 2cm


Constant phase elements (CPE)
-----------------------------

.. literalinclude:: examples/schematics/CPE1.sch

.. image:: examples/schematics/CPE1.png
   :width: 2cm        


Diodes
------

Diodes can be drawn but not simulated.   A standard diode is described using:

     Dname Np Nm

Different kinds of diodes can be specified by the `kind` option, for example,
           
.. literalinclude:: examples/schematics/diodes.sch

.. image:: examples/schematics/diodes.png
   :width: 10cm

The drawn style is controlled by the style option, for example, 

.. literalinclude:: examples/schematics/diodes2.sch

.. image:: examples/schematics/diodes2.png
   :width: 5cm


Ferrite beads
-------------

.. literalinclude:: examples/schematics/FB1.sch

.. image:: examples/schematics/FB1.png
   :width: 2cm


           
Gyrators
--------

.. literalinclude:: examples/schematics/GY1.sch

.. image:: examples/schematics/GY1.png
   :width: 2cm


Integrated circuits
-------------------

ICs can be drawn but not simulated.  Here's an example:

.. literalinclude:: examples/schematics/ic1.sch

.. image:: examples/schematics/ic1.png
   :width: 8cm

In this example, the `chip2121` keyword specifies a block with two
pins on the left, one on the bottom, two on the right, and one at the
top.  The component has pre-defined pinnames, `l1`, `l2`, `vss`, `r2`,
`r1`, and `vdd`; these can be modified.  Since the pin names start
with a dot the associated node names are prefixed by the name of the
chip, for example, `U1.out1`.

The supported chips are:
 - `chip1313`
 - `chip2121`  
 - `chip2222`
 - `chip3131`
 - `chip3333`  
 - `chip4141`
 - `buffer`
 - `inverter`
 - `regulator`
 - `adc`
 - `dac`
 - `dff`
 - `jkff`
 - `rslatch`
 - `fdopamp`
 - `inamp`
 - `isoamp`  
 - `opamp`  
 - `mux21`
 - `mux41`  
 - `mux42`   


.. image:: examples/schematics/Uchip1313.png
   :width: 5cm

.. image:: examples/schematics/Uchip2121.png
   :width: 5cm

.. image:: examples/schematics/Uchip2222.png
   :width: 5cm
        
.. image:: examples/schematics/Uchip3131.png
   :width: 5cm

.. image:: examples/schematics/Uchip3333.png
   :width: 5cm

.. image:: examples/schematics/Uchip4141.png
   :width: 5cm

.. image:: examples/schematics/Uregulator.png
   :width: 5cm

.. image:: examples/schematics/Uadc.png
   :width: 5cm                                        

.. image:: examples/schematics/Udac.png
   :width: 5cm

.. image:: examples/schematics/Uopamp.png
   :width: 5cm

.. image:: examples/schematics/Uinamp.png
   :width: 5cm        

.. image:: examples/schematics/Ufdopamp.png
   :width: 5cm        

.. image:: examples/schematics/Uisoamp.png
   :width: 5cm

.. image:: examples/schematics/Umux21.png
   :width: 5cm

.. image:: examples/schematics/Umux41.png
   :width: 5cm

.. image:: examples/schematics/Umux42.png
   :width: 5cm

.. image:: examples/schematics/Udff.png
   :width: 5cm

.. image:: examples/schematics/Ujkff.png
   :width: 5cm

.. image:: examples/schematics/Urslatch.png
   :width: 5cm                                                   

.. image:: examples/schematics/Uinverter.png
   :width: 5cm

.. image:: examples/schematics/Ubuffer.png
    :width: 5cm
        
           
Chips are subclassed from the shape class and thus the pins can be
labelled, renamed, etc.  For example:

.. literalinclude:: examples/schematics/pindefs1.sch

.. image:: examples/schematics/pindefs1.png
   :width: 4cm


Meters
------

Here's an example using a voltmeter and an ammeter:

.. literalinclude:: examples/schematics/meters2.sch

.. image:: examples/schematics/meters2.png
   :width: 5cm


Miscellanous components
-----------------------

Miscellaneous Circuitikz bipole components can be drawn using a `MISC`
component.  For example,

.. literalinclude:: examples/schematics/misc.sch

.. image:: examples/schematics/misc.png
   :width: 5cm

See the Circuitikz manual for bipole components that can be drawn.
           

Opamps
------

Opamps can be drawn using the `opamp` argument to a VCCS.   For example:

.. literalinclude:: examples/schematics/opamp1.sch

.. image:: examples/schematics/opamp1.png
   :width: 5cm

The size can be controlled with the `scale` and `size` options.  The
positions of the inverting and non-inverting inputs can be flipped
with the `mirror` option.

.. literalinclude:: examples/schematics/opamp2.sch

.. image:: examples/schematics/opamp2.png
   :width: 5cm


.. literalinclude:: examples/schematics/opamp3.sch

.. image:: examples/schematics/opamp3.png
   :width: 5cm


.. literalinclude:: examples/schematics/opamp4.sch

.. image:: examples/schematics/opamp4.png
   :width: 5cm

Fully differential opamps can be drawn in a similar manner using the
fdopamp argument to a VCCS.  For example:

.. literalinclude:: examples/schematics/fdopamp1.sch

.. image:: examples/schematics/fdopamp1.png
   :width: 5cm


Opamps and fully differential opamps have additional pins that can be connected:
           
.. image:: examples/schematics/opamps.png
    :width: 10cm

.. image:: examples/schematics/fdopamps.png
   :width: 10cm                   

Opamps and fully differential opamps can also be drawn without the
wires using the integrated circuit syntax.  However, these cannot be
analysed electrically.  For example:


.. literalinclude:: examples/schematics/Uopamp1.sch

.. image:: examples/schematics/Uopamp1.png
   :width: 7.5cm

Here are the named connections:
           
.. image:: examples/schematics/Uopamps.png
    :width: 10cm

.. image:: examples/schematics/Ufdopamps.png
   :width: 10cm                   

           
Potentiometers
--------------

.. literalinclude:: examples/schematics/RV1.sch

.. image:: examples/schematics/RV1.png
   :width: 1.6cm

Alternatively, a variable resistor can be defined using:

.. literalinclude:: examples/schematics/RV2.sch

.. image:: examples/schematics/RV2.png
   :width: 1.4cm


Switches
--------

Switches can be drawn but they are ignored for analysis since they
make the circuit time-varying.

The general format is:

     SWname Np Nm nc|no|push

Here's an example:

.. literalinclude:: examples/schematics/switches.sch

.. image:: examples/schematics/switches.png
   :width: 8cm

Switches can be mirrored and inverted, for example:

.. literalinclude:: examples/schematics/switches2.sch

.. image:: examples/schematics/switches2.png
   :width: 8cm

           
Transformers
------------

.. literalinclude:: examples/schematics/TF1.sch

.. image:: examples/schematics/TF1.png
   :width: 1.4cm

.. literalinclude:: examples/schematics/TFcore1.sch

.. image:: examples/schematics/TFcore1.png
   :width: 1.4cm

.. literalinclude:: examples/schematics/TFtap1.sch

.. image:: examples/schematics/TFtap1.png
   :width: 3cm

.. literalinclude:: examples/schematics/TFtapcore1.sch

.. image:: examples/schematics/TFtapcore1.png
   :width: 3cm


Transistors
-----------

Transistors (BJT, JFET, and MOSFET) can be drawn but not analyzed.  Both
are added to the netlist using a syntax similar to that of SPICE.  A BJT
is described using:
    
     Qname NC NB NE npn|pnp

where NC, NB, and NE denote the collector, base, and emitter nodes.
A MOSFET is described using:

     Mname ND NG NS nmos|pmos

where ND, NG, and NS denote the drain, gate, and source nodes.

A JFET is described using:

     Jname ND NG NS njf|pjf

where ND, NG, and NS denote the drain, gate, and source nodes.

Here's an example:

.. literalinclude:: examples/schematics/transistors.sch


.. image:: examples/schematics/transistors.png
   :width: 16cm

The transistors can be flipped up-down with the `mirror` attribute and left-right with the `invert` attribute, for example:           

.. literalinclude:: examples/schematics/transistors2.sch


.. image:: examples/schematics/transistors2.png
   :width: 6cm           


Transmission lines
------------------

A transmission line is a two-port device.  Here's an example:

.. literalinclude:: examples/schematics/tline3.sch

.. image:: examples/schematics/tline3.png
    :width: 8cm

The ground wires can be removed using the `nowires` attribute:
        
.. literalinclude:: examples/schematics/tline5.sch

.. image:: examples/schematics/tline5.png
   :width: 8cm        

For more generic transmission lines see :ref:`cables`.
           

Mechanical components
---------------------

Springs, dampers (dashpots), and masses are oneport components for modelling mechanical systems, for example,

.. literalinclude:: examples/schematics/massspringdamper1.sch

.. image:: examples/schematics/massspringdamper1.png
   :width: 8cm        


           
Wires
=====

Wires are useful for schematic formatting, for example,

   W 1 2; right

Here an anonymous wire is created since it has no identifier.

The line style of wires can be changed, such as dashed or dotted (see
:ref:`linestyles`).

Wires can be implicitly added using the `offset` attribute.  Here's an
example to draw two parallel resistors:

.. literalinclude:: examples/schematics/parallel.sch

.. image:: examples/schematics/parallel.png
   :width: 2.5cm


Stepped wires
-------------
           
Stepped wires can be drawn using the `steps` attribute.  For example:

.. literalinclude:: examples/schematics/steppedwire1.sch

.. image:: examples/schematics/steppedwire1.png
   :width: 3cm


.. literalinclude:: examples/schematics/steppedwire2.sch

.. image:: examples/schematics/steppedwire2.png
   :width: 3cm        

In these examples, the `free` attribute is used so that the wire places no constraints on the node positions.   Thus the `size` and `rotate` attributes are ignored.   The open-circuit component is used to fix the node locations.

The `-` character represents a horizontal step and the `|` character represents a vertical step.   The shape of the line is controlled by the step pattern.  For example `--|-` represents two steps horizontally, one step vertically, and then one step horizontally.  A number before the `-` or `|` symbol specifies the number of repeats of the step.  For example, `steps=-4|-` is equivalent to `steps=-||||-`.

If the step pattern is not specified, a default step pattern `-|` is chosen if the horizontal extent is longer than the vertical extent and `|-` is chosen otherwise.  For example,

.. literalinclude:: examples/schematics/steppedwire0.sch

.. image:: examples/schematics/steppedwire0.png
   :width: 3cm        

           
Arrows
------

Arrows can be drawn on wires using the `startarrow` and `endarrow` attributes.
There are many arrow styles, see the tikz manual.  For example,

.. literalinclude:: examples/schematics/arrows.sch

.. image:: examples/schematics/arrows.png
   :width: 10cm

           
Implicit wires
--------------

Implicit wires are commonly employed for power supply and ground
connections.  They have one of the following attributes:

- `implicit` equivalent to signal ground
- `sground`  signal ground      
- `ground`  earth ground
- `cground`  chassis ground
- `nground`  noiseless ground
- `pground`  protected ground
- `rground`  reference ground
- `vcc`      positive power supply (voltage to collectors)
- `vdd`      positive power supply (voltage to drains ;-)
- `vee`      negative power supply (voltage to emitters)
- `vss`      negative power supply (voltage to sources)    

Here are some ground examples:
   
.. literalinclude:: examples/schematics/grounds.sch

.. image:: examples/schematics/grounds.png
    :width: 15cm


Here are some power supply examples:
   
.. literalinclude:: examples/schematics/supplies.sch

.. image:: examples/schematics/supplies.png
    :width: 3cm
        

Connections
-----------

These are similar to implicit wires but are useful for denoting an off-sheet connection or an IC pin.   They have one of the attributes:

- `input`   input connection
- `output`  output connection
- `bidir`   bidirectional connection
- `pad`     generic connection


For example:
   
.. literalinclude:: examples/schematics/connections1.sch

.. image:: examples/schematics/connections1.png
   :width: 10cm  
    
The sizes of the pads can be controlled with the `width` and `aspect`
attributes.

For example:
   
.. literalinclude:: examples/schematics/connections2.sch

.. image:: examples/schematics/connections2.png
   :width: 15cm  


.. _cables:
           
Cables
======

The kind of cable is specified with the `kind` attribute.  This can be
`coax`, `twinax`, `twistedpair`, `shieldedtwistedpair`, or `tline`
(transmission line).  The default is `coax`.  Note, this component is
experimental and the syntax may change.

.. image:: examples/schematics/cable.png
   :width: 7.5cm  

Here are some examples:

.. literalinclude:: examples/schematics/cable-coax.sch

.. image:: examples/schematics/cable-coax.png
   :width: 7.5cm

.. literalinclude:: examples/schematics/cable-twinax.sch

.. image:: examples/schematics/cable-twinax.png
   :width: 7.5cm


.. literalinclude:: examples/schematics/cable-tp.sch

.. image:: examples/schematics/cable-tp.png
   :width: 7.5cm

.. literalinclude:: examples/schematics/cable-utp.sch

.. image:: examples/schematics/cable-utp.png
   :width: 7.5cm

.. literalinclude:: examples/schematics/cable-tline.sch

.. image:: examples/schematics/cable-tline.png
   :width: 7.5cm


.. literalinclude:: examples/schematics/guard1.sch

.. image:: examples/schematics/guard1.png
   :width: 12cm                             


Block diagrams
==============

Block diagrams can be constructed with the following components:
 - `TF` transfer function
 - `SPpp`, `SPpm`, `SPppp`, `SPpmm`, `SPppm` summing points
 - `MX` mixer
 - `box` rectangular box
 - `circle` circle (or ellipse)

Here's an example showing negative feedback:

.. literalinclude:: examples/schematics/negative-feedback3.sch

.. image:: examples/schematics/negative-feedback3.png
    :width: 8cm


Here's a more complicated example for a causal system:

.. literalinclude:: examples/schematics/LTFT.sch

.. image:: examples/schematics/LTFT.png
   :width: 12cm        

           
Summing points
--------------

There are a number of summing point varieties: `SPpp`, `SPpm`,
`SPppp`, `SPpmm`, `SPppm`.  The `p` suffix stands for plus, the `m`
suffix stands for minus.  The other variations can be generated using
the `mirror` attribute.

Here's an example:

.. literalinclude:: examples/schematics/SP4.sch

.. image:: examples/schematics/SP4.png
   :width: 2.5cm


Mixers
------

Here's a example of a mixer:

.. literalinclude:: examples/schematics/MX1.sch

.. image:: examples/schematics/MX1.png
   :width: 3cm


Shapes
------

Shapes include `box`, `circle`, `ellipse`, `triangle`.

`box`, `circle`, `ellipse`, and `triangle` shapes have default anchor
nodes based on the centre (`c`) and sixteen directions of the compass:
`n`, `nne`, `ne`, `ene`, `e`, `ese`, `se`, `sse`, `s`, `ssw`, `sw`,
`wsw`, `w`, `wnw`, `nw`, `nww`.

.. image:: examples/schematics/Sbox2.png
   :width: 5cm

.. image:: examples/schematics/Scircle2.png
   :width: 5cm

.. image:: examples/schematics/Striangle2.png
   :width: 5cm                


The aspect ratio of `box`, `circle`, and `triangle` can be controlled
with the `aspect` attribute.

Here's an example of their use:

.. literalinclude:: examples/schematics/fir5.sch

.. image:: examples/schematics/fir5.png
   :width: 5cm


`triangle` is an equilateral triangle.  Its shape can be changed with the `aspect` attribute.   It has anchors `n`, `e`, `s`, `w`, `c`, `c1`, `c2`, `c3`,
           

The label of a shape can be replaced by an image, using the `image` keyword.  For example,

.. literalinclude:: examples/schematics/image1.sch


Each shape has a number of predefined connection pins.  Associated
with each pin is an optional label.


The `pinlabels` option can be specified as:
 - `all` : the default labels for all the pins are shown
 - `connected` : the default labels for all the connected pins are shown  
 - `none` : none of the default labels are shown
 - `{pin1:label1, pin2:label2, ...}` : the labels are specified for the named pins.

The names of the pins can be drawn using the `pinnames` option.  This has a syntax:
 - `all` : the pin names for all the pins are shown
 - `connected` : the pin names for all the connected pins are shown  
 - `none` : none of the pin names are shown
 - `{pin1, pin2, ...}` : the specified pin names are shown.

The nodes of the pins can be drawn using the `pinnodes` option.  This has a syntax:
 - `all` : the pin nodes for all the pins are shown
 - `connected` : the pin nodes for all the connected pins are shown  
 - `none` : none of the pin nodes are shown
 - `{pin1, pin2, ...}` : the specified pin nodes are shown.     

The pin names can be redefined by the `pindefs` option.  This has a syntax:
  - `pindefs={new1=old1, new2=old2, ...}`

                    
Annotation
==========

Nodes can be annotated using the `A` net.   For example,

.. literalinclude:: examples/schematics/annotate1.sch

.. image:: examples/schematics/annotate1.png
   :width: 7cm
                    

Schematics can be annotated using additional tikz commands in the
netlist.  These are delimited by a line starting with two semicolons,
for example:

.. literalinclude:: examples/schematics/fit1.sch

This example draws dashed boxes around the nodes 0, 1, and 6 and 2, 3,
4, and 5:

.. image:: examples/schematics/fit1.png
   :width: 7cm

Alternatively, the boxes can be fit around named components, for
example::

    ;;\node[blue,draw,dashed,inner sep=5mm, fit=(R2) (C2), label=CMOS input model]{};


When referring to an anchor of a component it is necessary to use `@` instead of `.`, for example, `U1@tl` instead of `U1.tl`.  Here's an example:


.. literalinclude:: examples/schematics/fit3.sch

.. image:: examples/schematics/fit3.png
   :width: 10cm
    

Styles
======

Three component styles are supported: `american` (default), `british`, and
`european`.  The style is set by a style argument to the `draw` method
or by a schematic option.  For example,

.. literalinclude:: examples/schematics/lpf1-buffer-loaded3.sch

.. image:: examples/schematics/lpf1-buffer-loaded3.png
   :width: 10.5cm
 

Colors
------

By default the components are drawn in black.  This can be overridden
with the color attribute, for example:

   >>> cct.add('R1 1 2; right, color=blue')

Colors can be specified many ways, see https://en.wikibooks.org/wiki/LaTeX/Colors and https://latexcolor.com/

Here are some examples using the `fill` attribute:

.. image:: examples/schematics/colors1.png
   :width: 20cm

Shading can be performed using the `top color` and `bottom color` attributes, see https://pgf-tikz.github.io/pgf/pgfmanual.pdf
           

.. _linestyles:

Line styles
-----------

The line style of wires can be changed using the tikz attributes, `dashed`, `dotted`, `thick`, `ultra thick`, `line width`, `densely dotted`, `loosely dashed` and many others.  For example,

.. literalinclude:: examples/schematics/wirestyles.sch

.. image:: examples/schematics/wirestyles.png
   :width: 12cm


Labels
------

Each component has a component identifier label and a value label.
These can be augmented by explicit voltage, current, and flow labels.

- l=label -- component label

- i=label -- current label
 
- v=label -- voltage label

- f=label -- flow label

The label name can be displayed using LaTeX math mode by enclosing the
name between dollar signs.  Thus superscripts and subscripts can be
employed.  For example,

>>> cct.add('R1 1 2; right, i=$I_1$, v=$V_{R_1}$')

The component and voltage label positions can be controlled with the
`^` and `_` attrbutes.  The `^` attribute positions the label above
the component and the `_` attribute positions the label below the
component.  For example,

.. literalinclude:: examples/schematics/labels1.sch

.. image:: examples/schematics/labels1.png
   :width: 8cm

.. literalinclude:: examples/schematics/voltage_labels1.sch

.. image:: examples/schematics/voltage_labels1.png
   :width: 8cm

The current and flow labels have additional `<` and `>` attributes to
specify the flow direction.  If these come before the `^` and `_`
attributes, the label is positioned at the start of the component
otherwise it is positioned at the end of the component.

Here are some examples of current and flow label positioning:

.. literalinclude:: examples/schematics/current_labels1.sch

.. image:: examples/schematics/current_labels1.png
   :width: 20cm

.. literalinclude:: examples/schematics/current_labels2.sch

.. image:: examples/schematics/current_labels2.png
   :width: 20cm           

.. literalinclude:: examples/schematics/flow_labels1.sch

.. image:: examples/schematics/flow_labels1.png
   :width: 20cm                        

By default, if a component has a value label it is displayed,
otherwise the component identifier is displayed.  Both can be
displayed using:

    >>> cct.draw(label_ids=True, label_values=True)

Schematic options are separated using a comma.  If you need a comma,
say in a label, enclose the field in braces.  For example:

    >>> C1 1 0 100e-12; down, size=1.5, v={5\,kV}

Math-mode labels need to be enclosed in `$...$`.  There is an
experimental feature that is activated when the label starts with a
single un-matched `$`.  In this case, Lcapy tries to generate a nice LaTeX label.
For example, words in sub- and superscripts are converted into a roman
font using `mathrm`.  This feature is also activated if the label is
not enclosed in `$...$` but includes an `^` or `_`.

Voltage labels can be annotated between pairs of nodes using an
open-circuit component.   For example,

    >>> O1 1 0; down, v=V_1


Component attributes
--------------------

- `size`: scale factor for distance between component's nodes

- `scale`: scale factor for length of component

- `rotate`: angle in degrees to rotate component anti-clockwise

- `mirror`: mirror component in x-axis (opamps, transistors)

- `mirrorinputs`: mirror inputs for opamps

- `invisible`: connect to the other components but do not draw

- `ignore`: do not connect to the other components and do not draw (this is useful for simulating multiple mutual inductances but where it it is too hard to show them on a schematic)

- `free`: place no constraints on the node positions; this is useful for stepped wires.  With this attribute the `size` and `rotate` attributes are ignored.
  
- `color`: component color

- `variable`: for variable resistors, inductors, and capacitors

- `kind`: `electrolytic`, `polar`, or `variable` for capacitors; `variable` for inductors
  
- `fixed`: do not stretch

- `aspect`: set aspect ratio for boxes

- `pins`: define pin labels for ICs

- `anchors`: specify which anchors to show

- `offset`: distance to orthogonally offset component (useful for parallel components)
  

Here's an example using the variable attribute:

.. literalinclude:: examples/schematics/variable1.sch

.. image:: examples/schematics/variable1.png
   :width: 5cm

Here's an example using the kind attribute to specify the type of capacitor.


.. literalinclude:: examples/schematics/capacitors.sch

.. image:: examples/schematics/capacitors.png
   :width: 7cm

           

Schematic attributes
--------------------

- `node_spacing`: scale factor for distance between component nodes (default 2).

- `cpt_size`: length of component (default 1.5).

- `scale`: scale factor (default 1).

- `help_lines`: spacing between help lines (default 0 to disable).

- `draw_nodes`: specifies which nodes to draw (default `primary`). Its argument can either be `all`, `connections` (nodes that connect at least two components), `none`, or `primary` (node names not starting with an underscore).

- `label_nodes`: specifies which nodes to label (default `primary`).  Its argument can either be `all`, `alpha` (node names starting with a letter), `none`, or `primary` (node names not starting with an underscore).

- `label_ids`: specifies whether component ids are drawn (default `true`).

- `label_values`: specifies whether component values are drawn (default `true`).

- `style`: specifies the component style.  This is either `american`,  `british`, or `european` (default `american`).

- `dpi`: dots per inch (default 150) when converting to a PNG file (as used for displaying Jupyter notebooks).  This will change the displayed size of the schematic on the screen.
  
Schematic attributes apply to the whole schematic.  They can be specified by starting a netlist with a semicolon, for example,

    ;help_lines=1, draw_nodes=connections

The schematic attributes can be overridden using arguments to the `draw` method.  For example,
 
    >>> sch.draw(draw_nodes='alpha')


Includes
========

Large schematics can be composed by including smaller schematics using the `.include` directive, for example::
   
   .include part1.sch
   .include part2.sch

Each of the smaller schematics can be included into their own namespace to avoid conflicts, for example::

   .include LC1.sch as s1
   .include LC1.sch as s2
   W s1.2 s2.1; right=0.1
   W s1.3 s2.0; right=0.1



Namespaces
==========

Hierarchical namespaces are supported, for example::

   a.R1 1 2; right
   b.R1 1 2; right

This creates two resistors: `a.R1` with nodes `a.1` and `a.2` and `b.R1` with nodes `b.1` and `a.2`.   They can be joined using::

   W a.2 b.1; right

When node names start with a dot, they are defined relative to the
name of the component, for example::

   R1 .p .m; right
   W 1 R1.p; right
   W R1.m 2; right



Examples
========

Inverting opamp amplifier
-------------------------

.. literalinclude:: examples/schematics/opamp-inverting-amplifier.sch

.. image:: examples/schematics/opamp-inverting-amplifier.png
   :width: 5cm

           
Non-Inverting opamp amplifier
-----------------------------

.. literalinclude:: examples/schematics/opamp-noninverting-amplifier.sch

.. image:: examples/schematics/opamp-noninverting-amplifier.png
   :width: 5cm

           
Inverting opamp integrator
--------------------------

.. literalinclude:: examples/schematics/opamp-inverting-integrator.sch

.. image:: examples/schematics/opamp-inverting-integrator.png
   :width: 5cm


CMOS inverter
-------------

.. literalinclude:: examples/schematics/cmos1.sch

.. image:: examples/schematics/cmos1.png
   :width: 5cm


Diode bridge
------------

.. literalinclude:: examples/schematics/D4.sch

.. image:: examples/schematics/D4.png
   :width: 3.5cm


Labelled circuit
----------------           

.. literalinclude:: examples/schematics/VRL2.sch

.. image:: examples/schematics/VRL2.png
   :width: 8cm


Loaded opamp model
------------------           

.. literalinclude:: examples/schematics/lpf1-buffer-loaded2.sch

.. image:: examples/schematics/lpf1-buffer-loaded2.png
   :width: 10.5cm


Sallen Key filter           
-----------------

.. literalinclude:: examples/schematics/sallen-key-lpf1.sch

.. image:: examples/schematics/sallen-key-lpf1.png
   :width: 9cm


CMOS back-drive
---------------           
           
.. literalinclude:: examples/schematics/cmos-backdrive2.sch

.. image:: examples/schematics/cmos-backdrive2.png
   :width: 9cm


Pierce oscillator
-----------------
           
.. literalinclude:: examples/schematics/pierce-oscillator.sch

.. image:: examples/schematics/pierce-oscillator.png
    :width: 4cm

            
Accelerometer
-------------

In this example, a dashed wire connects the electrical and mechanical grounds for simulation.
            
.. literalinclude:: examples/schematics/accelerometer1.sch

.. image:: examples/schematics/accelerometer1.png
   :width: 10cm        


Customisation
=============

Circuitikz commands (indeed any TikZ/PGF macros) can be embedded in a netlist.  Here's an example that embeds a circuitikz command to change the inductor style:

.. literalinclude:: examples/schematics/L1.sch

.. image:: examples/schematics/L1.png
   :width: 5cm

           
File formats
============

Lcapy uses the filename extension to determine the file format to
produce.  This must be one of tex, schtex, pgf, png, svg, or pdf.  The
pgf format is useful for including schematics into LaTeX documents.
The tex, schtex, and pgf extension generates a standalone LaTeX file.
If no filename is specified, the schematic is displayed on the screen.

By default, the png format is used for interactive drawing.  However,
being a bit-mapped image, the quality is poor.  First, LaTeX is used to
create a temporary pdf file; this is then converted to png format.
Several strategies are tried to do the conversion:

 1. `ghostscript`

 2. ImageMagick `convert` (By default pdf conversions are disabled.  On a Linux system edit `/etc/ImageMagick-6/policy.xml` to enable this conversion.)

 3. `pdftoppm` (this does a poor job with thin lines)

When using a Jupyter notebook, the svg format can be used with
`draw(svg=True`).  However, Jupyter has problems loading multiple svg files.


.. _schtex:

schtex
======

`schtex` is a Python script that will generate a schematic from a
netlist file.  For example, here's how a png file can be generated:

   >>> schtex Dbridge.sch Dbridge.png

The generated stand-alone LaTeX file can be obtained using:

   >>> schtex Dbridge.sch Dbridge.tex

If you wish to include the schematic into a LaTeX file use:

   >>> schtex Dbridge.sch Dbridge.pgf

and then include the file with `\\input{Dbridge.pgf}`.

`schtex` has many command line options to configure the drawing.
These override the options specified in the netlist file.  For example:

   >>> schtex --draw_nodes=connections --label_nodes=false --cpt-size=1 --help_lines=1 Dbridge.sch Dbridge.pdf


One useful option is to renumber the nodes in a netlist.  For example,

   >>> schtex --renumber='10:1, 11:2' infile.sch outfile.sch

This will choose small integers for the node numbers, honoring the provided mapping.  Equipotential nodes will be distinguished using enumerated subscripts, e.g., 1_1, 1_2, 1_3 etc.   


Schematics in LaTeX
===================

Here's an example of how to include an Lcapy schematic in a LaTeX document.

.. literalinclude:: examples/schematics/pic4-demo.tex

A PDF file can be produced using:
                    
.. code:: bash
          
          $ schtex pic4.sch pic4.pgf
          $ pdflatex pic4-demo


   
Drawing tips
============

Lcapy uses a semi-automated approach to component layout.  For each
component it needs its orientation and size.  By default the size
is 1.  This is the minimum distance between its nodes (for a one-port
device). If the component can be stretched, Lcapy will increase but
never decrease this distance.

The x and y positions of nodes are computed independently using a
graph.  An error can occur if components have the wrong orientation
since this makes the graph inconsistent.  Unfortunately, it is not
trivial to find the offending component so it is best to draw a
schematic incrementally and to test it as you go.  A sketch on a piece
of paper showing the nodes is useful.

Problems can occur using components, such as integrated circuits and
opamps, that cannot be stretched.  Usually this is due to a conflict
between constraints.  A solution is to reduce the size of the
component if it can be stretched, such as a wire or resistor.
Sometimes it is necessary to add a short interconnecting wire.

The stretching of components can be prevented by specifying the
`fixed` attribute.

Additional constraints can be supplied by using an open-circuit to
align components.

Grid lines can be added to a schematic using some Tikz markup.  For
example::

   ;;\draw[help lines] (0,0) grid [xstep=0.1, ystep=0.1] (10,5);  
  

Unfortunately, the drawing quality depends on the installed version of
circuitikz due to slight tweakings of component sizes.
