nosql_db_prisma.py 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. import datetime
  2. import pathlib
  3. import pymongo
  4. import config_info.config
  5. from file_reader.file_reader import FileReader
  6. # noinspection DuplicatedCode
  7. class NoSQLPrisma:
  8. """Класс записи n, n7, t - файлов в MongoDB базу данных PRISMA-32"""
  9. __DB_URL = config_info.config.DB_URL
  10. __db_client = pymongo.MongoClient(__DB_URL)
  11. __prisma_db = __db_client["prisma-32_db"]
  12. __slots__ = ["cluster", "single_date", "file_reader"]
  13. def __init__(self, cluster, single_date):
  14. self.cluster = cluster
  15. self.single_date = single_date
  16. self.file_reader = FileReader(cluster=self.cluster, single_date=self.single_date,
  17. path_to_files=pathlib.PurePath('D:\\PRISMA20', f'P{self.cluster}'))
  18. def dinods_data_copier(self, event_datetime, trigger, det_params, dinode):
  19. """Метод, создающий запись в базе данных, пользуясь информацией из его аргументов,
  20. если запись в БД уже есть, то кидает ошибку"""
  21. try:
  22. new_record = {
  23. '_id': f'{event_datetime.date()}_{self.cluster:02}_{dinode:02}d' +
  24. f'_{int(event_datetime.hour):02}:' +
  25. f'{int(event_datetime.minute):02}:{int(event_datetime.second):02}.' +
  26. f'{str(event_datetime.microsecond)[:3]}.000.000',
  27. 'time_ns': int((int(event_datetime.hour) * 3600 + int(event_datetime.minute) * 60 + int(
  28. event_datetime.second)) * 10e8 + int(event_datetime.microsecond) * 1000),
  29. 'cluster': self.cluster,
  30. 'trigger': int(trigger),
  31. 'detectors': det_params
  32. }
  33. collection_prisma = NoSQLPrisma.__prisma_db[f'{str(event_datetime.date())}_{dinode}d']
  34. ins_result = collection_prisma.insert_one(new_record)
  35. print(f'Copied - {ins_result.inserted_id}')
  36. # with open('log.txt', 'a+') as log_file:
  37. # log_file.write(f'Copied - {ins_result.inserted_id}\n')
  38. except pymongo.errors.DuplicateKeyError:
  39. print(f'Запись существует - {self.cluster}cl - {dinode:02}d' +
  40. f' - {event_datetime.date()}-{event_datetime.time()}')
  41. # with open('log.txt', 'a+') as log_file:
  42. # log_file.write(f'Ошибка - {event_datetime.date()}-{event_datetime.time()}\n')
  43. def prisma_12d_past_data_copier(self):
  44. """Главный метод для данных 12-динода, в котором происходит чтение n
  45. и t-файлов и их соединение, определение их параметров и запись в БД"""
  46. n_file_today, n_file_day_after = self.file_reader.reading_n_file() # Если n-файла, нет то
  47. # проброс исключение идет в runner.py
  48. try:
  49. t_file = self.file_reader.t_file_conventer()
  50. n_file_today = n_file_today.merge(t_file) # А что делать, если не все строки в t-файле совпадают
  51. self.make_params_from_df_12_d(n_file_today, self.single_date)
  52. if any(n_file_day_after):
  53. n_file_day_after = n_file_day_after.merge(t_file)
  54. self.make_params_from_df_12_d(n_file_day_after,
  55. self.single_date + datetime.timedelta(
  56. days=1))
  57. # Идет проброс исключение на существование t-файла и вызывается метод make_params_from_df_12_d_no_t
  58. except FileNotFoundError:
  59. with open(f'files_not_found/t_{self.cluster}cl_files_not_found.txt', 'a+', encoding='utf-8') as t_log_file:
  60. t_log_file.write(f't-файла {self.cluster}-го кластера от {self.single_date} не существует\n')
  61. self.make_params_from_df_12_d_no_t(n_file_today, self.single_date)
  62. if any(n_file_day_after):
  63. self.make_params_from_df_12_d_no_t(n_file_day_after,
  64. self.single_date + datetime.timedelta(
  65. days=1))
  66. def prisma_7d_past_data_copier(self):
  67. """Главный метод для данных 7-динода, в котором происходит чтение n7,
  68. определение их параметров и запись в БД"""
  69. n7_file_today, n7_file_day_after = self.file_reader.reading_n7_file()
  70. self.make_params_from_df_7_d(n7_file_today, self.single_date)
  71. if any(n7_file_day_after):
  72. self.make_params_from_df_7_d(n7_file_day_after,
  73. self.single_date + datetime.timedelta(days=1))
  74. def make_params_from_df_12_d(self, df, date):
  75. """Метод для данных 12-динода, парсящий построчно n+t-dataframe, определяющий все нужные для БД
  76. параметры события: время регистрации, амплитуды и кол-во нейтронов по детекторно, триггер,
  77. время запаздывания нейтронов."""
  78. for index in range(len(df.index)):
  79. params = list(df.iloc[index])
  80. event_time = str(datetime.timedelta(seconds=params[0]))
  81. event_time_split = event_time.split(':')
  82. event_datetime = datetime.datetime(date.year, date.month, date.day,
  83. int(event_time_split[0]),
  84. int(event_time_split[1]),
  85. int(float(event_time_split[2])),
  86. int(round(
  87. float(event_time_split[2]) - int(
  88. float(event_time_split[2])),
  89. 2) * 10 ** 6)) - datetime.timedelta(hours=4)
  90. trigger = params[3]
  91. amp = [int(params[j]) for j in range(4, 36, 2)]
  92. n = [int(params[j]) for j in range(5, 37, 2)]
  93. n_time_delay = params[36]
  94. detector = params[37]
  95. n_in_step = params[38]
  96. det_params = {}
  97. for i in range(1, 17):
  98. n_time_delay_by_det = []
  99. detector_index = [ind for ind, v in enumerate(detector) if v == i]
  100. for j in detector_index:
  101. n_time_delay_by_det.extend([n_time_delay[j]] * int(n_in_step[j]))
  102. # В БД будут оставаться пустые списки при нуле нейтронов, надо ли это фиксить?
  103. det_params[f'det_{i:02}'] = {
  104. 'amplitude': amp[i - 1],
  105. 'neutrons': n[i - 1],
  106. 'time_delay': n_time_delay_by_det
  107. }
  108. # Вызывает в конце dinods_data_copier для записи в БД всю информацию о событии
  109. self.dinods_data_copier(event_datetime=event_datetime, trigger=trigger,
  110. det_params=det_params, dinode=12)
  111. def make_params_from_df_7_d(self, df, date):
  112. """Метод для данных 7-динода, парсящий построчно n7-dataframe, определяющий все нужные для БД
  113. параметры события: время регистрации, амплитуды по детекторно, триггер"""
  114. for index in range(len(df.index)):
  115. params = list(df.iloc[index])
  116. event_time = str(datetime.timedelta(seconds=params[0])) # перевод в utc-формат
  117. event_time_split = event_time.split(':')
  118. event_datetime = datetime.datetime(date.year, date.month, date.day,
  119. int(event_time_split[0]),
  120. int(event_time_split[1]),
  121. int(float(event_time_split[2])),
  122. int(round(
  123. float(event_time_split[2]) - int(
  124. float(event_time_split[2])),
  125. 2) * 10 ** 6)) - datetime.timedelta(hours=4)
  126. trigger = params[2]
  127. amp = [int(params[j]) for j in range(3, 19)]
  128. det_params = {}
  129. for i in range(1, 17):
  130. det_params[f'det_{i:02}'] = {
  131. 'amplitude': amp[i - 1]
  132. }
  133. # Вызывает в конце dinods_data_copier для записи в БД всю информацию о событии
  134. self.dinods_data_copier(event_datetime=event_datetime, trigger=trigger,
  135. det_params=det_params, dinode=7)
  136. def make_params_from_df_12_d_no_t(self, df, date):
  137. """Метод для данных 12-динода, парсящий построчно n-dataframe, так t-файла не существует в эту дату,
  138. определяющий все нужные для БД параметры события: время регистрации,
  139. амплитуды и кол-во нейтронов по детекторно, триггер."""
  140. for index in range(len(df.index)):
  141. params = list(df.iloc[index])
  142. event_time = str(datetime.timedelta(seconds=params[0]))
  143. event_time_split = event_time.split(':')
  144. event_datetime = datetime.datetime(date.year, date.month, date.day,
  145. int(event_time_split[0]),
  146. int(event_time_split[1]),
  147. int(float(event_time_split[2])),
  148. int(round(
  149. float(event_time_split[2]) - int(
  150. float(event_time_split[2])),
  151. 2) * 10 ** 6)) - datetime.timedelta(hours=4)
  152. trigger = params[3]
  153. amp = [int(params[j]) for j in range(4, 36, 2)]
  154. n = [int(params[j]) for j in range(5, 37, 2)]
  155. det_params = {}
  156. for i in range(1, 17):
  157. # В БД будут оставаться пустые списки при нуле нейтронов, надо ли это фиксить?
  158. det_params[f'det_{i:02}'] = {
  159. 'amplitude': amp[i - 1],
  160. 'neutrons': n[i - 1],
  161. 'time_delay': False
  162. }
  163. # Вызывает в конце dinods_data_copier для записи в БД всю информацию о событии
  164. self.dinods_data_copier(event_datetime=event_datetime, trigger=trigger,
  165. det_params=det_params, dinode=12)