file_reader.py 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. import datetime
  2. import pandas as pd
  3. class FileReader:
  4. __amp_n_cols = []
  5. for i in range(1, 17):
  6. __amp_n_cols.append(f'amp{i}')
  7. __amp_n_cols.append(f'n{i}')
  8. def __init__(self, cluster, single_date, path_to_files=''):
  9. self.cluster = cluster
  10. if cluster == 1:
  11. self.cluster_n = ''
  12. else:
  13. self.cluster_n = '2'
  14. self.path_to_files = path_to_files
  15. self.single_date = single_date
  16. self.n_file_path = self.making_file_path(file_type='n')
  17. self.n7_file_path = self.making_file_path(file_type='n7')
  18. self.t_file_path = self.making_file_path(file_type='t')
  19. self.p_file_path = self.making_file_path_eas_p(file_directory='nv', file_type='p')
  20. self.eas_file_path = self.making_file_path_eas_p(file_directory='EAS', file_type='eas')
  21. def __del__(self):
  22. pass
  23. def making_file_path(self, file_type):
  24. file_path = f'{self.path_to_files}\\{file_type}\\{self.cluster_n}{file_type}_{self.single_date.month:02}-{self.single_date.day:02}.{self.single_date.year - 2000:02} '
  25. return file_path
  26. def making_file_path_eas_p(self, file_directory, file_type):
  27. file_path = f'{self.path_to_files}\\{file_directory}\\{self.cluster}{file_type}_{self.single_date.month:02}-{self.single_date.day:02}.{self.single_date.year - 2000:02}'
  28. return file_path
  29. def reading_n_file(self):
  30. """Метод, прочитывающий n-файлы, возвращающий датафрейм дня на выходе. Или возвращающий filenotfounderror, если
  31. файла нет"""
  32. n_file = pd.read_csv(self.n_file_path,
  33. sep=r'\s[-]*\s*', header=None, skipinitialspace=True, index_col=False, engine='python')
  34. n_file.dropna(axis=1, how='all', inplace=True)
  35. n_file.columns = ['time', 'number', 'sum_n', 'trigger'] + FileReader.__amp_n_cols
  36. time_difference = n_file['time'].diff()
  37. bad_end_time_index = time_difference[time_difference < -10000].index
  38. if any(bad_end_time_index):
  39. n_file_today = n_file[n_file.index < bad_end_time_index[0]]
  40. n_file_day_after = n_file[n_file.index >= bad_end_time_index[0]]
  41. return n_file_today, n_file_day_after
  42. return n_file, []
  43. def reading_n7_file(self):
  44. n7_file = pd.read_csv(self.n7_file_path,
  45. sep=r'\s[-]*\s*', header=None, skipinitialspace=True, index_col=False, engine='python')
  46. n7_file.dropna(axis=1, how='all', inplace=True)
  47. for i in range(len(n7_file[0])):
  48. if type(n7_file[0][i]) is str:
  49. n7_file.loc[i, 0] = float('.'.join(n7_file.loc[i, 0].split(',')))
  50. time_difference = n7_file[0].diff()
  51. bad_end_time_index = time_difference[time_difference < -10000].index
  52. if any(bad_end_time_index):
  53. n7_file_today = n7_file[n7_file.index < bad_end_time_index[0]]
  54. n7_file_day_after = n7_file[n7_file.index >= bad_end_time_index[0]]
  55. return n7_file_today, n7_file_day_after
  56. return n7_file, []
  57. @staticmethod
  58. def concat_data(file_today, file_day_after, single_date, concat_n_df):
  59. file_today['Date'] = [single_date.date()] * len(file_today.index)
  60. concat_n_df = pd.concat([concat_n_df, file_today], ignore_index=True)
  61. if any(file_day_after):
  62. file_day_after['Date'] = [(single_date + datetime.timedelta(
  63. days=1)).date()] * len(file_day_after.index)
  64. concat_n_df = pd.concat([concat_n_df, file_day_after],
  65. ignore_index=True)
  66. return concat_n_df
  67. def reading_t_file(self):
  68. """Converter for PRISMA t-files"""
  69. with open(self.t_file_path) as f:
  70. raw_data = f.readlines()
  71. raw_data = [line.rstrip() for line in raw_data]
  72. # Убираем переводы строки
  73. event_list = []
  74. main_list = []
  75. sep = 0
  76. for i in range(len(raw_data)):
  77. if raw_data[i] == '*#*':
  78. main_list.append(raw_data[sep].split(' '))
  79. event_list.append(raw_data[sep + 1:i])
  80. sep = i + 1
  81. unit_delay = []
  82. for item in event_list:
  83. delay_per_event = []
  84. for line in item:
  85. step = line.split(' ')
  86. for i in range(1, 17):
  87. if int(step[i]) != 0:
  88. delay_per_event.append([round(int(step[0]) * (10 ** (-4)), 4), i, int(step[i])])
  89. unit_delay.append(delay_per_event)
  90. plural_data_list = []
  91. for i in unit_delay:
  92. time_list = []
  93. detector_list = []
  94. neut_quantity_list = []
  95. for j in i:
  96. time_list.append(j[0])
  97. detector_list.append(j[1])
  98. neut_quantity_list.append(j[2])
  99. plural_data_list.append([time_list, detector_list, neut_quantity_list])
  100. for i in range(len(main_list)):
  101. main_list[i].extend(plural_data_list[i])
  102. t_file_df = pd.DataFrame(main_list,
  103. columns=['time', 'number', 'sum_n', 'trigger', 'time_delay', 'detectors',
  104. 'n_per_step'])
  105. t_file_df = t_file_df.astype({"time": float, "number": int, "sum_n": int, "trigger": int})
  106. return t_file_df
  107. def reading_p_file(self):
  108. """Метод, прочитывающий p-файлы, возвращающий датафрейм дня на выходе. Или возвращающий filenotfounderror, если
  109. файла нет"""
  110. p_file = pd.read_csv(self.p_file_path,
  111. sep=r'\s[-]*\s*', header=None, skipinitialspace=True, engine='python')
  112. p_file.dropna(axis=1, how='all', inplace=True)
  113. corr_p_file = self.correcting_p_file(p_file)
  114. return corr_p_file
  115. @staticmethod
  116. def correcting_p_file(p_file):
  117. """Метод, корректирующий старые файлы ПРИЗМА-32, возвращающий скорректированный датафрейм.
  118. Данный костыль нужен для старых p-файлов ПРИЗМА-32(до 14-15 гг.), в которых индексы строк,
  119. по сути обозначающие 5 минут реального времени между ранами, могут повторяться. """
  120. p_file['time'] = p_file[0]
  121. del p_file[0]
  122. p_file = p_file.sort_values(by='time')
  123. if len(p_file['time']) > len(p_file['time'].unique()):
  124. p_file.drop_duplicates(keep=False, inplace=True)
  125. """После удаления полных дубликатов ищем повторяющиеся индексы. Сначала удаляем строки,
  126. состоящие полностью из нулей и точек (value = len(p_file.columns)), потом ищем множество
  127. дубликатов индексов и множество строк, почти полностью (value > 30) состоящих из нулей и точек.
  128. Берем пересечение этих двух множеств и удаляем находящиеся в пересечении строки"""
  129. null_row = dict(p_file.isin([0, '.']).sum(axis=1)) # Проверяем на нули и точки
  130. all_null_index = list(
  131. {key: value for key, value in null_row.items() if value == len(p_file.columns)}.keys())
  132. p_file.drop(index=all_null_index, inplace=True)
  133. null_index = list(
  134. {key: value for key, value in null_row.items() if value > len(p_file.columns) - 5}.keys())
  135. same_index = dict(p_file['time'].duplicated(keep=False))
  136. same_index_row = list({key: value for key, value in same_index.items() if value is True}.keys())
  137. bad_index = list(set(null_index) & set(same_index_row))
  138. p_file.drop(index=bad_index, inplace=True)
  139. """Также может быть, что после фильтрации осталось больше строк, чем нужно, так как в старых
  140. p-файлах может быть больше индексов, чем минут в дне. Тогда оставляем только 288"""
  141. if len(p_file.index) == 289:
  142. p_file = p_file.head(288)
  143. return p_file