File: README.md

package info (click to toggle)
libgdsii 0.2%2Bds.1-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, bullseye, sid, trixie
  • size: 896 kB
  • sloc: cpp: 1,622; makefile: 42; sh: 22
file content (323 lines) | stat: -rw-r--r-- 12,981 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
libGDSII is a C++ library for working with GDSII binary data files, intended primarily for use with the computational electromagnetism codes
[scuff-em](http://homerreid.github.io/scuff-em-documentation)
and
[meep](http://meep.readthedocs.org)
but sufficiently general-purpose to allow other uses as well.

The packages consists of

+ a C++ library (`libGDSII`)  with API functions for reading, processing, and exporting GDSII files

+ a command-line executable code (`GDSIIConvert`) for reporting statistics on GDSII geometries and
  exporting them to other file formats, notably including the [GMSH](http://gmsh.info) geometry format.

# Installation

```bash
% git clone http://github.com/HomerReid/libGDSII
% cd libGDSII
% sh autogen.sh --prefix=/path/to/installation/prefix
% make install
```

This will install the `GDSIIConvert` executable in `$(prefix)/bin`
and the `libGDSII.a` and/or `libGDSII.so` library binaries in `$(prefix)/lib`.

# Using the `GDSIIConvert` command-line tool

The GDSII file referenced in the following examples is 
[this silicon-photonics transceiver](https://github.com/lukasc-ubc/SiEPIC-Tools/blob/master/Examples/GSiP/RingModTransceiver/Layouts/GSiP_4_RingFilter.gds)
from the [SiEPIC-Tools](https://github.com/lukasc-ubc) project:

+ Lukas Chrostowski, Zeqin Lu, Jonas Flueckiger, Xu Wang, Jackson Klein, 
  Amy Liu, Jaspreet Jhoja, James Pond, 
  ["Design and simulation of silicon photonic schematics and layouts,"](http://edx.org/course/silicon-photonics-design-fabrication-ubcx-phot1x)
  Proc. SPIE 9891, Silicon Photonics and Photonic Integrated Circuits V, 989114 (May 13, 2016); doi:10.1117/12.2230376.

## Convert to [GMSH](http://gmsh.info) format: Option `--gmsh`

```bash
% GDSIIConvert --GMSH GSiP_4_RingFilter.gds

Read 2080 data records from file GSiP_4_RingFilter.gds.
Wrote 91 text strings to GSiP_4_RingFilter.pp.
Detecting metallization structures on layer   1: ... 34 polygons on layer 1
Detecting metallization structures on layer   3: ... 30 polygons on layer 3
Detecting metallization structures on layer   7: ... 2 polygons on layer 7
Detecting metallization structures on layer  10: ... 78 polygons on layer 10
Detecting metallization structures on layer  20: ... 1 polygons on layer 20
Detecting metallization structures on layer  21: ... 1 polygons on layer 21
Detecting metallization structures on layer  44: ... 12 polygons on layer 44
Detecting metallization structures on layer  47: ... 30 polygons on layer 47
Detecting metallization structures on layer  60: ... 2 polygons on layer 60
Detecting metallization structures on layer  63: ... 2 polygons on layer 63
Detecting metallization structures on layer  66: ... 87 polygons on layer 66
Detecting metallization structures on layer  68: ... 16 polygons on layer 68
Detecting metallization structures on layer  69: ... 46 polygons on layer 69
Detecting metallization structures on layer  81: ... 2 polygons on layer 81
Detecting metallization structures on layer 733: ... 2 polygons on layer 733
Wrote 345 metallization polygons to GSiP_4_RingFilter.geo.
Thank you for your support.
```

This produces two files: the GMSH geometry file `GSiP_4_RingFilter.geo,`
describing the polygons, and the GMSH post-processing file `GSiP_4_RingFilter.pp`
describing the text strings. These can be opened in GMSH for visualization:

```bash
% gmsh GSiP_4_RingFilter.geo GSiP_4_RingFilter.pp
```

![GMSH screenshot](GMSHScreenshot.png)

### Extracting individual layers

If you only want to extract polygons on a single layer, you can 
add e.g. `--MetalLayer 47` to the `GDSIIConvert` command line:

```bash
% GDSIIConvert --GMSH --MetalLayer 47 GSiP_4_RingFilter.geo --FileBase GSIP_47
% GDSIIConvert --GMSH --MetalLayer 69 GSiP_4_RingFilter.geo --FileBase GSIP_69
```

## Print text description of geometry hierarchy: Option `--analyze`

```bash

% GDSIIConvert --analyze GSiP_4_RingFilter.gds

Read 2080 data records from file GSiP_4_RingFilter.gds.
*
* File GSiP_4_RingFilter.gds:
* Unit=1.000000e-06 meters (file units = {1.000000e-03,1.000000e-09})
*
**************************************************
** Library SiEPIC_GSiP:
**************************************************
--------------------------------------------------
** Struct 0: $$$CONTEXT_INFO$$$
--------------------------------------------------
  Element 0: SREF (layer 0, datatype 0)
    (structure CIRCLE)
    (attribute 7: PCELL_CIRCLE)
    (attribute 6: P_actual_radius)
    (attribute 5: P_npoints)
    (attribute 4: P_handle___dpoint)
    (attribute 3: P_radius)
    (attribute 2: P_layer___layer)
    (attribute 1: LIB_Basic)
    (attribute 0: LIB_SiEPIC_GSiP)
     XY: 0 0

  Element 1: SREF (layer 0, datatype 0)
    (structure OpticalFibre__micron)
    (attribute 1: CELL_OpticalFibre__micron)
    (attribute 0: LIB_SiEPIC_GSiP)
     XY: 0 0

  Element 2: SREF (layer 0, datatype 0)
    (structure ROUND_PATH$)

...
...
...
  Element 18: SREF (layer 0, datatype 0)
    (structure ROUND_PATH$)
     XY: 0 0

  Element 19: SREF (layer 0, datatype 0)
    (structure ROUND_PATH$)
     XY: 0 0

  Element 20: BOUNDARY (layer 20, datatype 0)
     XY: 228898 187725 228803 187791 228898 187931 228898 187725

  Element 21: BOUNDARY (layer 21, datatype 0)
     XY: 234248 192138 234248 192595 234250 192366 234248 192138

Thank you for your support.
```

## Print low-level description of GDSII file structure (data records): Option `--raw`

```bash

% GDSIIConvert --raw GSiP_4_RingFilter.gds

Record 0:       HEADER ( 1)  = 600
Record 1:       BGNLIB ( 12)  = 2017 3 16 23 29 47 2017 3 16 23 29 47
Record 2:      LIBNAME ( 1)  = SiEPIC_GSiP
Record 3:        UNITS ( 2)  = 0.001 1e-09
Record 4:       BGNSTR ( 12)  = 2017 3 16 23 29 47 2017 3 16 23 29 47
Record 5:      STRNAME ( 1)  = $$$CONTEXT_INFO$$$
Record 6:         SREF =
Record 7:        SNAME ( 1)  = CIRCLE
Record 8:           XY ( 2)  = 0 0
Record 9:     PROPATTR ( 1)  = 7
Record 10:    PROPVALUE ( 1)  = PCELL_CIRCLE
Record 11:     PROPATTR ( 1)  = 6
Record 12:    PROPVALUE ( 1)  = P_actual_radius
...
...
...
Record 2066:           XY ( 2)  = 0 0
Record 2067:        ENDEL =
Record 2068:     BOUNDARY =
Record 2069:        LAYER ( 1)  = 20
Record 2070:     DATATYPE ( 1)  = 0
Record 2071:           XY ( 8)  = 228898 187725 228803 187791 228898 187931 228898 187725
Record 2072:        ENDEL =
Record 2073:     BOUNDARY =
Record 2074:        LAYER ( 1)  = 21
Record 2075:     DATATYPE ( 1)  = 0
Record 2076:           XY ( 8)  = 234248 192138 234248 192595 234250 192366 234248 192138
Record 2077:        ENDEL =
Record 2078:       ENDSTR =
Record 2079:       ENDLIB =
Read 2080 data records from file SiEPIC/GSiP_4_RingFilter.gds.
Thank you for your support. 
```

# Using the `libGDSII` API 


## Overview of the `libGDSII` API

`libGDSII` exports a C++ class called `GDSIIData,` whose
class constructor accepts the name of a binary GDSII file as input.

Internally, the constructor maintains both a *hierarchical* representation
of the geometry (involving structures that instantiate other structures,
arrays of structure elements, etc.) and a *flat* representation,
consisting simply of collections of polygons and text labels,
indexed by the layer on which they appeared. 

The flat representation consists of 

+ an integer-valued array `Layers`, with `Layers[0], Layers[1], ...` the indices of the layers present in the GDSII file
+ for each layer, an array of `Entity` structures, where each `Entity` is either a polygon or a text string:

```C++

std::vector<int> Layers;     // Layers[nl] = index of layer #nl in GDSII file

typedef struct Entity
 { char *Text;   // if NULL, the entity is a polygon; otherwise it is a text string
   dVec XY;      // vertex coordinates: 2 for a text string, 2N for an N-gon
   bool Closed;  // true if there exists an edge connecting the last to the first vertex
   char *Label;  // optional descriptive text, may be present or absent for polygons and texts
 } Entity;

typedef std::vector<Entity>     EntityList;
typedef std::vector<EntityList> EntityTable;   // EntityTable[nl][ne] = entity #ne on layer Layers[nl]

```

In the flat representation, all GDSII geometry elements---including
boundaries, boxes, paths, structure instantiations (`SREF`s), and
arrays (`AREF`s)---are reduced to polygons, described by lists
of *N>1* vertices, with each vertex having two coordinates (*x* and *y*).
The *2N* vertex coordinates are stored internally in the `XY` field
of `Entity`, a `double`-valued `std::vector.` The `Closed` flag
indicates whether or not the polygon includes an edge connecting 
vertex *N* back to vertex *1*.

If the `Text` field of `Entity` is non-NULL, the entity is not a polygon,
but is instead a text string. In this case the `XY` array has length 2,
the (*x,y*) coordinates of the text reference point.

Both polygons and text strings may be accompanied by
optional descriptive text, stored in the `*Label` field of `Entity.`

`GDSIIData` provides API routines for extracting polygons from GDSII geometries.
This can be done in a couple of ways:

+ You can ask for a list of all polygons on a given layer. If there is more than one polygon on the layer, you will get them all, in the form of an unsorted array.

+ You can specify a label (character string) and ask for only those polygons that contain the reference point of a text string, on the same layer, matching your string. You can restrict this search to a single layer, or search all layers in the file; in the latter case, only polygons that live on the same layer as the text string are returned.

Arrays of polygons are returned in the form of a `vector` of `double`-valued `vectors`:

```C++
typedef vector<double> dVec;
typedef vector<dVec> PolygonList; // PolygonList[np][2*nv+0,2*nv+1] = x,y coords of vertex #nv in polygon #np
```

## Sample code

```C++

#include "libGDSII.h"
using namespace std;
using namespace libGDSII;

  /********************************************************************/
  /* try to instantiate GDSIIData structure from binary GDSII file    */
  /********************************************************************/
  GDSIIData *gdsIIData  = new GDSIIData( string("GSiP_4_RingFilter.gds") );

  if (gdsIIData->ErrMsg)
   { printf("error: %s (aborting)\n",gdsIIData->ErrMsg->c_str());
     exit(1);
   }

  /***************************************************************/
  /* output a text-based description of the geometry             */
  /***************************************************************/
  gdsIIData->WriteDescription();                // writes to console
  gdsIIData->WriteDescription("MyOutputFile");

  /***************************************************************/
  /* get all polygons on layer 3 *********************************/
  /***************************************************************/
  PolygonList Layer3Polygons = gdsIIData->GetPolygons(3);

  printf("Found %lu polygons on layer 3: \n",Layer3Polygons.size());
  for(size_t np=0; np<Layer3Polygons.size(); np++)
   { printf("Polygon #%lu has vertices: ",np);
     for(int nv=0; nv<Layer3Polygons[np].size()/2; nv++)
      printf(" {%e,%e} ",Layer3Polygons[np][2*nv+0],Layer3Polygons[2*nv+1]);
     printf("\n");
   }

  /***************************************************************/
  /* get all polygons on layer 3 that contain the reference point*/
  /* of the text string "Geometry" (also on layer 3)             */
  /***************************************************************/
  PolygonList Layer3Polygons = gdsIIData->GetPolygons("Geometry", 3);

  /***************************************************************/
  /* get all polygons on any layer that contain the reference pt */
  /* of the text string "Geometry" on the same layer             */
  /***************************************************************/
  PolygonList Layer3Polygons = gdsIIData->GetPolygons("Geometry");
```

## Internal caching of `GDSIIData` structure

In the above snippet, we create an instance of `class GSDIIData`
and access the geometry by calling the class methods of this
instance. `libGDSII` also provides an alternative interface
in which you call non-class methods, passing only the GDSII file name:

```C++

  PolygonList Layer3Polygons = GetPolygons("MyGDSFile.GDS", 3);
  PolygonList Layer3Geometry = GetPolygons("MyGDSFile.GDS", "Geometry", 3);

  ...
  ...

  void ClearGDSIICache();

```
In this case what is going on is that `libGDSII` is creating and internally
storing a `GDSIIData` structure for the given GDS file. Successive 
calls to `GetPolygons` with the same file name will re-use the cached data
structure, saving the cost of rereading the GDS file. If you make 
subsequent calls to `GetPolygons` with a new GDS file, the cached data will
be destroyed and allocated anew for the new file.

When finished with a sequence of `GetPolygons()` calls of this form,
call `ClearGDSIICache()` to deallocate memory associated with the 
internally-cached structures.