Fast-HInt-ppi 0.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,780 @@
1
+ """ Create File_proteins object
2
+
3
+ Author: Quentin Rouger
4
+ """
5
+ import urllib.request
6
+ import re
7
+ from .Utils_HInt import *
8
+ import os
9
+ import copy
10
+ from rdkit import Chem,RDLogger
11
+
12
+ RDLogger.DisableLog('rdApp.*') #Disable RDKit warnings for SMILES parsing
13
+
14
+ class File_proteins() :
15
+ """
16
+ Manipulate and save the file that contains all proteins.
17
+ """
18
+ def __init__ (self, path_txt_file, baits, AF_version) :
19
+ """
20
+ Constructor :
21
+ Set attributes for a single entry file.
22
+
23
+ Parameters:
24
+ -----------
25
+ path_txt_file : string
26
+ baits : list
27
+ AF_version : string (2 or 3)
28
+ """
29
+ self.set_all_att(path_txt_file, baits, AF_version)
30
+
31
+ def set_proteins_sequence_SP (self, new_protein_sequence) :
32
+ """
33
+ Sets a dict of all sequences with Signal peptide.
34
+
35
+ Parameters:
36
+ ----------
37
+ new_protein_sequence = dictionary
38
+
39
+ Returns:
40
+ ----------
41
+ """
42
+ self.protein_sequence_SP = new_protein_sequence
43
+
44
+ def set_proteins_sequence_no_SP (self, new_protein_sequence) :
45
+ """
46
+ Sets a dict of all sequences without Signal peptide and set a lenght dict.
47
+
48
+ Parameters:
49
+ ----------
50
+ new_protein_sequence = dictionary
51
+
52
+ Returns:
53
+ ----------
54
+ """
55
+ self.protein_sequence_no_SP = new_protein_sequence
56
+ self.find_prot_lenght(new_protein_sequence)
57
+
58
+ def set_proteins (self, new_protein) :
59
+ """
60
+ Sets a list of all proteins.
61
+
62
+ Parameters:
63
+ ----------
64
+ new_protein = list
65
+
66
+ Returns:
67
+ ----------
68
+ """
69
+ self.protein = new_protein
70
+
71
+ def set_file_name (self, filename) :
72
+ """
73
+ Sets new filename for the txt file.
74
+
75
+ Parameters:
76
+ ----------
77
+ filename = string
78
+
79
+ Returns:
80
+ ----------
81
+ """
82
+ self.file_name = filename
83
+
84
+ def set_lenght_prot (self, lenght_prot) :
85
+ """
86
+ Sets lenght of all proteins.
87
+
88
+ Parameters:
89
+ ----------
90
+ lenght_prot = dictionary
91
+
92
+ Returns:
93
+ ----------
94
+ """
95
+ self.lenght_prot = lenght_prot
96
+
97
+ def set_result_dict (self, result_dict) :
98
+ """
99
+ Sets dict who will contains all results.
100
+
101
+ Parameters:
102
+ ----------
103
+ result_dict = dict
104
+
105
+ Returns:
106
+ ----------
107
+ """
108
+ self.result_dict = result_dict
109
+
110
+ def set_possible_prey (self, possible_prey) :
111
+ """
112
+ Sets list of all possible prey.
113
+
114
+ Parameters:
115
+ ----------
116
+ possible_prey : list
117
+
118
+ Returns:
119
+ ----------
120
+ """
121
+ self.possible_prey = possible_prey
122
+
123
+ def set_deeploc (self, deeploc) :
124
+ """
125
+ Sets a dict of all DeepLoc results.
126
+
127
+ Parameters:
128
+ ----------
129
+ deeploc : dictionary
130
+
131
+ Returns:
132
+ ----------
133
+ """
134
+ self.deeploc = deeploc
135
+
136
+ def set_int_score (self, int_score) :
137
+ """
138
+ Sets a dict of interaction score.
139
+
140
+ Parameters:
141
+ ----------
142
+ int_score : dictionary
143
+
144
+ Returns:
145
+ ----------
146
+ """
147
+ self.int_score = int_score
148
+
149
+ def set_homo_score (self, homo_score) :
150
+ """
151
+ Sets a dict of homo-oligomer score.
152
+
153
+ Parameters:
154
+ ----------
155
+ homo_score : dictionary
156
+
157
+ Returns:
158
+ ----------
159
+ """
160
+ self.homo_score = homo_score
161
+
162
+
163
+ def set_prot_SP (self, dict_SP) :
164
+ """
165
+ Sets a dict indicating whether each protein has a signal peptide (SP) or not.
166
+
167
+ Parameters:
168
+ ----------
169
+ int_score : dictionary
170
+
171
+ Returns:
172
+ ----------
173
+ """
174
+ self.prot_SP = dict_SP
175
+
176
+ def set_uniprot_prot (self, list_uniprot) :
177
+ """
178
+ Sets a list of protein set with uniprotID.
179
+
180
+ Parameters:
181
+ ----------
182
+ list_uniprot : list
183
+
184
+ Returns:
185
+ ----------
186
+ """
187
+ self.list_uniprot = list_uniprot
188
+
189
+ def set_compounds (self, compounds) :
190
+ """
191
+ Set a dict of compounds. Key of the dict is name of the compound and the value is the smile.
192
+
193
+ Parameters:
194
+ ----------
195
+ compounds : dict
196
+
197
+ Returns:
198
+ ----------
199
+ """
200
+ self.compounds = compounds
201
+
202
+ def set_time_dict (self, time_dict) :
203
+ """
204
+ Set a dict of differents step timing. Key of the dict is step and the value list of number of prey and time.
205
+
206
+ Parameters:
207
+ ----------
208
+ time_dict : dict
209
+
210
+ Returns:
211
+ ----------
212
+ """
213
+ self.time_dict = time_dict
214
+
215
+ def get_proteins_sequence_SP (self) :
216
+ """
217
+ Return the new amino acid sequence dictionary with SP.
218
+
219
+ Parameters:
220
+ ----------
221
+
222
+ Returns:
223
+ ----------
224
+ proteins_sequence : dictionary
225
+ """
226
+ return self.protein_sequence_SP
227
+
228
+ def get_proteins_sequence_no_SP (self) :
229
+ """
230
+ Return the new amino acid sequence dictionary without SP.
231
+
232
+ Parameters:
233
+ ----------
234
+
235
+ Returns:
236
+ ----------
237
+ proteins_sequence : dictionary
238
+ """
239
+ return self.protein_sequence_no_SP
240
+
241
+ def get_proteins (self) :
242
+ """
243
+ Return the new proteins name list.
244
+
245
+ Parameters:
246
+ ----------
247
+
248
+ Returns:
249
+ ----------
250
+ protein : list
251
+ """
252
+ return self.protein
253
+
254
+ def get_file_name (self) :
255
+ """
256
+ Return the name of the file.
257
+
258
+ Parameters:
259
+ ----------
260
+
261
+ Returns:
262
+ ----------
263
+ file_name : string
264
+ """
265
+ return self.file_name
266
+
267
+ def get_lenght_prot (self) :
268
+ """
269
+ Return the lenght of proteins.
270
+
271
+ Parameters:
272
+ ----------
273
+
274
+ Returns:
275
+ ----------
276
+ lenght_prot : dictionary
277
+ """
278
+ return self.lenght_prot
279
+
280
+ def get_result_dict (self) :
281
+ """
282
+ Return new result dict.
283
+
284
+ Parameters:
285
+ ----------
286
+
287
+ Returns:
288
+ ----------
289
+ result_dict : dict
290
+ """
291
+ return self.result_dict
292
+
293
+ def get_possible_prey (self) :
294
+ """
295
+ Return list of all possible prey.
296
+
297
+ Parameters:
298
+ ----------
299
+
300
+ Returns:
301
+ ----------
302
+ possible_prey : list
303
+ """
304
+ return self.possible_prey
305
+
306
+ def get_deeploc (self) :
307
+ """
308
+ Return the DeepLoc result dict.
309
+
310
+ Parameters:
311
+ ----------
312
+
313
+ Returns:
314
+ ----------
315
+ deeploc : dictionary
316
+ """
317
+ return self.deeploc
318
+
319
+ def get_int_score (self) :
320
+ """
321
+ Return the interaction result dict.
322
+
323
+ Parameters:
324
+ ----------
325
+
326
+ Returns:
327
+ ----------
328
+ int_score : dictionary
329
+ """
330
+ return self.int_score
331
+
332
+ def get_homo_score (self) :
333
+ """
334
+ Return the homo-oligomer result dict.
335
+
336
+ Parameters:
337
+ ----------
338
+
339
+ Returns:
340
+ ----------
341
+ homo_score : dictionary
342
+ """
343
+ return self.homo_score
344
+
345
+ def get_prot_SP (self) :
346
+ """
347
+ Return a dict indicating whether each protein has a signal peptide (SP) or not.
348
+
349
+ Parameters:
350
+ ----------
351
+
352
+ Returns:
353
+ ----------
354
+ int_score : dictionary
355
+ """
356
+ return self.prot_SP
357
+
358
+ def get_uniprot_prot (self) :
359
+ """
360
+ Return a list of protein set with uniprotID.
361
+
362
+ Parameters:
363
+ ----------
364
+
365
+ Returns:
366
+ ----------
367
+ list_uniprot : list
368
+ """
369
+ return self.list_uniprot
370
+
371
+ def get_compounds (self) :
372
+ """
373
+ Return a dict of compounds.
374
+
375
+ Parameters:
376
+ ----------
377
+
378
+ Returns:
379
+ ----------
380
+ compounds : dict
381
+ """
382
+ return self.compounds
383
+
384
+ def get_time_dict (self) :
385
+ """
386
+ Return a dict of timings.
387
+
388
+ Parameters:
389
+ ----------
390
+
391
+ Returns:
392
+ ----------
393
+ time_dict : dict
394
+ """
395
+ return self.time_dict
396
+
397
+
398
+
399
+ ### Generating of features and pre-file to run multimer
400
+
401
+ def set_all_att (self, path_txt, baits, AF_version) :
402
+ """
403
+ Initialize and populate all attributes from a protein input text file.
404
+
405
+ This method parses a text file containing protein identifiers and/or FASTA sequences, cleans NCBI-formatted headers, validates protein uniqueness,
406
+ checks sequence validity, and initializes all internal data structures required for downstream analyses.
407
+
408
+ The input file may contain :
409
+ - Comma-separated protein identifiers
410
+ - FASTA-formatted protein sequences
411
+ - NCBI-style headers, which are automatically cleaned and normalized
412
+
413
+ Parameters :
414
+ ----------
415
+ path_txt : string
416
+ baits : list
417
+ AF_version : string (2 or 3)
418
+
419
+ Notes :
420
+ ----------
421
+ - Protein identifiers are converted to uppercase for consistency.
422
+ - FASTA headers are simplified by extracting protein identifiers from NCBI annotations.
423
+ - Sequences containing non-standard amino acids are rejected to ensure compatibility with MSA generation and peptid signal.
424
+ """
425
+ new_proteins = list()
426
+ new_compounds = dict()
427
+ uniprot_prot = list()
428
+ sequence_SP = dict()
429
+ result_dict = dict()
430
+ prot_SP = dict()
431
+ already_fasta = dict()
432
+ int_score = dict()
433
+ homo_score = dict()
434
+ time_dict = dict()
435
+ save_prot = ""
436
+ list_new_prot_name = list()
437
+ with open(path_txt,"r") as check_f : #clean ncbi file
438
+ new_fasta = str()
439
+ for line in check_f :
440
+ if line[0] == ">" and "[protein_id=" in line or "[locus_tag=" in line or "[gbkey=" in line : #clean ncbi file
441
+ scrap_name = line.split(" ")[1].split("=")[1][0:len(line.split(" ")[1].split("=")[1])-1]
442
+ if scrap_name in list_new_prot_name :
443
+ for i in range(1,100) :
444
+ new_name = scrap_name + "_" + str(i)
445
+ if new_name not in list_new_prot_name :
446
+ scrap_name = new_name
447
+ break
448
+ new_fasta += ">" + scrap_name + "\n"
449
+ list_new_prot_name.append(scrap_name)
450
+ elif line[0] == ">" and " "in line :
451
+ scrap_name = line.split(" ")[0][1:]
452
+ new_fasta += ">" + scrap_name + "\n"
453
+ list_new_prot_name.append(scrap_name)
454
+ else :
455
+ new_fasta += line.replace("*", "")
456
+ with open(path_txt,"w") as w_file :
457
+ w_file.write(new_fasta)
458
+ with open(path_txt,"r") as in_file :
459
+ for line in in_file :
460
+ if "," in str(line) or (line[0] != ">" and save_prot == "" and line.strip() != "") :
461
+ save_prot = ""
462
+ new_line = (line.strip().split(","))
463
+ for prot in new_line :
464
+ clean_prot = prot.upper().strip()
465
+ compound_name = ""
466
+ mol = None
467
+ if ":" in clean_prot : #compounds set up
468
+ compound_name = clean_prot.split(":")[0]
469
+ smile = clean_prot.split(":")[1]
470
+ smile = smile.replace("CL","Cl")
471
+ smile = smile.replace("BR","Br")
472
+ smile = smile.replace("FL","Fl") #Clean smile
473
+ mol = Chem.MolFromSmiles(smile) #check if the line is a SMILES code
474
+ if clean_prot in new_proteins or compound_name in new_compounds.values() :
475
+ raise ValueError(f"Protein {clean_prot} is duplicated in the input file.")
476
+ else :
477
+ if mol is not None :
478
+ if ":" not in clean_prot :
479
+ raise ValueError(f"Missing compound name for {clean_prot}. Compounds should be in the format 'CompoundName:SMILES'.")
480
+ else :
481
+ mol_with_H = Chem.AddHs(mol) #Add explicit hydrogens to the molecule to ensure accurate SMILES representation
482
+ smiles_H = Chem.MolToSmiles(mol_with_H)
483
+ new_compounds[compound_name] = smiles_H
484
+ result_dict[compound_name] = dict()
485
+ int_score[compound_name] = dict()
486
+ else :
487
+ new_proteins.append(clean_prot)
488
+ uniprot_prot.append(clean_prot)
489
+ result_dict[clean_prot] = dict()
490
+ int_score[clean_prot] = dict()
491
+ homo_score[clean_prot] = dict()
492
+ elif line[0] == ">" :
493
+ save_prot = line[1:len(line)].strip("\n").strip(" ")
494
+ if save_prot in new_proteins :
495
+ raise ValueError(f"Protein {save_prot} is duplicated in the input file.")
496
+ else :
497
+ new_proteins.append(save_prot)
498
+ already_fasta[save_prot] = str()
499
+ sequence_SP[save_prot] = ""
500
+ result_dict[save_prot] = dict()
501
+ int_score[save_prot] = dict()
502
+ homo_score[save_prot] = dict()
503
+ elif len(line) > 1 and save_prot != "" :
504
+ sequence_SP[save_prot] = sequence_SP[save_prot] + line.strip("\n").strip("\t").replace(" ","").replace("-","")
505
+ for aa in ["O", "B", "Z", "J", "X", "U"] :
506
+ if aa in line.strip("\n") :
507
+ raise ValueError(f"Sequence {save_prot} contains {aa}.")
508
+ if new_compounds != {} :
509
+ if AF_version != "3" :
510
+ raise ValueError("Compounds screening need AlphaFold3.")
511
+ for protein in new_proteins :
512
+ if protein not in baits :
513
+ raise ValueError("HInt doesn't allow to screen compounds and proteins. Please remove no bait protein from the input file.")
514
+ self.set_time_dict(time_dict)
515
+ self.set_compounds(new_compounds)
516
+ self.set_uniprot_prot(uniprot_prot)
517
+ self.set_file_name(path_txt)
518
+ self.set_proteins(new_proteins)
519
+ self.set_possible_prey(new_proteins)
520
+ self.set_proteins_sequence_SP(sequence_SP)
521
+ self.set_int_score(int_score)
522
+ self.set_homo_score(homo_score)
523
+ self.set_result_dict(result_dict)
524
+ self.set_prot_SP(prot_SP)
525
+
526
+ def check_save_dict (self, Path_Pickle_Feature) :
527
+ """
528
+ Inspect previously saved computation states and determine missing features for each protein.
529
+
530
+ This method compares the current protein set and sequences with the persistent save dictionary (save_dict.pkl) in order to identify which
531
+ computational steps must be recomputed. It verifies the presence and consistency of :
532
+ - Multiple sequence alignments (MSA, .a3m files)
533
+ - Feature pickle files (.pkl)
534
+ - DeepLoc subcellular localization predictions
535
+ - Signal peptide annotations
536
+ - Interaction scores
537
+
538
+ Parameters :
539
+ ----------
540
+ Path_Pickle_Feature : str
541
+
542
+ Returns :
543
+ ----------
544
+ need_msa : list
545
+ need_pkl : list
546
+ need_DeepLoc : list
547
+
548
+ Notes :
549
+ ----------
550
+ - Sequence mismatches between MSAs and cached data trigger a full reset for the affected protein.
551
+ - Interaction scores are invalidated if the corresponding structural models are missing.
552
+ - UniProt sequences are retrieved using the API and cleaned to remove formatting artifacts.
553
+ - The save dictionary is always updated at the end of the procedure.
554
+ """
555
+ need_msa = list()
556
+ need_pkl = list()
557
+ need_DeepLoc = list()
558
+ protein_sequence_no_SP = dict()
559
+ deeploc_prot = dict()
560
+ prot_SP = dict()
561
+ int_score = self.get_int_score()
562
+ homo_score = self.get_homo_score()
563
+ result_dict = self.get_result_dict()
564
+ pattern = r"SQ SEQUENCE .* .*\n([\s\S]*)"
565
+ del_car = ["\n"," ","//"]
566
+
567
+ sequences_SP = self.get_proteins_sequence_SP()
568
+ proteins = self.get_proteins()
569
+
570
+ if os.path.isfile('log_file/save_dict.pkl') == True :
571
+ with open('log_file/save_dict.pkl', 'rb') as save_dict :
572
+ all_info = pickle.load(save_dict)
573
+ deeploc_prot = copy.deepcopy(all_info["deeploc"])
574
+ protein_sequence_no_SP = copy.deepcopy(all_info["sequence_no_SP"])
575
+ int_score.update(copy.deepcopy(all_info["int_score"]))
576
+ homo_score.update(copy.deepcopy(all_info["homo_score"]))
577
+ prot_SP = copy.deepcopy(all_info["Signal_peptide"])
578
+ for protein in proteins :
579
+ result_dict[protein] = dict()
580
+ if protein in deeploc_prot.keys() : #if protein in deeploc of save dict
581
+ result_dict[protein]["DeepLoc"] = deeploc_prot[protein]
582
+ if protein in prot_SP.keys() : #if protein in SP of save dict
583
+ result_dict[protein]["Signal_peptide"] = prot_SP[protein]
584
+ if protein in all_info["sequence_SP"].keys() : #if protein in sequence_SP of save dict
585
+ if protein in sequences_SP.keys() : #check if two sequence match
586
+ if sequences_SP[protein] != all_info["sequence_SP"][protein] : #if not match, remove MSA files and start at zero
587
+ cmd = f"rm -rf {Path_Pickle_Feature}/*{protein}*"
588
+ cmd2 = f"rm -rf ./result_PPI_int/*{protein}*"
589
+ cmd3 = f"rm -rf ./result_homo_int/*{protein}*"
590
+ os.system(cmd)
591
+ os.system(cmd2)
592
+ os.system(cmd3)
593
+ need_msa.append(protein)
594
+ need_DeepLoc.append(protein)
595
+ int_score[protein] = dict() #remove int score
596
+ homo_score[protein] = dict()
597
+ else : #sequences match, set all arguments
598
+ sequences_SP[protein] = all_info["sequence_SP"][protein]
599
+ if protein not in all_info["sequence_no_SP"].keys() :
600
+ need_msa.append(protein)
601
+ if protein not in all_info["deeploc"].keys() :
602
+ need_DeepLoc.append(protein)
603
+
604
+ else : #protein not in fasta format, so UniprotID is good
605
+ if protein in all_info["sequence_SP"].keys() :
606
+ sequences_SP[protein] = all_info["sequence_SP"][protein]
607
+ if protein not in all_info["sequence_no_SP"].keys() :
608
+ need_msa.append(protein)
609
+ if protein not in all_info["deeploc"].keys() :
610
+ need_DeepLoc.append(protein)
611
+ if protein not in all_info["sequence_SP"].keys() :
612
+ if protein not in sequences_SP.keys() : #if protein need sequence in Uniprot
613
+ logger.info("Search sequence for " + protein)
614
+ try:
615
+ urllib.request.urlretrieve("https://rest.uniprot.org/uniprotkb/"+protein+".txt","log_file/temp_file.txt")
616
+ except Exception as e :
617
+ raise Exception(f"{protein} is not a compliant UniprotID")
618
+
619
+ with open("log_file/temp_file.txt","r") as in_file:
620
+ for seq in re.finditer(pattern, in_file.read()) :
621
+ sequences_SP[protein] = seq.group(1)
622
+ # with open("temp_file.txt","r") as in_file:
623
+ # for name in re.finditer(pattern2, in_file.read()) :
624
+ # names[protein] = name.group(1)
625
+ for car in del_car :
626
+ sequences_SP[protein] = sequences_SP[protein].replace(car,"")
627
+ os.remove("log_file/temp_file.txt")
628
+ need_DeepLoc.append(protein) #add of new protein in txt file
629
+ need_msa.append(protein)
630
+ else : #protein in fasta format, who don't have sequence without SP and DeepLoc
631
+ need_DeepLoc.append(protein)
632
+ need_msa.append(protein)
633
+ if os.path.isfile(f"{Path_Pickle_Feature}/{protein}.a3m") == False and protein not in need_msa : #proteins without msa
634
+ need_msa.append(protein)
635
+ cmd = f"rm -rf {Path_Pickle_Feature}/*{protein}*" #remove residue files
636
+ os.system(cmd)
637
+ int_score[protein] = dict() #remove int score
638
+ homo_score[protein] = dict()
639
+ if os.path.isfile(f"{Path_Pickle_Feature}/{protein}.pkl") == False and os.path.isfile(f"{Path_Pickle_Feature}/{protein}.a3m") == True : #proteins with msa without pkl file
640
+ need_pkl.append(protein)
641
+ if os.path.isfile(f"{Path_Pickle_Feature}/{protein}.a3m") == True and protein not in need_msa : #check sequence in msa file match with save dict
642
+ with open(f"{Path_Pickle_Feature}/{protein}.a3m","r") as msa_file :
643
+ index = 0
644
+ for line in msa_file :
645
+ if index == 1 :
646
+ msa_seq = line.strip("\n")
647
+ break
648
+ if line[0] == ">" :
649
+ index += 1
650
+ if index == 0 : #empty msa file, so remove it and start at zero
651
+ cmd = f"rm -rf {Path_Pickle_Feature}/*{protein}*"
652
+ os.system(cmd)
653
+ need_msa.append(protein)
654
+ int_score[protein] = dict() #remove int score
655
+ elif msa_seq != all_info["sequence_no_SP"][protein] and index == 1 : #if not match, remove pkl file and start at zero
656
+ cmd = f"rm -rf {Path_Pickle_Feature}/*{protein}*"
657
+ os.system(cmd)
658
+ need_msa.append(protein)
659
+ need_DeepLoc.append(protein)
660
+ int_score[protein] = dict() #remove int score
661
+
662
+ #Check is save score interaction are still valid or delete it
663
+ for protein in all_info["int_score"].keys() :
664
+ for key in all_info["int_score"][protein].keys() :
665
+ bait = key.split(f"iQ_score_vs_")[1]
666
+ if not glob.glob(f"./result_PPI_int/{bait}_and_{protein}/ranked_0*") and not glob.glob(f"./result_PPI_int/{protein}_and_{bait}/ranked_0*") : #if no model for this interaction, remove score
667
+ if f"iQ_score_vs_{bait}" in int_score[protein].keys() :
668
+ del int_score[protein][f"iQ_score_vs_{bait}"]
669
+
670
+
671
+ #Check is save homo score interaction are valid
672
+
673
+
674
+ else : #no save dict, so check if protein have MSA or pkl
675
+ for protein in proteins :
676
+ if protein not in sequences_SP.keys() : #if protein need sequence in Uniprot
677
+ print("Search sequence for " + protein)
678
+ urllib.request.urlretrieve("https://rest.uniprot.org/uniprotkb/"+protein+".txt","log_file/temp_file.txt")
679
+ if os.path.getsize("log_file/temp_file.txt") == 0 :
680
+ logger.error(f"{protein} is not a compliant UniprotID")
681
+ with open("log_file/temp_file.txt","r") as in_file :
682
+ for seq in re.finditer(pattern, in_file.read()):
683
+ sequences_SP[protein] = seq.group(1)
684
+ # with open("temp_file.txt","r") as in_file :
685
+ # for name in re.finditer(pattern2, in_file.read()) :
686
+ # names[protein] = name.group(1)
687
+ for car in del_car :
688
+ sequences_SP[protein] = sequences_SP[protein].replace(car,"")
689
+
690
+ os.remove("log_file/temp_file.txt")
691
+ if os.path.isfile(f"{Path_Pickle_Feature}/{protein}.a3m") == False : #proteins without msa
692
+ cmd = f"rm -rf {Path_Pickle_Feature}/*{protein}*" #remove residue files
693
+ os.system(cmd)
694
+ if os.path.isfile(f"{Path_Pickle_Feature}/{protein}.pkl") == False and os.path.isfile(f"{Path_Pickle_Feature}/{protein}.a3m") == True : #proteins with msa without pkl file
695
+ need_pkl.append(protein)
696
+
697
+ need_msa.append(protein) #make SignalP and DeepLoc for all proteins, too create the save dict
698
+ need_DeepLoc.append(protein)
699
+
700
+ self.set_prot_SP(prot_SP)
701
+ self.set_result_dict(result_dict)
702
+ self.set_deeploc(deeploc_prot)
703
+ self.set_proteins_sequence_no_SP(protein_sequence_no_SP)
704
+ self.set_proteins_sequence_SP(sequences_SP)
705
+ self.set_int_score(int_score)
706
+ self.set_homo_score(homo_score)
707
+ self.Make_save_dict() #Save modification of the save dict
708
+ return need_msa, need_pkl, need_DeepLoc
709
+
710
+
711
+ def Make_save_dict (self) :
712
+ """
713
+ Save all relevant intermediate results into a pickle file in order to avoid recomputing completed steps in future runs.
714
+ """
715
+ pkl_dict = dict()
716
+ pkl_dict["sequence_SP"] = self.get_proteins_sequence_SP()
717
+ pkl_dict["sequence_no_SP"] = self.get_proteins_sequence_no_SP()
718
+ pkl_dict["deeploc"] = self.get_deeploc()
719
+ pkl_dict["int_score"] = self.get_int_score()
720
+ pkl_dict["homo_score"] = self.get_homo_score()
721
+ pkl_dict["Signal_peptide"] = self.get_prot_SP()
722
+ with open('log_file/save_dict.pkl', 'wb') as out_file :
723
+ pickle.dump(pkl_dict, out_file)
724
+
725
+ def find_prot_lenght (self, prot_dict = None) :
726
+ """
727
+ Compute and store the length (number of amino acids) of each protein based on sequences without signal peptides.
728
+
729
+ Parameters :
730
+ ----------
731
+ prot_dict = dict or None
732
+ """
733
+ if prot_dict == None :
734
+ proteins = self.get_proteins()
735
+ else :
736
+ proteins = prot_dict
737
+ sequences = self.get_proteins_sequence_no_SP()
738
+ lenght_prot = dict()
739
+ for protein in proteins :
740
+ lenght_prot[protein] = len(sequences[protein])
741
+ self.set_lenght_prot(lenght_prot)
742
+
743
+
744
+ def create_fasta_file (self, with_SP, need_msa=[], need_pkl=[]) :
745
+ """
746
+ Generate FASTA files for proteins requiring MSA or pkl generation.
747
+
748
+ Parameters :
749
+ ----------
750
+ with_SP : boolean
751
+ need_msa : list
752
+ need_pkl : list
753
+ """
754
+ line_msa = str()
755
+ sequences_SP = self.get_proteins_sequence_SP()
756
+ sequences_no_SP = self.get_proteins_sequence_no_SP()
757
+ file_name = self.get_file_name().split("/")[-1]
758
+ ext_f = "." + file_name.split(".")[-1]
759
+ file_msa = file_name.replace(ext_f,"_msa.fasta")
760
+ file_pkl = file_name.replace(ext_f,"_pkl.fasta")
761
+ if os.path.isfile(f"log_file/{file_msa}") == True :
762
+ os.remove(f"log_file/{file_msa}")
763
+ if os.path.isfile(f"log_file/{file_pkl}") == True :
764
+ os.remove(f"log_file/{file_pkl}")
765
+ if len(need_msa) != 0 :
766
+ if with_SP == True :
767
+ sequences = sequences_SP
768
+ if with_SP == False :
769
+ sequences = sequences_no_SP
770
+ for protein in need_msa :
771
+ line_msa += ">" + protein + "\n" + sequences[protein] + "\n"
772
+ with open(f"log_file/{file_msa}","w") as f_msa :
773
+ f_msa.write(line_msa)
774
+ line_pkl = str()
775
+ if len(need_pkl) != 0 :
776
+ for protein in need_pkl :
777
+ line_pkl += ">" + protein + "\n" + sequences_no_SP[protein] + "\n"
778
+ with open(f"log_file/{file_pkl}","w") as f_pkl :
779
+ f_pkl.write(line_pkl)
780
+