Package empro :: Package toolkit :: Module portparam
[frames] | no frames]

Source Code for Module empro.toolkit.portparam

  1  # Copyright 1983-2012 Keysight Technologies, Inc   
2 -def getSMatrix(context=None, sim=None, fftSize=None):
3 ''' 4 getSMatrix(context=None, sim=None, fftSize=None) -> DataSetMatrix 5 6 Returns the matrix of scattering parameters of a simulation. The function 7 parameters have the same meaning as for L{empro.toolkit.dataset.getResult}. 8 The resulting matrix is not necessarily square, as only columns for active 9 ports will be available. Port numbers are used a row and column subscripts. 10 ''' 11 from empro.toolkit import dataset 12 query, followQuery = dataset._startQuery(context) 13 dataset._setSim(query, followQuery, sim=sim) 14 S = {} 15 for runId in query.availableRunIds(): 16 query.runId = runId 17 activePort = _activePorts(query) 18 for p, q in _ports(query).items(): 19 transform = (None, 'Fft')['Transient' in q.availableTimeDependenceValues()] 20 S[p, activePort] = dataset.getResult(q, result='SParameters', transform=transform, fftSize=fftSize) 21 if any(len(s) == 0 for s in S.values()): 22 raise ValueError, "S matrix is not complete, some of the datasets are of zero length" 23 minSize, maxSize = [op(len(s) for s in S.values()) for op in min, max] 24 if minSize != maxSize: 25 assert 'Transient' in query.availableTimeDependenceValues(), "this should only happen with FDTD simulations" 26 assert not fftSize, "this should not happen if we have set an explicit fftSize" 27 return getSMatrix(context, sim, fftSize=maxSize) 28 return dataset.DataSetMatrix(S, name='S')
29 30
31 -def getVoltages(context=None, sim=None, run=None, transform='NoTransform', fftSize=None):
32 ''' 33 getVoltages(context=None, sim=None, run=None, transform='NoTransform', 34 fftSize=None) -> DataSetMatrix 35 36 Returns a column matrix of port voltages of one run, using port numbers as 37 subscripts. The function parameters have the same meaning as for the 38 function L{empro.toolkit.dataset.getResult}. Row and column subscripts are 39 port numbers or tuples of port numbers, similar to L{getSMatrix} 40 ''' 41 return _getPortVector('V', context, sim, run, transform=transform, fftSize=fftSize)
42 43
44 -def getCurrents(context=None, sim=None, run=None, transform='NoTransform', fftSize=None):
45 ''' 46 getCurrents(context=None, sim=None, run=None, transform='NoTransform', 47 fftSize=None) -> DataSetMatrix 48 49 Returns a column matrix of port currents of one run, using port numbers as 50 subscripts. The function parameters have the same meaning as for the 51 function L{empro.toolkit.dataset.getResult}. Row and column subscripts are 52 port numbers or tuples of port numbers, similar to L{getSMatrix} 53 ''' 54 return _getPortVector('I', context, sim, run, transform=transform, fftSize=fftSize)
55 56
57 -def getRefImpedances(context=None, sim=None):
58 ''' 59 getRefImpedances(context=None, sim=None) -> DataSetMatrix 60 61 Returns a diagonal matrix of the port reference impedances, using port numbers as 62 subscripts. The function parameters have the same meaning as for the 63 function L{empro.toolkit.dataset.getResult}. Row and column subscripts are 64 port numbers or tuples of port numbers, similar to L{getSMatrix} 65 ''' 66 from empro.toolkit import dataset 67 query, followQuery = dataset._startQuery(context) 68 dataset._setSim(query, followQuery, sim=sim) 69 dataset._setRun(query, followQuery, run=1) # must have one, doesn't matter which 70 Zref = dict(((p, p), _getRefImpedance(q)) for p, q in _ports(query).items()) 71 return dataset.DataSetMatrix(Zref, "Zref")
72 73
74 -def stoy(s, zRef=50, name=None):
75 ''' 76 Transform S parameters to Y parameters. 77 78 - s: can be a Python float, complex, DataSet or DataSetMatrix. 79 - zRef: must be a Python float or complex number for now. DataSet or DataSetMatrix is not supported yet. 80 - name: optional name of result, default is "Y". 81 ''' 82 from empro.toolkit import dataset 83 try: 84 assert s.isSquare(), "S matrix must be square" 85 except AttributeError: 86 pass 87 try: 88 assert zRef.isDiagonal(), "Reference impedance matrix must be diagonal" 89 except AttributeError: 90 pass 91 zRefConj = dataset._apply(zRef, dataset._conjugate) 92 gRef = dataset._apply(zRef, lambda z: .5 / dataset.sqrt(abs(dataset._real(z)))) 93 e = dataset._identity(s) 94 y = dataset._inversed(gRef) * dataset._inversed(s * zRef + e * zRefConj) * (e - s) * gRef 95 return dataset._named(y, name or "Y")
96 97
98 -def stoz(s, zRef=50, name=None):
99 ''' 100 Transform S parameters to Z parameters. 101 102 - s: can be a Python float, complex, DataSet or DataSetMatrix. 103 - zRef: must be a Python float or complex number for now. DataSet or DataSetMatrix is not supported yet. 104 - name: optional name of result, default is "Z". 105 ''' 106 from empro.toolkit import dataset 107 z = dataset._inversed(stoy(s, zRef)) 108 return dataset._named(z, name or "Z")
109 110
111 -def EMProPortNb2Name():
112 ''' 113 EMProPortNb2Name() -> Dictionary 114 115 Returns a dictionary with the portnumbers of the enabled ports in the current project as keys 116 and (portname,mode) tuples as values. For internal ports, which do not have modes, the second element 117 in the tuple is '-1'. 118 E.g.: {1: ('S(7)', -1), 2: ('S(4)', -1), 3: ('S(3)', -1), 4: ('S(1)_S(2)', 1), 5: ('S(1)_S(2)', 2), 6: ('S(6)', 1)} 119 ''' 120 import empro 121 EMPro_map={} 122 compList = empro.activeProject.circuitComponents() 123 for i in range(0,len(compList)): 124 c = compList[i] 125 pci = compList.getPortNumber(i) 126 if not c.port or not c.isEnabled: 127 continue 128 namet = (c.name,-1) 129 EMPro_map[pci]=namet 130 wgList = empro.activeProject.waveGuides() 131 for i in range(0,len(wgList)): 132 wg = wgList[i] 133 for j in range(0,wg.numberOfModes()): 134 wgm = wg.mode(j) 135 namet = (wgm.name or wg.name,j+1) 136 EMPro_map[wgm.id]=namet 137 return EMPro_map
138 139
140 -def _switchKeyValue(dictIn):
141 dictOut={} 142 for k,v in dictIn.iteritems(): 143 dictOut[v]=k 144 return dictOut
145
146 -def switchKeyValue(dictIn):
147 # Deprecated but used in sim.py of ADS 2011.03 # TODO: remove as soon as ADS 2011.03 is not supported anymore 148 ''' 149 switchKeyValue(dictIn) -> dictOut 150 151 Returns a dictionary that is the inverse of the input dictionary. 152 For each key value pair (k_in,v_in) in the input there will be a key value pair (k_out,v_out)=(v_in,k_in) in the output. 153 This function is deprecated !!! 154 ''' 155 return _switchKeyValue(dictIn)
156
157 -def _chainMapping(dictA,dictB,ignoreKeyError=True):
158 dictC={} 159 for k,v in dictA.iteritems(): 160 try: 161 dictC[k]=dictB[v] 162 except KeyError: 163 if not ignoreKeyError: 164 raise 165 try: 166 print "Portname",v[0],"not found in EMPro" 167 except TypeError: 168 print "Key",v,"not found" 169 dictC[k]=None 170 return dictC
171
172 -def chainMapping(dictA,dictB,ignoreKeyError=True):
173 # Deprecated but used in sim.py of ADS 2011.03 # TODO: remove as soon as ADS 2011.03 is not supported anymore 174 ''' 175 chainMapping(dictA,dictB,ignoreKeyError = True) -> dictC 176 177 Returns a dictionary that is the composite of the mappings expressed by the input dictionaries. 178 If (e1,e2) in dictA and (e2,e3) in dictB then (e1,e3) in dictC. 179 If (e1,e2) in dictA but dictB has no key e2 then a warning is printed (Portname not found) 180 and if ignoreKeyError = False a KeyError will be thrown. 181 This function is deprecated !!! 182 ''' 183 return _chainMapping(dictA,dictB,ignoreKeyError)
184
185 -def getEMPro2ADS_portmapping(ADS_map):
186 EMPro_map = EMProPortNb2Name() 187 # if an internal port was incorrectly assigned mode 1 instead of -1 in the ADS map, flip the sign 188 internalEMProPortNames = [name for (name,mode) in EMPro_map.itervalues() if mode == -1] 189 for portNb, (name,mode) in ADS_map.iteritems(): 190 if name in internalEMProPortNames and mode==1: 191 ADS_map[portNb]=(name,-1) 192 EMPro2ADS_portmapping = _chainMapping(EMPro_map,_switchKeyValue(ADS_map)) 193 return EMPro2ADS_portmapping
194
195 -def extractRLC(ctiFile, freqIndex=0):
196 from empro.toolkit import citifile 197 ctiData = citifile.read(ctiFile) 198 199 frequency = ctiData.var.at(freqIndex) 200 sMatrix = ctiData.asMatrix("S") 201 yMatrix = stoy(sMatrix) 202 zMatrix = stoz(sMatrix) 203 204 import math 205 omega = 2.0*math.pi * frequency 206 S11 = sMatrix[1,1].at(freqIndex) 207 Z11 = zMatrix[1,1].at(freqIndex) 208 Y11 = yMatrix[1,1].at(freqIndex) 209 210 C = (1.0/complex(0,omega*Z11)).real 211 RomegaL = 1.0/Y11 212 R = RomegaL.real 213 L = RomegaL.imag / omega 214 215 return frequency, R,L,C
216 # --- implementation ------------------------------------------------------------------------------- 217
218 -def _getPortVector(result, context=None, sim=None, run=None, **kwargs):
219 ''' 220 retrieve a column matrix of port voltages 221 ''' 222 from empro.toolkit import dataset 223 query, followQuery = dataset._startQuery(context) 224 dataset._setSim(query, followQuery, sim=sim) 225 dataset._setRun(query, followQuery, run=run) 226 activePort = _activePorts(query) 227 vector = dict(((p, activePort), dataset.getResult(q, result=result, **kwargs)) for p, q in _ports(query).items()) 228 return dataset.DataSetMatrix(vector, name=result)
229 230
231 -def _getRefImpedance(query):
232 from empro.toolkit import dataset 233 assert _isPort(query) 234 obj = query.getOutputObject() 235 activeQuery = _asActivePort(query) 236 name = "Zref%d" % obj.portNumber() 237 try: 238 isModal = obj.circuitComponentType() == 'PowerFeed' 239 except AttributeError: 240 isModal = False 241 if isModal: 242 result = { 243 'Zpv': 'ImpedancePowerVoltage', 244 'Zpi': 'ImpedancePowerCurrent', 245 'Zvc': 'ImpedanceVoltageCurrent', 246 }[obj.impedanceDefinition()] 247 return dataset.getResult(activeQuery, result=result, name=name) 248 assert obj.resistance() > 0 249 z = dataset.getResult(activeQuery, result='Impedance') 250 return dataset._constant(obj.resistance(), z, name=name)
251 252
253 -def _ports(query):
254 ports = {} 255 for objId in query.availableOutputObjectIds(): 256 query.outputObjectId = objId 257 if not _isPort(query): 258 continue 259 ports[query.getOutputObject().portNumber()] = query.clone() 260 return ports
261 262
263 -def _isPort(query):
264 obj = query.getOutputObject() 265 try: 266 return obj.isPort() 267 except AttributeError: 268 return False
269 270
271 -def _activePorts(query):
272 run = query.getRun() 273 portNumbers = [] 274 for portId in run.activePortIds(): 275 query.outputObjectId = portId 276 assert _isPort(query) 277 portNumbers.append(query.getOutputObject().portNumber()) 278 if len(portNumbers) == 1: 279 return portNumbers[0] 280 return tuple(portNumbers)
281 282
283 -def _asActivePort(query):
284 activeQuery = query.clone() 285 for runId in query.availableRunIds(): 286 activeQuery.runId = runId 287 if activeQuery.getRun().activePortIds() == (query.outputObjectId,): 288 return activeQuery 289 raise AssertionError("No run has been found with %r as active port" % query.outputObjectId)
290