1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import sys, time,logging, gc
23
24 from math import *
25 import profile,traceback,pstats,bisect
26 import string
27 import suffix_tree
28 import alignement
29 import utile
30 from Donnees.resultatAppli import Resultat
31 import synthetic
32
33
34
35
36
37
38
39
40
41 global long_min_pivots
42 global ratio_min_remplacement
43 global ratio_seuil_lissage
44
45
46
48 sepTable = string.maketrans("çéèàùâêîôûäëïöüÿÇÉÈÀÙÂÊÎÔÛÄËÏÖÜ","ceeauaeiouaeiouyCEEAUAEIOUAEIOU")
49 return txt.translate(sepTable)
50
51
52 -class ecartTextes(object):
53 - def __init__(self, chaine1, chaine2, pP1, pP2, pP3, carOuMot, caseSensitive, separatorSensivitive, diacriticSensitive, planTravail,algoAligneur=''):
54 self.tool = utile.Utile()
55
56 global long_min_pivots
57 global ratio_min_remplacement
58 global ratio_seuil_lissage
59 self.algoAligneur = algoAligneur
60
61
62 long_min_pivots = pP1
63 ratio_min_remplacement = pP2
64 ratio_seuil_lissage = pP3
65 self.carOuMot = carOuMot
66 self.caseSensitive = caseSensitive
67 self.separatorSensivitive = separatorSensivitive
68 self.diacriticSensitive = diacriticSensitive
69 self.texte1 = chaine1
70 self.texte2 = chaine2
71 self.texte_original = self.texte1 + self.texte2
72 self.texte1_original = self.texte1
73 self.texte2_original = self.texte2
74 self.planTravail = planTravail
75
76
77
78 self.sepTable = string.maketrans(" "," ")
79 self.texte1 = self.texte1.translate(self.sepTable)
80 self.texte2 = self.texte2.translate(self.sepTable)
81
82 if not self.diacriticSensitive:
83 self.sepTable = string.maketrans("çéèàùâêîôûäëïöüÿÇÉÈÀÙÂÊÎÔÛÄËÏÖÜ","ceeauaeiouaeiouyCEEAUAEIOUAEIOU")
84 self.texte1 = self.texte1.translate(self.sepTable)
85 self.texte2 = self.texte2.translate(self.sepTable)
86
87 if not self.caseSensitive:
88
89 self.texte1 = self.texte1.lower()
90 self.texte2 = self.texte2.lower()
91
92 if not self.separatorSensivitive:
93
94 self.sepTable = string.maketrans(""" !\r,\n:\t;-?"'`()""","................")
95 self.texte1 = self.texte1.translate(self.sepTable)
96 self.texte2 = self.texte2.translate(self.sepTable)
97
98 self.dictPosSuppression={}
99
100
101 self.tabNbSuppression={}
102 self.texte1,self.texte2=self.preTraitSuppSep(self.texte1,self.texte2)
103
104
105
106
107
108
109 self.lg_texte1 = len(self.texte1)
110 self.lg_texte2 = len(self.texte2)
111 self.lg_texte = self.lg_texte1 + self.lg_texte2
112
113
114 sys.stdout.flush()
115
116
117
118
119
120
121 self.blocs_texte = {}
122
123 sys.stderr.flush()
124 self.insertions = []
125 self.suppressions = []
126 self.identites = []
127
128 self.occs_texte1 = []
129 self.occs_texte2 = []
130 self.occs_deplaces = []
131 self.occs_remplacements = []
132 self.blocs_remplacements = []
133 self.tous_remplacements = []
134
135
136
137
138 - def preTraitSuppSep(self,texte1,texte2):
139 """ Prétraitement supprimant plusieurs séparateurs se suivant et n'en laissant qu'un
140 Prend en entrée texte1 et texte2 et les renvoie traités """
141 debut=0
142 j=0
143 comptSuppression=0
144 res=[]
145 for texte in [texte1,texte2]:
146 i=0
147 lTexte=[]
148 while i<len(texte)-1:
149 if texte[i]=='.' and texte[i+1]=='.':
150 comptSuppression+=1
151
152 self.dictPosSuppression[i+debut]='.'
153 else:
154 lTexte.append(texte[i])
155
156
157 self.tabNbSuppression[j]=comptSuppression
158 j+=1
159 i+=1
160 lTexte.append(texte[i])
161 self.tabNbSuppression[j]=comptSuppression
162 j+=1
163 debut=i+1
164 res.append(''.join(lTexte))
165 self.tabNbSuppression[j]=comptSuppression
166 return res[0],res[1]
167
168 - def postTraitSuppSep2(self,listeOcc):
169 res=[]
170 for (occ1,occ2) in listeOcc:
171
172 Nocc1 = occ1+self.tabNbSuppression[occ1]
173 Nocc2 = occ2+self.tabNbSuppression[occ2]
174
175
176
177
178
179
180
181
182
183 res.append((Nocc1,Nocc2))
184
185 return res
186
188 self.insertions = self.postTraitSuppSep2(self.insertions)
189 self.suppressions = self.postTraitSuppSep2(self.suppressions)
190 self.occs_deplaces = self.postTraitSuppSep2(self.occs_deplaces)
191 self.tous_remplacements = self.postTraitSuppSep2(self.tous_remplacements)
192 self.blocsCommuns = self.postTraitSuppSep2(self.blocsCommuns)
193 res=[]
194 for b in self.lDepl:
195 res.append(self.postTraitSuppSep2(b))
196 self.lDepl=res
197
198
199
200
201
202
203
204 self.texte1 = self.texte1_original
205 self.texte2 = self.texte2_original
206
207 self.lg_texte1 = len(self.texte1)
208 self.lg_texte2 = len(self.texte2)
209
210 - def toString(self):
211 return ("EcartTextes : long_min_pivots = "+str(long_min_pivots)+
212 " / ratio_min_remplacement = "+str(ratio_min_remplacement)+
213 " / ratio_seuil_lissage = "+str(ratio_seuil_lissage)+
214 "\ntexte1 = "+str(self.texte1)+
215 "\ntexte2 = "+str(self.texte2))
216
217 - def blocs_maximaux(self):
218 self.D = utile.stockage_chaines_optimales(self.Dict, self.texte, self.lg_texte1,self.carOuMot,long_min_pivots)
219 self.blocs_texte = self.D.blocs_texte
220 i=0
221 nbcar=0
222 nbocc=0
223 for bloc in self.blocs_texte:
224
225 nbcar += len(bloc)
226 nbocc += len(self.blocs_texte[bloc])
227 i+=1
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
267 """calcul optimise de E[a+a] * partir de E[a]
268 notons qu'au cours de ce calcul, on élimine de E[a] les
269 occurrences i qui appartiennent * E[a+a] car le but est
270 d'obtenir les sous-structures répétitives de taille maximale """
271
272
273 for radical in self.Dict.tous_radicaux_iteration(a):
274
275 for oc_chaine in self.Dict.toutes_occ_chaines_it(a, radical):
276
277 chaine = utile.chaineMot(self.texteMot.sliceC(oc_chaine, 0, oc_chaine, a), self.carOuMot,True)
278
279
280 occs = self.Dict.occs_chaine(chaine)
281
282
283
284
285
286
287
288
289
290 while (occs and ( -1 < self.texteMot.posCarMot(occs[0], a+a) < self.texteMot1.lengthC())):
291 occ = occs[0]
292
293
294 n_chaine = utile.chaineMot(self.texteMot.sliceC(occ, 0, occ, a+a), self.carOuMot, True)
295
296
297
298
299 if not self.Dict.occ_chaine(n_chaine) :
300
301
302
303
304 occs_suite = self.Dict.occs_chaine(utile.chaineMot(n_chaine.sliceM(a,0,0,n_chaine.lengthC()),self.carOuMot, True))
305 if occs_suite and not self.carOuMot:
306 l_aux=self.tool.composition_decalee_mot(occs,occs_suite,a,self.texteMot)
307 elif occs_suite and (len(occs_suite) > 5 or len(occs) > 7):
308 l_aux=self.tool.composition_decalee_b(occs,occs_suite,a)
309 else: l_aux=self.tool.composition_decalee_(occs,occs_suite,a)
310
311
312 occs = self.tool.difference(occs[1:],l_aux)
313
314 if self.repetition(l_aux):
315
316 self.Dict.ajout_occs(n_chaine, l_aux)
317 else: occs = occs[1:]
318
319
320 for radical in self.Dict.tous_radicaux_iteration(a+a):
321 for oc_chaine in self.Dict.toutes_occ_chaines_it(a+a, radical):
322
323 chaine = utile.chaineMot(self.texteMot.sliceC(oc_chaine,0,oc_chaine,a+a),self.carOuMot,True)
324
325 chaine0a = utile.chaineMot(chaine.sliceC(0,0,0,a),self.carOuMot,True)
326 occs_chaine_chaine = self.Dict.occs_chaine(chaine)
327 if not self.repetition(self.tool.difference(self.Dict.occs_chaine(chaine0a),
328 occs_chaine_chaine)):
329 self.Dict.eliminer_toutes_occurrences(chaine0a)
330 chainea2a = utile.chaineMot(chaine.sliceM(a,0,0,chaine.lengthC()),self.carOuMot,True)
331 if not self.carOuMot and not self.repetition(self.tool.composition_decalee_mot(self.Dict.occs_chaine(chainea2a),
332 occs_chaine_chaine,
333 a,self.texteMot)):
334 self.Dict.eliminer_toutes_occurrences(chainea2a)
335 elif not self.repetition(self.tool.composition_decalee_b(self.Dict.occs_chaine(chainea2a),
336 occs_chaine_chaine,
337 a)):
338 self.Dict.eliminer_toutes_occurrences(chainea2a)
339
340
342 debut=time.clock()
343 self.texteMot1 = utile.chaineMot(self.texte1, carOuMot, True)
344 self.texteMot2 = utile.chaineMot(self.texte2, carOuMot, True)
345 self.texteMot = utile.chaineMot(self.texte, carOuMot, True)
346
347 self.Dict = utile.dict_chaines(260, self.texteMot, self.lg_texte1, self.carOuMot)
348 k = 1
349
350
351
352 while 2*k <= min(self.texteMot1.lengthM(), self.texteMot2.lengthM()) :
353
354
355 self.construction_equivalence_double_opt(k)
356
357
358
359 k = 2*k
360
361
362
363
364
365
366
367
368
369
370
371
372 self.blocs_maximaux()
373
374
375 sys.stderr.write("construction blocs max = "+str(time.clock()-debut)+"\n")
376 sys.stderr.write("Nombre de blocs maximaux avant elimination recouvrements:"+ str(len(self.blocs_texte))+"\n")
377 self.debut=time.clock()
378 self.d1=self.blocs_texte
379
380
381 recouv = Recouvrement(self.texte,self.blocs_texte,self.lg_texte1)
382 self.blocs_texte = recouv.eliminer_recouvrements()
383
384
385 sys.stderr.write("Nombre de blocs maximaux apres elimination recouvrements:"+ str(len(self.blocs_texte))+"\n")
386
387
388
389 self.completer_blocs_m()
390 sys.stderr.write("completer_blocs_m done:"+ str(len(self.blocs_texte))+"\n")
391 sys.stderr.flush()
392
393
394 nbx=nby=0
395 for x in self.blocs_texte:
396 nbx+=1
397 for y in self.blocs_texte[x]:
398 nby+=1
399 sys.stderr.write("nbx:+"+str(nbx)+" / nby:"+str(nby)+"\n")
400
405
406
407
408
409
410
411
412 - def clean_bt(self):
413 dic={}
414 i=0
415 for x in self.blocs_texte:
416 if len(x)<long_min_pivots or len(self.blocs_texte[x])<2:
417 pass
418
419
420
421
422
423
424 else:
425 dic[x]=self.blocs_texte[x]
426 sys.stderr.write("Bloc "+x+ " " +str(dic[x])+" "+str(len(self.blocs_texte[x]))+"\n")
427 i+=1
428 sys.stderr.write("nb= "+str(i)+"\n")
429 self.blocs_texte=dic
430
432 debut=time.clock()
433 sequences = [self.texte1, self.texte2]
434 st = suffix_tree.GeneralisedSuffixTree(sequences)
435 self.blocs_texte={}
436 sys.stderr.write("construction blocs max1 = "+str(time.clock()-debut)+"\n")
437 debut=time.clock()
438 self.LL={}
439
440 self.LL=st.get_MEM_index_chaine(long_min_pivots)
441
442
443
444
445
446
447
448
449
450
451
452 self.blocs_texte=self.LL
453
454 self.d2={}
455 for x in self.blocs_texte:
456 self.d2[x]=self.blocs_texte[x]
457
458
459
460
461 sys.stderr.write("construction blocs max2 = "+str(time.clock()-debut)+"\n")
462
463
464
465 sys.stderr.write("Nombre de blocs maximaux avant elimination recouvrements:"+ str(len(self.blocs_texte))+"\n")
466 sys.stderr.flush()
467
468 self.debut=time.clock()
469
470 recouv = Recouvrement(self.texte,self.blocs_texte,self.lg_texte1)
471 self.blocs_texte = recouv.eliminer_recouvrements()
472
473
474
475 sys.stderr.write("Nombre de blocs maximaux apres elimination recouvrements:"+ str(len(self.blocs_texte))+"\n")
476 sys.stderr.flush()
477
478 self.completer_blocs_m()
479
480 sys.stderr.write("Nombre de blocs maximaux après complétion par les blocs uniques:"+ str(len(self.blocs_texte))+"\n")
481 sys.stderr.flush()
482
483
484
485
486 - def repetition(self, liste_occ) :
487
488
489 return (not liste_occ == [] and liste_occ[0] < self.lg_texte1 and liste_occ[-1] >= self.lg_texte1)
490
491 - def occurrence_valide(self, occ, k) :
492
493
494
495
496
497 return (((occ >= 0) and
498 (occ <= self.lg_texte1 - k)) or
499 ((occ >= self.lg_texte1) and
500 (occ <= self.lg_texte1 + self.lg_texte2 - k)))
501
503 L = [[0, self.lg_texte1], [self.lg_texte1, self.lg_texte1 + self.lg_texte2]]
504 LC = self.blocs_texte.keys()
505 for chaine in LC :
506 k = len(chaine)
507 for occ in self.blocs_texte[chaine] :
508
509 L = self.tool.dif_intervalles(L, [occ, occ+k])
510
511
512 for inter in L :
513 if self.blocs_texte.has_key(self.texte[inter[0]:inter[1]]):
514 self.blocs_texte[self.texte[inter[0]:inter[1]]].append(inter[0])
515
516 else: self.blocs_texte[self.texte[inter[0]:inter[1]]] = [inter[0]]
517
518
520 """ Constructions des listes d'insertion et suppressions """
521 for Clef in self.blocs_texte.keys():
522 Occs = self.blocs_texte[Clef]
523
524 if (not self.repetition(Occs)):
525 for occ in Occs:
526 if occ < self.lg_texte1:
527 self.suppressions = self.tool.ajout_intervalle(self.suppressions,[occ, occ + len(Clef)])
528 else:
529 self.insertions = self.tool.ajout_intervalle(self.insertions,[occ, occ + len(Clef)])
530 else:
531 for occ in Occs:
532 self.identites = self.tool.addition_intervalle(self.identites, [occ, occ + len(Clef)])
533
535
536
537 insertions = self.tool.fusion(self.tool.rang_blocs(self.insertions, self.occs_texte2, self.occs_deplaces))
538 suppressions = self.tool.fusion(self.tool.rang_blocs(self.suppressions, self.occs_texte1, self.occs_deplaces))
539
540
541
542
543
544 self.tous_remplacements = self.tool.correspondance_(suppressions, insertions, self.texte, ratio_min_remplacement)
545 self.occs_remplacements = self.tool.correspondance(suppressions, insertions, self.texte, ratio_min_remplacement)
546 aux0 = []
547 aux1 = []
548 for x in self.occs_remplacements[0]:
549 aux0.append(self.texte[x[0][0]: x[0][1]])
550 for x in self.occs_remplacements[1]:
551 aux1.append(self.texte[x[0][0]: x[0][1]])
552 self.blocs_remplacements = [aux0, aux1]
553
554 insertions_ = []
555 for x in insertions:
556
557 W = self.tool.soustr_l_intervalles([x[0]], self.occs_deplaces)
558
559
560 ratio = float(self.tool.longueur(W))/float(x[0][1]-x[0][0])
561
562 if ratio > ratio_seuil_lissage:
563 insertions_.append(x[0])
564 else:
565 insertions_ = self.tool.union(insertions_ , W)
566
567 suppressions_ = []
568 for x in suppressions:
569
570 W = self.tool.soustr_l_intervalles([x[0]], self.occs_deplaces)
571 ratio = float(self.tool.longueur(W))/(x[0][1]-x[0][0])
572
573 if ratio > ratio_seuil_lissage:
574 suppressions_.append(x[0])
575 else:
576 suppressions_ = self.tool.union(suppressions_ , W)
577
578
579
580 self.insertions = self.tool.elimine_int_couverts(self.tous_remplacements, insertions_)
581
582 self.suppressions = self.tool.elimine_int_couverts(self.supp_liste(self.tous_remplacements,1), suppressions_)
583
584
585
586
587
588 - def supp_liste(self,L,texte1):
589 res=[]
590 for x in L:
591 if texte1 and x[1]<=self.lg_texte1:
592 res.append(x)
593 elif not texte1 and x[0]>=self.lg_texte1:
594 res.append(x)
595 return res
596
598 self.occs_texte1 = []
599 self.occs_texte2 = []
600 self.occs_deplaces = []
601
602
603 for x in self.identites:
604 if x[0] < self.lg_texte1:
605 self.occs_texte1.append(x)
606 else: self.occs_texte2.append(x)
607
608 self.statBlocs()
609 sys.stderr.write("Debut de l'alignement\n")
610 sys.stderr.flush()
611 deb_al=time.clock()
612 aligneur = alignement.AlignAstar2(self.texte)
613 self.occs_deplaces,self.blocsCommuns = aligneur.deplacements_pond(self.occs_texte1, self.occs_texte2)
614
615 sys.stderr.write("Fin de l'alignement : "+str(time.clock()-deb_al)+"\n")
616 sys.stderr.flush()
617 self.statLB(self.blocsCommuns,"BC")
618 self.statLB(self.occs_deplaces,"Dep")
619
620
621 for x in self.occs_deplaces:
622 if self.tool.adjacent_(x, self.insertions):
623
624 self.insertions = self.tool.ajout_intervalle(self.insertions, x)
625 if self.tool.adjacent_(x, self.suppressions):
626
627 self.suppressions = self.tool.ajout_intervalle(self.suppressions, x)
628
629 for x in self.insertions:
630 self.occs_texte2 = self.tool.addition_intervalle(self.occs_texte2, x)
631 for x in self.suppressions:
632 self.occs_texte1 = self.tool.addition_intervalle(self.occs_texte1, x)
633
634
635 self.construire_remplacements()
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688 self.lDepl = self.calcPairesBlocsDeplaces(self.occs_deplaces)
689
690 if not self.separatorSensivitive:
691 self.postTraitSuppSep()
692
693 - def trace(self,commande,dic_locals):
694
695 profile.runctx(commande,globals(), dic_locals,'c:\workspace\medite\statFile')
696 s = pstats.Stats('c:\workspace\medite\statFile')
697 s.sort_stats('time')
698 s.print_stats()
699 sys.stderr.flush()
700 sys.stdout.flush()
701
702 - def calcPairesBlocsDeplaces(self, blocsDepl, filtrageDeplacements=True):
703 """Construction de paires de blocs déplacés entre le source et le cible.
704
705 On met en correspondance chaque bloc du source et le ou les blocs identiques du cible.
706 On peut avoir un bloc source qui correspond à plusieurs cibles et vice-versa,
707 auquel cas on aura autant de paires 2 à 2 qu'il y a de correspondances.
708
709 Si on filtre les déplacements, alors on enlève ceux trop petits en fonction
710 de leur distance. Et on replace ces bocs dans les listes d'insérés ou supprimés.
711 @type blocsDepl: list
712 @param blocsDepl: liste des blocs déplacés
713 @type filtrageDeplacements: boolean
714 @param filtrageDeplacements: si vrai on filtre les déplacement non intéressants"""
715 lDepl = []
716 i=0
717 while (len(blocsDepl) > 0 and blocsDepl[i][0] < self.lg_texte1):
718
719 longueur = blocsDepl[i][1] - blocsDepl[i][0]
720 for y in blocsDepl[i+1:]:
721 if (y[0] > self.lg_texte1-1 and longueur == y[1] - y[0] and
722 self.texte1[blocsDepl[i][0]:blocsDepl[i][1]] == self.texte2[y[0]-self.lg_texte1:y[1]-self.lg_texte1]):
723 lDepl.append((blocsDepl[i],y))
724 i += 1
725
726 if filtrageDeplacements:
727 newLDepl = []
728
729 for b1,b2 in lDepl:
730 longueurBloc = b1[1] - b1[0]
731 ajoutBloc = False
732
733 if longueurBloc > 15:
734 ajoutBloc = True
735 else:
736 assert longueurBloc <= 15
737 positionRelativeT1 = b1[0]
738 positionRelativeT2 = b2[0] - self.lg_texte1
739 assert 0 <= positionRelativeT1 < self.lg_texte1
740 assert 0 <= positionRelativeT2 < self.lg_texte2
741
742 distanceBloc = abs(positionRelativeT1 - positionRelativeT2)
743
744
745 if longueurBloc < 8 and distanceBloc < 3000:
746 ajoutBloc = True
747
748 elif 8 <= longueurBloc <= 15 and distanceBloc < 9000:
749 ajoutBloc = True
750
751
752
753 if ajoutBloc:
754 newLDepl.append((b1,b2))
755 else:
756
757
758 self.suppressions = self.tool.addition_intervalle(self.suppressions, (b1[0],b1[1]))
759 self.insertions = self.tool.addition_intervalle(self.insertions, (b2[0],b2[1]))
760 try:
761 k = self.occs_deplaces.index(b1)
762
763 self.occs_deplaces.pop(k)
764 except ValueError:
765
766 pass
767
768 try:
769 k = self.occs_deplaces.index(b2)
770 self.occs_deplaces.pop(k)
771
772 except ValueError:
773
774 pass
775 del lDepl
776 lDepl = newLDepl
777 return lDepl
778
779
780 - def comparaison(self):
785
786 - def dico_to_listes(self):
787 """ Transformation du dico des blocs maximaux disjoints en 2 listes ordonnées, 1 par texte
788 Les 2 listes contiennent des paires (debut de bloc, fin de bloc) """
789 t1 = []
790 t2 = []
791 t3 = []
792 for x in self.blocs_texte:
793 t3.append((x,self.blocs_texte[x]))
794 for y in self.blocs_texte[x]:
795 if y < self.lg_texte1:
796 t1.append((y,y+len(x)))
797 else:
798 t2.append((y,y+len(x)))
799
800 t1.sort()
801 t2.sort()
802 t3.sort()
803 t4 = [t for t in t1]
804 t5 = [t for t in t2]
805 t6 = [t for t in t3]
806 return t4,t5,t6
807
808 - def mode_car(self):
809 NLC = self.m1()
810 self.blocs_texte = NLC
811
812
813
814 - def rang2(self, I, S):
815 """ Retourne la distance du bloc I dans la liste S en nombre de caractères et en nb de blocs """
816 ncar = 0
817 nbloc = 0
818 i=0
819 while i < len(S) and self.texte[I[0]:I[1]] <> self.texte[S[i][0]:S[i][1]]:
820 ncar = ncar + S[i][1] - S[i][0]
821 nbloc += 1
822 i += 1
823 if nbloc>1: nbloc -= 1
824 return ncar,nbloc
825
827 """ Affinage du mode caractère """
828 t1,t2 = self.dico_to_listes()
829 listeBlocsCommuns=[]
830 NLC={}
831
832 NLC1={}
833 NLC2={}
834 LDEP={}
835 locCumul={}
836 cumulStr2=""
837 cumulCompt=prevCumulCompt=0
838 d1=(0,0)
839
840 f1=(0,0)
841 d2=(self.lg_texte1,self.lg_texte1)
842 f2=(self.lg_texte1,self.lg_texte1)
843 bComp = False
844 firstAlignementDone = False
845
846 while (t1!=[] and t2!=[]):
847
848 if t1==[]:
849
850 t2=[]
851 elif t2==[]:
852
853 t1=[]
854 elif self.texte[t1[0][0]:t1[0][1]] == self.texte[t2[0][0]:t2[0][1]]:
855
856
857 if firstAlignementDone: d1=f1
858 f1=(t1[0][0],t1[0][1])
859 if firstAlignementDone: d2=f2
860 f2=(t2[0][0],t2[0][1])
861 t1=t1[1:]
862 t2=t2[1:]
863 bComp = True
864 firstAlignementDone = True
865 elif self.absent(t1[0], t2):
866
867 t1=t1[1:]
868 elif self.absent(t2[0], t1):
869
870 t2=t2[1:]
871 else:
872
873
874 ecart1,nbloc1 = self.rang2(t1[0],t2)
875 ecart2,nbloc2 = self.rang2(t2[0],t1)
876
877 if (ecart1 < ecart2 or (ecart1 == ecart2 and (t1[0][1] - t1[0][0]) > (t2[0][1] - t2[0][0]))):
878 t2=t2[nbloc1:]
879 else: t1=t1[nbloc2:]
880
881
882 if (bComp or (t1==[] and t2==[])):
883 listeBlocsCommuns.append((f1,f2))
884 str1 = self.texte[d1[1]:f1[0]]
885 str2 = self.texte[d2[1]:f2[0]]
886
887
888
889 if not(str1=="" and str2==""):
890 appli2 = ecartTextes(str1, str2,long_min_pivots,ratio_min_remplacement, ratio_seuil_lissage,
891 1, self.caseSensitive, self.separatorSensivitive)
892 appli2.construction_blocs_maximaux()
893 for x in appli2.blocs_texte:
894 if x!="":
895 l=[]
896 if NLC.has_key(x):
897 l=NLC[x]
898
899 for y in appli2.blocs_texte[x]:
900
901 if (y>=len(str1) or str1==""):
902 z=y+d2[1]-len(str1)
903 NLC2[z]=x
904 else:
905 z=y+d1[1]
906 NLC1[z]=x
907 l.append(z)
908 NLC[x]=l
909
910
911
912
913
914
915
916 if not(str1=="" and cumulStr2==""):
917 appli3 = ecartTextes(str1, cumulStr2,long_min_pivots,ratio_min_remplacement, ratio_seuil_lissage,
918 1, self.caseSensitive, self.separatorSensivitive)
919 appli3.construction_blocs_maximaux()
920 for x in appli3.blocs_texte:
921 if (x!="" and len(appli3.blocs_texte[x])>1):
922 l=[]
923 if LDEP.has_key(x):
924 l=LDEP[x]
925
926 for y in appli3.blocs_texte[x]:
927 if (y>=len(str1) or str1==""): z=y+locCumul[y-len(str1)][0]-len(str1)-locCumul[y-len(str1)][1]
928 else: z=y+d1[1]
929 if l.count(z)==0: l.append(z)
930 LDEP[x]=l
931
932
933
934
935 while cumulCompt<prevCumulCompt+len(str2):
936 locCumul[cumulCompt]=(d2[1],prevCumulCompt)
937 cumulCompt+=1
938 prevCumulCompt=cumulCompt
939 cumulStr2+=str2
940 bComp = False
941
942
943
944
945
946
947
948 moved=True
949 while moved:
950 moved=False
951 for b1,b2 in listeBlocsCommuns:
952 sys.stderr.write("*")
953 a=b1[1]
954 b=b2[1]
955 if (NLC1.has_key(a) and NLC2.has_key(b)):
956 x=NLC1[a]
957 y=NLC2[b]
958 if (self.texte[b1[0]:a+len(x)] == self.texte[b2[0]:b+len(y)]):
959 listeBlocsCommuns.remove((b1,b2))
960 sys.stderr.write("remove lBC "+str((b1,b2))+"\n")
961 listeBlocsCommuns.append(((b1[0],a+len(x)),(b2[0],b+len(y))))
962 sys.stderr.write("add lBC"+str(((b1[0],a+len(x)),(b2[0],b+len(y))))+"\n")
963 sys.stderr.write("del "+str(NLC1[a])+" / "+str(NLC2[b])+" / "+str(NLC[x])+"\n")
964 del NLC1[a]
965 del NLC2[b]
966 l=NLC[x]
967 l.remove(a)
968 l.remove(b)
969 if l==[]: del NLC[x]
970 else: NLC[x]=l
971 moved=True
972
973 for b1,b2 in listeBlocsCommuns:
974 cle1 = self.texte[b1[0]:b1[1]]
975
976 if cle1!="":
977
978 if self.blocs_texte.has_key(cle1): NLC[cle1] = self.blocs_texte[cle1]
979 else:NLC[cle1]=[b1[0],b2[0]]
980
981
982 for x in LDEP:
983 l=LDEP[x]
984 if NLC.has_key(x):
985 l2=NLC[x]
986 for e1 in l:
987 if l2.count(e1)==0:l2.append(e1)
988 NLC[x]=l2
989 else:NLC[x]=l
990 sys.stderr.write("EXIT M1\n")
991 return NLC
992
993 - def statBlocs(self):
994 nbx=0
995 cum=0.0
996 LB=[]
997 for x in self.identites:
998 nbx+=1
999 lx=x[1]-x[0]
1000 cum+=lx
1001 LB.append(lx)
1002 LB.sort()
1003 sys.stderr.write("Nb blocs:+"+str(nbx)+" / Tmoy:"+str(cum/nbx)+" / Tmed:"+str(LB[len(LB)/2])+"\n")
1004
1005 - def statLB(self,liste,nom):
1006 if len(liste)==0: return
1007 nb=0
1008 taille=0.0
1009 L=[]
1010 BC={}
1011 LBC=[]
1012 i=0
1013 for x in liste:
1014 t=self.texte[x[0]:x[1]]
1015 if x[1]<=self.lg_texte1:
1016 nb+=1
1017 taille+=x[1]-x[0]
1018 L.append((x[1]-x[0],(x[0],x[1])))
1019 LBC.append(t)
1020 if not BC.has_key(t): BC[t]=[]
1021 BC[t].append(x[0])
1022
1023 i+=1
1024 L.sort()
1025 logging.info("%s : Nb = %d / moy = %.2f / med = %.2f / +gros = %s",nom,nb,taille/nb,L[len(L)/2][0],L[-1])
1026 sys.stderr.flush()
1027
1029
1030 self.construction_blocs_maximaux()
1031
1032
1033
1034
1035
1036
1037
1038 if (self.carOuMot == 0):
1039 self.mode_car()
1040 self.Dict.etat_dict()
1041 self.insertions_et_suppressions()
1042
1043
1044 self.reconstituer_textes()
1045
1046
1047 sys.stderr.write("2e phase = "+str(time.clock()-self.debut)+"\n")
1048
1049 resultat = Resultat(self.insertions, self.suppressions,
1050 self.occs_deplaces, self.tous_remplacements,
1051 self.lg_texte1, self.texte_original,
1052 self.blocsCommuns, self.lDepl)
1053 return resultat
1054
1055 -class ecartTextesRecur(ecartTextes):
1056 """ Classe utilisant les premiers algos d'alignement récursifs """
1057 - def testIn(self,L,name):
1058 for x in L:
1059
1060
1061
1062 if " dans l" in self.texte[x[0]:x[1]]:print " dans l in "+name+str(x)+self.texte[x[0]:x[1]]
1063
1065 self.occs_texte1 = []
1066 self.occs_texte2 = []
1067 self.occs_deplaces = []
1068
1069
1070 for x in self.identites:
1071 if x[0] < self.lg_texte1:
1072 self.occs_texte1.append(x)
1073 else: self.occs_texte2.append(x)
1074
1075 self.statBlocs()
1076 sys.stderr.write("Début de l'alignement\n")
1077 sys.stderr.flush()
1078 deb_al=time.clock()
1079 aligneur = alignement.AlignAstarRecur4(self.texte,self.lg_texte1,long_min_pivots)
1080 self.occs_deplaces,self.blocsCommuns,self.LUnique = aligneur.deplacements_pond(self.occs_texte1, self.occs_texte2)
1081
1082 sys.stderr.write("Fin de l'alignement : "+str(time.clock()-deb_al)+"\n")
1083 self.statLB(self.blocsCommuns,"BC")
1084 self.statLB(self.occs_deplaces,"Dep")
1085
1086 for x in self.LUnique:
1087 if x[0] < self.lg_texte1:
1088 self.suppressions = self.tool.ajout_intervalle(self.suppressions,x)
1089 else: self.insertions = self.tool.ajout_intervalle(self.insertions,x)
1090
1091
1092 self.suppressions = self.tool.soustr_l_intervalles(self.suppressions,self.blocsCommuns)
1093 self.insertions = self.tool.soustr_l_intervalles(self.insertions,self.blocsCommuns)
1094 for x in self.blocsCommuns:
1095
1096 if x[0] < self.lg_texte1:
1097 self.occs_texte1 = self.tool.addition_intervalle(self.occs_texte1, x)
1098 else: self.occs_texte2 = self.tool.addition_intervalle(self.occs_texte2, x)
1099
1100 for x in self.occs_deplaces:
1101 if self.tool.adjacent_(x, self.insertions):
1102 self.insertions = self.tool.ajout_intervalle(self.insertions, x)
1103 if self.tool.adjacent_(x, self.suppressions):
1104 self.suppressions = self.tool.ajout_intervalle(self.suppressions, x)
1105
1106 for x in self.insertions:
1107 self.occs_texte2 = self.tool.addition_intervalle(self.occs_texte2, x)
1108 for x in self.suppressions:
1109 self.occs_texte1 = self.tool.addition_intervalle(self.occs_texte1, x)
1110
1111
1112 self.construire_remplacements()
1113
1114
1115 self.lDepl = self.calcPairesBlocsDeplaces(self.occs_deplaces)
1116
1117 if not self.separatorSensivitive:
1118 self.postTraitSuppSep()
1119
1120 -class ecartTextesRecur2(ecartTextes):
1121 """ Classe utilisant l'algo d'alignement récursif simplifié et amélioré"""
1123 self.suppressions = [[0, self.lg_texte1]]
1124 for x in occs_t1:
1125 self.suppressions = self.tool.dif_intervalles(self.suppressions, x)
1126 self.insertions = [[self.lg_texte1, self.lg_texte1 + self.lg_texte2]]
1127 for x in occs_t2:
1128 self.insertions = self.tool.dif_intervalles(self.insertions, x)
1129
1131 self.occs_texte1 = []
1132 self.occs_texte2 = []
1133
1134
1135 logging.info("Debut de l'alignement")
1136 deb_al=time.clock()
1137
1138 aligneur = alignement.AlignAstarRecur5(self.texte,self.lg_texte1,long_min_pivots)
1139
1140 self.occs_deplaces,self.blocsCommuns = aligneur.run(self.texte1, self.texte2)
1141
1142 logging.info("Fin de l'alignement : %.2f s",time.clock()-deb_al)
1143 self.statLB(self.blocsCommuns,"BC")
1144 self.statLB(self.occs_deplaces,"Dep")
1145
1146 for x in self.occs_deplaces+self.blocsCommuns:
1147 if x[0] < self.lg_texte1: self.occs_texte1.append(x)
1148 else: self.occs_texte2.append(x)
1149 self.extraire_ins_supp(self.occs_texte1, self.occs_texte2)
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166 for x in self.occs_deplaces:
1167
1168
1169 if x[0] >= self.lg_texte1:
1170 self.insertions = self.tool.ajout_intervalle(self.insertions, x)
1171 else:
1172
1173
1174 self.suppressions = self.tool.ajout_intervalle(self.suppressions, x)
1175
1176 for x in self.insertions:
1177 self.occs_texte2 = self.tool.addition_intervalle(self.occs_texte2, x)
1178 for x in self.suppressions:
1179 self.occs_texte1 = self.tool.addition_intervalle(self.occs_texte1, x)
1180
1181
1182
1183 self.construire_remplacements()
1184
1185 self.lDepl = self.calcPairesBlocsDeplaces(self.occs_deplaces)
1186
1187 if not self.separatorSensivitive:
1188 self.postTraitSuppSep()
1189
1190
1191 - def reconstituer_textes(self, coeff=None):
1192 self.occs_texte1 = []
1193 self.occs_texte2 = []
1194
1195 logging.log(5,"Debut de l'alignement")
1196 deb_al=time.clock()
1197
1198
1199 if self.algoAligneur == 'Shapira' :
1200 aligneur = alignement.AlignShapiraRecur(self.lg_texte1,
1201 long_min_pivots, algoAlign=self.algoAligneur, coeff=coeff, sep=self.separatorSensivitive)
1202 elif self.algoAligneur == 'ShapiraGap' :
1203 aligneur = alignement.AlignShapiraRecurGap(self.lg_texte1,
1204 long_min_pivots, algoAlign=self.algoAligneur, coeff=coeff, sep=self.separatorSensivitive)
1205 elif self.algoAligneur == 'MOAstar':
1206 aligneur = alignement.AlignAstarRecur2(self.lg_texte1,
1207 long_min_pivots, coeff=coeff, sep=self.separatorSensivitive)
1208 else : aligneur = alignement.AlignAstarRecur(self.lg_texte1,
1209 long_min_pivots, algoAlign=self.algoAligneur, coeff=coeff, sep=self.separatorSensivitive)
1210
1211 self.occs_deplaces,self.blocsCommuns = aligneur.run(self.texte1, self.texte2)
1212 logging.log(5,"Fin de l'alignement : %.2f s",time.clock()-deb_al)
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225 for x in self.occs_deplaces:
1226 if x[0] < self.lg_texte1: self.occs_texte1 = self.tool.addition_intervalle(self.occs_texte1, x)
1227 else: self.occs_texte2 = self.tool.addition_intervalle(self.occs_texte2, x)
1228 for x in self.blocsCommuns:
1229 if x[0] < self.lg_texte1: self.occs_texte1 = self.tool.addition_intervalle(self.occs_texte1, x)
1230 else: self.occs_texte2 = self.tool.addition_intervalle(self.occs_texte2, x)
1231 self.insertions = self.tool.miroir(self.occs_texte2,self.lg_texte1,self.lg_texte)
1232 self.suppressions = self.tool.miroir(self.occs_texte1,0,self.lg_texte1)
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246 self.lDepl = self.calcPairesBlocsDeplaces(self.occs_deplaces)
1247
1248 self.insertions = self.fusionItemsAdjacents(self.insertions)
1249 self.suppressions = self.fusionItemsAdjacents(self.suppressions)
1250
1251 if not self.separatorSensivitive:
1252 self.postTraitSuppSep()
1253
1254 - def fusionItemsAdjacents(self, liste):
1255 """Fusionne les items qui se "touchent" dans une liste
1256
1257 cad les items dont la fin de l'un est le début de l'autre
1258 @type liste: list
1259 @param liste: liste de tuplet de blocs (debut,fin)"""
1260 i = 0
1261
1262 while i < len(liste)-1:
1263
1264 (deb,fin) = liste[i]
1265 (deb2, fin2) = liste[i+1]
1266 if ((deb == deb2 and fin == fin2) or
1267 (deb2 <= deb and fin <= fin2) or
1268 (deb <= deb2 and fin2 <= fin) or
1269 (fin == deb2)):
1270 liste[i:i+2] = [(deb,fin2)]
1271 else:
1272 i += 1
1273
1274 return liste
1276 self.reconstituer_textes__()
1277
1278
1279 resultat = Resultat(self.insertions, self.suppressions,
1280 self.occs_deplaces, self.tous_remplacements,
1281 self.lg_texte1, self.texte_original,
1282 self.blocsCommuns, self.lDepl)
1283
1284 bbl = synthetic.BiBlocListWD(resultat,self.planTravail)
1285 res = bbl.toResultat()
1286 res.setPairesBlocsDeplaces(self.calcPairesBlocsDeplaces(res.getListeDeplacements()))
1287
1288 bbl.print_html()
1289 return res
1290
1291
1293 """Comparaison de 2 textes déjà alignés ligne à ligne"""
1294 def addInter(src, dest1=None,dest2=None,testEquality=False):
1295 assert dest1 is not None or dest2 is not None
1296 e1 = e2 = 0
1297 for inter in src:
1298 if isinstance(inter[0],list):
1299 dest1.append(([inter[0][0]+increment1,inter[0][1]+increment1],
1300 [inter[1][0]+increment2,inter[1][1]+increment2]))
1301 else:
1302 if inter[1] <= self.lg_texte1:
1303 increment = increment1
1304 x = (inter[0]+increment,inter[1]+increment)
1305 assert 0 <= x[0] < x[1] <= lg_texte1
1306 dest1.append(x)
1307 e1+=1
1308 else:
1309 increment = increment2-len(l1)
1310 x = (inter[0]+increment,inter[1]+increment)
1311 assert lg_texte1 <= x[0] < x[1] <= lg_texte,str(lg_texte1)+str(x)+str(lg_texte)
1312 dest2.append(x)
1313 e2+=1
1314 if testEquality: assert e1 == e2
1315
1316
1317 insertions = [] ; suppressions = [] ; occs_deplaces1 = [] ; occs_deplaces2 = []
1318 tous_remplacements1 = [] ; tous_remplacements2 = [] ; blocsCommuns1 = []
1319 blocsCommuns2 = [] ; lDepl = []
1320
1321 texte1 = self.texte1 ; texte2 = self.texte2 ; lg_texte1 = self.lg_texte1 ; lg_texte2 = self.lg_texte2
1322 sepSensitive = self.separatorSensivitive ;
1323 lg_texte = lg_texte1 + lg_texte2
1324
1325 self.separatorSensivitive = True
1326 ltexte1 = texte1.splitlines(True)
1327 ltexte2 = texte2.splitlines(True)
1328
1329
1330
1331 assert len(ltexte1) == len(ltexte2) ,str(len(ltexte1))+'/'+str(len(texte2))
1332 if __debug__:
1333 t1 = t2 = 0
1334 for l in ltexte1: t1 += len(l)
1335 for l in ltexte2: t2 += len(l)
1336 assert t1 == lg_texte1 and t2 == lg_texte-lg_texte1
1337 increment1 = 0 ; increment2 = lg_texte1
1338
1339 i = 0
1340 while len(ltexte1) > 0:
1341 logging.debug("itération %d l à l",i)
1342
1343 l1 = ltexte1.pop(0) ; l2 = ltexte2.pop(0)
1344
1345 self.texte1 = l1 ; self.texte2 = l2
1346
1347 self.lg_texte1 = len(l1) ; self.lg_texte2 = len(l2)
1348 self.lg_texte = self.lg_texte1 + self.lg_texte2
1349 self.reconstituer_textes()
1350 addInter(self.insertions, dest2=insertions)
1351 addInter(self.suppressions, dest1=suppressions)
1352 addInter(self.occs_deplaces, occs_deplaces1, occs_deplaces2)
1353 addInter(self.tous_remplacements, tous_remplacements1, tous_remplacements2, True)
1354 addInter(self.blocsCommuns, blocsCommuns1, blocsCommuns2, True)
1355 addInter(lDepl, self.lDepl)
1356 increment1 += len(l1) ; increment2 += len(l2)
1357 i += 1
1358 self.texte1 = texte1 ; self.texte2 = texte2
1359 self.lg_texte1 = lg_texte1 ; self.lg_texte2 = lg_texte2
1360 self.lg_texte = self.lg_texte1 + self.lg_texte2
1361 self.separatorSensivitive = sepSensitive
1362 self.insertions = insertions ; self.suppressions = suppressions
1363 occs_deplaces1.extend(occs_deplaces2) ; self.occs_deplaces = occs_deplaces1
1364 tous_remplacements1.extend(tous_remplacements2)
1365 self.tous_remplacements = tous_remplacements1
1366 blocsCommuns1.extend(blocsCommuns2) ; self.blocsCommuns = blocsCommuns1
1367 self.lDepl = lDepl
1368 if not self.separatorSensivitive:
1369 self.postTraitSuppSep()
1370
1371 - def run(self, textesApparies=False, dossierRapport=None, coeff=None):
1372 """Lancement de la comparaison entre les 2 textes
1373 si texteApparies est vrai, cela signifie que les 2 textes doivent
1374 déjà être alignés ligne à ligne, ainsi, la comparaison se fera par ligne
1375
1376 @type textesApparies: bool
1377 @param textesApparies: les textes sont préappariés ligneà ligne
1378 @type dossierRapport: string
1379 @param dossierRapport: chemin du dossier où écrire le rapport HTML
1380 @type coeff: tuple
1381 @param coeff: tuple des 3 coefficients d'agrégation"""
1382
1383 if textesApparies:
1384 self.reconstituer_textes_apparies()
1385
1386 else:
1387 self.reconstituer_textes(coeff)
1388
1389 self.tous_remplacements = []
1390 resultat = Resultat(self.insertions, self.suppressions,
1391 self.occs_deplaces, self.tous_remplacements,
1392 self.lg_texte1, self.texte_original,
1393 self.blocsCommuns, self.lDepl)
1394 logging.debug('Création BiBlocListWD')
1395 bbl = synthetic.BiBlocListWD(resultat,self.planTravail)
1396
1397
1398 logging.debug('BiBlocListWD.toResultat()')
1399 res = bbl.toResultat()
1400 if not textesApparies:
1401 logging.debug('calcPairesBlocsDeplaces()')
1402
1403
1404 res.setPairesBlocsDeplaces(self.lDepl)
1405 logging.debug('BiBlocListWD.print_html()')
1406 bbl.print_html(dossierOutput=dossierRapport)
1407 try:
1408 bbl.evaluation()
1409 except ZeroDivisionError:
1410 logging.debug("Erreur d'evaluation ZeroDivisionError")
1411
1412 self.bbl = bbl
1413
1414 return res
1415
1416 - def calcPairesBlocsDeplaces2(self,blocsDepl1,blocsDepl2):
1417 """Construction de paires de blocs déplacés entre le source et le cible.
1418 On met en correspondance chaque bloc du source et le ou les blocs identiques du cible.
1419 On peut avoir un bloc source qui correspond à plusieurs cibles et vice-versa,
1420 auquel cas on aura autant de paires 2 à 2 qu'il y a de correspondances."""
1421 lDepl = []
1422 i=0 ; len_blocsDepl1 = len(blocsDepl1)
1423 while (i < len_blocsDepl1 and blocsDepl1[i][0] < self.lg_texte1):
1424 texte1 = self.texte1[blocsDepl1[i][0]:blocsDepl1[i][1]]
1425 longueur = blocsDepl1[i][1] - blocsDepl1[i][0]
1426 for y in blocsDepl2:
1427 if (y[0] > self.lg_texte1-1 and longueur == y[1] - y[0] and
1428 texte1 == self.texte2[y[0]-self.lg_texte1:y[1]-self.lg_texte1]):
1429 lDepl.append((blocsDepl1[i],y))
1430 i += 1
1431
1432 return lDepl
1433
1434 - def trace(self,commande,dic_locals):
1435 import hotshot,hotshot.stats,sys
1436 prof = hotshot.Profile("c:\workspace\medite\statFile")
1437 benchtime = prof.runctx(commande,globals(), dic_locals)
1438 prof.close()
1439 stats = hotshot.stats.load("c:\workspace\medite\statFile")
1440 stats.strip_dirs()
1441 stats.sort_stats('cumulative','calls','time')
1442 stats.print_stats()
1443
1444
1445 - def xpNgram(self):
1446 def concTok(tok):
1447 if len(tok) == 1: return tok[0]
1448 elif len(tok) == 2: return tok[0]+' '+tok[1]
1449 else: return tok[0]+' '+tok[1]+' '+tok[2]
1450 texte = self.texte1 + self.texte2
1451 dicLeftNgram = {} ; dicRightNgram = {} ; dicLeftRightNgram = {}
1452 i = 0
1453 while i < len(self.bbl.liste)-1:
1454 b1,b2 = self.bbl.liste[i]
1455 if b1 is not None and b1[0] == 'R':
1456 b1_prec,b2_prec = self.bbl.liste[i-1]
1457 b1_suiv,b2_suiv = self.bbl.liste[i+1]
1458 if b1_prec is None or b2_prec is None or b1_suiv is None or b2_suiv is None:
1459
1460 i += 1 ; continue
1461 if b1_prec[0] != 'BC' or b2_prec[0] != 'BC' or b1_suiv[0] != 'BC' or b2_suiv[0] != 'BC':
1462
1463 i += 1 ; continue
1464 tp = texte[b1_prec[1]:b1_prec[2]] ; ts = texte[b1_suiv[1]:b1_suiv[2]]
1465 tokenp = tp.split() ; tokens = ts.split()
1466 tokenp = tokenp[-3:] ; tokens = tokens[-3:]
1467 assert len(tokenp) <= 3 and len(tokens) <= 3
1468 tokenp = concTok(tokenp) ; tokens = concTok(tokens)
1469 try: dicLeftNgram[tokenp] += 1
1470 except KeyError: dicLeftNgram[tokenp] = 1
1471 try: dicRightNgram[tokens] += 1
1472 except KeyError: dicRightNgram[tokens] = 1
1473 item = (texte[b1[1]:b1[2]],texte[b2[1]:b2[2]])
1474 try:
1475 nb,liste = dicLeftRightNgram[tokenp,tokens]
1476 liste.append(item)
1477 dicLeftRightNgram[tokenp,tokens] = nb+1, liste
1478 except KeyError:
1479 dicLeftRightNgram[tokenp,tokens] = 1, [item]
1480 i += 1
1481 listeLeftNgram = [] ; listeRightNgram = [] ; listeLeftRightNgram = []
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494 for token,(nb,item) in dicLeftRightNgram.iteritems():
1495 bisect.insort_right(listeLeftRightNgram,(nb,token,'==>',item))
1496 listeLeftRightNgram.reverse()
1497 logging.info('listeLeftRightNgram:')
1498 for x in listeLeftRightNgram: logging.debug(x)
1499 logging.info('==============================')
1500
1501
1502
1503 -class ecartTextesRecur3(ecartTextesRecur2):
1504 """ pas utilisé """
1505 - def postTraitSuppSep(self, bbl):
1506 """Modifie bbl pour reprendre les coordonnées du texte original """
1507 tabNbSuppression = self.tabNbSuppression
1508 for i in xrange(len(bbl)-1,-1,-1):
1509 B1,B2 = bbl[i]
1510 if B1 is None: NB1 = None
1511 else: NB1 = (B1[0], B1[1] + tabNbSuppression[B1[1]], B1[2] + tabNbSuppression[B1[2]],
1512 [(d1+tabNbSuppression[d1],d2+tabNbSuppression[d2]) for (d1,d2) in B1[3]])
1513 if B2 is None: NB2 = None
1514 else: NB2 = (B2[0], B2[1] + tabNbSuppression[B2[1]], B2[2] + tabNbSuppression[B2[2]],
1515 [(d1+tabNbSuppression[d1],d2+tabNbSuppression[d2]) for (d1,d2) in B2[3]])
1516 bbl[i] = (NB1, NB2)
1517
1518 self.texte1 = self.texte1_original
1519 self.texte2 = self.texte2_original
1520
1521 self.lg_texte1 = len(self.texte1)
1522 self.lg_texte2 = len(self.texte2)
1523
1525 logging.log(5,"Debut de l'alignement")
1526 deb_al=time.clock()
1527 aligneur = alignement.AlignAstarRecurBBL(self.lg_texte1,long_min_pivots)
1528 bbl = aligneur.run(self.texte1, self.texte2)
1529 logging.log(5,"Fin de l'alignement : %.2f s",time.clock()-deb_al)
1530 return bbl
1531
1532
1533 - def reconstituer_textes_apparies(self, stream=False, dossierRapport=None):
1534 """Comparaison de 2 textes déjà alignés ligne à ligne"""
1535 bbl = []
1536
1537 texte1 = self.texte1 ; texte2 = self.texte2 ; lg_texte1 = self.lg_texte1 ; lg_texte2 = self.lg_texte2
1538 sepSensitive = self.separatorSensivitive ;
1539 lg_texte = lg_texte1 + lg_texte2
1540
1541 self.separatorSensivitive = True
1542 ltexte1 = texte1.splitlines(True)
1543 ltexte2 = texte2.splitlines(True)
1544 assert len(ltexte1) == len(ltexte2) ,str(len(ltexte1))+'/'+str(len(texte2))
1545 if __debug__:
1546 t1 = t2 = 0
1547 for l in ltexte1: t1 += len(l)
1548 for l in ltexte2: t2 += len(l)
1549 assert t1 == lg_texte1 and t2 == lg_texte-lg_texte1
1550 increment1 = 0 ; increment2 = lg_texte1
1551 i = 0 ; premier = True
1552
1553 while len(ltexte1) > 0:
1554 if i%100 == 0: logging.debug("itération %d l à l",i)
1555 i += 1
1556 l1 = ltexte1.pop(0) ; l2 = ltexte2.pop(0)
1557 len_l1 = len(l1) ; len_l2 = len(l2)
1558 self.texte1 = l1 ; self.texte2 = l2
1559 self.lg_texte1 = len_l1 ; self.lg_texte2 = len_l2
1560 self.lg_texte = self.lg_texte1 + self.lg_texte2
1561 bblLigne = self.reconstituer_textes()
1562 for B1,B2 in bblLigne:
1563 if B1 is None: NB1 = None
1564 else: NB1 = (B1[0], B1[1] + increment1, B1[2] + increment1,
1565 [(d1+increment1,d2+increment1) for (d1,d2) in B1[3]])
1566 if B2 is None: NB2 = None
1567 else: NB2 = (B2[0], B2[1] + increment2-len_l1, B2[2] + increment2-len_l1,
1568 [(d1+increment2-len_l1,d2+increment2-len_l1) for (d1,d2) in B2[3]])
1569 bbl.append((NB1, NB2))
1570 increment1 += len_l1 ; increment2 += len_l2
1571 if i%50 == 0 and stream:
1572 if not sepSensitive: self.postTraitSuppSep(bbl)
1573 bbl2 = synthetic.BiBlocListWDListe(bbl, self.planTravail,
1574 self.texte_original, texte1)
1575 if premier:
1576 fBuffer = bbl2.print_html_streaming(dossierOutput=dossierRapport,justPrintEntete=True)
1577 premier = False
1578 bbl2.printTableLine(fBuffer)
1579
1580
1581
1582
1583
1584
1585 del bbl ; del bbl2 ; bbl = []
1586
1587
1588
1589
1590
1591 if stream:
1592 if not sepSensitive: self.postTraitSuppSep(bbl)
1593 bbl2 = synthetic.BiBlocListWDListe(bbl, self.planTravail,
1594 self.texte_original, texte1)
1595 bbl2.printTableLine(fBuffer)
1596 bbl2.printCloseTable(fBuffer)
1597 del bbl2 ; bbl = []
1598
1599 self.texte1 = texte1 ; self.texte2 = texte2
1600 self.lg_texte1 = lg_texte1 ; self.lg_texte2 = lg_texte2
1601 self.lg_texte = self.lg_texte1 + self.lg_texte2
1602 self.separatorSensivitive = sepSensitive
1603 return bbl
1604
1605
1606 - def run(self, textesApparies=False, dossierRapport=None):
1607 """Lancement de la comparaison entre les 2 textes
1608 si texteApparies est vrai, cela signifie que les 2 textes doivent
1609 déjà être alignés ligne à ligne, ainsi, la comparaison se fera par ligne """
1610
1611 logging.debug('debut run')
1612 if textesApparies:
1613 bbl = self.reconstituer_textes_apparies()
1614
1615 else:
1616 bbl = self.reconstituer_textes()
1617 if not self.separatorSensivitive:
1618 self.postTraitSuppSep(bbl)
1619 logging.debug('BiBlocListWDListe(bbl)')
1620 bbl = synthetic.BiBlocListWDListe(bbl, self.planTravail, self.texte_original, self.lg_texte1)
1621 logging.debug('BiBlocListWD.toResultat()')
1622 res = bbl.toResultat()
1623 if not textesApparies:
1624 logging.debug('calcPairesBlocsDeplaces()')
1625 res.setPairesBlocsDeplaces(self.calcPairesBlocsDeplaces2(
1626 res.getListeDeplacementsT1(),res.getListeDeplacementsT2()))
1627 logging.debug('BiBlocListWD.print_html()')
1628 bbl.print_html(dossierOutput=dossierRapport)
1629 bbl.evaluation()
1630
1631 return res
1632
1633 - def runStream(self, textesApparies=False, dossierRapport=None):
1634 """Lancement de la comparaison entre les 2 textes
1635 si texteApparies est vrai, cela signifie que les 2 textes doivent
1636 déjà être alignés ligne à ligne, ainsi, la comparaison se fera par ligne """
1637
1638 logging.debug('debut run')
1639 self.bbl = self.reconstituer_textes_apparies(stream=True, dossierRapport=dossierRapport)
1640 return []
1641