processing_data_prisma_ver_2.py 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. # import datetime
  2. from collections import defaultdict
  3. import pandas as pd
  4. """Вопросы:
  5. 1)Обязательны p-file для временных обработок или перейти на n-file и db.
  6. 2)Начальную и конечную дату нужно ли передавать в этот класс или брать из n_data
  7. 3)Можно больше не конкатенировать датафреймы для амплитудного распределения
  8. 4)..."""
  9. class ProccessingPrismaCl:
  10. def __init__(self, n_data):
  11. self.n_data = n_data
  12. def period_processing_for_report(self, start_date, end_date):
  13. worktime_dict = defaultdict(list)
  14. n_vs_zero_tr_dict = defaultdict(list)
  15. event_counter_fr_4 = defaultdict(list)
  16. breaks_dict = defaultdict(list)
  17. count_rate_amp_5_fr_2 = defaultdict(list)
  18. count_rate_amp_10_fr_1 = defaultdict(list)
  19. for single_date in pd.date_range(start_date, end_date):
  20. worktime_dict['Date'].append(single_date)
  21. n_vs_zero_tr_dict['Date'].append(single_date)
  22. count_rate_amp_5_fr_2['Date'].append(single_date)
  23. count_rate_amp_10_fr_1['Date'].append(single_date)
  24. event_counter_fr_4['Date'].append(single_date)
  25. single_n_data = self.n_data[self.n_data['Date'] == single_date].reset_index(drop=True)
  26. if len(single_n_data) == 0:
  27. worktime_dict['Worktime'].append(0.00)
  28. for i in range(16):
  29. n_vs_zero_tr_dict[f'n{i + 1}'].append(0.00)
  30. count_rate_amp_5_fr_2[f'amp{i + 1}'].append(0.00)
  31. count_rate_amp_10_fr_1[f'amp{i + 1}'].append(0.00)
  32. event_counter_fr_4['Events'].append(0.00)
  33. continue
  34. break_time_dict, worktime_item = self._counting_break_time(single_n_data, delta_time_crit=600)
  35. worktime_dict['Worktime'].append(worktime_item)
  36. # print(break_time_dict)
  37. if break_time_dict:
  38. breaks_dict['Date'].extend([single_date.date()] * len(break_time_dict['StartSeconds']))
  39. breaks_dict['StartSeconds'].extend(break_time_dict['StartSeconds'])
  40. breaks_dict['EndSeconds'].extend(break_time_dict['EndSeconds'])
  41. neutron_to_zero_trigger = self._neutron_to_zero_trigger(single_n_data)
  42. for i in range(16):
  43. n_vs_zero_tr_dict[f'n{i + 1}'].append(neutron_to_zero_trigger[i])
  44. count_rate_amp_5_fr_2[f'amp{i + 1}'].append(
  45. self._set_event_counter(single_n_data, a_crit=6, freq=2)['count_rate'][i + 1])
  46. count_rate_amp_10_fr_1[f'amp{i + 1}'].append(
  47. self._set_event_counter(single_n_data, a_crit=11, freq=1)['count_rate'][i + 1])
  48. event_counter_fr_4['Events'].append(
  49. self._set_event_counter(single_n_data, a_crit=6, freq=4)['sum_events'])
  50. amp_5_fr_2_frame = self.set_amp_df(a_crit=6, freq=2)
  51. amp_10_fr_1_frame = self.set_amp_df(a_crit=11, freq=1)
  52. worktime_frame = pd.DataFrame(worktime_dict)
  53. n_vs_zero_tr_frame = pd.DataFrame(n_vs_zero_tr_dict)
  54. breaks_frame = pd.DataFrame(breaks_dict)
  55. event_counter_fr_4 = pd.DataFrame(event_counter_fr_4)
  56. count_rate_amp_5_fr_2 = pd.DataFrame(count_rate_amp_5_fr_2)
  57. count_rate_amp_10_fr_1 = pd.DataFrame(count_rate_amp_10_fr_1)
  58. for column in [f'amp{i}' for i in range(1, 17)]:
  59. count_rate_amp_5_fr_2[column] = count_rate_amp_5_fr_2[column] / worktime_frame['Worktime']
  60. count_rate_amp_10_fr_1[column] = count_rate_amp_10_fr_1[column] / worktime_frame['Worktime']
  61. return worktime_frame, breaks_frame, n_vs_zero_tr_frame, event_counter_fr_4, count_rate_amp_5_fr_2, count_rate_amp_10_fr_1, amp_5_fr_2_frame, amp_10_fr_1_frame
  62. @staticmethod
  63. def _counting_break_time(n_file, delta_time_crit):
  64. """Метод, выявляющий в n-file 5-минутки, когда кластер не работал, возвращает начальное время остановки и
  65. конечное время остановки"""
  66. time_difference = n_file['time'].diff()
  67. daily_breaks_dict = defaultdict(list)
  68. worktime_item = 24.00
  69. # print(f'{time_difference=}')
  70. for i in range(1, len(time_difference)):
  71. if time_difference[i] > delta_time_crit:
  72. daily_breaks_dict['StartSeconds'].append(n_file['time'][i - 1])
  73. daily_breaks_dict['EndSeconds'].append(n_file['time'][i])
  74. if n_file['time'][0] > delta_time_crit:
  75. daily_breaks_dict['StartSeconds'].append(0)
  76. daily_breaks_dict['EndSeconds'].append(n_file['time'][0])
  77. if n_file['time'][len(n_file['time'])-1] < 86400 - delta_time_crit:
  78. daily_breaks_dict['StartSeconds'].append(n_file['time'][len(n_file['time'])-1])
  79. daily_breaks_dict['EndSeconds'].append(86399)
  80. if daily_breaks_dict:
  81. worktime_item = worktime_item - round(sum(
  82. [daily_breaks_dict['EndSeconds'][index] - daily_breaks_dict['StartSeconds'][index] for index in
  83. range(len(daily_breaks_dict['StartSeconds']))]) / 3600, 2)
  84. return daily_breaks_dict, worktime_item
  85. else:
  86. return None, worktime_item
  87. @staticmethod
  88. def _neutron_to_zero_trigger(n_file):
  89. """Метод, обрабатывающий данные n-файлов ПРИЗМА-32, дающий на выходе нормированное число в событии,
  90. отобранных как нейтрон, при самозапуске"""
  91. counter_zero_tr = len(n_file[n_file['trigger'] == 0].index)
  92. zero_tr_frame = n_file[n_file['trigger'] == 0]
  93. return [round(zero_tr_frame[f'n{i}'].sum() / counter_zero_tr, 3) for i in range(1, 17)]
  94. # except ZeroDivisionError: Нужно дописать, если допустим нет нулевых триггеров
  95. @staticmethod
  96. def _set_event_counter(n_file, a_crit, freq):
  97. """Метод, обрабатывающий данные n-файлов ПРИЗМА-32, на вход подаются определенная амплитуда и количество
  98. детекторов, на которых амплитуда превышает заданную, на выходе метод возвращает словарь с параметрами:
  99. 1) суммарное число событий на кластере, подходящих под заданные условия;
  100. 2) датафрейм с амплитудами детекторов для каждого события, подходящего под заданные условия;
  101. 3) количество превышений заданной амплитуды у детектора в событиях, подходящих под заданные условия; """
  102. cluster_count_rate = {}
  103. amp_frame = n_file[[f'amp{i}' for i in range(1, 17)]]
  104. amp_frame['fr_sum'] = amp_frame.isin(range(a_crit, 520)).sum(axis=1, skipna=True) # noqa
  105. amp_frame = amp_frame[amp_frame['fr_sum'] >= freq].reset_index(drop=True)
  106. for i in range(1, 17):
  107. cluster_count_rate[i] = len(amp_frame[amp_frame[f'amp{i}'] >= a_crit])
  108. return {'sum_events': len(amp_frame.index),
  109. 'count_rate': cluster_count_rate}
  110. def set_amp_df(self, a_crit, freq):
  111. amp_frame = self.n_data[[f'amp{i}' for i in range(1, 17)]]
  112. amp_frame['fr_sum'] = amp_frame.isin(range(a_crit, 520)).sum(axis=1, skipna=True) # noqa
  113. amp_frame = amp_frame[amp_frame['fr_sum'] >= freq].reset_index(drop=True)
  114. return amp_frame[[f'amp{i}' for i in range(1, 17)]]