Index by: file name | procedure name | procedure call | annotation
gscope_taxo.tcl (annotations | original source)

#rR gscope_taxo.tcl
#rR ici on trouvera Tax qui appelle soit TaxGetz (obsolete) soit TaxNCBI soit TaxUniProt (voir TaxSystem)
#rR Attention dans un meme cafe des sciences on ne peut pas mélanger les 2 

#rR Normalement Tax appelle QuestionDeScience EVImm Tax  pouen epas avoir à le charger
#rR   sauf si EVImm (bien sûr) ou si TaxWithQDS 0 est positionné.
#rR   Le chargemetn dure 30 secondes depuis 2017/04/18 car j'ai mis le array dans un tableau.
#rR Si un projet Gscope veut faire beaucoup de Tax alors il vaut mieux faire
#rR   TaxWithQDS 0  en début  puis utiliser Tax en self service.

#rR il y a aussi des choses pour faire une base de donnees Sql (Luc a tout fait pour ça)

#rR attention les Name d'un noeud ne sont pas uniques. Il y a par exemple 2 craniata, l'un étant un genre de moule !!!

proc TaxoblaKeepOnly {{KeepWhat ""} {Extension ""} {TaxoblaOrigin ""}} {
    if {$KeepWhat     ==""} { set KeepWhat "AEB_ListOf_OX" }
    if {$Extension    ==""} { set Extension $KeepWhat }
    if {$TaxoblaOrigin==""} { set TaxoblaOrigin "taxobla" }

    set LesKeepedOX {}
    if {[regexp {^([A-Z]+)_([^_]+)_([^_]+)$} $KeepWhat Match Domaines Lo W]} {
	foreach D [split $Domaines ""] {
	    Espionne "OiCodeForDomain $D $Lo $W"
	    set LesOX [OiCodeForDomain $D $Lo $W]
	    LConcat LesKeepedOX $LesOX
	}
    }

    Espionne $LesKeepedOX
    foreach OX $LesKeepedOX {
	set Keep($OX) 1
    }

    NousAllonsAuBoulot [RepertoireDuGenome]
    set DestDir "taxobla$Extension"
    foreach Nom [ListeDesPABs] {
	if {[PasTouche $Nom]} { continue }
	set Orig "$TaxoblaOrigin/$Nom"
	set Dest "$DestDir/$Nom"
	file mkdir $DestDir
	if {[FileExists $Orig] && [FileAbsent $Dest]} {
	    set LeNew {}
	    foreach Ligne [LesLignesDuFichier $Orig] {
		scan $Ligne "%s %s %s" Pn Score OX
		if { ! [info exists Keep($OX)]} { continue }
		lappend LeNew $Ligne
	    }
	    SauveLesLignes $LeNew dans $Dest
	    Espionne $Dest
	    lappend LesNouveaux $Dest
	}
	FinPasTouche $Nom
    }
    OnRevientDuBoulot
    return $LesNouveaux
}  

proc NiceChildrenOf TaxId {
    set TaxId [Tax $TaxId "TaxId"]
    set LesC {}
    foreach C [Tax $TaxId Children] {
	lappend LesC [Tax $C Name]
    }
    return $LesC
}

proc CreeTaxoblaWithMyMissBlast {} {
    set LesCrees {}
    foreach Ligne [MyMissBlast] {
	scan $Ligne "%s %s %s" Nom Id Seq
	set SL [string length $Seq]
	set Ac [NIAG $Nom "A"]
	set PN 0.00
	set Score 1
	set TaxId [NotreOX]
	set Orga [NotreOS]
	set Info [PremiereLigneDuFichier [GscopeFile $Nom prottfa]]
	set Info [join [lrange [split $Info " "] 2 end] " "]
	set Info "$Id $Ac $Info SL=$SL" 
	if {[string length $Orga]>36} { set Orga "[string range $Orga 0 36]..." }
	set LigneTaxobla [format "%7s\t%6s\t%8s\t%-40s\t%s" $PN $Score $TaxId $Orga $Info]
	Espionne $LigneTaxobla
	set FicTaxobla [GscopeFile $Nom taxobla]
	if {[FileExists $FicTaxobla] && [file size $FicTaxobla]>0} {
	    if { ! [OuiOuNon "$FicTaxobla already exists; Do I overwrite ?"]} { continue }
	} 
	lappend LesCrees [Sauve $LigneTaxobla dans $FicTaxobla]
    }
    return $LesCrees
}

proc CreeTaxoblaVide {} {
    if { ! [OuiOuNon "Attention on crée des fichiers vides ... Si les blasts sont faits plus tard il faut penser à les supprimer\nJe crée quand même les vides"]} { return "" }
    set LesCrees {}
    foreach Nom [ListeDesPABs] {
	set FiTaxo [GscopeFile $Nom "taxobla"]
	if {[FileAbsent $FiTaxo]} {
	    lappend LesCrees [Sauve "" dans $FiTaxo] } 
    }
    return $LesCrees
}

proc TaxonomyDuBlastPourTous {{RepBlast ""} {RepTaxobla ""} {CutPN ""} {MaxListe ""}} {
    if {$RepBlast==""}   { set RepBlast   "[RepertoireDuGenome]/blastp" }
    if {$RepTaxobla==""} { set RepTaxobla "[RepertoireDuGenome]/taxobla" }
    if { ! [regexp "/" $RepBlast]}   { set RepBlast   "[RepertoireDuGenome]/$RepBlast" }
    if { ! [regexp "/" $RepTaxobla]} { set RepTaxobla "[RepertoireDuGenome]/$RepTaxobla" }
    if {[FileAbsent $RepTaxobla]} { file mkdir $RepTaxobla }
    set I 0
    set LesFichierTaxoblaCrees {}
    foreach Nom [ListeDesPABs] {
	if {$I%100==0} { Espionne "TaxonomyDuBlast $Nom" }
	incr I
	set FichierTaxobla $RepTaxobla/$Nom
	if {[file exists $FichierTaxobla] && [file size $FichierTaxobla]>0} { continue }
	set FichierBlast "$RepBlast/$Nom"
	if {[PasTouche "Taxobla$Nom"]} { continue } 
	set F [TaxonomyDuBlast $FichierBlast $CutPN $MaxListe $FichierTaxobla "AvecMemoTaxo"]
	lappend LesFichierTaxoblaCrees $F
	set L [llength [LesLignesDuFichier $F]]
	Espionne "$FichierTaxobla [format %6d $L] different organisms"
	FinPasTouche "Taxobla$Nom"
    }
    return $LesFichierTaxoblaCrees
}

proc LesOrganismesDuBlast {TexteOuListeOuFichier {CutPN ""} {MaxListe ""} {GetWhat ""} {AvecMemoTaxo ""}} {
    #Pour raison de compatibilité je le garde pour le moment pour Arnaud
    return [TaxonomyDuBlast $TexteOuListeOuFichier $CutPN $MaxListe $GetWhat $AvecMemoTaxo]
}

proc TaxonomyDuBlast {TexteOuListeOuFichier {CutPN ""} {MaxListe ""} {GetWhat ""} {AvecMemoTaxo ""}} {
    #rR Toute cette histoire de taxonomy présente dans le blast date de CilioCarta (2015)
    #rR Ca marche si la banque blast a été créée avec les OX que je rajoute pour tout Uniprot
    #rR on lit les chevrons du blast qui contiennent l'expect et le TaxId (pour CilioCarta en tout cas)
    #rR on rend la liste du premier hit de chaque orga rencontré sauf si CutPN contient KeepAll

    set KeepAll [regexp -nocase "KeepAll" $CutPN]
    if {$KeepAll} {
	regsub -nocase "KeepAll" $CutPN "" CutPN
    }

    if {$CutPN==""   || $CutPN   =="-" } { set CutPN "9999999" } 
    if {$MaxListe==""|| $MaxListe=="-" } { set MaxListe "9999999" } 
    if {$GetWhat==""}  { set GetWhat "Show" } 

    if {[regexp -nocase "Memo" $AvecMemoTaxo]} { global MemoTaxoPourTaxobla }

    set LesRetenus {}

    set Nom ""
    if {[EstUnPAB $TexteOuListeOuFichier]} {
	set Nom $TexteOuListeOuFichier
	set TexteOuListeOuFichier [GscopeFile $Nom "blastp"]
	if {[FileAbsent TexteOuListeOuFichier]} {
	    set ListeDesLignes {}
	} else {
	    set ListeDesLignes [LesLignesDuFichier $TexteOuListeOuFichier]
	}
	#rR ici on prend le fichier 
	set FichierTaxobla [GscopeFile $Nom "taxobla"]
	if {[file exists $FichierTaxobla]} {
	    set LesRetenus [LesLignesDuFichier $FichierTaxobla]
	}
    } elseif {[regexp "^/FromOi/(.+)$" $TexteOuListeOuFichier Match Nom]} {
	set ListeDesLignes [BlastFromOi $Nom]
    } elseif {[regexp "\n" $TexteOuListeOuFichier]} {
	set ListeDesLignes [split $TexteOuListeOuFichier "\n"]
    } elseif {[regexp " " $TexteOuListeOuFichier]} {
	set ListeDesLignes $TexteOuListeOuFichier
    } elseif {[file exists $TexteOuListeOuFichier]} {
	set ListeDesLignes [LesLignesDuFichier $TexteOuListeOuFichier]
	set Nom [file tail $TexteOuListeOuFichier]
    } elseif {[string length $TexteOuListeOuFichier] > 100} {
	set ListeDesLignes [split [Base64Decode $TexteOuListeOuFichier] "\n"]
    } else {
	FaireLire "I don't know how to analyse the blast\n$TexteOuListeOuFichier\n\
		It's not a text, not a list, not a file"
	return ""
    }

    if {$LesRetenus=={}} {
	set DansChevron 0
	set NbLus 0
	foreach Ligne $ListeDesLignes {
	    set Chev [regexp "^>" $Ligne]
	    if { ! $DansChevron && ! $Chev} { continue }
	    if { ! $DansChevron &&   $Chev} {
		regsub ">" $Ligne "" Ligne
		scan $Ligne "%s" Access		
		if {[info exists DejaVu($Access)]} { set DansChevron 0 ; continue }
		set DejaVu($Access) $Ligne
		set Info $Ligne
		set Expect ""
		set DansChevron 1
		continue
	    }
	    if {[regexp "^ *Identities" $Ligne]} { set DansChevron 0 ; continue }
	    if {[regexp {Expect *= *([^\,]+)} $Ligne Match sPN]} {

		set Score [expr round([StringApres "Score =" dans $Ligne])]           ;#rR rajoute le 2015/06/08 

		regsub {^[eE]} $sPN "1e" sPN
		#	scan $sPN "%f" PN
		set PN $sPN
		if {[catch { expr $PN > $CutPN } ]} {
		    Warne "Oh le vilain $PN"
		    set PN 1E-200
		}
		if {[expr $PN <= $CutPN]} {
		    regsub -all " +" $Info " " Info
		    set Info [string trim $Info]
		    set TaxId ""
		    if {[regexp -nocase {(TAXID|OX)(=|:)([0-9]+)( |$)} $Info Match K S T]} {
			set TaxId $T
		    } else {
			if {[regexp {OS=(.*)$} $Info Match OS]} {
			    regsub { [A-Z]+=.*$} $OS "" OS
			    regsub -all {\[} $OS "\\\[" OS
			    regsub -all {\]} $OS "\\\]" OS
			    regsub {\.$} $OS "" OS
			    if {[info exists MemoTaxoPourTaxobla($OS)]} {
				set TaxId $MemoTaxoPourTaxobla($OS)
			    } else {
				regsub -all " " $OS "_" O_S
				set TaxId [Tax $O_S]
				if {$TaxId==""} {
				    lassign [split $O_S "_"] Genre Espece
				    set G_E "${Genre}_$Espece"
				    set TaxId [Tax $G_E]
				}
				set MemoTaxoPourTaxobla($OS) $TaxId
			    }
			} 
		    }
		    if {[info exists MemoTaxoPourTaxobla($TaxId)]} {
			set Orga $MemoTaxoPourTaxobla($TaxId)
		    } else {
			if {$TaxId!=""} {
			    set Orga [Tax $TaxId]
			    set MemoTaxoPourTaxobla($TaxId) $Orga
			} else {
			    set Orga "Unknown unknown"
			}
		    }
		    if { $KeepAll || ! [info exists DejaVu($TaxId)] } {
			if {[string length $Orga]>36} { set Orga "[string range $Orga 0 36]..." }
			lappend LesRetenus [format "%7s\t%6s\t%8s\t%-40s\t%s" $PN $Score $TaxId $Orga $Info]  ;#rR rajout de score 2015/06/08
			if {[incr NbLus]>$MaxListe} { break }
			set DejaVu($TaxId) 1
		    }
		}
		set Info ""
		set Access ""
		set DansChevron 0
		continue
	    }
	    append Info " $Ligne"
	}
    }
    
    if {$GetWhat=="GetList"} { return $LesRetenus }
    if {$GetWhat=="GetText"} { return [join $LesRetenus "\n"] }
    if {$GetWhat=="Show"} {
	#rR On peut postponé les TouchePour ... ils sont mis en mémoire et rajoutés en queue des boutons :)
	set Clavier "Postpone"
	TouchePour $Clavier NouvelleGamme
	TouchePour $Clavier NouvelleCouleur "Orange"
	TouchePour $Clavier "See Taxo"        "AfficheTaxoFromTaxoLine \[selection get\] $Nom"
	TouchePour "<2>"    "/ Fetch"         "AfficheFetchFromTaxoLine \[selection get\] $Nom"
	TouchePour $Clavier NouvelleCouleur "Magenta"
	TouchePour $Clavier "OutlierOrganism" "OutlierOrganismInBlast $Nom"
	TouchePour $Clavier "Set Current Clade" "HighlightClade @F@ New"          ;#rR les @F@ seront remplacés par la fenêtre car Postpone
	TouchePour "<2>"    "/ See"             "HighlightClade @F@ See"
	TouchePour $Clavier "Highlight Clade"   "HighlightClade @F@ Current"
	if {[PourWscope]} { return [AfficheListe $LesRetenus "GrandeLargeur" $Nom] }
	set F [AfficheListe $LesRetenus "GrandeLargeur" $Nom]
    }

    set Fichier ""
    if {[regexp "/" $GetWhat]} { set Fichier $GetWhat }
    if {$GetWhat=="Save" && [EstUnPAB $Nom]} { mkdir "[RepertoireDuGenome]/taxobla"; set Fichier [GscopeFile $Nom "taxobla"] }
    if {$Fichier!=""} { return [SauveLesLignes $LesRetenus dans $Fichier] }
    if {$GetWhat=="GetText"} { return [join $LesRetenus "\n"] }
    return $LesRetenus
}

proc HighlightClade {Fenetre Action} {
    set Clade ""
    if {$Action=="Current"} { set Clade [CladeCourant] } 
    if {$Action=="New"}     { set Clade [CladeCourant "New"] } 
    if {$Action=="See"}     { return    [CladeCourant "See"] } 

    set Clade [Tax $Clade "TaxId"]
    set LesIllumines {}
    set Max -10
    foreach Ligne [split [PagePropre $Fenetre] "\n"] {
	if {[incr Max -1]==0} { break }
	set TaxId ""
	scan $Ligne "%s %s %d" E S TaxId
	if { ! [JeSuisTonAncetre $Clade $TaxId]} { continue }
	lappend LesIllumines " $TaxId "
    }
    if {$LesIllumines=={}} { return {} }
    return [IllumineLaListe $LesIllumines $Fenetre ]
}

proc AfficheTaxoFromTaxoLine {Ligne {Titre ""}} {
    set LeMessage {}
    foreach Li [split $Ligne "\n"] {
	set TaxId [lindex [LesMotsDeLaLigne $Li] 2]
	set Message "[format %-7s $TaxId] [TaxClass $TaxId Name]"
	lappend LeMessage $Message
    }
    return [AfficheListe $LeMessage "" $Titre]
}

proc AfficheFetchFromTaxoLine {Ligne {Titre ""}} {
    if {[regexp "\n" $Ligne]} {
	set LesFen {}
	foreach Li [split $Ligne "\n"] {
	    lappend LesFen [AfficheFetchFromTaxoLine $Li $Titre] 
	}
	return $LesFen
    }
    set iDernierDoubleBlanc [string last "  " $Ligne]
    set Access ""
    scan [string range $Ligne $iDernierDoubleBlanc end] "%s" Access
    return [AfficheFetch $Access $Titre]
}

proc TaxWithQds {{Valeur ""}} {
    global TaxWithQds

    if {$Valeur!=""} { set TaxWithQds $Valeur }

    if {[info exists TaxWithQds]} { return $TaxWithQds }
    if {[TaxSystem]=="AK"} { return 0 }
    if {[OnTraite "EVImm"]} { set TaxWithQds 0 }
    return $TaxWithQds 
}

proc Tax {Query {Quoi ""} {Valeur ""}} {

    if {$Query==""} { return "" } 

    regsub -all " +" [string trim $Query] "_" Query

    if { [TaxWithQds] } { return [QuestionDeScience EVImm "ret Tax $Query $Quoi $Valeur"] }
    
    set TaxSystem [TaxSystem]
    return [Tax$TaxSystem $Query $Quoi $Valeur]
}

proc TaxSystem {{Value ""}} {
    global TaxSystem

#   set DefaultValue "NCBI"
#   set DefaultValue "UniProt"
    set DefaultValue "AK"

    if {$Value!=""} {
	set VALUE [string toupper $Value]
	set TaxSys(GETZ)    "Getz"
	set TaxSys(NCBI)    "NCBI"
	set TaxSys(UNIPROT) "UniProt"
	set TaxSys(AK)      "AK"
	if {[info exists TaxSys($VALUE)]} {
	    set Value $TaxSys($VALUE)
	} else {
	    set DEFAULT [string toupper $DefaultValue]
	    set Better $TaxSys($DEFAULT)
	    Warne "Attention $Value is not a valid TaxSystem I'll use $Better" 
	    set Value $Better
	}
	set TaxSystem $Value
    }
    if { ! [info exists TaxSystem]} { set TaxSystem $DefaultValue }
    return $TaxSystem
}

proc TestTaxParQdsMemo {} {
    Espionne [TaxParQdsMemo "Frog virus 3 (isolate Goorha)"]
    Espionne [TaxParQdsMemo "Frog virus 3 (isolate Goorha)"]
    Espionne [TaxParQdsMemo 9606]
    Espionne [TaxParQdsMemo "Homo sapiens"]
    Espionne [TaxParQdsMemo "Homo_sapiens"]
}

proc TaxParQdsMemo {{Qui ""}} {
    #rR on appelle QuestionDeScience et on mémorise pour le coup d'après.
    global TaxParQdsMemo

    regsub -all "_" $Qui " " Qui

    if {[info exists TaxParQdsMemo($Qui)]} { return $TaxParQdsMemo($Qui)}

    set Q $Qui
    regsub -all {\[} $Q "\\\[" Q 
    regsub -all {\]} $Q "\\\]" Q 
    set R [Tax $Q]
    set TaxParQdsMemo($Qui) $R
    if {$R!=""} { set TaxParQdsMemo($R) $Qui }
    return $R
}



proc TestSock {} {
    LogWscope "dans TestSock"
    return "Bonjour"
}

proc LesClassesDuDescriptif {Nom {Expect ""}} {
    set FD [GscopeFile $Nom "descriptifs"]
    if {[FileAbsent $FD]} { return {} }
    set LesClasses {}
    foreach Ligne [LesLignesDuFichier $FD] {
	set Classe [StringSuivant "OC:" dans $Ligne]
	regsub {OX: .*} $Classe "" Classe
	if {$Classe==""} { continue }
	lappend LesClasses $Classe
    }
    return $LesClasses
}

proc CreateSqlTaxonomySynonym {} {
    
    set LesTaxId [lsort -integer [TaxNCBI List TaxId]]
    set Pk 0
    foreach TaxId $LesTaxId {
	set Name     [TaxNCBI $TaxId "Name"]
	set ItsNames [TaxNCBI $TaxId "ItsNames"]
	if {$Name==""} { continue }

	foreach Syno $ItsNames {
	    set BeauSyno $Syno
	    regsub -all {\\} $BeauSyno {\\\\} BeauSyno
	    regsub -all {\'} $BeauSyno "\\'"  BeauSyno
	    if { ! [string equal $Syno $BeauSyno]} { Espionne "$Syno\n$BeauSyno" }
	    if {[info exists SynoDejaVu($Syno)]} {
#		FaireLire "DejaVu $TaxId $Syno $SynoDejaVu($Syno)"
	    }
	    set SynoDejaVu($Syno) $TaxId

	    incr Pk
	    set Csv "$Pk|$TaxId|$BeauSyno"
	    lappend LesSynCsv $Csv
	}
    }
    set FicSynCsv [SauveLesLignes $LesSynCsv dans "[RepertoireDuGenome]/createtaxoSyn.csv"]
    return $FicSynCsv
} 

proc CreateSqlTaxonomy {} {
    
    set LesTaxId [lsort -integer [TaxNCBI List TaxId]]
    foreach TaxId $LesTaxId {
	set Name   [TaxNCBI $TaxId "Name"]
	set Parent [TaxNCBI $TaxId "Parent"]
	Espionne "$TaxId $Name"
	if {$Name==""} { continue }

	if {[info exists NameDejaVu($TaxId)]} {
	    FaireLire "DejaVu $TaxId $NameDejaVu($TaxId)"
	}
	if {0 && [info exists TaxIdDejaVu($Name)]} {
	    FaireLire "DejaVu $Name $TaxIdDejaVu($Name)"
	}
	set NameDejaVu($TaxId) $Name 
	set TaxIdDejaVu($Name)  $TaxId

	regsub -all {\'} $Name "\\'" BeauName
	set Csv "$TaxId|$Parent|$BeauName"
	lappend LesCreCsv $Csv
    }
    foreach TaxId $LesTaxId {
	set Parent [TaxNCBI $TaxId "Parent"]
	if { ! [info exists TaxIdDejaVu($Name)]} {
	    FaireLire "Parent $Parent of $TaxId $NameDejaVu($TaxId)\ndoesn't exist."
	    continue
	}
    }
    set FicCreCsv [SauveLesLignes $LesCreCsv dans "[RepertoireDuGenome]/createtaxoCre.csv"]
    return $FicCreCsv
} 

proc CreateMsfOfFamiliarOrganismsForAll {} {
    set CreateFiles {}
    set Rep "[RepertoireDuGenome]/msffam"
    if { ! [file exists $Rep]} { file mkdir $Rep }
    foreach Nom [ListeDesPABs] {
	set FamMsfFile "$Rep/$Nom"
	if {[file exists $FamMsfFile]} { continue }
	set FamMsf [MsfOfFamiliarOrganisms $Nom]
	if {$FamMsf==""} { continue }
	Espionne [Sauve $FamMsf dans $FamMsfFile]
	lappend CreateFiles $$FamMsfFile
    }
    return $CreateFiles
}

proc AfficheMsfOfFamiliarOrganisms NomOrigine {
    
    set Nom [file tail $NomOrigine]
    set FamMsf [MsfOfFamiliarOrganisms $Nom]
    if {$FamMsf==""} { return "" }
    return [AfficheVariable $FamMsf "AvecEtudeMSFGrandeLargeur" $NomOrigine]
}

proc MsfOfFamiliarOrganisms Nom {
    set FichierMSF "[RepertoireDuGenome]/msf/$Nom"
    if { ! [file exists $FichierMSF]} { return "" }
    set MSF [ContenuDuFichier $FichierMSF]
    set LesAccess [FamiliarOrganismsInMSF $Nom]
    if {$LesAccess==""} { return "" }
    set PetitMSF [MSFSelection $MSF $LesAccess "In"]
    return $PetitMSF
}

proc FamiliarOrganismsInMSF Nom {

    set Nom [file tail $Nom]
    set FichierMSF "[RepertoireDuGenome]/msf/$Nom"
    DecortiqueUnMSF $FichierMSF LesAccess
    set LesAccessInteressants {}
    foreach Access $LesAccess {
	set TaxIds [TaxIdDuAccess $Access $Nom]
	if {$TaxIds==""} { continue }
	foreach TaxId [split $TaxIds " "] {
	    if {$TaxId==""} { continue }
	    if {[FamiliarTaxId $TaxId]} {
		lappend LesAccessInteressants $Access
		break
	    }
	}
    }
    return $LesAccessInteressants
}

proc TaxIdOfFamiliarOrganisms {} {
    set LesOrgaTaxId {}
    foreach Orga [FamiliarOrganism LaListeMerci] {
	set TaxId [Tax $Orga TaxId]
	if {$TaxId=="" || [regexp "ERROR" $TaxId]} {
	    FaireLire "I can't find TaxId for $Orga. I'll skip"
	    continue
	}
	lappend LesOrgaTaxId "$Orga $TaxId"
    }
    SauveLesLignes $LesOrgaTaxId dans "[RepertoireDuGenome]/fiches/familiar_organism_with_taxid"
    return $LesOrgaTaxId
}

proc EstUnEucaryote TaxId {
    if {[regexp -nocase {[a-z]} $TaxId]} { set TaxId [Tax $TaxId] }

    set Class [TaxClass $TaxId "" "" TaxId] 
    return [regexp " 2759;" $Class]
}

proc EstUneBacterie TaxId {
    if {[regexp -nocase {[a-z]} $TaxId]} { set TaxId [Tax $TaxId] }

    set Class [TaxClass $TaxId "" "" TaxId] 
    return [regexp " 2;" $Class]
}

proc TaxoValide {Liste {Quoi ""}} {
    if {$Quoi == ""} { set Quoi "GetValid" } 
    set LesValides {}
    set LesInconnus {}
    foreach A $Liste {
	if {[Tax $A "TaxId"]==""} {
	    lappend LesInconnus $A
	} else {
	    lappend LesValides $A
	}
    }
    if {[regexp -nocase "Valid" $Quoi]} { return $LesValides }
    return $LesInconnus
}

proc JeSuisDescendantDe {As B} {
    regsub -all {[ \,;\n\t]+} $As "," As
    set As [split [string trim $As ","] ","]
    set iB [Tax $B TaxId]
    foreach A $As {
	set iA [Tax $A TaxId]
	set iC [AncetreCommun $iA $iB]
	Espionne "$iA $iB $iC"
	if {$iC==$iA} { return 1 }
    }
    return 0
}

proc JeSuisTonAncetre {Parent Enfant} {
    #rR petite magouille car les clades excavata et archaeplastida n'existent pas
    set FichierComposition "[RepertoireDuGenome]/bilan/CompositionDuClade$Parent.txt"
    if {[file exists $FichierComposition]} {
	foreach Mot [LesMotsDuTexte [ContenuDuFichier $FichierComposition]] {
	    if {[JeSuisTonAncetre $Mot $Enfant]} { return 1 }
	}
	return 0
    }

    set ParId [Tax $Parent "TaxId"]
    set EnfId [Tax $Enfant "TaxId"]
    if {$ParId=="" || $EnfId==""} { return 0 }
    if {[TaxSystem]=="AK"} {
	#rR Fastoche avec la taxo AK de Arnaud Kress !
	return [Taxo::isAncestor $ParId $EnfId]
    }
	
    set Classe [TaxClass $EnfId "All" "Forward" "TaxId"]
    regsub -all {[ ;]+} $Classe " " Classe
    set LesAncetres [split [string trim $Classe " "]]
    if {[lsearch $LesAncetres $ParId]<0} { return 0 }
    return 1
}

proc Descendant {A B {ForceAncestorFirst ""}} {
    set ForceAncestorFirst [regexp -nocase "first" $ForceAncestorFirst]
    set iA [Tax $A TaxId]
    set iB [Tax $B TaxId]
    set iC [AncetreCommun $iA $iB]
    if {$iC==$iA} { return 1 }
    if {$ForceAncestorFirst} { return 0 }
    if {$iC==$iB} { return 1 }
    return 0
} 

proc AncetreCommunDeLaListe {Liste {Quoi ""}} {
    if {$Quoi=="" || $Quoi=="IdCommun"} { set Quoi "TaxId" }
    set A [lindex $Liste 0]
    set A [Tax $A "TaxId"]
    set LesAutres [lrange $Liste 1 end]
    while {$LesAutres!={}} {
	set B [lindex $LesAutres 0]
	set LesAutres [lrange $LesAutres 1 end]
	set A [AncetreCommun $A $B]
    }
    set R [Tax $A $Quoi]
    return $R
}

proc AncetreCommun {A B {Quoi ""}} {

    Wup "On part des feuilles et on remonte une fois l'un une fois l'autre jusqu'a trouver un commun"

    #if {$Quoi==""} { set Quoi "IdCommun" }
    if {$Quoi==""} { set Quoi "Id" }

    if {[regexp {[^0-9]} $A]} { set A [Tax $A] }
    if {[regexp {[^0-9]} $B]} { set B [Tax $B] }
    if {$A=="" || $B==""} { return "" } 


    if {[TaxSystem]=="AK"} {
	return [Taxo::lastCommonAncestor $A $B $Quoi]
    }

    set ParentsDeA [list $A]
    set ParentsDeB [list $B]

    set AuTourDeA 1
    while 1 {
	set AncetreA [lindex $ParentsDeA end]
	set AncetreB [lindex $ParentsDeB end]
	#Espionne "A=$ParentsDeA/$AncetreA/[Tax $AncetreA]/ B=$ParentsDeB/$AncetreB/[Tax $AncetreB]/"
	if {[set iA [lsearch -exact $ParentsDeA $AncetreB]]>=0} {
	    if {[string equal -nocase $Quoi "IdCommun" ]} { return $AncetreB }
	    if {[string equal -nocase $Quoi "TwoLists" ]} {
		return [list [lrange $ParentsDeA 0 $iA] $ParentsDeB]
	    }
	    return [Tax $AncetreB $Quoi]
	}
	if {[set iB [lsearch -exact $ParentsDeB $AncetreA]]>=0} {
	    if {[string equal -nocase $Quoi "IdCommun" ]} { return $AncetreA }
	    if {[string equal -nocase $Quoi "TwoLists" ]} {
		return [list $ParentsDeA [lrange $ParentsDeB 0 $iB]]
	    }
	    return [Tax $AncetreA $Quoi]
	}
	if {   $AuTourDeA && $AncetreA<=1} { set AuTourDeA 0 }
	if { ! $AuTourDeA && $AncetreB<=1} { set AuTourDeA 1 }
	
	if {$AuTourDeA} {
	    set  AncetreA [Tax $AncetreA "RankedParent"]
	    if {$AncetreA==""} { return "" } 
	    lappend ParentsDeA $AncetreA
	    set AuTourDeA 0
	} else {
	    set  AncetreB [Tax $AncetreB "RankedParent"]
	    if {$AncetreB==""} { return "" } 
	    lappend ParentsDeB $AncetreB
	    set AuTourDeA 1
	}
    }
}

proc TaxIdDuGenomeComplet Banque {
    global TaxIdDuGenomeComplet
    set Banque [string toupper $Banque]
    if {[info exists TaxIdDuGenomeComplet($Banque)]} { return [set TaxIdDuGenomeComplet($Banque)] }
    if {[info exists TaxIdDuGenomeComplet("EstCharge")]} { return "" }

    set FichierTaxIdDuGenomeComplet "[RepertoireDuGenome]/fiches/taxid_des_genomes_complets"
    if { ! [file exists $FichierTaxIdDuGenomeComplet]} {
	set FichierTaxIdDuGenomeComplet "[GscopeDatabaseDir Common]/fiches/taxid_des_genomes_complets"
    }
    if {[file exists $FichierTaxIdDuGenomeComplet]} {
	array set TaxIdDuGenomeComplet [LesLignesDuFichier $FichierTaxIdDuGenomeComplet]
    }

    set FichierTaxIdDuGenomeCompletRR "[RepertoireDuGenome]/fiches/taxid_des_genomes_complets_RR"
    if { ! [file exists $FichierTaxIdDuGenomeCompletRR]} {
	set FichierTaxIdDuGenomeCompletRR "[GscopeDatabaseDir Common]/fiches/taxid_des_genomes_complets_RR"
    }
    if {[file exists $FichierTaxIdDuGenomeCompletRR]} {
	array set TaxIdDuGenomeComplet [LesLignesDuFichier $FichierTaxIdDuGenomeCompletRR]
    }
    foreach {C V} [array get TaxIdDuGenomeComplet] {
	lappend TaxIdDuGenomeComplet(LESNOMS) $C
	lappend TaxIdDuGenomeComplet(LESTAXIDS) $V
    } 
    set TaxIdDuGenomeComplet("EstCharge") 1
    return [TaxIdDuGenomeComplet $Banque]
}

proc RefDuGenomeComplet Banque {
    global RefDuGenomeComplet
    set Banque [string toupper $Banque]
    if {[info exists RefDuGenomeComplet($Banque)]} { return [set RefDuGenomeComplet($Banque)] }
    if {[info exists RefDuGenomeComplet("EstCharge")]} { return "" }

    set FichierRefDuGenomeComplet "[RepertoireDuGenome]/fiches/ref_des_genomes_complets"
    if { ! [file exists $FichierREfDuGenomeComplet]} {
	set FichierRefDuGenomeComplet "[GscopeDatabaseDir Common]/fiches/ref_des_genomes_complets"
    }
    if {[file exists $FichierRefDuGenomeComplet]} {
	array set RefDuGenomeComplet [LesLignesDuFichier $FichierRefDuGenomeComplet]
    }
    set RefDuGenomeComplet("EstCharge") 1
    return [RefDuGenomeComplet $Banque]
}

proc TaxIdDuFichierRef Fichier {
    global TaxIdDuFichierRef
    if {[info exists TaxIdDuFichierRef($Fichier)]} { return [set TaxIdDuFichierRef($Fichier)] }
    if {[info exists TaxIdDuFichierRef("EstCharge")]} { return "" }

    set FichierTaxIdDuFichierRef "/genomics/link/Common/fiches/taxid_du_fichierref"
    array set TaxIdDuFichierRef [LesLignesDuFichier $FichierTaxIdDuFichierRef]
    set TaxIdDuFichierRef("EstCharge") 1
    return [TaxIdDuFichierRef $Fichier]
}

proc BetterTaxId TaxId {
    global BetterTaxId
    if {[info exists BetterTaxId($TaxId)]} { return [set BetterTaxId($TaxId)] }
    if {[info exists BetterTaxId("EstCharge")]} { return $TaxId }

    foreach Ligne [LesLignesDuFichier "/genomics/link/Common/fiches/TaxNCBI/merged.dmp"] {
	scan $Ligne "%s %s %s" Old Bidon New
	set BetterTaxId($Old) $New
    }
    foreach Ligne [LesLignesDuFichier "/genomics/link/Common/fiches/TaxNCBI/better_de_rr.dmp"] {
	scan $Ligne "%s %s" Old New
	set BetterTaxId($Old) $New
    }
    set BetterTaxId("EstCharge") 1
    return [BetterTaxId $TaxId]
}

proc LesTaxIdDesGenomesComplets {} {
    set LesRepAvecFichier {}
    set LesRepAvecTaxId   {}
    foreach FiGBK [concat [glob -nocomplain "/genome/*/*.ref"] [glob -nocomplain "/genome/*/*.gbk"]] {
	Espionne $FiGBK
	set Rep [file tail [file dirname $FiGBK]]
	if {$Rep=="Archaea" || $Rep=="Bacteria" || $Rep=="H.sapiens" || $Rep=="YeastGenome"} { continue }
	lappend LesRepAvecFichier $Rep
	set TaxId ""
	if { ! [info exists LesTaxIdDuRep($Rep)]} { set LesTaxIdDuRep($Rep) {} }
	foreach Ligne [LesLignesIaJDuFichier $FiGBK 1 1000] {
	    if { ! [regexp {/db_xref=\"taxon\:} $Ligne]} { continue }
	    set TaxId [IntegerApres "taxon\:" dans $Ligne]
	    if {$TaxId==""} { continue }
	    set TaxId [BetterTaxId $TaxId]
	    set Organisme [Tax $TaxId]
	    lappend LesTaxIdDuFichierRef($FiGBK) $TaxId
	    if {[info exists FichierDuRep($Rep,$TaxId)]} { lappend FichierDuRep($Rep,$TaxId) $FiGBK ; continue }
	    lappend LesRepAvecTaxId $Rep
	    lappend FichierDuRep($Rep,$TaxId) $FiGBK
	    lappend LesTaxIdDuRep($Rep) $TaxId
	    break 
	}
    }

    foreach FiGBK [array names LesTaxIdDuFichierRef] {
	set LesT [set LesTaxIdDuFichierRef($FiGBK)]
	if {[llength LesT]>1} {
	    FaireLire "I found more than 1 TaxId for $FiGBK\n[join $LesT " "]"
	}
	set LesTaxIdDuFichierRef($FiGBK) [lsort -u [set LesTaxIdDuFichierRef($FiGBK)]]
	Espionne [SauveLesLignes [array get LesTaxIdDuFichierRef] dans "/genomics/link/Common/fiches/taxid_du_fichierref"]
    }

    foreach Rep [lsort -unique $LesRepAvecFichier] {
	if {[set LesTaxIdDuRep($Rep)]=={}} {
	    lappend LesPauvres "Rep sans TaxId $Rep"
	    Espionne "Rep sans TaxId $Rep"
	}
    }
    foreach Rep [lsort -unique $LesRepAvecTaxId] {
	if {[llength [set LesTaxIdDuRep($Rep)]]==1} {
	    set TaxId [lindex [set LesTaxIdDuRep($Rep)] 0]
	    lappend LesBons "\n$Rep $TaxId [Tax $TaxId]"
	    continue
	}
	lappend LesMultis "\n$Rep [join [set LesTaxIdDuRep($Rep)] " "]" 
	foreach TaxId [set LesTaxIdDuRep($Rep)] {
	    lappend LesMultis "   $TaxId [Tax $TaxId]"
	    lappend LesMultis [join [set FichierDuRep($Rep,$TaxId)] "\n"]
	}
    }
    Espionne [SauveLesLignes $LesBons    dans "/genomics/link/Common/fiches/les_genomes_un_taxid"]
    Espionne [SauveLesLignes $LesPauvres dans "/genomics/link/Common/fiches/les_genomes_sans_taxid"]
    Espionne [SauveLesLignes $LesMultis  dans "/genomics/link/Common/fiches/les_genomes_multi_taxid"]
    exit
}

proc RecupereLesVraisEmbls {} {
    foreach Ligne [LesLignesDuFichier "[RepertoireDuGenome]/fiches/original_description"] {
	regsub -all {[\:\|]} $Ligne " " Ligne
	scan $Ligne "%s %s %s %s %s" PAB b c d Access
	set AccessDuEmbl($PAB) $Access
    }
    foreach Nom [ListeDesPABs] {
	Espionne $Nom
	set Narcisse [Narcisse $Nom]
	set Access   [set AccessDuEmbl($Nom)]
	if { ! [string equal -nocase $Narcisse $Access]} { Espionne "$Nom $Narcisse $Access" }
	set Embl [join [LaSequenceDesBanques $Access $Access a "OnVeutEMBL"] "\n"]
	if {$Embl==""} { Espionne "$Access introuvable" ; continue }
	set Tfa [SequenceFormatTFA $Embl $Access "embl"]
	set SaSeq [QueLaSequenceDuTexteTFA $Tfa]
	set MaSeq [QueLaSequenceDuTFA "[RepertoireDuGenome]/prottfa/$Nom"]
	if {$MaSeq!=$SaSeq} { Espionne "$Nom\n$MaSeq\n$SaSeq" }
	Sauve $Embl dans "[RepertoireDuGenome]/protemblnew/$Nom"
    }
    exit
}

proc TaxIdDuTexteEmbl Embl {
    foreach Ligne [split $Embl "\n"] {
	if { ! [regexp {^OX   } $Ligne]} { continue }
	set TaxId [StringSuivant "NCBI_TaxID=" dans $Ligne]
	regsub -all {[\.\;\,]} $TaxId " " TaxId
	set TaxId [string trim $TaxId]
	if { ! [regexp {^[0-9 ]+$} $TaxId]} {
	    FaireLire "The Embl file contains following OX line\n$Ligne\n\nPlease help me ..."
	    set TaxId [Entre $TaxId]	    
	}
	while {[regexp -all "  " $TaxId]} { regsub -all "  " $TaxId " " TaxId }
	return $TaxId
    }
    return ""
}

proc TaxIdDuAccess {Access {Nom ""}} {
    if {$Nom!=""} {
	set TaxId [TaxIdDuMacsim $Access $Nom]
	if {$TaxId!=""} { return $TaxId }
	set TaxId [ChampDaedalus "OX" $Access $Nom ]
	if {$TaxId!=""} { return $TaxId }
	set Descriptif [LeDescriptif $Access $Nom]
	set TaxId [ChampDuDescriptif $Descriptif "OX"]
	if {$TaxId!=""} { return $TaxId }
	return ""
    }
    set Embl [join [LaSequenceDesBanques $Access $Access a "OnVeutEMBL"] "\n"]
    if {$Embl!=""} { return [TaxIdDuTexteEmbl $Embl] }

    Espionne "Je n'ai pas trouve LaSequenceDesBanques $Access"
    return ""
}

proc TaxIdDuPAB Nom {
    global TaxIdDuPAB
    if {[info exists TaxIdDuPAB($Nom)]} { return [set TaxIdDuPAB($Nom)] }
    if {[info exists TaxIdDuPAB("EstCharge")]} { return "" }

    set FichierTaxIdDuPAB "[RepertoireDuGenome]/fiches/taxiddespabs"
    if {[file exists $FichierTaxIdDuPAB]} {
	array set TaxIdDuPAB [LesLignesDuFichier $FichierTaxIdDuPAB]
	set TaxIdDuPAB("EstCharge") 1
	return [TaxIdDuPAB $Nom]
    }

    while { ! [OuiOuNon "Do I create TaxIdDesPABs ?"]} {
	if {[OuiOuNon "Do I create an empty file ?\n(You can delete it later and run this prog again)"]} {
	    SauveLesLignes {} dans FichierTaxIdDuPAB
	    return ""
	}
	if {[OuiOuNon "Do I cancel TaxIdDuPAB ?"]} { return "" }	
    }

    set TaxIdDuPAB("EstCharge") 1
	set Sql "insert (pk_into taxonomy values ($TaxId, DEFAULT, $Name)"
	lappend LesSql $Sql

    if {[OuiOuNon "Do I search in OX field from protembl ?"]} {
	foreach PAB [ListeDesPABs] {
	    set Embl [ContenuDuFichier "[RepertoireDuGenome]/protembl/$PAB"]
	    set TaxIdDuPAB($PAB) [TaxIdDuTexteEmbl $Embl]
	}
    }

    SauveLesLignes [array get TaxIdDuPAB] dans $FichierTaxIdDuPAB
    return [TaxIdDuPAB $Nom]
}

proc TestTaxClass {} {
    Espionne [TaxClass 9606]
    Espionne [TaxClass 9606]
    Espionne [TaxClass 9605]
    Espionne [TaxClass 9606 "" "" Name]
    Espionne [TaxClass 9606 "" "" Rank]
    Espionne [TaxClass 9606 "" "" All]
    Espionne [TaxClass 9606 "" "" Name]
    exit
}

proc TestTaxClassBis {} {
    set Ts [TaxClass 9606 TaxId]
    set Ns [TaxClass 9606 Name]
    foreach T [split $Ts ";"] {
	set T [string trim $T]
	Espionne "$T [Tax $T]"
    }
    exit
}

proc TaxClass {Query {AllOrRankOnly ""} {Reverse ""} {Quoi ""}} {
    #rR ATTENTION suivant TaxSystem on utilise TaxAK de Arnaud Kress
    global TaxClass
    #rR sauf pour AK on parcourt recursivement les classes ... mais on stocke en memoire ce qui a deja ete vu

    regsub -all "_" $Query " " Query
    if {[regexp "^ERROR" $Query]} { return $Query }
    if {$Query==""} { return "" }
    if {$Query=="IsAlreadyLoaded"} {
	if {[TaxSystem]=="TaxAK"} { return 1 }
	return [info exists TaxClass]
    }
    if {[regexp -nocase {[a-z]} $Query]} { set Query [Tax $Query TaxId] }

    #rR c'était tellement le bordel !!! là on se fout de l'ordre des arguments 
    if {[regexp -nocase "TaxId" "$AllOrRankOnly $Reverse $Quoi"]} { set Quoi "TaxId" }
    if {[regexp -nocase "Name"  "$AllOrRankOnly $Reverse $Quoi"]} { set Quoi "Name" }
    if {[regexp -nocase "Rev"   "$AllOrRankOnly $Reverse $Quoi"]} { set Reverse "Reverse" }
    if {[regexp -nocase "For"   "$AllOrRankOnly $Reverse $Quoi"]} { set Reverse "Forward" }

    #if {[regexp -nocase "Name" $AllOrRankOnly]} { set Quoi "Name"; set AllOrRankOnly "" }
    #if {[regexp -nocase "Name" $Reverse]}       { set Quoi "Name"; set Reverse "" }

    #if {$Quoi==""} { set Quoi "TaxId" }
    #if {[regexp -nocase "Name" $Quoi]} { set Quoi "Name" }

    #if {[regexp -nocase "Rev"          $Reverse]      } { set Reverse "Reverse" } else { set Reverse "Forward" }
    if {[regexp -nocase "RankOnly|Rank" $AllOrRankOnly]} { set AllOrRankOnly "RankOnly" } else { set AllOrRankOnly "All" }
    if {$AllOrRankOnly==""} { set AllOrRankOnly "All" }

    #rR Traitement spécial si on utilise le Tax de Arnaud Kress qui va très vite ...
    if {[TaxSystem]=="AK"} {
	set TaxClass("OnFaitCommeSiIlEtaitCharge") 1
	#set LaClasse [TaxAK $Query lineage $Quoi $Reverse] .......................... faudrait corriger Taxo de AK
	#set Start 1 ; set Debut "; "
	#rR je ne sais pas s'il faut mettre root en début ? ........................... 2021/03/12
	set LaClasse [TaxAK $Query lineage $Quoi]
	set Start 0 ; set Debut ""
	if {[regexp -nocase "rev" $Reverse]} { set LaClasse [lreverse $LaClasse] }
	if {[regexp -nocase "rev" $Reverse]} { set Start 0 ; set Debut "" }
	set Classe "$Debut[join [lrange $LaClasse $Start end] {; }]"
	return $Classe
    }

    if {[info exists TaxClass($Query,$AllOrRankOnly,$Reverse,$Quoi)]} {
	 return [set TaxClass($Query,$AllOrRankOnly,$Reverse,$Quoi)]
    }

    set  Moi $Query
    if {$Moi==1} { return [Tax $Moi $Quoi]}
    set  Moi [Tax $Moi $Quoi]

    set Parent [Tax $Query "Parent"]
    set Ancetres [TaxClass [Tax $Query "Parent"] $AllOrRankOnly $Reverse $Quoi]
    if {[regexp -nocase "Rank" $AllOrRankOnly] && [Tax $Query "Rank"]=="no rank"} {
	return $Ancetres
    } 
    if {[string equal -nocase $Reverse "Reverse"]} {
	set Class "$Moi; $Ancetres"
    } else {
	set Class "$Ancetres; $Moi"
    }
    set TaxClass($Query,$AllOrRankOnly,$Reverse,$Quoi) $Class
    return $Class
}

proc TaxGetz {Query {Quoi ""}} {

    regsub -all "_" $Query "" Query

    set RankOnly 0
    if {$Quoi=="RankedParent"} { set Quoi "Parent" ; set RankOnly 1 }

    if {$Quoi==""} {
	set Quoi "TaxId"
	if {[regexp -nocase {^[0-9]+$} $Query]} { set Quoi "Name" }
    }

    if {[string equal -nocase $Quoi "ID"]}   { set Quoi "TaxId" }
    if {[string equal -nocase $Quoi "Name"]} { set Quoi "Name" }

    set ChampQuery "Taxon"
    if {[regexp -nocase {^[0-9]+$} $Query]} { set ChampQuery "ID" }
Espionne "getz -e \[TAXONOMY-$ChampQuery:$Query\]"
    if {[catch {set Reponse [exec getz -e \[TAXONOMY-$ChampQuery:$Query\]]} Message]} {
	regsub -all "\n" $Message " " Message
#	return "error from getz : $Message"
    }
    foreach Ligne [split $Reponse "\n"] {
	set Var ""
	if {[regexp -nocase {^ID *\: *}              $Ligne Match]} { set Var "TaxId" } 
	if {[regexp -nocase {^PARENT ID *\: *}       $Ligne Match]} { set Var "Parent" } 
	if {[regexp -nocase {^RANK *\: *}            $Ligne Match]} { set Var "Rank" } 
	if {[regexp -nocase {^GC ID *\: *}           $Ligne Match]} { set Var "GCID" } 
	if {[regexp -nocase {^MGC ID *\: *}          $Ligne Match]} { set Var "MGCID" } 
	if {[regexp -nocase {^SCIENTIFIC NAME *\: *} $Ligne Match]} { set Var "Name" } 
	if {[regexp -nocase {^SYNONYM *\: *}         $Ligne Match]} { set Var "Synonym" } 
	if {[regexp -nocase {^EQUIVALENT NAME *\: *} $Ligne Match]} { set Var "Equiv" } 
	if {$Var==""} { continue }
	set Info [StringSuivant ":" dans $Ligne]
	set $Var [string trim $Info]
#	regsub $Match $Ligne "" $Var
#	set $Var [string trim [set $Var]]
    }
    if {[info exists $Quoi]} {
	if {$RankOnly && $Parent>1 && [TaxGetz $Parent Rank]=="no rank"} { return [TaxGetz $Parent "RankedParent"] }
	return [set $Quoi]
    }
    return "ERROR in TaxGetz $Query $Quoi I got $Reponse"
}

proc BrowseTaxNCBI {{Texte ""} {Quoi ""}} {

    if {[regexp "\n" $Texte]} {
	foreach Ligne [split $Texte "\n"] {
	    if { ! [regexp -nocase {[a-z0-9]} $Ligne]} { continue }
	    BrowseTaxNCBI $Ligne $Quoi
	}
	return
    }

    if {$Texte==""} { set Texte "AskForAction" }

    if {$Texte=="AskForAction"} {
	lappend LesActions "Ask for a node ..."
	lappend LesActions "BrowseTaxNCBI List Queries"
	lappend LesActions "BrowseTaxNCBI 1 TaxId"
	lappend LesActions "BrowseTaxNCBI 9606 Parent"
	lappend LesActions "CreateSqlTaxonomy ShowOnly"
	lappend LesActions "CreateSqlTaxonomy"
	set Action [ChoixParmi $LesActions]
	if {$Action==""} { return "" }
	if {[regexp "^Ask " $Action]} {
	    set Texte [Entre "9606"]
	    return [BrowseTaxNCBI $Texte $Quoi]
	}
	return [eval $Action]
    }

    if {$Quoi==""} {
	set Quoi [ChoixParmi [TaxNCBI List Queries]]
    }
    if {$Quoi==""} { return "" }

    scan $Texte "%s" Id
    if {[regexp {^[0-9]+$} $Id]} { set BonTexte $Id } else { set BonTexte $Texte }  
    set V [TaxNCBI $BonTexte $Quoi]
    if {[regexp "^Its" $Quoi]} {
	set LesVs $V
    } else {
	set LesVs [list $V]
    }
    set LeNouveauTexte {}
    foreach V $LesVs {
	if {[regexp {^[0-9]+$} $V]} {
	    set Noeud $V
	    set LesNoeuds [list [TaxNCBI $Noeud Name]]
	    if {[info exists DejaVu]} { unset DejaVu }
	    set DejaVu($Noeud) 1
	    while 1 {
		if {$Noeud==1} { break }
		set Parent [TaxNCBI $Noeud Parent]
		set NomDuNoeudParent [TaxNCBI $Parent Name]
		lappend LesNoeuds $NomDuNoeudParent
		set Noeud $Parent
		if {[info exists DejaVu($Noeud)]} { break }
		set DejaVu($Noeud) 1
	    }
	    set Classe [join $LesNoeuds ";"]
	    set BeauV "$V $Classe"
	} else {
	    set BeauV $V
	}
	lappend LeNouveauTexte $BeauV
    }
    if {$LeNouveauTexte=={}} { return "" }
    set NouveauTexte [join $LeNouveauTexte "\n"]
    set Fen [AfficheVariable $NouveauTexte "AvecTaxNCBI"]
    Illumine "" $Fen
    return $Fen
}

proc OsOcParTaxNCBI {{Action ""}} {
    set LeTout {}
    foreach Name [TaxNCBI "ListOf" "Names"] {
	set Class [TaxClass $Name "All" "Forward" "Name"]
	lappend LeTout $Name $Class
    }
    return [SauveLesLignes $LeTout dans "[TaxDir]/OsOcParTaxNCBI.txt"]
}

proc OCduOS {OS {OS2 ""}} {
    global OCduOS
    global OrthographeCanoniqueInverse

    if {$OS2!=""} { set OS "$OS $OS2" }

    return [TaxClass $OS "" Names]

    set OS [string toupper $OS]
    regsub -all "_" $OS " " OS

    if {[info exists OCduOS($OS)]} {
	set C [set OCduOS($OS)]
	regsub {^root; cellular organisms; } $C "" C
	return $C
    }
    if {[info exists OCduOS("EstCharge")]} {
	if {[regexp -nocase {([A-Z][a-z]+) sp\.?$} $OS Match OSwithoutSP]} { return [OCduOS $OSwithoutSP] } 
	return "ClassUnknown"
	set TaxClass [TaxClass $OS "" "" name]
	if {$TaxClass!=""} { regsub {^root; *} $TaxClass "" TaxClass ; return $TaxClass }
	return "ClassUnknown"
    }
    set OCduOS("EstCharge") 1

#    set AL "ALVINELLA POMPEJANA"
#    set OCduOS($AL) "Eukaryota; Metazoa; Annelida; Polychaeta; Palpata; Canalipalpata; Terebellida; Alvinellidae; Alvinella."


    set FichierLesOSOCsDeQuidSeq "/biolo/wscope/quidseq/lesosocs"
    Espionne $FichierLesOSOCsDeQuidSeq
    if {[file exists $FichierLesOSOCsDeQuidSeq]} {
	set n 0
	foreach Ligne [LesLignesDuFichier $FichierLesOSOCsDeQuidSeq] {
	    incr n
	    set OC "ClassUnknown"
	    ScanLaListe [split $Ligne ":"] OSlu OC
	    set OSlu [string toupper $OSlu]
	    set OCduOS($OSlu) $OC
	    lappend OCduOS("LaListeMerci") $OSlu
	}
	foreach Good [array names OrthographeCanoniqueInverse] {
	    if {[info exists OCduOS($Good)]} { Espionne [set OCduOS($Good)] ; continue }
	    foreach Bad [set OrthographeCanoniqueInverse($Good)] {
		set BAD [string toupper $Bad]
		if {[info exists OCduOS($BAD)]} {
		    set OCduOS([string toupper $Good]) [set OCduOS($BAD)]
		    continue
		}
	    }
	}
	set OCduOS(SOURCE) "gscope_glossaire.classes"
	return [OCduOS $OS]
    }

    set FichierOsOcParTaxId "/genomics/link/Common/fiches/TaxNCBI/OsOcParTaxNCBI.txt.gz"
    if {[file exists $FichierOsOcParTaxId]} {
	array set OCduOS [LesLignesDuFichier $FichierOsOcParTaxId]
	foreach {S C} [array get OCduOS] {
	    set OCduOS([string toupper $S]) $C
	}
	set OCduOS(SOURCE) "TaxNCBI"
	set OCduOS("EstCharge") 1
	return [OCduOS $OS]
    }

    foreach Ligne [LesLignesDuFichier "[GscopeEtc]/gscope_glossaire.classes"] {
	scan $Ligne "%s %s" G E
	regsub "^$G $E " $Ligne "" C
	set O [string toupper "$G $E"]
	if { ! [info exists OCduOS($O)] || $OCduOS($O)=="ClassUnknown"} {
	    set OCduOS($O) $C
	}
    }
    set OCduOS(SOURCE) "gscope_glossaire.classes"

    
    #return [OCduOS $OS]
    if {[info exists OCduOS($OS)]} {
	return [set OCduOS($OS)]
    } else {
	return "ClassUnknown"
    }
}

proc TaxDir {{system ""}} {
    if {$system==""} { set system "UniProt" }
    #rR 20191018 set TaxDir "[GscopeDatabaseDir Common]/fiches/Tax$system"
    set TaxDir "/commun/banbi/taxonomy/production"
    return $TaxDir
}

proc TaxNCBI {TaxId {Quoi ""} {Value ""}} {
    global TaxNCBI

    #rR je ne sais pas pourquoi il n'y a pas de ranked comme dans Getz
    if {$Quoi=="RankedParent"} { set Quoi "Parent" }

    set TaxId [string map [list "_" " "] $TaxId]

    if {$Quoi==""} {
	set Quoi "TaxId"
	if {[regexp -nocase {^[0-9]+$} $TaxId]} { set Quoi "Name" }
    }

    if {$Value==""} { set Value "GetValue" }
    if {[string equal -nocase $Value "GetValue"]} {
	if {[info exists TaxNCBI($TaxId,$Quoi)]} { return [set TaxNCBI($TaxId,$Quoi)] }
	if { ! [info exists TaxNCBI("EstCharge")]} {
	    LoadTaxNCBI
	    return [TaxNCBI $TaxId $Quoi $Value]
	}   
	if {$Quoi=="Deleted"} { return 0 }
	if {($Quoi=="Name" || $Quoi=="Parent" || $Quoi=="Children"  || $Quoi=="ItsNames")\
		&& ! [regexp {^[0-9]+$} $TaxId]} {
	    set TNCBI [TaxNCBI $TaxId TaxId]
	    if {$TNCBI==""} { return "" }
	    return [TaxNCBI $TNCBI $Quoi]
	}
	set MAJUSCULE [string toupper $TaxId]
	if {[info exists TaxNCBI($MAJUSCULE,OriginalCase)] \
		&& [info exists TaxNCBI($TaxNCBI($MAJUSCULE,OriginalCase),$Quoi)]} {
	    return $TaxNCBI($TaxNCBI($MAJUSCULE,OriginalCase),$Quoi)
	}
	return ""
    }
    set TaxNCBI("EstCharge") 1

    #rR ***************************************** il faut =value **************
    if { ! [regexp "^=" $Value]} { return "" } 
    set Value [string map [list "=" ""] $Value]

    if { ! [info exists TaxNCBI(Query,$Quoi)]} {
	set TaxNCBI(Query,$Quoi) 1
	lappend TaxNCBI(List,Queries) $Quoi
    }
    if {[string equal -nocase $Value "ResetValue"]} {
	if {[info exists TaxNCBI($TaxId,$Quoi)]} {
	    set V [set TaxNCBI($TaxId,$Quoi)] 
	    unset TaxNCBI($TaxId,$Quoi)
	}
	return $V
    }

    if {$TaxId=="SortUnique" && $Quoi=="ListOf" && $Value=="Names"} {
	set TaxNCBI(ListOf,Names) [lsort -unique $TaxNCBI(ListOf,Names)]
	return 1
    }

    set MAJUSCULE [string toupper $TaxId]
    set TaxNCBI($MAJUSCULE,OriginalCase) $TaxId

    if {$TaxId=="ListOf" && $Quoi=="Names"} {
	lappend TaxNCBI(ListOf,Names) $Value
	return $Value
    }

    if {$Quoi=="ItsNames" || $Quoi=="ItsTaxIds" || $Quoi=="Children"} {
	lappend TaxNCBI($TaxId,$Quoi) $Value
	return [set TaxNCBI($TaxId,$Quoi)]
    }
    set TaxNCBI($TaxId,$Quoi) $Value
    if {$Quoi=="Name"} {
	if { ! [info exists TaxNCBI($TaxId,exists)]} {
	    set TaxNCBI($TaxId,exists) 1
	    lappend TaxNCBI(List,TaxId) $TaxId
	}
    }
    return $Value
}

proc LoadTaxNCBI {} {
    #rR on lit le fichier et on stocke tout en utilisant TaxNCBI Qui Quoi =Valeur
    #rR j'ai rajoute le = obligatoire pour modifier la valeur 2012/04/10
    set TaxDir [TaxDir "NCBI"]
    set Fichier "$TaxDir/delnodes.dmp"
    set f [open $Fichier "r"]
    while {[gets $f Ligne]>=0} {
	set LesChamps [split $Ligne "\t"]
	ScanLaListe $LesChamps TaxId
	TaxNCBI $TaxId Deleted "=1"
    }
    close $f

    set Fichier "$TaxDir/merged.dmp"
    set f [open $Fichier "r"]
    while {[gets $f Ligne]>=0} {
	regsub -all "\t" $Ligne "" Ligne
	set LesChamps [split $Ligne "|"]
	ScanLaListe $LesChamps TaxId Nouveau
	TaxNCBI $TaxId Merged "=$Nouveau"
    }
    close $f

    set Fichier "$TaxDir/nodes.dmp"
    set f [open $Fichier "r"]
    while {[gets $f Ligne]>=0} {
	regsub -all "\t" $Ligne "" Ligne
	set LesChamps [split $Ligne "|"]
	ScanLaListe $LesChamps TaxId Parent Rank Embl Division
	TaxNCBI $Parent Children "=$TaxId"
	TaxNCBI $TaxId  Parent   "=$Parent"
	TaxNCBI $TaxId  Rank     "=$Rank"
#	TaxNCBI $TaxId  Embl     "=$Embl"
#	TaxNCBI $TaxId  Division "=$Division"
    }
    close $f

    Espionne "Chargement $TaxDir/names.dmp"
    set Fichier "$TaxDir/names.dmp"
    set f [open $Fichier "r"]
    set nTaxId 0
#    set iMaxPourTest 999
    set iMaxPourTest -1
    while {[gets $f Ligne]>=0} {
	if {[incr iMaxPourTest -1]%10000==0} { Espionne $Ligne }
	if {[incr iMaxPourTest -1] == 0} { break }
	regsub -all "\t" $Ligne "" Ligne
	set LesChamps [split $Ligne "|"]
	ScanLaListe $LesChamps TaxId Name UniqueName NameClass
	if {$TaxId=="1890940"} { Espionne $Ligne } 
	if {[info exists DejaVu($Name)]} { lappend LesDoublons $Name }
	set DejaVu($Name) 1
	TaxNCBI $TaxId TaxId    "=$TaxId"
	TaxNCBI $TaxId ItsNames "=$Name"
	if {$UniqueName!=""} {
	    TaxNCBI $TaxId UniqueName "=$UniqueName"
	    TaxNCBI $Name  ItsTaxIds  "=$TaxId"
	}
	TaxNCBI $Name TaxId     "=$TaxId"
	TaxNCBI $Name NameClass "=$NameClass"
	if {[string equal -nocase $NameClass "scientific name"]} {
	    incr nTaxId
	    TaxNCBI $TaxId Name "=$Name"
	}
	TaxNCBI "ListOf" "Names" "=$Name"
    }
    TaxNCBI "SortUnique" "ListOf" "=Names"   ;#rR attention il faut aussi le =
    close $f
    set LesDoublons [lsort $LesDoublons]
    
#    SauveLesLignes $LesDoublons dans "$TaxDir/DoublonsNames.txt"
    return $nTaxId
}

proc TestNCBINames {} {
    set Fichier "./names.dmp"
    set f [open $Fichier "r"]
    set nTaxId 0
#    set iMaxPourTest 999
    set iMaxPourTest -1
    while {[gets $f Ligne]>=0} {
	if {[incr iMaxPourTest -1]%1000==0} { Espionne $Ligne }
	if {[incr iMaxPourTest -1] == 0} { break }
	regsub -all "\t" $Ligne "" Ligne
	set LesChamps [split $Ligne "|"]
	ScanLaListe $LesChamps TaxId Name UniqueName NameClass
	if {$TaxId=="1890940"} { Espionne $Ligne } 
	if {[info exists DejaVu($Name)]} { lappend LesDoublons $Name }
	set DejaVu($Name) 1
	TaxNCBI $TaxId TaxId    "=$TaxId"
	TaxNCBI $TaxId ItsNames "=$Name"
	if {$UniqueName!=""} {
	    TaxNCBI $TaxId UniqueName "=$UniqueName"
	    TaxNCBI $Name  ItsTaxIds  "=$TaxId"
	}
	TaxNCBI $Name TaxId     "=$TaxId"
	TaxNCBI $Name NameClass "=$NameClass"
	if {[string equal -nocase $NameClass "scientific name"]} {
	    incr nTaxId
	    TaxNCBI $TaxId Name "=$Name"
	}
	TaxNCBI "ListOf" "Names" "=$Name"
    }
}

proc DoublonsDansTaxUniProt {} {
    #rR C'est la merde absolue ..................................
    #rR les noms des noeuds ne sont pas uniques
    #rR IL y a 2 Craniata et 2 Vertebrata

    set UrlPourLaMiseAJour "http://www.uniprot.org/taxonomy/?query=&force=yes&format=tab"

    set TaxDir [TaxDir "UniProt"]
    set Fichier "$TaxDir/taxonomy-all.tab"
    set f [open $Fichier "r"]
    set PrendPremiereLigne 0
    while {[gets $f Ligne]>=0} {
	if {! $PrendPremiereLigne} {
	    #lM premiere ligne contient les noms des champs
	    # Taxon | Mnemonic | Scientific name | Common name | Synonym | Other Names | Reviewed | Rank | Lineage | Parent
	    set PrendPremiereLigne 1
	    continue
	}
	
	set LesChamps [split $Ligne "\t"]
	lassign $LesChamps TaxId Mnemonic Name CommonName Synonym OtherNames Reviewed Rank Lineage Parent
	if {$Name==""} { continue }
	if {[string trim $Rank] eq ""} {
	    set Rank "no rank"
	}
	if {[info exists DejaVu($Name)]} {
	    lappend LesDoublons $Name
	    if { ! [regexp environment $Name]} {
		Espionne "\n[join $DejaVu($Name) \n]\n$Ligne"
	    }
	}
	lappend DejaVu($Name) $Ligne 
    }
    return 
}

proc LoadTaxUniProt {{TaxDir ""}} {
    global TaxUniProt
    #rR on lit le fichier et on stocke tout en utilisant TaxUniprot Qui Quoi =Valeur
    #rR Attention il y a des doublons pour les nom de noeud !!!!!!!!!!!
    #rR J'ai mis en dur Vertebrata et Craniata voir ci-dessous !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

    if {$TaxDir==""} { set TaxDir [TaxDir "UniProt"] }

    #rR set Fichier               "$TaxDir/taxonomy-all.tab"
    #rR set FichierTaxUniProtMemo "$TaxDir/taxonomy-all.arraytcl"
    set Fichier               "$TaxDir/taxonomy.dat"
    set FichierTaxUniProtMemo "$TaxDir/taxonomy.arraytcl"

    if {[file exists $FichierTaxUniProtMemo]} {
	if {[file mtime $Fichier] < [file mtime $FichierTaxUniProtMemo]} {
	    array set TaxUniProt [ContenuDuFichier $FichierTaxUniProtMemo]
	    return $FichierTaxUniProtMemo
	}
    }


    set UrlPourLaMiseAJour "http://www.uniprot.org/taxonomy/?query=&force=yes&format=tab"

    TaxUniProt 1       TaxId     "=1"
    TaxUniProt 1       Name      "=root"
    TaxUniProt "root"  TaxId     "=1"
    TaxUniProt "root"  Name      "=root"
    
    TaxUniProt 1       ItsTaxIds "=1"
    TaxUniProt 1       ItsNames  "=root"
    TaxUniProt "root"  ItsTaxIds "=1"
    TaxUniProt "root"  ItsNames  "=root"
    
    TaxUniProt 1       Rank      "=no rank"
    
    TaxUniProt 1       Children  "=10239"
    TaxUniProt 1       Children  "=12884"
    TaxUniProt 1       Children  "=12908"
    TaxUniProt 1       Children  "=28384"
    TaxUniProt 1       Children  "=131567"
    
    TaxUniProt  10239  Parent    "=1"
    TaxUniProt  12884  Parent    "=1"
    TaxUniProt  12908  Parent    "=1"
    TaxUniProt  28384  Parent    "=1"
    TaxUniProt 131567  Parent    "=1"

    set f [open $Fichier "r"]
    set PrendPremiereLigne 0
    while {[gets $f Ligne]>=0} {
	if {! $PrendPremiereLigne} {
	    #lM premiere ligne contient les noms des champs
	    # Taxon | Mnemonic | Scientific name | Common name | Synonym | Other Names | Reviewed | Rank | Lineage | Parent
	    set PrendPremiereLigne 1
	    continue
	}
	
	set LesChamps [split $Ligne "\t"]
	lassign $LesChamps TaxId Mnemonic Name CommonName Synonym OtherNames Reviewed Rank Lineage Parent
	if {[string trim $Rank] eq ""} {
	    set Rank "no rank"
	}
	
	if {[info exists DejaVu($Name)]} {
	    Espionne "$Name $DejaVu($Name)"
	    set DejaVu($Name) $Ligne
	}
	
	TaxUniProt $TaxId  TaxId     "=$TaxId"
	TaxUniProt $TaxId  Name      "=$Name"
	TaxUniProt $Name   TaxId     "=$TaxId"
	TaxUniProt $TaxId  ItsNames  "=$Name"
	TaxUniProt $Name   ItsTaxIds "=$TaxId"
	TaxUniProt $TaxId  Rank      "=$Rank"
	TaxUniProt $TaxId  Lineage   "=$Lineage"
	TaxUniProt $TaxId  Parent    "=$Parent"
	TaxUniProt $Parent Children  "=$TaxId"

	TaxUniProt "ListOf" "Names" "=$Name"
    }
    TaxUniProt "SortUnique" "ListOf" "=Names"   ;#rR attention il faut aussi le =

    close $f

    TaxUniProt Vertebrata   TaxId     "=7742"
    TaxUniProt Craniata     TaxId     "=89593"
    set TaxUniProt(Vertebrata,TaxId) 7742
    set TaxUniProt(Craniata,TaxId)  89593
    Sauve [array get TaxUniProt] dans $FichierTaxUniProtMemo

    return $Fichier
}

proc TaxAK {TaxId {Quoi ""} {Quid ""} {Quid2 ""}} {
    global TaxAK

    if {$Quoi=="RankedParent"} { set Quoi "Parent" }

    set Quoi [string tolower $Quoi]
    if {$Quoi=="taxid"} { set Quoi "id" }

    set TaxId [string map [list "_" " "] $TaxId]

    if {$TaxId=="ListOf"} {
	return [Taxo::request "select distinct($Quoi) from taxon order by quoi"]
    }
    if {$Quoi=="AllDescendants"} {
	return [Taxo::getAllDescendants $TaxId $Quid $Quid2]
    }
    if {$Quoi=="TaxId"} { set Quoi "" }                  ; #rR 2021/03/12 pour TaxClass ********************** 
    set Reponse [Taxo::get $TaxId $Quoi $Quid $Quid2]
    return $Reponse
}

proc TaxUniProt {TaxId {Quoi ""} {Value ""}} {
    global TaxUniProt
    #lM a repris TaxNCBI et l'a change pour faire UniProt taxonomy

    #rR je ne sais pas pourquoi il n'y a pas de ranked comme dans Getz
    if {$Quoi=="RankedParent"} { set Quoi "Parent" }

    set TaxId [string map [list "_" " "] $TaxId]

    if {$Quoi==""} {
	set Quoi "TaxId"
	if {[regexp -nocase {^[0-9]+$} $TaxId]} { set Quoi "Name" }
    }

    if {$Value==""} { set Value "GetValue" }
    if {[string equal -nocase $Value "GetValue"]} {
	if {[info exists TaxUniProt($TaxId,$Quoi)]} { return [set TaxUniProt($TaxId,$Quoi)] }
	if { ! [info exists TaxUniProt("EstCharge")]} {
	    LoadTaxUniProt
	    return [TaxUniProt $TaxId $Quoi $Value]
	}   

	if {($Quoi=="Name" || $Quoi=="Parent" || $Quoi=="Children"  || $Quoi=="ItsNames")\
		&& ! [regexp {^[0-9]+$} $TaxId]} {
	    return [TaxUniProt [TaxUniProt $TaxId TaxId] $Quoi]
	}
	set MAJUSCULE [string toupper $TaxId]
	if {[info exists TaxUniProt($MAJUSCULE,OriginalCase)] \
		&& [info exists TaxUniProt($TaxUniProt($MAJUSCULE,OriginalCase),$Quoi)]} {
	    return $TaxUniProt($TaxUniProt($MAJUSCULE,OriginalCase),$Quoi)
	}
	return ""
    }
    set TaxUniProt("EstCharge") 1

    #rR ***************************************** il faut =value **************
    if { ! [regexp "^=" $Value]} { return "" } 
    set Value [string map [list "=" ""] $Value]

    if { ! [info exists TaxUniProt(Query,$Quoi)]} {
	set TaxUniProt(Query,$Quoi) 1
	lappend TaxUniProt(List,Queries) $Quoi
    }
    if {[string equal -nocase $Value "ResetValue"]} {
	if {[info exists TaxUniProt($TaxId,$Quoi)]} {
	    set V [set TaxUniProt($TaxId,$Quoi)] 
	    unset TaxUniProt($TaxId,$Quoi)
	}
	return $V
    }

    if {$TaxId=="SortUnique" && $Quoi=="ListOf" && $Value=="Names"} {
	set TaxUniProt(ListOf,Names) [lsort -unique $TaxUniProt(ListOf,Names)]
	return 1
    }

    set MAJUSCULE [string toupper $TaxId]
    set TaxUniProt($MAJUSCULE,OriginalCase) $TaxId

    if {$TaxId=="ListOf" && $Quoi=="Names"} {
	lappend TaxUniProt(ListOf,Names) $Value
	return $Value
    }

    if {$Quoi=="ItsNames" || $Quoi=="ItsTaxIds" || $Quoi=="Children"} {
	lappend TaxUniProt($TaxId,$Quoi) $Value
	return [set TaxUniProt($TaxId,$Quoi)]
    }
    set TaxUniProt($TaxId,$Quoi) $Value
    if {$Quoi=="Name"} {
	if { ! [info exists TaxUniProt($TaxId,exists)]} {
	    set TaxUniProt($TaxId,exists) 1
	    lappend TaxUniProt(List,TaxId) $TaxId
	}
    }
    return $Value
}

proc CondenseTaxName TN {
    if {[regexp {\(} $TN]} {
	set iO [string last "(" $TN]
	set Nouveau [string trim [string range $TN 0 [incr iO -1]]]
	return $Nouveau
    }
    set G ""
    set E ""
    set R ""
    scan $TN "%s %s %s" G E R
    if {$R==""} { return "" }
    return "$G $E"
}

proc LesChampsIndividuels {Texte {Separateur ","}} {

    if { ! [regexp $Separateur $Texte] } { regsub {[\.\;]$} $Texte "" Texte ; return [list $Texte] }

    set P 0
    set Bon ""
    set LesBons {}
    foreach C [split $Texte ""] {
	if {$C=="("} { incr P  1 }
	if {$C==")"} { incr P -1 }
	if {$C==$Separateur && $P==0 } { lappend LesBons $Bon ; continue }
	append Bon $C
    }
    regsub {^ +and *}   $Bon ""     Bon
    regsub {[\.\;]$} $Bon ""     Bon
    regsub " sp$"    $Bon " sp." Bon
    
    lappend LesBons $Bon
    return $LesBons
}

proc TaxN {TaxId} {
    global TaxI
    global TaxJ
    global TaxN
    global TaxC

    if {[info exists TaxN($TaxId)]} { return [set TaxN($TaxId)] }
    if {[info exists TaxN("EstCharge")]} { return "" }
    ChargeTaxIJNC
    return [TaxN $TaxId]    
}

proc TaxC {TaxIdOuTaxName {E ""}} {
    global TaxI
    global TaxJ
    global TaxN
    global TaxC

    if {[info exists TaxC($TaxIdOuTaxName)]} { return [set TaxC($TaxIdOuTaxName)] }
    if {[regexp -nocase {[a-z]} $TaxIdOuTaxName]} {
	set TaxId [TaxI $TaxIdOuTaxName $E]
    } else {
	set TaxId $TaxIdOuTaxName
    }

    if {[info exists TaxC($TaxId)]} { return [set TaxC($TaxId)] }
    if {[info exists TaxC("EstCharge")]} { return "" }
    ChargeTaxIJNC
    return [TaxC $TaxId]    
}

proc TaxI {TaxName {E ""}} {
    global TaxI
    global TaxJ
    global TaxN
    global TaxC

    if {$E!=""} { set TaxName "$TaxName $E" }

    if {[info exists TaxI($TaxName)]} { return [set TaxI($TaxName)] }
    if {[info exists TaxI("EstCharge")]} {
	set TN $TaxName
	while {$TN!=""} {
	    if {[info exists TaxJ($TN)]} { return [set TaxJ($TN)] }
	    set TN [CondenseTaxName $TN]
	}
	return ""
    }
    ChargeTaxIJNC
    return [TaxI $TaxName]    
}

proc ChargeTaxIJNC {} {
    global TaxI
    global TaxJ
    global TaxN
    global TaxC

    set TaxI("EstCharge") 1
    set TaxJ("EstCharge") 1
    set TaxN("EstCharge") 1
    set TaxC("EstCharge") 1


    set FichierSwiss "/prot/gcgswissprot/swissprot.ref"
#    set FichierSwiss "[HomeRipp]/sw.ref"

    set FichierTaxI "[GscopeDatabaseDir Common]/fiches/taxi"
    set FichierTaxJ "[GscopeDatabaseDir Common]/fiches/taxj"
    set FichierTaxN "[GscopeDatabaseDir Common]/fiches/taxn"
    set FichierTaxC "[GscopeDatabaseDir Common]/fiches/taxc"
    set ErrorLogI   "[GscopeDatabaseDir Common]/fiches/error_taxi.log"
    set ErrorLogN   "[GscopeDatabaseDir Common]/fiches/error_taxn.log"
    set ErrorLogC   "[GscopeDatabaseDir Common]/fiches/error_taxc.log"

    if {[file exists $FichierTaxI]} {
	if {[file exists $FichierTaxI]} { array set TaxI [LesLignesDuFichier $FichierTaxI] }
	if {[file exists $FichierTaxJ]} { array set TaxJ [LesLignesDuFichier $FichierTaxJ] }
	if {[file exists $FichierTaxN]} { array set TaxN [LesLignesDuFichier $FichierTaxN] }
	if {[file exists $FichierTaxC]} { array set TaxC [LesLignesDuFichier $FichierTaxC] }
	return
    }

    catch {unset OS}
    catch {unset OX}
    catch {unset OC}
    catch {unset LOS}
    catch {unset LOX}
    catch {unset LesOS}
    catch {unset LesOX}
    set OX ""
    set OldAccess ""
    set n 9999
    set FS [open $FichierSwiss "r"]
    while {[gets $FS Ligne]>=0} {
	if {[regexp "^>" $Ligne]} {
	    if { [expr $n%100==0] } { Espionne $n }
	    if { ! [incr n -1] } { break }
	    if {[info exists DejaVu($OX)] || ! [regexp -nocase "NCBI_TaxID=" $OX]} { continue }
	    set LesS [LesChampsIndividuels $OS]
	    regsub -nocase "NCBI_TaxID=" $OX "" OX
	    set LesX [LesChampsIndividuels $OX] 
	    if {[llength $LesS]!=[llength $LesX]} {
		FaireLire "Different list length\n $OS\n$OX"
		catch {unset OS}
		catch {unset OX}
		catch {unset OC}
		catch {unset LOS}
		catch {unset LOX}
		catch {unset LOC}
		catch {unset LesOS}
		catch {unset LesOX}
		regsub {>+} $Ligne "" OldAccess
		continue
	    }
	    if {[llength $LesS]==1} {
		foreach S $LesS X $LesX {
		    if { ! [info exists TaxN($X)]} { set TaxN($X) $S }
		    if { ! [info exists TaxI($S)]} { set TaxI($S) $X }
		    if {$S!=[set TaxN($X)]} {
			AppendAuFichier $ErrorLogI \
				"\nI saw already \n[set TaxN($X)]\n instead of\n$S\n$OldAccess for $X" 
			break 
		    }
		    if {$X!=[set TaxI($S)]} {
			AppendAuFichier $ErrorLogN \
				"\nI saw already \n[set TaxI($S)]\n instead of\n$X\n$OldAccess for $X" 
			break
		    }
		    set TN $S
		    while {[set TN [CondenseTaxName $TN]]!=""} {
			set TaxJ($TN) $X
		    }
		}
		if {[info exists OC]} {
		    set X [lindex $LesX 0]
		    set Class $OC
		    if {[info exists TaxC($X)] && [set TaxC($X)]!=$Class} {
			AppendAuFichier $ErrorLogC \
				"\nI saw already \n[set TaxC($X)]\n instead of\n[set TaxC($X)]\
				\n$\n$OldAccess for $X"
			break
		    }
		    set TaxC($X) $Class
		    set S [lindex $LesS 0]
		    if {[info exists TaxC($S)] && [set TaxC($S)]!=$Class} {
			AppendAuFichier $ErrorLogClass \
				"\nI saw already \n[set TaxC($S)]\n instead of\n[set TaxC($S)]\
				\n$\n$OldAccess for $S"
			break
		    }
		    set TaxC($S) $Class
		}
	    }
	    set DejaVu($OX) 1
	    catch {unset OS}
	    catch {unset OX}
	    catch {unset OC}
	    catch {unset LOS}
	    catch {unset LOX}
	    catch {unset LOC}
	    catch {unset LesOS}
	    catch {unset LesOX}
	    regsub {>+} $Ligne "" OldAccess
	    continue
	}
	if {[regexp "^OS " $Ligne]} {
	    if { ! [info exists LOS]} { set LOS {} }
	    regsub {^OS +} $Ligne "" O
	    lappend LOS $O
	    if {[regexp {\.$} $Ligne]} {
		set OS [join $LOS " "]
	    }
	}
	if {[regexp "^OC " $Ligne]} {
	    if { ! [info exists LOC]} { set LOC {} }
	    regsub {^OC +} $Ligne "" O
	    lappend LOC $O
	    if {[regexp {\.$} $Ligne]} {
		set OC [join $LOC " "]
	    }
	}
	if {[regexp "^OX " $Ligne]} {
	    if { ! [info exists LOX]} { set LOX {} }
	    regsub {^OX +} $Ligne "" O
	    lappend LOX $O
	    if {[regexp {\;$} $Ligne]} {
		set OX [join $LOX " "]
	    }
	}
    }
    close $FS
    SauveLesLignes [array get TaxI] dans $FichierTaxI
    SauveLesLignes [array get TaxJ] dans $FichierTaxJ
    SauveLesLignes [array get TaxN] dans $FichierTaxN
    SauveLesLignes [array get TaxC] dans $FichierTaxC
    return
}


Index by: file name | procedure name | procedure call | annotation
File generated 2022-04-05 at 12:55.