For simplified generation of device CAD files.
Stable and latest versions available. Use "latest" until this package is officially registered.
Old documentation available here.
Julia package for CAD of superconducting devices operating at microwave frequencies.
License: Other
See PR #29 for new features to document.
...resulting in undesirable behavior in most conceivable cases. Possible solutions include:
abs
of the length and emitting no warningabs
of the length and emitting a warningArgumentError
With units supported, we should not mix Cells with and without units.
It would be nice to be able to use render methods without introducing a cell, just to get the raw polygons. Perhaps something like
r = Rectangle(10µm, 10µm)
plgs = render(r, Rectangles.Rounded(2µm))
Not urgent to fix, but it seems like an LCDFonts test fails every once in a while, e.g. https://travis-ci.org/PainterQubits/Devices.jl/jobs/276978411
LCDFonts: Test Failed
Expression: height(bounds(c)) ≈ pix_size + pix_spacing * 4 + (ceil(length(a_string) / ll) - 1) * pix_spacing * 11
Evaluated: 56325.56643644704 nm ≈ 68.9438041053689 μm
Stacktrace:
[1] macro expansion at /home/travis/.julia/v0.6/Devices/test/runtests.jl:1163 [inlined]
[2] macro expansion at ./test.jl:860 [inlined]
[3] macro expansion at /home/travis/.julia/v0.6/Devices/test/runtests.jl:1106 [inlined]
[4] macro expansion at ./test.jl:860 [inlined]
[5] anonymous at ./<missing>:?
cc @mtfang
Minimal reproducer:
using Devices, Devices.PreferMicrons
using FileIO
c = Cell("rect", μm)
r = Rectangle(20μm, 10μm)
render!(c, r)
d = Cell("main", μm)
push!(d.refs, CellReference(c, Point(0μm, 0μm)))
push!(d.refs, CellReference(c, Point(0μm, 0μm), xrefl=true, rot=180°))
save("test.gds", d) # correct
save("test2.gds", flatten(d)) # incorrect
Found by @eunjongkim.
I could imagine there being situations where it is useful to have overall path styles in addition to the segment styles. Examples:
Would need some API consideration.
Devices.jl worked with StaticArrays 0.6.4. It seems the first commit that broke Devices.jl was JuliaArrays/StaticArrays.jl@025a991#comments
Causes flatten! method to fail (dimension incompatibility error) when flattening CellReferences
I had some ideas for tests whenever you have some time:
linelimit
: Test for the expected bounding box for a cell given a large string input using bounds(cell)
scripting
: Test bounding box for a short string for scripting
equal to true
or false
pixelsize
, pixelspacing
: Test expected bounding boxes for a single character string given various pixelsize, pixelspacing inputs, including w/ and w/o units?referenced_characters_demo
, characters_demo
, scripted_demo
. One idea would be to add in runtests.jl
the lines:
characters_demo("/path/to/output.gds")
@test length(read("/path/to/output.gds")) == 30254
test
directory.P.S. docs now include inline demos using SVG graphics.
e.g. sometimes CellReference(c, Point(0,0))
will fail with an InexactError
.
Add exhaustive tests to ensure that everything works as expected.
How to do this? diff with known good result files?
Including but not limited to:
CompoundSegment
function continues as expected beyond endpointsGiven how often we want to taper a path it makes sense to make proper style types.
Related to #26. Should be more explicit that "x-reflection" means a reflection over the x-axis, not x -> -x
.
See the constructor for CellReference
for how to implement synonyms in kwargs.
The following works:
temp_cell = Cell("temp", nm)
width = 46μm
gap = 5μm
styleCPW = Paths.CPW(width, gap)
res = Path(nm)
straight!(res, 100μm, styleCPW)
render!(temp_cell, res, GDSMeta(BASE_METAL))
temp_cell
Whereas the following:
temp_cell = Cell("temp", nm)
width = 46μm
gap = 5μm
styleCPW = Paths.CPW(width, gap)
res = Path(nm)
straight!(res, 100μm, styleCPW)
turn!(res, -π/2, 10μm)
render!(temp_cell, res, GDSMeta(BASE_METAL))
temp_cell
throws an error:
in foo at PhononicShieldResonators.jl:59
in #render!#7 at Devices\src\render\paths.jl:24
in render! at Devices\src\render\render.jl:12
in #render!#61 at Devices\src\render\render.jl:12
in #render!#25 at Devices\src\render\cpw.jl:10
in #adapted_grid#1 at Devices\src\utils.jl:28
in adapted_grid at Devices\src\utils.jl:31
in assemble_grids at Devices\src\utils.jl:42
in #27 at Devices\src\render\cpw.jl:10
in direction at Devices\src\paths\paths.jl:239
in derivative at Devices\src\units.jl:42
in broadcast at base\broadcast.jl:434
in broadcast_c at StaticArrays\src\broadcast.jl:32
in _broadcast at StaticArrays\src\broadcast.jl:50
in macro expansion at StaticArrays\src\broadcast.jl:108
The following doesn't work:
p = Path(Point(2000μm, 200μm))
straight!(p, 3000μm, styleCPW)
attach!(p, CellReference(any_cell), 1000μm)
fl = Cell("feedline", nm)
render!(fl, p, GDSMeta(BASE_METAL))
and throws the error
LoadError: DimensionError: 0.0 and 2000.0 μm are not dimensionally compatible.
while loading X:\Michael\Devices\PhononicShieldResonators.jl, in expression starting on line 126
in main at PhononicShieldResonators.jl:119
in #render!#7 at Devices\src\render\paths.jl:24
in render! at Devices\src\render\decorated.jl:11
in #render!#56 at Devices\src\render\decorated.jl:19
in _map at StaticArrays\src\mapreduce.jl:14
in macro expansion at StaticArrays\src\mapreduce.jl:23
but when you specify an explicit origin for the CellReference, you obtain the desired result without error:
p = Path(Point(2000μm, 200μm))
straight!(p, 3000μm, styleCPW)
attach!(p, CellReference(any_cell, Point(0.0μm, 0.0μm)), 1000μm) # different here
fl = Cell("feedline", nm)
render!(fl, p, GDSMeta(BASE_METAL))
The old behavior was that an origin did not need to be specified. Not really an issue, but thought I'd let you know.
Hi,
I have noticed that meander!
function gives incorrect result when the input argument α
is negative. That is, one can use this function to generate meandering path only when it's starting from positive turn. For meander paths starting from negative turn, there is no error coming from the function but the pathlength of the output path differs a lot from the input argument len
.
I have checked that a simple correction resolves this issue:
on line 653 of path.jl
:
unit = straightlen + r * abs(α)
Best,
Eunjong
The master branch is failing on Julia 0.7. I see the julia07
branch works ok, with some deprecations, but haven't tested too deeply. What's the status of the migration to 0.7, and is there any way we could help?
The PCSCALE factor used to integrate with Clipper is actually harmful when units are used.
It is necessary when no units are used so that values to the right of the decimal point are not neglected. Without units, you have no idea how many decimal points will actually matter in the output GDS file, because the database unit is not known at the time of polygon clipping.
Short-term solution: If you encounter problems, provided you use units, set this constant to 1.0.
Suggested long-term solution: remove support for unitless coordinates.
Rotations and magnifications of cell arrays and cell references are always flagged as absolute. This is unintentional and due to a misunderstanding of the GDS-II spec. It seems that some GDS-II viewers were ignoring these flags, but some were not, leading to inconsistent interpretations of the same pattern file, hence why the issue was not noticed until now. A fix is inbound.
<g>
tag) to write the color of polygons on a given layer just once, rather than once per polygon, resulting in much smaller file sizes.CellReference
s could be implemented by putting the polygons into <defs>
and using the translation, rotation, and reflection features of the transform
attribute in <use>
.c/o @mtfang
In the attach! method, is it possible to also allow for t and i to be of type Array instead of Real/Integer? This way multiple objects can be attached directly instead of through some for loop or map function.
Use case example (attaching multiple bridges to multiple segments):
for j in [1, 6, 8, 10]
for k in 0:0.1:1
attach!(p12, CellReference(default_bridge, rot = π/2), k, j)
end
end
Would be:
attach!(p12, CellReference(default_bridge, rot = π/2), 0:0.1:1, [1, 6, 8, 10])
From @eunjongkim
I noticed some cases of Paths.Taper() failing on my code and wanted to report this bug. [...] It seems that Paths.Taper() is not rendering properly for some reasons I couldn’t figure out.
While trying to work with Paths.TaperCPW style, I noticed that constructors for Paths.TaperTrace and Paths.TaperCPW are incorrectly defined on paths\contstyles\tapers.jl
The functions in line 8 and line 24 of the file must have namesTaperTrace
andTaperCPW
if I’m understanding the code correctly (currently, they are both overloading the method forCPW
). This resolved the issue in my code but Paths.Taper() style is still not working.
There is a handle_generic_tapers!
method that gets called from within render!(::Cell, ::Path{T}, ::Meta) where {T} that doesn't detect nodes that have been simplify!
-ied. I think @platawiec wrote most of the taper code so I haven't delved too much into the details. I don't have time to investigate / fix it right now. Regarding the constructors, I guess it does seem kind of misleading to overload CPW
and Trace
that way.
Some readers (like Klayout) support the parsing of PCells. I've become aware that some ebeam preparation tools (like BEAMER) can support the parsing of certain PCells to improve performance (namely, circles).
Unfortuntaly, PCells are not within the GDS spec, and as of now I'm not aware of any specification for PCells. Is it possible to include support for generating PCells?
In attempting to read a gds file (dd=load(File{format"GDS"}("filename.gds")), I receive
ERROR: unimplemented token 0x0c00 (TEXT) in BGNSTR tag.
(I'm new to both gds and this package.) Is there a reasonable work-around to enable this package to use this file?
number of steps can be determined from the meta array.
Instead, the failure occurs later upon saving when failing to find an appropriate traverse!
method.
Sometimes it is useful to only flatten cell references/arrays a few levels down, not all the way down.
I'm not sure if this is a Devices.jl issue, or a Clipper.jl issue, but I thought I would ask:
If I create a mask with a hole, in this way:
square_pts = Point.([(-1,-1),(-1,1),(1,1),(1,-1)])
small_square = Polygon(square_pts)
big_square = Polygon(2.*square_pts)
mask = first(clip(Clipper.ClipTypeDifference,big_square,small_square))
and that I clip this mask from a larger canvas by taking the difference, this is what is obtained:
canvas = Polygon(5.*square_pts)
x = clip(Clipper.ClipTypeDifference,canvas,mask)
c = Cell("squares")
for p in x
render!(c,p, GDSMeta(0))
end
Instead, I would expect to get two shapes (in x
), the outline, plus the hole (the small square):
Do you know where the problem might lie?
Thank you.
Jeremy
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.