1
2 import empro, os
3 from empro.toolkit import Bunch
4 from empro.toolkit.results import UnavailableError, excitation_based
5
6 _coordinateSystem = THETA_PHI, ALPHA_EPSILON, AZIMUTH_ELEVATION = 1,2,3
7
10 self._phi = phi
11 self._theta = theta
13 thetaIndex = -1
14 phiIndex = -1
15 for thetaId in range(1, len(thetaDs)):
16 if (self._theta <= thetaDs.at(thetaId) and self._theta >= thetaDs.at(thetaId - 1)):
17 if ( (self._theta - thetaDs.at(thetaId - 1)) > (thetaDs.at(thetaId) - self._theta)):
18 thetaIndex = thetaId
19 break
20 else:
21 thetaIndex = thetaId - 1
22 break
23 if thetaIndex == -1:
24 raise RuntimeError("The specified theta is not in the range!")
25 for phiId in range(1, len(phiDs)):
26 if (self._phi <= phiDs.at(phiId) and self._phi >= phiDs.at(phiId - 1)):
27 if ( (self._phi - phiDs.at(phiId - 1)) > (phiDs.at(phiId) - self._phi)):
28 phiIndex = phiId
29 break
30 else:
31 phiIndex = phiId - 1
32 break
33
34 if thetaIndex == -1:
35 raise RuntimeError("The specified phi is not in the range!")
36 indices = [thetaIndex, phiIndex]
37 return indices
38
40 """
41 PhiTheta(phi, theta)
42 arguments:
43 phi --- the value of angle phi in radian
44 theta --- the value of angle theta in radian
45 """
48
50 """
51 AzimuthElevation(azimuth, elevation)
52 arguments:
53 azimuth --- the value of azimuth in radian
54 elevation --- the value of elevation in radian
55 """
62
63
71
72
73
74
75
76 -class FarField(excitation_based.ExcitationBased):
77 - def __init__(self, results, sensorName, **kwargs):
78 excitation_based.ExcitationBased.__init__(self, results, **kwargs)
79
80 self._sim = self._results._sim
81 if isinstance(self._results._sim, int):
82 self._sim = '%06d' % self._results._sim
83
84 basequery = empro.output.ResultQuery()
85 basequery.projectId = self._results._proj
86 basequery.simulationId = self._sim
87
88 self._sensorName = sensorName
89 if not self._sensorName:
90 sim = basequery.getSimulation()
91 r = sim.run(sim.availableRunIds()[0])
92 numSens = 0
93 sensorName = ""
94 for ooid in r.availableOutputObjectIds():
95 if ooid[0] == "FarZoneSensor":
96 numSens = numSens + 1
97 sensorName = ooid[0]
98 if numSens!=1:
99 raise UnavailableError("")
100 else:
101 self._sensorName = sensorName
102
103
104 self._shifts = []
105 self._shifts.append(empro.geometry.Vector3d(0.0, 0.0, 0.0))
106
107 self._rotationAngles = []
108 self._rotationAngles.append(0.0)
109
110 self._rotationAxes = []
111 self._rotationAxes.append(empro.geometry.Vector3d(1.0, 0.0, 0.0))
112
113
114 self._results._extractAvailableExcitationToRun(basequery)
115 self._baseMultiExcitation = kwargs.get('excitation', {'source1' : 1.0})
116 self._multipleExcitationCoeffs = {}
117 for key in self._baseMultiExcitation.keys():
118 self._multipleExcitationCoeffs["%s_1"%(key)] = complex(1.0, 0.0)
119
120 if (len( self._results._availableExcitationsToRun)!=len(self._baseMultiExcitation)):
121 raise RuntimeError("The excitation set is not complete")
122
123 self._excBasis = empro.enparams.MultiComponentEvaluator()
124 self._excitationExtract()
125
127 import numbers
128 self._allNumbers = True
129 self._allExcitation = True
130
131 for value in self._baseMultiExcitation.values():
132 if not isinstance(value, numbers.Number):
133 self._allNumbers = False
134 break
135 if self._allNumbers:
136 self._addConstantWeights(self._baseMultiExcitation)
137 self._allExcitation = False
138
139 if not self._allNumbers:
140 import excitation
141 coeff = {}
142 for value in self._baseMultiExcitation.values():
143 if not isinstance(value, excitation.Excitation):
144 self._allExcitation = False
145 break
146 if self._allExcitation:
147 self._addExcitationWeights(self._baseMultiExcitation, self._multipleExcitationCoeffs)
148 self._allNumbers = False
149 pass
150 if not self._allNumbers and not self._allExcitation:
151 raise RuntimeError("Excitation specification is not supported")
152
153
154
156 for key, value in excitation.iteritems():
157 if key in self._results._availableExcitationsToRun:
158 excNameInArray = "%s_%s"%(key, len(self._shifts))
159 self._multipleExcitationCoeffs[excNameInArray] = value
160 else:
161 raise RuntimeError("The excitation %s does not exist"%(key))
162 pass
163
164
166 for key, spec in excitation.iteritems():
167 if key in self._results._availableExcitationsToRun:
168 excNameInArray = "%s_%s"%(key, len(self._shifts))
169 self._excBasis.add(excNameInArray, spec.source, spec.feedType, spec.R, spec.L, spec.C, spec.arrangement)
170 self._multipleExcitationCoeffs[excNameInArray] = excitationcoeffs["%s_1"%(key)]
171 else:
172 raise RuntimeError("The excitation %s does not exist"%(key))
173
174
175
176 - def plot(self, resultType="E"):
189
191 if type(other) != type(self) or other._sensorName != self._sensorName:
192 raise RuntimeError('Incompatible result')
193
194 for shift in other._shifts:
195 self._shifts.append(shift)
196
197 for angle in other._rotationAngles:
198 self._rotationAngles.append(angle)
199
200 for axis in other._rotationAxes:
201 self._rotationAxes.append(axis)
202
203 if self._allNumbers and other._allNumbers:
204 self._addConstantWeights(other._baseMultiExcitation)
205 elif self._allExcitation and other._allExcitation:
206 self._addExcitationWeights(other._baseMultiExcitation, other._multipleExcitationCoeffs)
207 else:
208 raise RuntimeError("Excitation specification is not supported")
209 return self
210
212 if other is 0:
213 return self
214 return other.__add__(self)
215
217 if self._allNumbers:
218 for key, value in self._baseMultiExcitation.iteritems():
219 self._baseMultiExcitation[key] = coef*value
220 for key, value in self._multipleExcitationCoeffs.iteritems():
221 self._multipleExcitationCoeffs[key] = coef*value
222 elif self._allExcitation:
223 for key, value in self._multipleExcitationCoeffs.iteritems():
224 self._multipleExcitationCoeffs[key] = coef*value
225
226 return self
227
229 if self._allNumbers:
230 for key, value in self._baseMultiExcitation.iteritems():
231 self._baseMultiExcitation[key] = coef*value
232 for key, value in self._multipleExcitationCoeffs.iteritems():
233 self._multipleExcitationCoeffs[key] = coef*value
234 elif self._allExcitation:
235 for key, value in self._multipleExcitationCoeffs.iteritems():
236 self._multipleExcitationCoeffs[key] = coef*value
237
238 return self
239
241 """
242 translate( translation )
243 @type translation: Vector3d
244 @param translation: the translation vector of the farfield
245 @rtype: farField
246 @return: the translated farfield
247 """
248 for i in range(0, len(self._shifts)):
249 self._shifts[i].x = self._shifts[i].x + translation.x
250 self._shifts[i].y = self._shifts[i].y + translation.y
251 self._shifts[i].z = self._shifts[i].z + translation.z
252 return self
253
254 - def rotate(self, angle, axis):
255 """
256 rotate(angle, axis)
257 @type angle: float
258 @param angle: rotation angle
259 @type axis: Vector3D
260 @param axis: rotation axis
261 @rtype: farField
262 @return: the rotated farField
263 """
264 for i in range(0, len(self._rotationAngles)):
265 self._rotationAngles[i] = angle
266
267 for i in range(0, len(self._rotationAxes)):
268 self._rotationAxes[i].x = axis.x
269 self._rotationAxes[i].y = axis.y
270 self._rotationAxes[i].z = axis.z
271 return self
272
273 - def EphiTheta(self, frequency, angle = None):
274 """
275 EphiTheta(frequency) -> returns the Ephi and Etheta values at the given frequency
276 @type frequency: double
277 @param frequency: the frequency of interest
278 @rtype: list of paired doubles
279 @return: list of [Etheta, Ephi]
280 """
281
282 query = empro.output.array_farfields(self._results._proj, self._sim, self._sensorName, self._shifts, self._rotationAngles, self._rotationAxes)
283 query.useMultipleExcitation = True
284 query.multipleExcitation = self._multipleExcitationCoeffs
285 if self._allExcitation:
286 query.setExcitationBasis(self._excBasis)
287 query.resultComponent = "Theta"
288 query.complexPart = "RealPart"
289 EthetaReadlDs = empro.output.ResultDataSet("farfields", query)
290
291 query.resultComponent = "Theta"
292 query.complexPart = "ImaginaryPart"
293 EthetaImagDs = empro.output.ResultDataSet("farfields", query)
294
295 query.resultComponent = "Phi"
296 query.complexPart = "RealPart"
297 EphiReadlDs = empro.output.ResultDataSet("farfields", query)
298
299 query.resultComponent = "Phi"
300 query.complexPart = "ImaginaryPart"
301 EphiImagDs = empro.output.ResultDataSet("farfields", query)
302
303 freqDs, thetaDs, phiDs = EthetaReadlDs.dimensions()
304 freqIndex = -1
305 for freqId in range(0, len(freqDs)):
306 if freqDs.at(freqId) == frequency:
307 freqIndex = freqId
308 break
309 if freqIndex == -1 :
310 raise RuntimeError("The specified frequency is not in the list of excitation frequencies!")
311 data = []
312
313 if angle:
314 thetaPhiIndices = angle._findIndices(thetaDs,phiDs)
315 thetaReal = EthetaReadlDs.at(freqIndex, thetaPhiIndices[0], thetaPhiIndices[1])
316 thetaImag = EthetaImagDs.at(freqIndex, thetaPhiIndices[0], thetaPhiIndices[1])
317 phiReal = EphiReadlDs.at(freqIndex, thetaPhiIndices[0], thetaPhiIndices[1])
318 phiImag = EphiImagDs.at(freqIndex, thetaPhiIndices[0], thetaPhiIndices[1])
319 data.append([complex(thetaReal, thetaImag), complex(phiReal, phiImag)])
320 return data
321
322 for thetaId in range(0, len(thetaDs)):
323 for phiId in range(0, len(phiDs)):
324 thetaReal = EthetaReadlDs.at(freqIndex, thetaId, phiId)
325 thetaImag = EthetaImagDs.at(freqIndex, thetaId, phiId)
326 phiReal = EphiReadlDs.at(freqIndex, thetaId, phiId)
327 phiImag = EphiImagDs.at(freqIndex, thetaId, phiId)
328 data.append([complex(thetaReal, thetaImag), complex(phiReal, phiImag)])
329 return data
330
347
362
364 """
365 radiatedPower(frequency = None)
366 @type frequency: float
367 @param frequency: frequency of interest --- The default is None which considers all the frequencies
368 @rtype: double
369 @return: radiated power at the given frequency (in case of frequency = None, a list of all values for all frequencies is returned)
370 """
371 query = empro.output.array_farfields(self._results._proj, self._sim, self._sensorName, self._shifts, self._rotationAngles, self._rotationAxes)
372 query.useMultipleExcitation = True
373 query.multipleExcitation = self._multipleExcitationCoeffs
374 if self._allExcitation:
375 query.setExcitationBasis(self._excBasis)
376 query.resultType = "RadiatedPower"
377 ds = query.dataset()
378 freqDs = ds.dimension(0)
379 results = []
380 for i in range(len(ds)):
381 if frequency == None:
382 results.append(ds.at(i))
383 elif (freqDs.at(i) == frequency):
384 return ds.at(i)
385 if frequency == None:
386 return results
387 else:
388 raise RuntimeError("The given frequency does not exist!")
389 return 0.0
390
392 """
393 netAvailablePower(frequency = None)
394 @type frequency: float
395 @param frequency: frequency of interest --- The default is None which considers all the frequencies
396 @rtype: double
397 @return: net available power at the given frequency (in case of frequency = None, a list of all values for all frequencies is returned)
398 """
399 query = empro.output.array_farfields(self._results._proj, self._sim, self._sensorName, self._shifts, self._rotationAngles, self._rotationAxes)
400 query.useMultipleExcitation = True
401 query.multipleExcitation = self._multipleExcitationCoeffs
402 if self._allExcitation:
403 query.setExcitationBasis(self._excBasis)
404 query.resultType = "NetAvailablePower"
405 ds = query.dataset()
406 freqDs = ds.dimension(0)
407 results = []
408 for i in range(len(ds)):
409 if frequency == None:
410 results.append(ds.at(i))
411 elif (freqDs.at(i) == frequency):
412 return ds.at(i)
413 if frequency == None:
414 return results
415 else:
416 raise RuntimeError("The given frequency does not exist!")
417 return 0.0
418
446
476
506
507 - def maxEphi(self, frequency = None):
536
566
596
597 - def mainLobeDirection(self, frequency = None):
598 """
599 mainLobeDirection(frequency = None)
600 @type frequency: float
601 @param frequency: frequency of interest --- The default is None which considers all the frequencies
602 @rtype: a pair of floats
603 @return: the direction of the main lobe in radian([theta, phi]) at the given frequency (in case of frequency = None, a list of all values for all frequencies is returned)
604 """
605 query = empro.output.array_farfields(self._results._proj, self._sim, self._sensorName, self._shifts, self._rotationAngles, self._rotationAxes)
606 query.useMultipleExcitation = True
607 query.multipleExcitation = self._multipleExcitationCoeffs
608 if self._allExcitation:
609 query.setExcitationBasis(self._excBasis)
610 query.resultType = "MainLobeDirection"
611 query.resultComponent = "Theta"
612 query.complexPart = "NotComplex"
613 dstheta = query.dataset()
614 query.resultComponent = "Phi"
615 dsphi = query.dataset()
616 assert( len(dstheta) == len(dsphi) )
617 freqDs = dstheta.dimension(0)
618 results = []
619 for i in range(len(dstheta)):
620 if frequency == None:
621 angle = [dstheta.at(i), dsphi.at(i)]
622 results.append(angle)
623 elif (freqDs.at(i) == frequency):
624 angle = [dstheta.at(i), dsphi.at(i)]
625 return angle
626 if frequency == None:
627 return results
628 else:
629 raise RuntimeError("The given frequency does not exist!")
630 return 0.0
631
633 """
634 systemEfficiency(frequency = None)
635 @type frequency: float
636 @param frequency: frequency of interest --- The default is None which considers all the frequencies
637 @rtype: double
638 @return: system efficiency at the given frequency (in case of frequency = None, a list of all values for all frequencies is returned)
639 """
640 query = empro.output.array_farfields(self._results._proj, self._sim, self._sensorName, self._shifts, self._rotationAngles, self._rotationAxes)
641 query.useMultipleExcitation = True
642 query.multipleExcitation = self._multipleExcitationCoeffs
643 if self._allExcitation:
644 query.setExcitationBasis(self._excBasis)
645 query.resultType = "SystemEfficiency"
646 ds = query.dataset()
647 freqDs = ds.dimension(0)
648 results = []
649 for i in range(len(ds)):
650 if frequency == None:
651 results.append(ds.at(i))
652 elif (freqDs.at(i) == frequency):
653 return ds.at(i)
654 if frequency == None:
655 return results
656 else:
657 raise RuntimeError("The given frequency does not exist!")
658 return 0.0
659
660
662 """
663 radiationEfficiency(frequency = None)
664 @type frequency: float
665 @param frequency: frequency of interest --- The default is None which considers all the frequencies
666 @rtype: double
667 @return: radiation efficiency at the given frequency (in case of frequency = None, a list of all values for all frequencies is returned)
668 """
669 query = empro.output.array_farfields(self._results._proj, self._sim, self._sensorName, self._shifts, self._rotationAngles, self._rotationAxes)
670 query.useMultipleExcitation = True
671 query.multipleExcitation = self._multipleExcitationCoeffs
672 if self._allExcitation:
673 query.setExcitationBasis(self._excBasis)
674 query.resultType = "RadiationEfficiency"
675 ds = query.dataset()
676 freqDs = ds.dimension(0)
677 results = []
678 for i in range(len(ds)):
679 if frequency == None:
680 results.append(ds.at(i))
681 elif (freqDs.at(i) == frequency):
682 return ds.at(i)
683 if frequency == None:
684 return results
685 else:
686 raise RuntimeError("The given frequency does not exist!")
687 return 0.0
688