|
2 | 2 | import pathlib |
3 | 3 | import pprint |
4 | 4 | import time |
5 | | -from typing import Literal |
| 5 | +from typing import Literal, cast |
6 | 6 |
|
7 | 7 | import gdsfactory as gf |
8 | 8 | import meow as mw |
@@ -48,6 +48,54 @@ def list_unique_layer_stack_z( |
48 | 48 | } |
49 | 49 |
|
50 | 50 |
|
| 51 | +def _compute_s_matrix(modes_per_cell, cells): |
| 52 | + """Compute S-matrix, compatible with sax >= 0.16 nets format. |
| 53 | +
|
| 54 | + meow's compute_s_matrix passes connections as a dict, but sax >= 0.16 |
| 55 | + expects a list of {"p1": ..., "p2": ...} dicts (Nets). This wrapper |
| 56 | + converts the format. |
| 57 | + """ |
| 58 | + from meow.eme.sax import ( |
| 59 | + _get_netlist, |
| 60 | + compute_interface_s_matrices, |
| 61 | + compute_propagation_s_matrices, |
| 62 | + ) |
| 63 | + |
| 64 | + propagations = compute_propagation_s_matrices(modes_per_cell, cells) |
| 65 | + interfaces = compute_interface_s_matrices(modes_per_cell) |
| 66 | + |
| 67 | + net = _get_netlist(propagations, interfaces) |
| 68 | + _, analyze_circuit, evaluate_circuit = sax.circuit_backends[ |
| 69 | + sax.into[sax.Backend]("default") |
| 70 | + ] |
| 71 | + net["instances"] = {k: sax.scoo(v) for k, v in net["instances"].items()} |
| 72 | + |
| 73 | + # Convert old-style connections dict to new-style nets list |
| 74 | + connections = net["connections"] |
| 75 | + if isinstance(connections, dict): |
| 76 | + nets = [{"p1": k, "p2": v} for k, v in connections.items()] |
| 77 | + else: |
| 78 | + nets = connections |
| 79 | + |
| 80 | + analyzed = analyze_circuit(net["instances"], nets, net["ports"]) |
| 81 | + S, port_map = sax.sdense(evaluate_circuit(analyzed, instances=net["instances"])) |
| 82 | + S = np.asarray(S) |
| 83 | + |
| 84 | + # Sort ports consistently |
| 85 | + current_port_map = { |
| 86 | + (p, int(i)): j |
| 87 | + for (p, i), j in { |
| 88 | + tuple(pm.split("@")): idx for pm, idx in port_map.items() |
| 89 | + }.items() |
| 90 | + } |
| 91 | + desired_port_map = {pm: i for i, pm in enumerate(sorted(current_port_map))} |
| 92 | + idxs = [current_port_map[pm] for pm in desired_port_map] |
| 93 | + S = S[idxs, :][:, idxs] |
| 94 | + port_map = {f"{p}@{m}": v for (p, m), v in desired_port_map.items()} |
| 95 | + |
| 96 | + return cast(sax.SDenseMM, (S, port_map)) |
| 97 | + |
| 98 | + |
51 | 99 | class MEOW: |
52 | 100 | def __init__( |
53 | 101 | self, |
@@ -430,7 +478,7 @@ def rename(p): |
430 | 478 |
|
431 | 479 | self.compute_all_modes() |
432 | 480 |
|
433 | | - self.S, self.port_map = mw.compute_s_matrix(self.modes_per_cell, self.cells) |
| 481 | + self.S, self.port_map = _compute_s_matrix(self.modes_per_cell, self.cells) |
434 | 482 |
|
435 | 483 | sdict = sax.sdict((self.S, self.port_map)) |
436 | 484 |
|
|
0 commit comments