|
24 | 24 |
|
25 | 25 | import csv |
26 | 26 | import logging |
| 27 | +import math |
27 | 28 | import os |
28 | 29 | from pathlib import Path |
29 | 30 | import re |
30 | 31 |
|
| 32 | +from ansys.aedt.core import settings |
31 | 33 | from ansys.aedt.core.generic.constants import CSS4_COLORS |
32 | 34 | from ansys.aedt.core.generic.constants import SI_UNITS |
33 | 35 | from ansys.aedt.core.generic.constants import unit_system |
@@ -211,6 +213,177 @@ def convert_nearfield_data(dat_folder, frequency=6, invert_phase_for_lower_faces |
211 | 213 | return and_full_file |
212 | 214 |
|
213 | 215 |
|
| 216 | +@pyaedt_function_handler() |
| 217 | +def convert_farfield_data(input_file, output_file=None) -> str: |
| 218 | + """Convert a far field data file to hfss `ffd` file. |
| 219 | +
|
| 220 | + Parameters |
| 221 | + ---------- |
| 222 | + input_file : str or :class:`pathlib.Path` |
| 223 | + Input source file to convert. The file can be either a `.ffs` or `.ffe` file. |
| 224 | + output_file : str or :class:`pathlib.Path`, optional |
| 225 | + Output file to save the converted data. |
| 226 | + If not specified, the output file will be in the same folder as the input file. |
| 227 | +
|
| 228 | + Returns |
| 229 | + ------- |
| 230 | + str |
| 231 | + Full path to the converted `.ffd` file. |
| 232 | + """ |
| 233 | + input_file = Path(input_file) |
| 234 | + |
| 235 | + if not output_file: |
| 236 | + output_folder = input_file.parent |
| 237 | + output_file = output_folder / input_file.with_suffix(".ffd") |
| 238 | + if input_file.suffix.lower() == ".ffs": |
| 239 | + return __convert_ffs_data(input_file, output_file) |
| 240 | + elif input_file.suffix.lower() == ".ffe": |
| 241 | + return __convert_ffe_data(input_file, output_file) |
| 242 | + |
| 243 | + |
| 244 | +@pyaedt_function_handler() |
| 245 | +def __convert_ffs_data(input_file, output_file): |
| 246 | + freqs = [] |
| 247 | + output_data = {} |
| 248 | + if not input_file.exists(): |
| 249 | + raise FileNotFoundError(f"File ({input_file}) not found.") |
| 250 | + |
| 251 | + inp_file = open(input_file) |
| 252 | + data = inp_file.readlines() |
| 253 | + cnt = 0 |
| 254 | + freq = 0 |
| 255 | + no_of_freq_points = 1 |
| 256 | + theta_start = 0.0 |
| 257 | + theta_end = 90.0 |
| 258 | + phi_start = 0.0 |
| 259 | + phi_end = 0.0 |
| 260 | + for line in data: |
| 261 | + if "Frequencies" in line: |
| 262 | + no_of_freq_points = int(data[cnt + 1]) |
| 263 | + if "Radiated" in line: |
| 264 | + for i in range(no_of_freq_points): |
| 265 | + freqs.append(float(data[cnt + 4 + i * 5])) |
| 266 | + |
| 267 | + # Now get number of samples |
| 268 | + if "samples" in line: |
| 269 | + temp_list = data[cnt + 1].split(" ") |
| 270 | + no_of_phi_samples = int(temp_list[0]) |
| 271 | + no_of_theta_samples = int(temp_list[1]) |
| 272 | + |
| 273 | + # Now get the Phi and Theta Sample Pixelations |
| 274 | + if "E_Theta" in line: |
| 275 | + temp_list = data[cnt + 1].split(" ") |
| 276 | + new_list = [] |
| 277 | + for entry in temp_list: |
| 278 | + if entry != "": |
| 279 | + new_list.append(entry) |
| 280 | + phi_start = float(new_list[0]) |
| 281 | + theta_start = float(new_list[1]) |
| 282 | + # Now construct end points |
| 283 | + temp_list = data[cnt + no_of_phi_samples * no_of_theta_samples].split(" ") |
| 284 | + new_list = [] |
| 285 | + for entry in temp_list: |
| 286 | + if entry != "": |
| 287 | + new_list.append(entry) |
| 288 | + phi_end = float(new_list[0]) |
| 289 | + theta_end = float(new_list[1]) |
| 290 | + |
| 291 | + if "Re(E_Theta)" in line: |
| 292 | + freq = freq + 1 |
| 293 | + settings.logger.info(f"===========freq number {freq}") |
| 294 | + output_data["total_data_%s" % freq] = {} |
| 295 | + for i in range(no_of_phi_samples * no_of_theta_samples + 1): |
| 296 | + temp_list1 = data[cnt + i].split(" ") |
| 297 | + temp_list2 = [] |
| 298 | + for item in temp_list1: |
| 299 | + if item != "": |
| 300 | + temp_list2.append(item) |
| 301 | + output_data["total_data_%s" % freq][temp_list2[1] + "," + temp_list2[0]] = ( |
| 302 | + temp_list2[2] + " " + temp_list2[3] + " " + temp_list2[4] + " " + temp_list2[5].replace("\\n", "") |
| 303 | + ) |
| 304 | + |
| 305 | + cnt = cnt + 1 |
| 306 | + |
| 307 | + out_file = open(output_file, "w") |
| 308 | + # First write start end and number of theta divisions |
| 309 | + out_file.write(str(theta_start) + " " + str(theta_end) + " " + str(no_of_theta_samples)) |
| 310 | + out_file.write("\n") |
| 311 | + out_file.write(str(phi_start) + " " + str(phi_end) + " " + str(no_of_phi_samples)) |
| 312 | + out_file.write("\n") |
| 313 | + out_file.write("Frequencies" + " " + str(no_of_freq_points)) |
| 314 | + out_file.write("\n") |
| 315 | + for freq in range(no_of_freq_points): |
| 316 | + out_file.write("Frequency" + " " + str(freqs[freq])) |
| 317 | + out_file.write("\n") |
| 318 | + theta_incr = int(math.ceil((theta_end - theta_start) / no_of_theta_samples)) |
| 319 | + phi_incr = int(math.ceil((phi_end - phi_start) / no_of_phi_samples)) |
| 320 | + for i in range(0, int(math.ceil(theta_end)) + theta_incr, theta_incr): |
| 321 | + for j in range(0, int(math.ceil(phi_end)) + phi_incr, phi_incr): |
| 322 | + my_data = output_data["total_data_%s" % (freq + 1)][str(i) + ".000" + "," + str(j) + ".000"] |
| 323 | + out_file.write(str(my_data)) |
| 324 | + if freq < no_of_freq_points - 1: |
| 325 | + out_file.write("\n") |
| 326 | + out_file.close() |
| 327 | + return str(output_file) |
| 328 | + |
| 329 | + |
| 330 | +@pyaedt_function_handler() |
| 331 | +def __convert_ffe_data(input_file, output_file): |
| 332 | + data = [] |
| 333 | + quantity = [] |
| 334 | + |
| 335 | + frequency = 1e9 |
| 336 | + Ntheta = 1 |
| 337 | + Nphi = 1 |
| 338 | + |
| 339 | + if not input_file.exists(): |
| 340 | + raise FileNotFoundError(f"File ({input_file}) not found.") |
| 341 | + |
| 342 | + with open(input_file) as f: |
| 343 | + text = f.readlines() |
| 344 | + |
| 345 | + for i in text: |
| 346 | + if len(i.strip()) == 0: |
| 347 | + pass |
| 348 | + |
| 349 | + elif i.startswith("#Frequency"): |
| 350 | + frequency = float(i.split(":")[1]) |
| 351 | + |
| 352 | + elif "Theta Samples" in i: |
| 353 | + Ntheta = int(i.split(":")[1]) |
| 354 | + |
| 355 | + elif "Phi Samples" in i: |
| 356 | + Nphi = int(i.split(":")[1]) |
| 357 | + |
| 358 | + elif '"Theta"' in i and '"Phi"' in i: |
| 359 | + quantity = [j.replace('"', "") for j in i.split()[1:]] |
| 360 | + |
| 361 | + elif len(i.split()) == len(quantity): |
| 362 | + data.append(tuple(map(float, i.split()))) |
| 363 | + |
| 364 | + else: |
| 365 | + pass |
| 366 | + |
| 367 | + data = sorted(data, key=lambda x: (x[0], x[1])) |
| 368 | + data2 = dict(zip(quantity, zip(*data))) |
| 369 | + |
| 370 | + min_data_theta2 = min(data2["Theta"]) |
| 371 | + max_data_theta2 = max(data2["Theta"]) |
| 372 | + ffd = f"{min_data_theta2} {max_data_theta2} {Ntheta}\n" |
| 373 | + min_data_phi2 = min(data2["Phi"]) |
| 374 | + max_data_phi2 = max(data2["Phi"]) |
| 375 | + ffd += f"{min_data_phi2} {max_data_phi2} {Nphi}\n" |
| 376 | + ffd += "Frequencies 1\n" |
| 377 | + ffd += f"Frequency {frequency}\n" |
| 378 | + |
| 379 | + for i in zip(data2["Re(Etheta)"], data2["Im(Etheta)"], data2["Re(Ephi)"], data2["Im(Ephi)"]): |
| 380 | + ffd += "{:+15.8e} {:+15.8e} {:+15.8e} {:+15.8e}\n".format(*i) |
| 381 | + |
| 382 | + with open(output_file, "w") as f: |
| 383 | + f.write(ffd) |
| 384 | + return str(output_file) |
| 385 | + |
| 386 | + |
214 | 387 | @pyaedt_function_handler() |
215 | 388 | def parse_rdat_file(file_path): |
216 | 389 | """ |
|
0 commit comments