DrugDesign Data Analysis
Module of the DrugDesign project responsible for loading and pre-processing data from ChEMBL and PubChem
All Classes Namespaces Files Functions Variables Pages
files_funcs Namespace Reference

Functions

 CombineCSVInFolder (str folder_name, str combined_file_name)
 
 DeleteFilesInFolder (str folder_name, list[str] except_items=[], bool delete_folders=False)
 
bool IsFileInFolder (str file_name, str folder_name)
 
bool IsFolderEmpty (str folder_name)
 
 MoveFileToFolder (str file_name, str curr_folder_name, str folder_name)
 
 SaveMolfilesToSDF (pd.DataFrame data, str file_name, str molecule_id_column_name, pd.DataFrame extra_data=pd.DataFrame(), bool indexing_lists=False)
 

Detailed Description

Utils/files_funcs.py Этот модуль содержит набор функций для работы с файлами и директориями, включая удаление, перемещение, объединение файлов, а также сохранение молекулярных структур в формате SDF.

Function Documentation

◆ CombineCSVInFolder()

files_funcs.CombineCSVInFolder ( str folder_name,
str combined_file_name )
Склеивает все .csv файлы в папке в один. Args: folder_name (str): имя папки с .csv файлами. combined_file_name (str): имя склеенного .csv файла.
124 combined_file_name: str):
125 """
126 Склеивает все .csv файлы в папке в один.
127
128 Args:
129 folder_name (str): имя папки с .csv файлами.
130 combined_file_name (str): имя склеенного .csv файла.
131 """
132
133 # получаем конфигурацию для объединения CSV-файлов.
134 combine_config: Config = config["Utils"]["CombineCSVInFolder"]
135
136 # получаем индекс формата логгера.
137 restore_index: int = v_logger.UpdateFormat(
138 combine_config["logger_label"], combine_config["logger_color"]) - 1
139
140 v_logger.info("Start combining downloads...")
141 v_logger.info("-", LogMode.VERBOSELY)
142
143 # если файл уже существует и нужно пропускать скачанные, выходим.
144 if IsFileInFolder(folder_name, f"{combined_file_name}.csv") and\
145 config["skip_downloaded"]:
146 v_logger.info(
147 f"File '{combined_file_name}.csv' is in folder, no need to "
148 f"combine.",
149 LogMode.VERBOSELY)
150
151 # восстанавливаем формат логгера.
152 v_logger.RestoreFormat(restore_index)
153 return
154
155 # создаем пустой DataFrame для объединения.
156 combined_df = pd.DataFrame()
157
158 # если папка пуста, выходим.
159 if len(os.listdir(folder_name)) == 0:
160 v_logger.info(f"{folder_name} is empty, no need to combine.")
161
162 # восстанавливаем формат логгера.
163 v_logger.RestoreFormat(restore_index)
164 return
165
166 # итерируемся по файлам в папке.
167 for file_name in os.listdir(folder_name):
168 # проверяем, является ли файл CSV-файлом и не является ли он
169 # результирующим.
170 if file_name.endswith('.csv') and file_name != \
171 f"{combined_file_name}.csv":
172 # формируем полный путь к файлу.
173 full_file_name: str = os.path.join(folder_name, file_name)
174
175 v_logger.info(
176 f"Collecting '{file_name}' to pandas.DataFrame...",
177 LogMode.VERBOSELY)
178
179 # читаем CSV-файл в DataFrame.
180 df = pd.read_csv(full_file_name, sep=config["csv_separator"],
181 low_memory=False)
182
183 v_logger.success(
184 f"Collecting '{file_name}' to pandas.DataFrame!",
185 LogMode.VERBOSELY)
186 v_logger.info(
187 f"Concatenating '{file_name}' to combined_data_frame...",
188 LogMode.VERBOSELY)
189
190 # объединяем DataFrame с общим DataFrame.
191 combined_df = pd.concat([combined_df, df], ignore_index=True)
192
193 v_logger.success(
194 f"Concatenating '{file_name}' to combined_data_frame!",
195 LogMode.VERBOSELY)
196 v_logger.info("-", LogMode.VERBOSELY)
197
198 v_logger.info(f"Collecting to combined .csv file in '{folder_name}'...",
199 LogMode.VERBOSELY)
200
201 # сохраняем объединенный DataFrame в CSV-файл.
202 combined_df.to_csv(
203 f"{folder_name}/{combined_file_name}.csv",
204 sep=config["csv_separator"], index=False)
205
206 v_logger.success(
207 f"Collecting to combined .csv file in '{folder_name}'!", LogMode.VERBOSELY)
208 v_logger.info("-", LogMode.VERBOSELY)
209 v_logger.success("End combining downloads!")
210
211 # восстанавливаем формат логгера.
212 v_logger.RestoreFormat(restore_index)
213
214

◆ DeleteFilesInFolder()

files_funcs.DeleteFilesInFolder ( str folder_name,
list[str] except_items = [],
bool delete_folders = False )
Удаляет все файлы в указанной папке, кроме файлов в списке исключений. Args: folder_name (str): путь к папке. except_items (list[str], optional): список исключений (файлов или папок), которые не нужно удалять. Defaults to []. delete_folders (bool, optional): удалять ли вложенные папки. Defaults to False.
22 delete_folders: bool = False):
23 """
24 Удаляет все файлы в указанной папке, кроме файлов в списке исключений.
25
26 Args:
27 folder_name (str): путь к папке.
28 except_items (list[str], optional): список исключений (файлов или папок),
29 которые не нужно удалять.
30 Defaults to [].
31 delete_folders (bool, optional): удалять ли вложенные папки.
32 Defaults to False.
33 """
34
35 # итерируемся по элементам в папке.
36 for item in os.listdir(folder_name):
37 # формируем путь к текущему элементу.
38 item_path: str = os.path.join(folder_name, item)
39
40 # если элемент не в списке исключений.
41 if item not in except_items:
42 # если это файл, удаляем его.
43 if os.path.isfile(item_path):
44 os.remove(item_path)
45
46 # если нужно удалять папки и это папка, удаляем её.
47 elif delete_folders and os.path.isdir(item_path):
48 shutil.rmtree(item_path)
49
50

◆ IsFileInFolder()

bool files_funcs.IsFileInFolder ( str file_name,
str folder_name )
Проверяет, существует ли файл в указанной папке. Args: file_name (str): имя файла для проверки. folder_name (str): путь к папке. Returns: bool: True, если файл существует, иначе False.
51def IsFileInFolder(file_name: str, folder_name: str) -> bool:
52 """
53 Проверяет, существует ли файл в указанной папке.
54
55 Args:
56 file_name (str): имя файла для проверки.
57 folder_name (str): путь к папке.
58
59 Returns:
60 bool: True, если файл существует, иначе False.
61 """
62
63 # формируем полный путь к файлу.
64 full_file_name = os.path.join(folder_name, file_name)
65 # возвращаем True, если файл существует, иначе False.
66 return os.path.exists(full_file_name)
67
68

◆ IsFolderEmpty()

bool files_funcs.IsFolderEmpty ( str folder_name)
Проверяет, является ли папка пустой. Args: folder_name (str): путь к папке. Returns: bool: True, если папка пуста, иначе False.
69def IsFolderEmpty(folder_name: str) -> bool:
70 """
71 Проверяет, является ли папка пустой.
72
73 Args:
74 folder_name (str): путь к папке.
75
76 Returns:
77 bool: True, если папка пуста, иначе False.
78 """
79
80 try:
81 # если количество элементов в папке равно нулю, возвращаем True.
82 return len(os.listdir(folder_name)) == 0
83
84 # если папка не найдена, возвращаем True.
85 except FileNotFoundError:
86 return True
87
88

◆ MoveFileToFolder()

files_funcs.MoveFileToFolder ( str file_name,
str curr_folder_name,
str folder_name )
Перемещает файл в указанную папку. Args: file_name (str): имя файла. curr_folder_name (str): путь к текущей папке файла. folder_name (str): путь к целевой папке.
91 folder_name: str):
92 """
93 Перемещает файл в указанную папку.
94
95 Args:
96 file_name (str): имя файла.
97 curr_folder_name (str): путь к текущей папке файла.
98 folder_name (str): путь к целевой папке.
99 """
100
101 # создаем целевую папку, если она не существует.
102 os.makedirs(folder_name, exist_ok=True)
103
104 # формируем полный путь к файлу.
105 full_file_name = os.path.join(curr_folder_name, file_name)
106 # формируем полный путь к файлу в целевой папке.
107 next_file_name = os.path.join(folder_name, file_name)
108
109 # если файл с таким именем уже существует в целевой папке, удаляем его.
110 if os.path.exists(next_file_name):
111 os.remove(next_file_name)
112
113 # если файл существует, перемещаем его.
114 if os.path.exists(full_file_name):
115 shutil.move(full_file_name, folder_name)
116
117 # если файл не существует, логируем предупреждение.
118 else:
119 v_logger.warning(f"{full_file_name} does not exist!",
120 LogMode.VERBOSELY)
121
122

◆ SaveMolfilesToSDF()

files_funcs.SaveMolfilesToSDF ( pd.DataFrame data,
str file_name,
str molecule_id_column_name,
pd.DataFrame extra_data = pd.DataFrame(),
bool indexing_lists = False )
Сохраняет molfiles из pd.DataFrame в .sdf файл. Args: data (pd.DataFrame): DataFrame с колонками molfile и id. file_name (str): имя файла (без ".sdf"). molecule_id_column_name (str): имя колонки с id соединения. extra_data (pd.DataFrame, optional): дополнительная информация. Defaults to pd.DataFrame(). indexing_lists (bool, optional): нужно ли индексировать списки. Defaults to False.
219 indexing_lists: bool = False):
220 """
221 Сохраняет molfiles из pd.DataFrame в .sdf файл.
222
223 Args:
224 data (pd.DataFrame): DataFrame с колонками molfile и id.
225 file_name (str): имя файла (без ".sdf").
226 molecule_id_column_name (str): имя колонки с id соединения.
227 extra_data (pd.DataFrame, optional): дополнительная информация.
228 Defaults to pd.DataFrame().
229 indexing_lists (bool, optional): нужно ли индексировать списки.
230 Defaults to False.
231 """
232
233 def WriteColumnAndValueToSDF(file: TextIOWrapper,
234 value: Any,
235 column: str = ""):
236 """
237 Записывает столбец и значение в .sdf файл.
238
239 Args:
240 file (TextIOWrapper): открытый файл для записи.
241 value (Any): значение, которое нужно записать.
242 column (str, optional): имя столбца. Defaults to "".
243 """
244
245 # если столбец не задан, выходим.
246 if not column:
247 return
248
249 # если значение - список или pd.Series.
250 if isinstance(value, list) or isinstance(value, pd.Series):
251 file.write(f"> <{column}>\n")
252
253 i: int = 0
254 # итерируемся по элементам списка.
255 for elem in value:
256 # если элемент - словарь.
257 if isinstance(elem, dict):
258 # рекурсивно вызываем функцию для записи словаря.
259 WriteColumnAndValueToSDF(file, elem)
260
261 # если элемент - не словарь.
262 else:
263 # преобразуем элемент в строку.
264 elem = str(elem)
265
266 # если элемент не пустой, записываем его.
267 if elem != "nan" and elem != "None" and elem != "":
268 # если нужно индексировать списки.
269 if indexing_lists:
270 file.write(f"{i}: {elem}\n")
271 # если не нужно индексировать списки.
272 else:
273 file.write(f"{elem}\n")
274 i += 1
275
276 # если значение - словарь.
277 elif isinstance(value, dict):
278 file.write(f"> <{column}>\n")
279
280 # итерируемся по элементам словаря.
281 for key, elem in value.items():
282 # преобразуем элемент в строку.
283 elem = str(elem)
284
285 # если элемент не пустой, записываем его.
286 if elem != "nan" and elem != "None" and elem != "":
287 file.write(f"{key}: {elem}\n")
288
289 # если значение - не список и не словарь.
290 else:
291 # преобразуем значение в строку.
292 value = str(value)
293
294 # если значение не пустое, записываем его.
295 if value != "nan" and value != "None" and value != "":
296 file.write(f"> <{column}>\n")
297
298 file.write(f"{value}\n")
299
300 # записываем пустую строку для разделения значений.
301 file.write("\n")
302
303 # открываем файл для записи.
304 with open(f"{file_name}.sdf", "w", encoding="utf-8") as f:
305 # итерируемся по строкам DataFrame.
306 for value in data.values:
307 # получаем id молекулы и molfile.
308 molecule_id, molfile = value
309
310 # записываем id молекулы и molfile в файл.
311 f.write(f"{molecule_id}{molfile}\n\n")
312
313 # если есть дополнительная информация.
314 if not extra_data.empty:
315 # устанавливаем id молекулы в качестве индекса.
316 df = extra_data.set_index(f"{molecule_id_column_name}")
317
318 # итерируемся по столбцам DataFrame.
319 for column in df.columns:
320 # записываем столбец и значение в файл.
321 WriteColumnAndValueToSDF(
322 f, df.loc[molecule_id, column], column)
323
324 # записываем разделитель между молекулами.
325 f.write("$$$$\n")
326
327 v_logger.info(
328 f"Writing {molecule_id} data to .sdf file...",
329 LogMode.VERBOSELY)