xml_generator.py 4.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. from yattag import Doc, indent
  2. class XMLGenerator:
  3. """
  4. Генератор XML синхронизации в формате, совместимом с test1_full/srv_interp.py
  5. """
  6. def generate(self, sync_data: dict, path: str, hw):
  7. number_of_blocks = sync_data["number_of_blocks"]
  8. gate_rf = sync_data["gate_rf"]
  9. gate_tr_switch = sync_data["gate_tr_switch"]
  10. gate_adc = sync_data["gate_adc"]
  11. blocks_duration = sync_data["blocks_duration"]
  12. synchro_block_timer = sync_data["synchro_block_timer"]
  13. min_block_time = sync_data["min_block_time"]
  14. doc, tag, text = Doc().tagtext()
  15. with tag("root"):
  16. with tag("ParamCount"):
  17. text(number_of_blocks + 1)
  18. adc_times_values = []
  19. adc_times_starts = []
  20. # Массивы синхронизатора имеют ведущий seed-элемент на индексе 0
  21. # (стартовый блок), значимые блоки идут по индексам 1..nb. Seed
  22. # представлен заголовочным тегом (*1), поэтому в цикле эмитим
  23. # элементы 1..nb: block_iter k -> индекс массива k + 1.
  24. # (Совпадает с эталонной логикой srv_interp.synchronization.)
  25. with tag("RF"):
  26. with tag("RF1"):
  27. text(0)
  28. for rf_iter in range(number_of_blocks):
  29. with tag("RF" + str(rf_iter + 2)):
  30. text(gate_rf[rf_iter + 1])
  31. with tag("SW"):
  32. with tag("SW1"):
  33. text(1)
  34. for sw_iter in range(number_of_blocks):
  35. with tag("SW" + str(sw_iter + 2)):
  36. text(gate_tr_switch[sw_iter + 1])
  37. with tag("ADC"):
  38. with tag("ADC1"):
  39. text(0)
  40. for adc_iter in range(number_of_blocks):
  41. idx = adc_iter + 1
  42. # Непрерывный участок HIGH (в т.ч. собранный из разбитых
  43. # блоков) считается одним событием ADC: засекаем фронт и
  44. # суммируем длительность всего участка для points-окна.
  45. is_rising_edge = (
  46. gate_adc[idx] == 1 and gate_adc[idx - 1] == 0
  47. )
  48. if is_rising_edge:
  49. adc_times_starts.append(sum(blocks_duration[0:idx]))
  50. run_duration = 0
  51. run_iter = idx
  52. while (run_iter < len(gate_adc)
  53. and gate_adc[run_iter] == 1):
  54. run_duration += blocks_duration[run_iter]
  55. run_iter += 1
  56. adc_times_values.append(run_duration)
  57. with tag("ADC" + str(adc_iter + 2)):
  58. text(gate_adc[idx])
  59. with tag("GR"):
  60. with tag("GR1"):
  61. text(1)
  62. for gr_iter in range(number_of_blocks):
  63. # Последнее событие импульсной последовательности
  64. # переводим из LOW в HIGH (включение градиентной системы)
  65. gr_value = 1 if gr_iter == number_of_blocks - 1 else 0
  66. with tag("GR" + str(gr_iter + 2)):
  67. text(gr_value)
  68. with tag("CL"):
  69. with tag("CL1"):
  70. text(int(min_block_time / synchro_block_timer))
  71. for cl_iter in range(number_of_blocks):
  72. with tag("CL" + str(cl_iter + 2)):
  73. text(int(blocks_duration[cl_iter + 1] / synchro_block_timer))
  74. xml_string = indent(doc.getvalue(), indentation=" " * 4, newline="\r")
  75. with open(path, "w", encoding="utf-8") as f:
  76. f.write(xml_string)
  77. return adc_times_values, adc_times_starts