2024-04-11 15:51:56 +02:00
// readGeneticAnalysis provides function to read genetic analyses
package readGeneticAnalysis
import "seekia/resources/geneticReferences/monogenicDiseases"
import "seekia/resources/geneticReferences/polygenicDiseases"
import "seekia/resources/geneticReferences/traits"
2024-06-02 10:43:39 +02:00
import "seekia/internal/encoding"
import "seekia/internal/genetics/geneticAnalysis"
import "seekia/internal/genetics/locusValue"
2024-04-11 15:51:56 +02:00
import "seekia/internal/helpers"
import "errors"
2024-06-02 10:43:39 +02:00
// This converts a person genetic analysis MessagePack to a PersonAnalysis object
func ReadPersonGeneticAnalysisString ( inputAnalysisString string ) ( geneticAnalysis . PersonAnalysis , error ) {
2024-04-11 15:51:56 +02:00
inputAnalysisBytes := [ ] byte ( inputAnalysisString )
2024-06-02 10:43:39 +02:00
var newAnalysisObject geneticAnalysis . PersonAnalysis
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
err := encoding . DecodeMessagePackBytes ( false , inputAnalysisBytes , & newAnalysisObject )
if ( err != nil ) { return geneticAnalysis . PersonAnalysis { } , err }
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
return newAnalysisObject , nil
2024-04-11 15:51:56 +02:00
}
2024-06-02 10:43:39 +02:00
// This converts a couple genetic analysis MessagePack to a CoupleAnalysis object
func ReadCoupleGeneticAnalysisString ( inputAnalysisString string ) ( geneticAnalysis . CoupleAnalysis , error ) {
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
inputAnalysisBytes := [ ] byte ( inputAnalysisString )
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
var newAnalysisObject geneticAnalysis . CoupleAnalysis
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
err := encoding . DecodeMessagePackBytes ( false , inputAnalysisBytes , & newAnalysisObject )
if ( err != nil ) { return geneticAnalysis . CoupleAnalysis { } , err }
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
return newAnalysisObject , nil
}
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
//Outputs:
// -[][16]byte: All raw genome identifiers list (excluding combined genomes)
// -bool: Multiple genomes exist
// -[16]byte: OnlyExcludeConflicts GenomeIdentifier
// -[16]byte: OnlyIncludeShared GenomeIdentifier
// -error
func GetMetadataFromPersonGeneticAnalysis ( inputGeneticAnalysis geneticAnalysis . PersonAnalysis ) ( [ ] [ 16 ] byte , bool , [ 16 ] byte , [ 16 ] byte , error ) {
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
analysisVersion := inputGeneticAnalysis . AnalysisVersion
if ( analysisVersion != 1 ) {
// This analysis must have been created by a newer version of Seekia
// We cannot read it
return nil , false , [ 16 ] byte { } , [ 16 ] byte { } , errors . New ( "Cannot read analysis: Is a newer analysis version." )
}
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
allRawGenomeIdentifiersList := inputGeneticAnalysis . AllRawGenomeIdentifiersList
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
combinedGenomesExist := inputGeneticAnalysis . CombinedGenomesExist
if ( combinedGenomesExist == false ) {
return allRawGenomeIdentifiersList , false , [ 16 ] byte { } , [ 16 ] byte { } , nil
2024-04-11 15:51:56 +02:00
}
2024-06-02 10:43:39 +02:00
onlyExcludeConflictsGenomeIdentifier := inputGeneticAnalysis . OnlyExcludeConflictsGenomeIdentifier
onlyIncludeSharedGenomeIdentifier := inputGeneticAnalysis . OnlyIncludeSharedGenomeIdentifier
return allRawGenomeIdentifiersList , true , onlyExcludeConflictsGenomeIdentifier , onlyIncludeSharedGenomeIdentifier , nil
2024-04-11 15:51:56 +02:00
}
//Outputs:
2024-06-02 10:43:39 +02:00
// -[16]byte: Pair 1 Person 1 Genome Identifier
// -[16]byte: Pair 1 Person 2 Genome Identifier
2024-04-11 15:51:56 +02:00
// -bool: Second Genome pair exists
2024-06-02 10:43:39 +02:00
// -[16]byte: Pair 2 Person 1 Genome Identifier
// -[16]byte: Pair 2 Person 2 Genome Identifier
// -bool: Person 1 Has Multiple Genomes
// -[16]byte: Person 1 OnlyExcludeConflicts Genome Identifier
// -[16]byte: Person 1 OnlyIncludeShared Genome Identifier
// -bool: Person 2 Has Multiple Genomes
// -[16]byte: Person 2 OnlyExcludeConflicts Genome Identifier
// -[16]byte: Person 2 OnlyIncludeShared Genome Identifier
2024-04-11 15:51:56 +02:00
// -error
2024-06-02 10:43:39 +02:00
func GetMetadataFromCoupleGeneticAnalysis ( inputGeneticAnalysis geneticAnalysis . CoupleAnalysis ) ( [ 16 ] byte , [ 16 ] byte , bool , [ 16 ] byte , [ 16 ] byte , bool , [ 16 ] byte , [ 16 ] byte , bool , [ 16 ] byte , [ 16 ] byte , error ) {
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
analysisVersion := inputGeneticAnalysis . AnalysisVersion
if ( analysisVersion != 1 ) {
// This analysis must have been created by a newer version of Seekia
// We cannot read it
return [ 16 ] byte { } , [ 16 ] byte { } , false , [ 16 ] byte { } , [ 16 ] byte { } , false , [ 16 ] byte { } , [ 16 ] byte { } , false , [ 16 ] byte { } , [ 16 ] byte { } , errors . New ( "Cannot read analysis: Is a newer analysis version." )
}
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
pair1Person1GenomeIdentifier := inputGeneticAnalysis . Pair1Person1GenomeIdentifier
pair1Person2GenomeIdentifier := inputGeneticAnalysis . Pair1Person2GenomeIdentifier
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
secondPairExists := inputGeneticAnalysis . SecondPairExists
if ( secondPairExists == false ) {
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
return pair1Person1GenomeIdentifier , pair1Person2GenomeIdentifier , false , [ 16 ] byte { } , [ 16 ] byte { } , false , [ 16 ] byte { } , [ 16 ] byte { } , false , [ 16 ] byte { } , [ 16 ] byte { } , nil
}
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
pair2Person1GenomeIdentifier := inputGeneticAnalysis . Pair2Person1GenomeIdentifier
pair2Person2GenomeIdentifier := inputGeneticAnalysis . Pair2Person2GenomeIdentifier
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
getPerson1MultipleGenomesInfo := func ( ) ( bool , [ 16 ] byte , [ 16 ] byte , error ) {
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
person1HasMultipleGenomes := inputGeneticAnalysis . Person1HasMultipleGenomes
if ( person1HasMultipleGenomes == false ) {
return false , [ 16 ] byte { } , [ 16 ] byte { } , nil
2024-04-11 15:51:56 +02:00
}
2024-06-02 10:43:39 +02:00
person1OnlyExcludeConflictsGenomeIdentifier := inputGeneticAnalysis . Person1OnlyExcludeConflictsGenomeIdentifier
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
person1OnlyIncludeSharedGenomeIdentifier := inputGeneticAnalysis . Person1OnlyIncludeSharedGenomeIdentifier
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
return true , person1OnlyExcludeConflictsGenomeIdentifier , person1OnlyIncludeSharedGenomeIdentifier , nil
}
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
getPerson2MultipleGenomesInfo := func ( ) ( bool , [ 16 ] byte , [ 16 ] byte , error ) {
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
person2HasMultipleGenomes := inputGeneticAnalysis . Person2HasMultipleGenomes
if ( person2HasMultipleGenomes == false ) {
return false , [ 16 ] byte { } , [ 16 ] byte { } , nil
2024-04-11 15:51:56 +02:00
}
2024-06-02 10:43:39 +02:00
person2OnlyExcludeConflictsGenomeIdentifier := inputGeneticAnalysis . Person2OnlyExcludeConflictsGenomeIdentifier
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
person2OnlyIncludeSharedGenomeIdentifier := inputGeneticAnalysis . Person2OnlyIncludeSharedGenomeIdentifier
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
return true , person2OnlyExcludeConflictsGenomeIdentifier , person2OnlyIncludeSharedGenomeIdentifier , nil
}
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
person1HasMultipleGenomes , person1OnlyExcludeConflictsGenomeIdentifier , person1OnlyIncludeSharedGenomeIdentifier , err := getPerson1MultipleGenomesInfo ( )
if ( err != nil ) { return [ 16 ] byte { } , [ 16 ] byte { } , false , [ 16 ] byte { } , [ 16 ] byte { } , false , [ 16 ] byte { } , [ 16 ] byte { } , false , [ 16 ] byte { } , [ 16 ] byte { } , err }
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
person2HasMultipleGenomes , person2OnlyExcludeConflictsGenomeIdentifier , person2OnlyIncludeSharedGenomeIdentifier , err := getPerson2MultipleGenomesInfo ( )
if ( err != nil ) { return [ 16 ] byte { } , [ 16 ] byte { } , false , [ 16 ] byte { } , [ 16 ] byte { } , false , [ 16 ] byte { } , [ 16 ] byte { } , false , [ 16 ] byte { } , [ 16 ] byte { } , err }
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
return pair1Person1GenomeIdentifier , pair1Person2GenomeIdentifier , true , pair2Person1GenomeIdentifier , pair2Person2GenomeIdentifier , person1HasMultipleGenomes , person1OnlyExcludeConflictsGenomeIdentifier , person1OnlyIncludeSharedGenomeIdentifier , person2HasMultipleGenomes , person2OnlyExcludeConflictsGenomeIdentifier , person2OnlyIncludeSharedGenomeIdentifier , nil
2024-04-11 15:51:56 +02:00
}
// This function will take a couple and person analysis
// It takes in a genome identifier from the couple analysis
// It returns the equivalent genome identifier from the person analysis
// This is needed for combined genomes, because their identifiers are generated randomly for each analysis
//Inputs:
2024-06-02 10:43:39 +02:00
// -bool: Is person 1
// -geneticAnalysis.PersonAnalysis: Person 1 Analysis
// -geneticAnalysis.PersonAnalysis: Person 2 Analysis
// -geneticAnalysis.CoupleAnalysis: Couple Analysis
// -[16]byte: Input Genome Identifier (Should be from Couple identifier)
2024-04-11 15:51:56 +02:00
//Outputs:
2024-06-02 10:43:39 +02:00
// -[16]byte: Genome identifier from person analysis
2024-04-11 15:51:56 +02:00
// -bool: Person analysis has multiple genomes
// -bool: Genome is a combined genome
// -string: Genome combined type ("Only Exclude Conflicts"/"Only Include Shared")
// -error
2024-06-02 10:43:39 +02:00
func GetMatchingPersonAnalysisGenomeIdentifierFromCoupleAnalysis ( isPerson1 bool , person1AnalysisObject geneticAnalysis . PersonAnalysis , person2AnalysisObject geneticAnalysis . PersonAnalysis , coupleAnalysisObject geneticAnalysis . CoupleAnalysis , inputGenomeIdentifier [ 16 ] byte ) ( [ 16 ] byte , bool , bool , string , error ) {
2024-04-11 15:51:56 +02:00
// We need to figure out which genome identifier the current genome identifier corresponds to within the person analysis
// If the genome is not a combined genome, then the genome identifier should be identical between each analysis
// If it is a combined genome, we need to determine which genome it corresponds to
2024-06-02 10:43:39 +02:00
_ , _ , secondGenomePairExists , _ , _ , person1HasMultipleGenomes , person1OnlyExcludeConflictsGenomeIdentifier , person1OnlyIncludeSharedGenomeIdentifier , person2HasMultipleGenomes , person2OnlyExcludeConflictsGenomeIdentifier , person2OnlyIncludeSharedGenomeIdentifier , err := GetMetadataFromCoupleGeneticAnalysis ( coupleAnalysisObject )
if ( err != nil ) { return [ 16 ] byte { } , false , false , "" , err }
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
if ( isPerson1 == true ) {
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
if ( person1HasMultipleGenomes == false ) {
2024-04-11 15:51:56 +02:00
// This person does not have multiple genomes. The genome identifier is the same between both analyses
return inputGenomeIdentifier , false , false , "" , nil
}
if ( secondGenomePairExists == false ) {
return inputGenomeIdentifier , true , false , "" , nil
}
2024-06-02 10:43:39 +02:00
_ , multipleGenomesExist , onlyExcludeConflictsGenomeIdentifier , onlyIncludeSharedGenomeIdentifier , err := GetMetadataFromPersonGeneticAnalysis ( person1AnalysisObject )
if ( err != nil ) { return [ 16 ] byte { } , false , false , "" , err }
2024-04-11 15:51:56 +02:00
if ( multipleGenomesExist == false ) {
2024-06-02 10:43:39 +02:00
return [ 16 ] byte { } , false , false , "" , errors . New ( "Couple analysis says person has multiple genomes, person analysis does not." )
2024-04-11 15:51:56 +02:00
}
2024-06-02 10:43:39 +02:00
if ( inputGenomeIdentifier == person1OnlyExcludeConflictsGenomeIdentifier ) {
2024-04-11 15:51:56 +02:00
return onlyExcludeConflictsGenomeIdentifier , true , true , "Only Exclude Conflicts" , nil
}
2024-06-02 10:43:39 +02:00
if ( inputGenomeIdentifier == person1OnlyIncludeSharedGenomeIdentifier ) {
2024-04-11 15:51:56 +02:00
return onlyIncludeSharedGenomeIdentifier , true , true , "Only Include Shared" , nil
}
2024-06-02 10:43:39 +02:00
return [ 16 ] byte { } , false , false , "" , errors . New ( "Combined genome identifier from couple analysis does not correspond to either combined genome from person analysis." )
2024-04-11 15:51:56 +02:00
}
2024-06-02 10:43:39 +02:00
// isPerson1 == false
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
if ( person2HasMultipleGenomes == false ) {
2024-04-11 15:51:56 +02:00
// This person does not have multiple genomes. The genome identifier is the same between both analyses
return inputGenomeIdentifier , false , false , "" , nil
}
if ( secondGenomePairExists == false ) {
return inputGenomeIdentifier , true , false , "" , nil
}
2024-06-02 10:43:39 +02:00
_ , multipleGenomesExist , onlyExcludeConflictsGenomeIdentifier , onlyIncludeSharedGenomeIdentifier , err := GetMetadataFromPersonGeneticAnalysis ( person2AnalysisObject )
if ( err != nil ) { return [ 16 ] byte { } , false , false , "" , err }
2024-04-11 15:51:56 +02:00
if ( multipleGenomesExist == false ) {
2024-06-02 10:43:39 +02:00
return [ 16 ] byte { } , false , false , "" , errors . New ( "Couple analysis says person has multiple genomes, person analysis does not." )
2024-04-11 15:51:56 +02:00
}
2024-06-02 10:43:39 +02:00
if ( inputGenomeIdentifier == person2OnlyExcludeConflictsGenomeIdentifier ) {
2024-04-11 15:51:56 +02:00
return onlyExcludeConflictsGenomeIdentifier , true , true , "Only Exclude Conflicts" , nil
}
2024-06-02 10:43:39 +02:00
if ( inputGenomeIdentifier == person2OnlyIncludeSharedGenomeIdentifier ) {
2024-04-11 15:51:56 +02:00
return onlyIncludeSharedGenomeIdentifier , true , true , "Only Include Shared" , nil
}
2024-06-02 10:43:39 +02:00
return [ 16 ] byte { } , false , false , "" , errors . New ( "Combined genome identifier from couple analysis does not correspond to either combined genome from person analysis." )
2024-04-11 15:51:56 +02:00
}
//Outputs:
2024-06-02 10:43:39 +02:00
// -bool: Disease info known
// -bool: Person has disease
2024-04-11 15:51:56 +02:00
// -int: Probability of passing a disease variant
// -string: Probability of passing a disease variant formatted (with % suffix)
// -int: Number of variants tested
2024-06-02 10:43:39 +02:00
// -int: Number of loci tested
// -int: Number of phased loci
// -bool: Conflict exists
2024-04-11 15:51:56 +02:00
// -error
2024-06-02 10:43:39 +02:00
func GetPersonMonogenicDiseaseInfoFromGeneticAnalysis ( personAnalysisObject geneticAnalysis . PersonAnalysis , diseaseName string , genomeIdentifier [ 16 ] byte ) ( bool , bool , int , string , int , int , int , bool , error ) {
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
personMonogenicDiseasesMap := personAnalysisObject . MonogenicDiseasesMap
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
personMonogenicDiseaseInfo , exists := personMonogenicDiseasesMap [ diseaseName ]
if ( exists == false ) {
return false , false , 0 , "" , 0 , 0 , 0 , false , nil
}
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
personMonogenicDiseaseInfoMap := personMonogenicDiseaseInfo . MonogenicDiseaseInfoMap
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
genomeMonogenicDiseaseInfo , exists := personMonogenicDiseaseInfoMap [ genomeIdentifier ]
if ( exists == false ) {
return false , false , 0 , "" , 0 , 0 , 0 , false , nil
}
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
conflictExists := personMonogenicDiseaseInfo . ConflictExists
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
personHasDisease := genomeMonogenicDiseaseInfo . PersonHasDisease
numberOfVariantsTested := genomeMonogenicDiseaseInfo . NumberOfVariantsTested
numberOfLociTested := genomeMonogenicDiseaseInfo . NumberOfLociTested
numberOfPhasedLoci := genomeMonogenicDiseaseInfo . NumberOfPhasedLoci
probabilityOfPassingAVariant := genomeMonogenicDiseaseInfo . ProbabilityOfPassingADiseaseVariant
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
probabilityOfPassingAVariantString := helpers . ConvertIntToString ( probabilityOfPassingAVariant )
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
probabilityOfPassingAVariantFormatted := probabilityOfPassingAVariantString + "%"
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
return true , personHasDisease , probabilityOfPassingAVariant , probabilityOfPassingAVariantFormatted , numberOfVariantsTested , numberOfLociTested , numberOfPhasedLoci , conflictExists , nil
2024-04-11 15:51:56 +02:00
}
2024-06-02 10:43:39 +02:00
2024-04-11 15:51:56 +02:00
//Outputs:
2024-06-02 10:43:39 +02:00
// -bool: Probability Offspring Has Disease Is Known
2024-04-11 15:51:56 +02:00
// -int: Percentage Probability of offspring having disease
// -string: Probability of offspring having disease formatted (with % suffix)
2024-06-02 10:43:39 +02:00
// -bool: Probability Offspring Has Variant Is Known
2024-04-11 15:51:56 +02:00
// -int: Percentage probability of offspring having a disease variant
// -string: Percentage probability of offspring having a disease variant formatted (with % suffix)
// -bool: Conflict exists between genome pairs
// -error
2024-06-02 10:43:39 +02:00
func GetOffspringMonogenicDiseaseInfoFromGeneticAnalysis ( coupleAnalysisObject geneticAnalysis . CoupleAnalysis , diseaseName string , genomePairIdentifier [ 32 ] byte ) ( bool , int , string , bool , int , string , bool , error ) {
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
offspringMonogenicDiseasesMap := coupleAnalysisObject . MonogenicDiseasesMap
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
offspringMonogenicDiseaseInfoObject , exists := offspringMonogenicDiseasesMap [ diseaseName ]
if ( exists == false ) {
return false , 0 , "" , false , 0 , "" , false , nil
}
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
monogenicDiseaseInfoMap := offspringMonogenicDiseaseInfoObject . MonogenicDiseaseInfoMap
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
offspringGenomePairMonogenicDiseaseInfo , exists := monogenicDiseaseInfoMap [ genomePairIdentifier ]
if ( exists == false ) {
return false , 0 , "" , false , 0 , "" , false , nil
}
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
conflictExists := offspringMonogenicDiseaseInfoObject . ConflictExists
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
probabilityOffspringHasDiseaseIsKnown := offspringGenomePairMonogenicDiseaseInfo . ProbabilityOffspringHasDiseaseIsKnown
probabilityOffspringHasDisease := offspringGenomePairMonogenicDiseaseInfo . ProbabilityOffspringHasDisease
probabilityOffspringHasVariantIsKnown := offspringGenomePairMonogenicDiseaseInfo . ProbabilityOffspringHasVariantIsKnown
probabilityOffspringHasVariant := offspringGenomePairMonogenicDiseaseInfo . ProbabilityOffspringHasVariant
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
getProbabilityOffspringHasDiseaseFormatted := func ( ) string {
if ( probabilityOffspringHasDiseaseIsKnown == false ) {
return ""
}
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
probabilityOffspringHasDiseaseString := helpers . ConvertIntToString ( probabilityOffspringHasDisease )
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
probabilityOffspringHasDiseaseFormatted := probabilityOffspringHasDiseaseString + "%"
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
return probabilityOffspringHasDiseaseFormatted
}
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
probabilityOffspringHasDiseaseFormatted := getProbabilityOffspringHasDiseaseFormatted ( )
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
getProbabilityOffspringHasVariantFormatted := func ( ) string {
if ( probabilityOffspringHasVariantIsKnown == false ) {
return ""
2024-04-11 15:51:56 +02:00
}
2024-06-02 10:43:39 +02:00
probabilityOffspringHasVariantString := helpers . ConvertIntToString ( probabilityOffspringHasVariant )
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
probabilityOffspringHasVariantFormatted := probabilityOffspringHasVariantString + "%"
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
return probabilityOffspringHasVariantFormatted
2024-04-11 15:51:56 +02:00
}
2024-06-02 10:43:39 +02:00
probabilityOffspringHasVariantFormatted := getProbabilityOffspringHasVariantFormatted ( )
return probabilityOffspringHasDiseaseIsKnown , probabilityOffspringHasDisease , probabilityOffspringHasDiseaseFormatted , probabilityOffspringHasVariantIsKnown , probabilityOffspringHasVariant , probabilityOffspringHasVariantFormatted , conflictExists , nil
2024-04-11 15:51:56 +02:00
}
2024-06-02 10:43:39 +02:00
2024-04-11 15:51:56 +02:00
//Outputs:
2024-06-02 10:43:39 +02:00
// -bool: Number of mutations is known
2024-04-11 15:51:56 +02:00
// -int: Number of mutations
// -error
2024-06-02 10:43:39 +02:00
func GetPersonMonogenicDiseaseVariantInfoFromGeneticAnalysis ( personAnalysisObject geneticAnalysis . PersonAnalysis , diseaseName string , variantIdentifier [ 3 ] byte , genomeIdentifier [ 16 ] byte ) ( bool , int , error ) {
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
personMonogenicDiseasesMap := personAnalysisObject . MonogenicDiseasesMap
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
personMonogenicDiseaseInfo , exists := personMonogenicDiseasesMap [ diseaseName ]
if ( exists == false ) {
return false , 0 , nil
}
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
personMonogenicDiseaseInfoMap := personMonogenicDiseaseInfo . MonogenicDiseaseInfoMap
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
genomeMonogenicDiseaseInfo , exists := personMonogenicDiseaseInfoMap [ genomeIdentifier ]
if ( exists == false ) {
return false , 0 , nil
}
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
variantsInfoMap := genomeMonogenicDiseaseInfo . VariantsInfoMap
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
variantInfoObject , exists := variantsInfoMap [ variantIdentifier ]
if ( exists == false ) {
// The genome's variant info is unknown for this variant
return false , 0 , nil
}
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
base1HasVariant := variantInfoObject . Base1HasVariant
base2HasVariant := variantInfoObject . Base2HasVariant
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
numberOfMutations := 0
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
if ( base1HasVariant == true ) {
numberOfMutations += 1
}
if ( base2HasVariant == true ) {
numberOfMutations += 1
2024-04-11 15:51:56 +02:00
}
2024-06-02 10:43:39 +02:00
return true , numberOfMutations , nil
2024-04-11 15:51:56 +02:00
}
//Outputs:
// -bool: Offspring Probabilities Known
// -int: Lower Bound Percentage Probability of 0 mutations
// -int: Upper Bound Percentage Probability of 0 mutations
// -string: Percentage probability of 0 mutations formatted (has % suffix and - between non-identical bounds)
// -int: Lower Bound Percentage probability of only 1 mutation
// -int: Upper Bound Percentage probability of only 1 mutation
// -string: Percentage probability of 1 mutation formatted (has % suffix and - between non-identical bounds)
// -int: Lower Bound Percentage probability of 2 mutations
// -int: Upper Bound Percentage probability of 2 mutations
// -string: Percentage probability of 2 mutations formatted (has % suffix and - between non-identical bounds)
// -error
2024-06-02 10:43:39 +02:00
func GetOffspringMonogenicDiseaseVariantInfoFromGeneticAnalysis ( coupleAnalysisObject geneticAnalysis . CoupleAnalysis , diseaseName string , variantIdentifier [ 3 ] byte , genomePairIdentifier [ 32 ] byte ) ( bool , int , int , string , int , int , string , int , int , string , error ) {
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
coupleMonogenicDiseasesMap := coupleAnalysisObject . MonogenicDiseasesMap
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
coupleMonogenicDiseaseInfo , exists := coupleMonogenicDiseasesMap [ diseaseName ]
if ( exists == false ) {
return false , 0 , 0 , "" , 0 , 0 , "" , 0 , 0 , "" , nil
}
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
coupleMonogenicDiseaseInfoMap := coupleMonogenicDiseaseInfo . MonogenicDiseaseInfoMap
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
genomePairMonogenicDiseaseInfo , exists := coupleMonogenicDiseaseInfoMap [ genomePairIdentifier ]
if ( exists == false ) {
return false , 0 , 0 , "" , 0 , 0 , "" , 0 , 0 , "" , nil
}
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
genomePairVariantsInfoMap := genomePairMonogenicDiseaseInfo . VariantsInfoMap
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
variantInfoObject , exists := genomePairVariantsInfoMap [ variantIdentifier ]
if ( exists == false ) {
return false , 0 , 0 , "" , 0 , 0 , "" , 0 , 0 , "" , nil
}
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
probabilityOf0MutationsLowerBound := variantInfoObject . ProbabilityOf0MutationsLowerBound
probabilityOf0MutationsUpperBound := variantInfoObject . ProbabilityOf0MutationsUpperBound
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
probabilityOf1MutationLowerBound := variantInfoObject . ProbabilityOf1MutationLowerBound
probabilityOf1MutationUpperBound := variantInfoObject . ProbabilityOf1MutationUpperBound
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
probabilityOf2MutationsLowerBound := variantInfoObject . ProbabilityOf2MutationsLowerBound
probabilityOf2MutationsUpperBound := variantInfoObject . ProbabilityOf2MutationsUpperBound
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
getOffspringProbabilityOf0MutationsFormatted := func ( ) string {
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
probabilityOf0MutationsLowerBoundString := helpers . ConvertIntToString ( probabilityOf0MutationsLowerBound )
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
probabilityOf0MutationsLowerBoundFormatted := probabilityOf0MutationsLowerBoundString + "%"
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
if ( probabilityOf0MutationsLowerBound == probabilityOf0MutationsUpperBound ) {
return probabilityOf0MutationsLowerBoundFormatted
2024-04-11 15:51:56 +02:00
}
2024-06-02 10:43:39 +02:00
probabilityOf0MutationsUpperBoundString := helpers . ConvertIntToString ( probabilityOf0MutationsUpperBound )
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
probabilityOf0MutationsUpperBoundFormatted := probabilityOf0MutationsUpperBoundString + "%"
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
formattedResult := probabilityOf0MutationsLowerBoundFormatted + " - " + probabilityOf0MutationsUpperBoundFormatted
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
return formattedResult
}
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
probabilityOf0MutationsFormatted := getOffspringProbabilityOf0MutationsFormatted ( )
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
getOffspringProbabilityOf1MutationFormatted := func ( ) string {
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
probabilityOf1MutationLowerBoundString := helpers . ConvertIntToString ( probabilityOf1MutationLowerBound )
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
probabilityOf1MutationLowerBoundFormatted := probabilityOf1MutationLowerBoundString + "%"
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
if ( probabilityOf1MutationLowerBound == probabilityOf1MutationUpperBound ) {
return probabilityOf1MutationLowerBoundFormatted
2024-04-11 15:51:56 +02:00
}
2024-06-02 10:43:39 +02:00
probabilityOf1MutationUpperBoundString := helpers . ConvertIntToString ( probabilityOf1MutationUpperBound )
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
probabilityOf1MutationUpperBoundFormatted := probabilityOf1MutationUpperBoundString + "%"
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
formattedResult := probabilityOf1MutationLowerBoundFormatted + " - " + probabilityOf1MutationUpperBoundFormatted
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
return formattedResult
}
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
probabilityOf1MutationFormatted := getOffspringProbabilityOf1MutationFormatted ( )
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
getOffspringProbabilityOf2MutationsFormatted := func ( ) string {
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
probabilityOf2MutationsLowerBoundString := helpers . ConvertIntToString ( probabilityOf2MutationsLowerBound )
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
probabilityOf2MutationsLowerBoundFormatted := probabilityOf2MutationsLowerBoundString + "%"
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
if ( probabilityOf2MutationsLowerBound == probabilityOf2MutationsUpperBound ) {
return probabilityOf2MutationsLowerBoundFormatted
}
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
probabilityOf2MutationsUpperBoundString := helpers . ConvertIntToString ( probabilityOf2MutationsUpperBound )
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
probabilityOf2MutationsUpperBoundFormatted := probabilityOf2MutationsUpperBoundString + "%"
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
formattedResult := probabilityOf2MutationsLowerBoundFormatted + " - " + probabilityOf2MutationsUpperBoundFormatted
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
return formattedResult
2024-04-11 15:51:56 +02:00
}
2024-06-02 10:43:39 +02:00
probabilityOf2MutationsFormatted := getOffspringProbabilityOf2MutationsFormatted ( )
return true , probabilityOf0MutationsLowerBound , probabilityOf0MutationsUpperBound , probabilityOf0MutationsFormatted , probabilityOf1MutationLowerBound , probabilityOf1MutationUpperBound , probabilityOf1MutationFormatted , probabilityOf2MutationsLowerBound , probabilityOf2MutationsUpperBound , probabilityOf2MutationsFormatted , nil
2024-04-11 15:51:56 +02:00
}
//Outputs:
// -bool: Polygenic Disease Risk Score known
// -int: Disease risk score
2024-06-02 10:43:39 +02:00
// -string: Disease risk score formatted (has "/10" suffix)
2024-04-11 15:51:56 +02:00
// -int: Number of loci tested
// -bool: Conflict exists
// -error
2024-06-02 10:43:39 +02:00
func GetPersonPolygenicDiseaseInfoFromGeneticAnalysis ( personAnalysisObject geneticAnalysis . PersonAnalysis , diseaseName string , genomeIdentifier [ 16 ] byte ) ( bool , int , string , int , bool , error ) {
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
personPolygenicDiseasesMap := personAnalysisObject . PolygenicDiseasesMap
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
personPolygenicDiseaseInfo , exists := personPolygenicDiseasesMap [ diseaseName ]
if ( exists == false ) {
return false , 0 , "" , 0 , false , nil
}
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
personPolygenicDiseaseInfoMap := personPolygenicDiseaseInfo . PolygenicDiseaseInfoMap
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
genomePolygenicDiseaseInfo , exists := personPolygenicDiseaseInfoMap [ genomeIdentifier ]
if ( exists == false ) {
return false , 0 , "" , 0 , false , nil
}
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
conflictExists := personPolygenicDiseaseInfo . ConflictExists
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
personDiseaseRiskScore := genomePolygenicDiseaseInfo . RiskScore
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
numberOfLociTested := genomePolygenicDiseaseInfo . NumberOfLociTested
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
personDiseaseRiskScoreString := helpers . ConvertIntToString ( personDiseaseRiskScore )
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
personDiseaseRiskScoreFormatted := personDiseaseRiskScoreString + "/10"
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
return true , personDiseaseRiskScore , personDiseaseRiskScoreFormatted , numberOfLociTested , conflictExists , nil
2024-04-11 15:51:56 +02:00
}
//Outputs:
2024-06-02 10:43:39 +02:00
// -bool: Offspring Disease Risk Score known
2024-04-11 15:51:56 +02:00
// -int: Disease risk score
2024-06-02 10:43:39 +02:00
// -string: Disease risk score formatted (has "/10" suffix)
2024-04-11 15:51:56 +02:00
// -int: Number of loci tested
// -bool: Conflict exists
// -error
2024-06-02 10:43:39 +02:00
func GetOffspringPolygenicDiseaseInfoFromGeneticAnalysis ( coupleAnalysisObject geneticAnalysis . CoupleAnalysis , diseaseName string , genomePairIdentifier [ 32 ] byte ) ( bool , int , string , int , bool , error ) {
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
couplePolygenicDiseasesMap := coupleAnalysisObject . PolygenicDiseasesMap
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
couplePolygenicDiseaseInfo , exists := couplePolygenicDiseasesMap [ diseaseName ]
if ( exists == false ) {
return false , 0 , "" , 0 , false , nil
}
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
polygenicDiseaseInfoMap := couplePolygenicDiseaseInfo . PolygenicDiseaseInfoMap
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
genomePairPolygenicDiseaseInfo , exists := polygenicDiseaseInfoMap [ genomePairIdentifier ]
if ( exists == false ) {
return false , 0 , "" , 0 , false , nil
}
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
conflictExists := couplePolygenicDiseaseInfo . ConflictExists
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
numberOfLociTested := genomePairPolygenicDiseaseInfo . NumberOfLociTested
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
offspringRiskScore := genomePairPolygenicDiseaseInfo . OffspringRiskScore
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
offspringRiskScoreString := helpers . ConvertIntToString ( offspringRiskScore )
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
offspringRiskScoreFormatted := offspringRiskScoreString + "/10"
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
return true , offspringRiskScore , offspringRiskScoreFormatted , numberOfLociTested , conflictExists , nil
2024-04-11 15:51:56 +02:00
}
//Outputs:
// -bool: Risk Weight and base pair known
// -int: Locus risk weight
2024-06-02 10:43:39 +02:00
// -string: Locus base 1
// -string: Locus base 2
2024-04-11 15:51:56 +02:00
// -bool: Locus odds ratio known
// -float64: Locus odds ratio
// -string: Locus odds ratio formatted (with x suffix)
// -error
2024-06-02 10:43:39 +02:00
func GetPersonPolygenicDiseaseLocusInfoFromGeneticAnalysis ( personAnalyisObject geneticAnalysis . PersonAnalysis , diseaseName string , locusIdentifier [ 3 ] byte , genomeIdentifier [ 16 ] byte ) ( bool , int , string , string , bool , float64 , string , error ) {
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
personPolygenicDiseasesMap := personAnalyisObject . PolygenicDiseasesMap
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
personPolygenicDiseaseMap , exists := personPolygenicDiseasesMap [ diseaseName ]
if ( exists == false ) {
return false , 0 , "" , "" , false , 0 , "" , nil
}
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
personPolygenicDiseaseInfoMap := personPolygenicDiseaseMap . PolygenicDiseaseInfoMap
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
personGenomePolygenicDiseaseInfo , exists := personPolygenicDiseaseInfoMap [ genomeIdentifier ]
if ( exists == false ) {
return false , 0 , "" , "" , false , 0 , "" , nil
}
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
genomeLociInfoMap := personGenomePolygenicDiseaseInfo . LociInfoMap
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
locusInfoObject , exists := genomeLociInfoMap [ locusIdentifier ]
if ( exists == false ) {
return false , 0 , "" , "" , false , 0 , "" , nil
}
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
locusRiskWeight := locusInfoObject . RiskWeight
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
locusBase1 := locusInfoObject . LocusBase1
locusBase2 := locusInfoObject . LocusBase2
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
locusOddsRatioIsKnown := locusInfoObject . OddsRatioIsKnown
if ( locusOddsRatioIsKnown == false ) {
return true , locusRiskWeight , locusBase1 , locusBase2 , false , 0 , "" , nil
}
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
locusOddsRatio := locusInfoObject . OddsRatio
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
genomeLocusOddsRatioString := helpers . ConvertFloat64ToStringRounded ( locusOddsRatio , 2 )
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
locusOddsRatioFormatted := genomeLocusOddsRatioString + "x"
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
return true , locusRiskWeight , locusBase1 , locusBase2 , true , locusOddsRatio , locusOddsRatioFormatted , nil
2024-04-11 15:51:56 +02:00
}
//Outputs:
// -bool: Offspring risk weight known
// -int: Offspring risk weight
// -bool: Offspring odds ratio known
// -float64: Offspring odds ratio
// -string: Offspring odds ratio formatted (with + and < from unknownFactors weight sum and x suffix)
// -error
2024-06-02 10:43:39 +02:00
func GetOffspringPolygenicDiseaseLocusInfoFromGeneticAnalysis ( coupleAnalysisObject geneticAnalysis . CoupleAnalysis , diseaseName string , locusIdentifier [ 3 ] byte , genomePairIdentifier [ 32 ] byte ) ( bool , int , bool , float64 , string , error ) {
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
offspringPolygenicDiseasesMap := coupleAnalysisObject . PolygenicDiseasesMap
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
offspringPolygenicDiseaseInfo , exists := offspringPolygenicDiseasesMap [ diseaseName ]
if ( exists == false ) {
return false , 0 , false , 0 , "" , nil
}
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
offspringPolygenicDiseaseMap := offspringPolygenicDiseaseInfo . PolygenicDiseaseInfoMap
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
genomePairPolygenicDiseaseInfo , exists := offspringPolygenicDiseaseMap [ genomePairIdentifier ]
if ( exists == false ) {
return false , 0 , false , 0 , "" , nil
}
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
genomePairLociInfoMap := genomePairPolygenicDiseaseInfo . LociInfoMap
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
locusInfoObject , exists := genomePairLociInfoMap [ locusIdentifier ]
if ( exists == false ) {
return false , 0 , false , 0 , "" , nil
}
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
offspringRiskWeight := locusInfoObject . OffspringRiskWeight
offspringOddsRatioIsKnown := locusInfoObject . OffspringOddsRatioIsKnown
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
if ( offspringOddsRatioIsKnown == false ) {
return true , offspringRiskWeight , false , 0 , "" , nil
}
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
offspringOddsRatio := locusInfoObject . OffspringOddsRatio
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
getOddsRatioFormatted := func ( ) string {
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
offspringUnknownOddsRatiosWeightSum := locusInfoObject . OffspringUnknownOddsRatiosWeightSum
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
offspringOddsRatioString := helpers . ConvertFloat64ToStringRounded ( offspringOddsRatio , 2 )
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
if ( offspringUnknownOddsRatiosWeightSum == 0 ) {
result := offspringOddsRatioString + "x"
2024-04-11 15:51:56 +02:00
return result
}
2024-06-02 10:43:39 +02:00
if ( offspringUnknownOddsRatiosWeightSum < 0 ) {
result := "<" + offspringOddsRatioString + "x"
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
return result
}
// offspringUnknownOddsRatiosWeightSum > 0
result := offspringOddsRatioString + "x+"
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
return result
2024-04-11 15:51:56 +02:00
}
2024-06-02 10:43:39 +02:00
oddsRatioFormatted := getOddsRatioFormatted ( )
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
return true , offspringRiskWeight , true , offspringOddsRatio , oddsRatioFormatted , nil
2024-04-11 15:51:56 +02:00
}
//Outputs:
2024-06-02 10:43:39 +02:00
// -map[int64]locusValue.LocusValue (rsID -> Base pair) (missing rsIDs represent unknown values)
2024-04-11 15:51:56 +02:00
// -bool: Any Trait Rule known/tested
2024-06-02 10:43:39 +02:00
// -map[string]int: Trait outcomes scores map (Outcome -> Number of points)
2024-04-11 15:51:56 +02:00
// -int: Number of rules tested
// -bool: Conflict exists
// -error
2024-06-02 10:43:39 +02:00
func GetPersonTraitInfoFromGeneticAnalysis ( personAnalysisObject geneticAnalysis . PersonAnalysis , traitName string , genomeIdentifier [ 16 ] byte ) ( map [ int64 ] locusValue . LocusValue , bool , map [ string ] int , int , bool , error ) {
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
personTraitsMap := personAnalysisObject . TraitsMap
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
personTraitInfoObject , exists := personTraitsMap [ traitName ]
if ( exists == false ) {
emptyMap := make ( map [ int64 ] locusValue . LocusValue )
return emptyMap , false , nil , 0 , false , nil
}
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
personTraitInfoMap := personTraitInfoObject . TraitInfoMap
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
personGenomeTraitInfoObject , exists := personTraitInfoMap [ genomeIdentifier ]
if ( exists == false ) {
emptyMap := make ( map [ int64 ] locusValue . LocusValue )
return emptyMap , false , nil , 0 , false , nil
}
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
conflictExists := personTraitInfoObject . ConflictExists
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
genomeNumberOfRulesTested := personGenomeTraitInfoObject . NumberOfRulesTested
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
genomeLocusValuesMap := personGenomeTraitInfoObject . LocusValuesMap
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
genomeOutcomeScoresMap := personGenomeTraitInfoObject . OutcomeScoresMap
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
return genomeLocusValuesMap , true , genomeOutcomeScoresMap , genomeNumberOfRulesTested , conflictExists , nil
2024-04-11 15:51:56 +02:00
}
//Outputs:
// -bool: Trait Outcome Scores known
// -map[string]float64: Trait average outcome scores map (OutcomeName -> AverageScore)
// -int: Number of rules tested
// -bool: Conflict exists
// -error
2024-06-02 10:43:39 +02:00
func GetOffspringTraitInfoFromGeneticAnalysis ( coupleAnalysisObject geneticAnalysis . CoupleAnalysis , traitName string , genomePairIdentifier [ 32 ] byte ) ( bool , map [ string ] float64 , int , bool , error ) {
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
offspringTraitsMap := coupleAnalysisObject . TraitsMap
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
traitInfoObject , exists := offspringTraitsMap [ traitName ]
if ( exists == false ) {
return false , nil , 0 , false , nil
}
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
traitInfoMap := traitInfoObject . TraitInfoMap
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
genomePairTraitInfoObject , exists := traitInfoMap [ genomePairIdentifier ]
if ( exists == false ) {
return false , nil , 0 , false , nil
}
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
conflictExists := traitInfoObject . ConflictExists
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
numberOfRulesTested := genomePairTraitInfoObject . NumberOfRulesTested
offspringAverageOutcomeScoresMap := genomePairTraitInfoObject . OffspringAverageOutcomeScoresMap
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
return true , offspringAverageOutcomeScoresMap , numberOfRulesTested , conflictExists , nil
2024-04-11 15:51:56 +02:00
}
2024-06-02 10:43:39 +02:00
2024-04-11 15:51:56 +02:00
//Outputs:
2024-06-02 10:43:39 +02:00
// -bool: Rule status is known (we know if the rule is passed or not)
2024-04-11 15:51:56 +02:00
// -bool: Genome passes rule
// -error
2024-06-02 10:43:39 +02:00
func GetPersonTraitRuleInfoFromGeneticAnalysis ( personAnalysisObject geneticAnalysis . PersonAnalysis , traitName string , ruleIdentifier [ 3 ] byte , genomeIdentifier [ 16 ] byte ) ( bool , bool , error ) {
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
personTraitsMap := personAnalysisObject . TraitsMap
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
traitInfoObject , exists := personTraitsMap [ traitName ]
if ( exists == false ) {
return false , false , nil
}
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
personTraitInfoMap := traitInfoObject . TraitInfoMap
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
genomeTraitInfoObject , exists := personTraitInfoMap [ genomeIdentifier ]
if ( exists == false ) {
return false , false , nil
}
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
genomePassesRulesMap := genomeTraitInfoObject . GenomePassesRulesMap
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
genomePassesRule , statusIsKnown := genomePassesRulesMap [ ruleIdentifier ]
if ( statusIsKnown == false ) {
return false , false , nil
2024-04-11 15:51:56 +02:00
}
2024-06-02 10:43:39 +02:00
return true , genomePassesRule , nil
2024-04-11 15:51:56 +02:00
}
//Outputs:
// -bool: Offspring trait rule probability known
// -int: Offspring probability of passing rule (0 - 100)
// -string: Offspring probability of passing rule formatted (with % suffix)
// -error
2024-06-02 10:43:39 +02:00
func GetOffspringTraitRuleInfoFromGeneticAnalysis ( coupleAnalysisObject geneticAnalysis . CoupleAnalysis , traitName string , ruleIdentifier [ 3 ] byte , genomePairIdentifier [ 32 ] byte ) ( bool , int , string , error ) {
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
offspringTraitsMap := coupleAnalysisObject . TraitsMap
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
offspringTraitInfo , exists := offspringTraitsMap [ traitName ]
if ( exists == false ) {
return false , 0 , "" , nil
}
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
offspringTraitInfoMap := offspringTraitInfo . TraitInfoMap
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
offspringTraitInfoObject , exists := offspringTraitInfoMap [ genomePairIdentifier ]
if ( exists == false ) {
return false , 0 , "" , nil
}
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
offspringProbabilityOfPassingRulesMap := offspringTraitInfoObject . ProbabilityOfPassingRulesMap
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
offspringProbabilityOfPassingRule , exists := offspringProbabilityOfPassingRulesMap [ ruleIdentifier ]
if ( exists == false ) {
return false , 0 , "" , nil
}
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
offspringProbabilityOfPassingRuleString := helpers . ConvertIntToString ( offspringProbabilityOfPassingRule )
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
offspringProbabilityOfPassingRuleFormatted := offspringProbabilityOfPassingRuleString + "%"
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
return true , offspringProbabilityOfPassingRule , offspringProbabilityOfPassingRuleFormatted , nil
2024-04-11 15:51:56 +02:00
}
// We use this function to verify a person genetic analysis is well formed
2024-06-02 10:43:39 +02:00
//TODO: Perform sanity checks on data
func VerifyPersonGeneticAnalysis ( personAnalysisObject geneticAnalysis . PersonAnalysis ) error {
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
allRawGenomeIdentifiersList , personHasMultipleGenomes , onlyExcludeConflictsGenomeIdentifier , onlyIncludeSharedGenomeIdentifier , err := GetMetadataFromPersonGeneticAnalysis ( personAnalysisObject )
2024-04-11 15:51:56 +02:00
if ( err != nil ) { return err }
allGenomeIdentifiersList := allRawGenomeIdentifiersList
if ( personHasMultipleGenomes == true ) {
allGenomeIdentifiersList = append ( allGenomeIdentifiersList , onlyExcludeConflictsGenomeIdentifier , onlyIncludeSharedGenomeIdentifier )
}
monogenicDiseaseObjectsList , err := monogenicDiseases . GetMonogenicDiseaseObjectsList ( )
if ( err != nil ) { return err }
for _ , monogenicDiseaseObject := range monogenicDiseaseObjectsList {
diseaseName := monogenicDiseaseObject . DiseaseName
for _ , genomeIdentifier := range allGenomeIdentifiersList {
2024-06-02 10:43:39 +02:00
_ , _ , _ , _ , _ , _ , _ , _ , err := GetPersonMonogenicDiseaseInfoFromGeneticAnalysis ( personAnalysisObject , diseaseName , genomeIdentifier )
2024-04-11 15:51:56 +02:00
if ( err != nil ) { return err }
}
diseaseVariantObjectsList := monogenicDiseaseObject . VariantsList
for _ , diseaseVariantObject := range diseaseVariantObjectsList {
2024-06-02 10:43:39 +02:00
variantIdentifierHex := diseaseVariantObject . VariantIdentifier
variantIdentifier , err := encoding . DecodeHexStringTo3ByteArray ( variantIdentifierHex )
if ( err != nil ) { return err }
2024-04-11 15:51:56 +02:00
for _ , genomeIdentifier := range allGenomeIdentifiersList {
2024-06-02 10:43:39 +02:00
_ , _ , err := GetPersonMonogenicDiseaseVariantInfoFromGeneticAnalysis ( personAnalysisObject , diseaseName , variantIdentifier , genomeIdentifier )
2024-04-11 15:51:56 +02:00
if ( err != nil ) { return err }
}
}
}
polygenicDiseaseObjectsList , err := polygenicDiseases . GetPolygenicDiseaseObjectsList ( )
if ( err != nil ) { return err }
for _ , diseaseObject := range polygenicDiseaseObjectsList {
diseaseName := diseaseObject . DiseaseName
for _ , genomeIdentifier := range allGenomeIdentifiersList {
2024-06-02 10:43:39 +02:00
_ , _ , _ , _ , _ , err := GetPersonPolygenicDiseaseInfoFromGeneticAnalysis ( personAnalysisObject , diseaseName , genomeIdentifier )
2024-04-11 15:51:56 +02:00
if ( err != nil ) { return err }
}
diseaseLocusObjectsList := diseaseObject . LociList
for _ , diseaseLocusObject := range diseaseLocusObjectsList {
2024-06-02 10:43:39 +02:00
locusIdentifierHex := diseaseLocusObject . LocusIdentifier
locusIdentifier , err := encoding . DecodeHexStringTo3ByteArray ( locusIdentifierHex )
if ( err != nil ) { return err }
2024-04-11 15:51:56 +02:00
for _ , genomeIdentifier := range allGenomeIdentifiersList {
2024-06-02 10:43:39 +02:00
_ , _ , _ , _ , _ , _ , _ , err := GetPersonPolygenicDiseaseLocusInfoFromGeneticAnalysis ( personAnalysisObject , diseaseName , locusIdentifier , genomeIdentifier )
2024-04-11 15:51:56 +02:00
if ( err != nil ) { return err }
}
}
}
traitObjectsList , err := traits . GetTraitObjectsList ( )
if ( err != nil ) { return err }
for _ , traitObject := range traitObjectsList {
traitName := traitObject . TraitName
for _ , genomeIdentifier := range allGenomeIdentifiersList {
2024-06-02 10:43:39 +02:00
_ , _ , _ , _ , _ , err := GetPersonTraitInfoFromGeneticAnalysis ( personAnalysisObject , traitName , genomeIdentifier )
2024-04-11 15:51:56 +02:00
if ( err != nil ) { return err }
}
traitRulesList := traitObject . RulesList
for _ , traitRuleObject := range traitRulesList {
2024-06-02 10:43:39 +02:00
ruleIdentifierHex := traitRuleObject . RuleIdentifier
ruleIdentifier , err := encoding . DecodeHexStringTo3ByteArray ( ruleIdentifierHex )
if ( err != nil ) { return err }
2024-04-11 15:51:56 +02:00
for _ , genomeIdentifier := range allGenomeIdentifiersList {
2024-06-02 10:43:39 +02:00
_ , _ , err := GetPersonTraitRuleInfoFromGeneticAnalysis ( personAnalysisObject , traitName , ruleIdentifier , genomeIdentifier )
2024-04-11 15:51:56 +02:00
if ( err != nil ) { return err }
}
}
}
return nil
}
2024-06-02 10:43:39 +02:00
// We use this function to verify a couple genetic analysis is well formed
//TODO: Perform sanity checks on data
func VerifyCoupleGeneticAnalysis ( coupleAnalysisObject geneticAnalysis . CoupleAnalysis ) error {
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
pair1Person1GenomeIdentifier , pair1Person2GenomeIdentifier , secondGenomePairExists , pair2Person1GenomeIdentifier , pair2Person2GenomeIdentifier , _ , _ , _ , _ , _ , _ , err := GetMetadataFromCoupleGeneticAnalysis ( coupleAnalysisObject )
2024-04-11 15:51:56 +02:00
if ( err != nil ) { return err }
2024-06-02 10:43:39 +02:00
pair1GenomeIdentifier := helpers . JoinTwo16ByteArrays ( pair1Person1GenomeIdentifier , pair1Person2GenomeIdentifier )
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
allGenomePairIdentifiersList := [ ] [ 32 ] byte { pair1GenomeIdentifier }
2024-04-11 15:51:56 +02:00
if ( secondGenomePairExists == true ) {
2024-06-02 10:43:39 +02:00
pair2GenomeIdentifier := helpers . JoinTwo16ByteArrays ( pair2Person1GenomeIdentifier , pair2Person2GenomeIdentifier )
2024-04-11 15:51:56 +02:00
allGenomePairIdentifiersList = append ( allGenomePairIdentifiersList , pair2GenomeIdentifier )
}
monogenicDiseaseObjectsList , err := monogenicDiseases . GetMonogenicDiseaseObjectsList ( )
if ( err != nil ) { return err }
for _ , monogenicDiseaseObject := range monogenicDiseaseObjectsList {
diseaseName := monogenicDiseaseObject . DiseaseName
for _ , genomePairIdentifier := range allGenomePairIdentifiersList {
2024-06-02 10:43:39 +02:00
_ , _ , _ , _ , _ , _ , _ , err = GetOffspringMonogenicDiseaseInfoFromGeneticAnalysis ( coupleAnalysisObject , diseaseName , genomePairIdentifier )
2024-04-11 15:51:56 +02:00
if ( err != nil ) { return err }
}
diseaseVariantObjectsList := monogenicDiseaseObject . VariantsList
for _ , diseaseVariantObject := range diseaseVariantObjectsList {
2024-06-02 10:43:39 +02:00
variantIdentifierHex := diseaseVariantObject . VariantIdentifier
variantIdentifier , err := encoding . DecodeHexStringTo3ByteArray ( variantIdentifierHex )
if ( err != nil ) { return err }
2024-04-11 15:51:56 +02:00
for _ , genomePairIdentifier := range allGenomePairIdentifiersList {
2024-06-02 10:43:39 +02:00
_ , _ , _ , _ , _ , _ , _ , _ , _ , _ , err := GetOffspringMonogenicDiseaseVariantInfoFromGeneticAnalysis ( coupleAnalysisObject , diseaseName , variantIdentifier , genomePairIdentifier )
2024-04-11 15:51:56 +02:00
if ( err != nil ) { return err }
}
}
}
polygenicDiseaseObjectsList , err := polygenicDiseases . GetPolygenicDiseaseObjectsList ( )
if ( err != nil ) { return err }
for _ , diseaseObject := range polygenicDiseaseObjectsList {
diseaseName := diseaseObject . DiseaseName
for _ , genomePairIdentifier := range allGenomePairIdentifiersList {
2024-06-02 10:43:39 +02:00
_ , _ , _ , _ , _ , err := GetOffspringPolygenicDiseaseInfoFromGeneticAnalysis ( coupleAnalysisObject , diseaseName , genomePairIdentifier )
2024-04-11 15:51:56 +02:00
if ( err != nil ) { return err }
}
diseaseLocusObjectsList := diseaseObject . LociList
for _ , diseaseLocusObject := range diseaseLocusObjectsList {
2024-06-02 10:43:39 +02:00
locusIdentifierHex := diseaseLocusObject . LocusIdentifier
locusIdentifier , err := encoding . DecodeHexStringTo3ByteArray ( locusIdentifierHex )
if ( err != nil ) { return err }
2024-04-11 15:51:56 +02:00
for _ , genomePairIdentifier := range allGenomePairIdentifiersList {
2024-06-02 10:43:39 +02:00
_ , _ , _ , _ , _ , err := GetOffspringPolygenicDiseaseLocusInfoFromGeneticAnalysis ( coupleAnalysisObject , diseaseName , locusIdentifier , genomePairIdentifier )
2024-04-11 15:51:56 +02:00
if ( err != nil ) { return err }
}
}
}
traitObjectsList , err := traits . GetTraitObjectsList ( )
if ( err != nil ) { return err }
for _ , traitObject := range traitObjectsList {
traitName := traitObject . TraitName
for _ , genomePairIdentifier := range allGenomePairIdentifiersList {
2024-06-02 10:43:39 +02:00
_ , _ , _ , _ , err := GetOffspringTraitInfoFromGeneticAnalysis ( coupleAnalysisObject , traitName , genomePairIdentifier )
2024-04-11 15:51:56 +02:00
if ( err != nil ) { return err }
}
traitRulesList := traitObject . RulesList
for _ , traitRuleObject := range traitRulesList {
2024-06-02 10:43:39 +02:00
ruleIdentifierHex := traitRuleObject . RuleIdentifier
ruleIdentifier , err := encoding . DecodeHexStringTo3ByteArray ( ruleIdentifierHex )
if ( err != nil ) { return err }
2024-04-11 15:51:56 +02:00
for _ , genomePairIdentifier := range allGenomePairIdentifiersList {
2024-06-02 10:43:39 +02:00
_ , _ , _ , err := GetOffspringTraitRuleInfoFromGeneticAnalysis ( coupleAnalysisObject , traitName , ruleIdentifier , genomePairIdentifier )
2024-04-11 15:51:56 +02:00
if ( err != nil ) { return err }
}
}
}
return nil
}