2024-04-11 15:51:56 +02:00
package gui
// viewAnalysisGui_Couple.go implements pages to view a couple genetic analysis
import "fyne.io/fyne/v2"
import "fyne.io/fyne/v2/container"
import "fyne.io/fyne/v2/layout"
import "fyne.io/fyne/v2/theme"
import "fyne.io/fyne/v2/widget"
2024-06-07 02:04:13 +02:00
import "fyne.io/fyne/v2/canvas"
2024-04-11 15:51:56 +02:00
2024-07-19 19:16:28 +02:00
import "seekia/resources/geneticPredictionModels"
2024-04-11 15:51:56 +02:00
import "seekia/resources/geneticReferences/monogenicDiseases"
import "seekia/resources/geneticReferences/polygenicDiseases"
import "seekia/resources/geneticReferences/traits"
import "seekia/internal/appMemory"
2024-06-07 02:04:13 +02:00
import "seekia/internal/createCharts"
2024-06-02 10:43:39 +02:00
import "seekia/internal/encoding"
import "seekia/internal/genetics/geneticAnalysis"
2024-04-11 15:51:56 +02:00
import "seekia/internal/genetics/myGenomes"
import "seekia/internal/genetics/myPeople"
import "seekia/internal/genetics/readGeneticAnalysis"
import "seekia/internal/helpers"
2024-06-07 02:04:13 +02:00
import "seekia/internal/statisticsDatum"
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
import "slices"
2024-06-07 02:04:13 +02:00
import "image"
2024-04-11 15:51:56 +02:00
import "errors"
2024-06-02 10:43:39 +02:00
func setViewCoupleGeneticAnalysisPage ( window fyne . Window , person1Identifier string , person2Identifier string , person1AnalysisObject geneticAnalysis . PersonAnalysis , person2AnalysisObject geneticAnalysis . PersonAnalysis , coupleAnalysisObject geneticAnalysis . CoupleAnalysis , numberOfPerson1GenomesAnalyzed int , numberOfPerson2GenomesAnalyzed int , previousPage func ( ) ) {
2024-04-11 15:51:56 +02:00
appMemory . SetMemoryEntry ( "CurrentViewedPage" , "ViewCoupleGeneticAnalysisPage" )
2024-06-02 10:43:39 +02:00
currentPage := func ( ) { setViewCoupleGeneticAnalysisPage ( window , person1Identifier , person2Identifier , person1AnalysisObject , person2AnalysisObject , coupleAnalysisObject , numberOfPerson1GenomesAnalyzed , numberOfPerson2GenomesAnalyzed , previousPage ) }
2024-04-11 15:51:56 +02:00
title := getPageTitleCentered ( "Viewing Genetic Analysis" )
backButton := getBackButtonCentered ( previousPage )
2024-06-02 10:43:39 +02:00
warningLabel1 := getBoldLabelCentered ( "WARNING: Results are not accurate!" )
warningLabel2 := getBoldLabelCentered ( "The analysis algorithms have known issues that are being worked on." )
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
person1Found , person1Name , _ , _ , err := myPeople . GetPersonInfo ( person1Identifier )
2024-04-11 15:51:56 +02:00
if ( err != nil ) {
setErrorEncounteredPage ( window , err , previousPage )
return
}
2024-06-02 10:43:39 +02:00
if ( person1Found == false ) {
2024-07-19 19:16:28 +02:00
setErrorEncounteredPage ( window , errors . New ( "Couple person 1 not found." ) , previousPage )
2024-04-11 15:51:56 +02:00
return
}
2024-06-02 10:43:39 +02:00
person2Found , person2Name , _ , _ , err := myPeople . GetPersonInfo ( person2Identifier )
2024-04-11 15:51:56 +02:00
if ( err != nil ) {
setErrorEncounteredPage ( window , err , previousPage )
return
}
2024-06-02 10:43:39 +02:00
if ( person2Found == false ) {
2024-07-19 19:16:28 +02:00
setErrorEncounteredPage ( window , errors . New ( "Couple person 2 not found." ) , previousPage )
2024-04-11 15:51:56 +02:00
return
}
coupleNameLabel := widget . NewLabel ( "Couple Name:" )
2024-06-02 10:43:39 +02:00
coupleNameText := getBoldLabel ( person1Name + " + " + person2Name )
2024-04-11 15:51:56 +02:00
coupleNameRow := container . NewHBox ( layout . NewSpacer ( ) , coupleNameLabel , coupleNameText , layout . NewSpacer ( ) )
numberOfAnalyzedGenomesLabel := getLabelCentered ( "Number of Analyzed Genomes:" )
2024-06-02 10:43:39 +02:00
person1NameLabel := widget . NewLabel ( person1Name + ":" )
person1NumberOfGenomesAnalyzedString := helpers . ConvertIntToString ( numberOfPerson1GenomesAnalyzed )
person1NumberOfGenomesAnalyzedLabel := getBoldLabel ( person1NumberOfGenomesAnalyzedString )
person1NumberOfAnalyzedGenomesRow := container . NewHBox ( layout . NewSpacer ( ) , person1NameLabel , person1NumberOfGenomesAnalyzedLabel , layout . NewSpacer ( ) )
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
person2NameLabel := widget . NewLabel ( person2Name + ":" )
person2NumberOfGenomesAnalyzedString := helpers . ConvertIntToString ( numberOfPerson2GenomesAnalyzed )
person2NumberOfGenomesAnalyzedLabel := getBoldLabel ( person2NumberOfGenomesAnalyzedString )
person2NumberOfAnalyzedGenomesRow := container . NewHBox ( layout . NewSpacer ( ) , person2NameLabel , person2NumberOfGenomesAnalyzedLabel , layout . NewSpacer ( ) )
2024-04-11 15:51:56 +02:00
generalButton := widget . NewButton ( "General" , func ( ) {
//TODO: Offspring inbred rating (kinship of parents), ancestry
showUnderConstructionDialog ( window )
} )
monogenicDiseasesButton := widget . NewButton ( "Monogenic Diseases" , func ( ) {
2024-06-02 10:43:39 +02:00
setViewCoupleGeneticAnalysisMonogenicDiseasesPage ( window , person1Name , person2Name , person1AnalysisObject , person2AnalysisObject , coupleAnalysisObject , currentPage )
2024-04-11 15:51:56 +02:00
} )
polygenicDiseasesButton := widget . NewButton ( "Polygenic Diseases" , func ( ) {
2024-06-02 10:43:39 +02:00
setViewCoupleGeneticAnalysisPolygenicDiseasesPage ( window , person1Name , person2Name , person1AnalysisObject , person2AnalysisObject , coupleAnalysisObject , currentPage )
2024-04-11 15:51:56 +02:00
} )
2024-07-19 19:16:28 +02:00
discreteTraitsButton := widget . NewButton ( "Discrete Traits" , func ( ) {
setViewCoupleGeneticAnalysisDiscreteTraitsPage ( window , person1Name , person2Name , person1AnalysisObject , person2AnalysisObject , coupleAnalysisObject , currentPage )
} )
numericTraitsButton := widget . NewButton ( "Numeric Traits" , func ( ) {
//TODO
showUnderConstructionDialog ( window )
2024-04-11 15:51:56 +02:00
} )
2024-07-19 19:16:28 +02:00
categoryButtonsGrid := getContainerCentered ( container . NewGridWithColumns ( 1 , generalButton , monogenicDiseasesButton , polygenicDiseasesButton , discreteTraitsButton , numericTraitsButton ) )
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
page := container . NewVBox ( title , backButton , widget . NewSeparator ( ) , warningLabel1 , warningLabel2 , widget . NewSeparator ( ) , coupleNameRow , widget . NewSeparator ( ) , numberOfAnalyzedGenomesLabel , person1NumberOfAnalyzedGenomesRow , person2NumberOfAnalyzedGenomesRow , widget . NewSeparator ( ) , categoryButtonsGrid )
2024-04-11 15:51:56 +02:00
setPageContent ( page , window )
}
2024-06-02 10:43:39 +02:00
func setViewCoupleGeneticAnalysisMonogenicDiseasesPage ( window fyne . Window , person1Name string , person2Name string , person1AnalysisObject geneticAnalysis . PersonAnalysis , person2AnalysisObject geneticAnalysis . PersonAnalysis , coupleAnalysisObject geneticAnalysis . CoupleAnalysis , previousPage func ( ) ) {
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
currentPage := func ( ) { setViewCoupleGeneticAnalysisMonogenicDiseasesPage ( window , person1Name , person2Name , person1AnalysisObject , person2AnalysisObject , coupleAnalysisObject , previousPage ) }
2024-04-11 15:51:56 +02:00
title := getPageTitleCentered ( "Viewing Genetic Analysis - Monogenic Diseases" )
backButton := getBackButtonCentered ( previousPage )
description := getLabelCentered ( "Below is an analysis of the monogenic disease probabilities for the couple's offspring." )
//TODO: Sort so highest risk diseases are at the top. Everything else should be in normal order
getMonogenicDiseasesGrid := func ( ) ( * fyne . Container , error ) {
2024-06-02 10:43:39 +02:00
pair1Person1GenomeIdentifier , pair1Person2GenomeIdentifier , secondGenomePairExists , _ , _ , _ , _ , _ , _ , _ , _ , err := readGeneticAnalysis . GetMetadataFromCoupleGeneticAnalysis ( coupleAnalysisObject )
2024-04-11 15:51:56 +02:00
if ( err != nil ) { return nil , err }
emptyLabelA := widget . NewLabel ( "" )
diseaseNameLabel := getItalicLabelCentered ( "Disease Name" )
offspringProbabilityOfLabel := getItalicLabelCentered ( "Offspring Probability Of" )
havingDiseaseLabel := getItalicLabelCentered ( "Having Disease" )
emptyLabelB := widget . NewLabel ( "" )
conflictExistsLabel := getItalicLabelCentered ( "Conflict Exists?" )
emptyLabelC := widget . NewLabel ( "" )
emptyLabelD := widget . NewLabel ( "" )
diseaseNameColumn := container . NewVBox ( emptyLabelA , diseaseNameLabel , widget . NewSeparator ( ) )
offspringProbabilityOfHavingDiseaseColumn := container . NewVBox ( offspringProbabilityOfLabel , havingDiseaseLabel , widget . NewSeparator ( ) )
conflictExistsColumn := container . NewVBox ( emptyLabelB , conflictExistsLabel , widget . NewSeparator ( ) )
viewButtonsColumn := container . NewVBox ( emptyLabelC , emptyLabelD , widget . NewSeparator ( ) )
monogenicDiseaseNamesList , err := monogenicDiseases . GetMonogenicDiseaseNamesList ( )
if ( err != nil ) { return nil , err }
for _ , diseaseName := range monogenicDiseaseNamesList {
2024-06-02 10:43:39 +02:00
pair1GenomeIdentifierSlice := slices . Concat ( pair1Person1GenomeIdentifier [ : ] , pair1Person2GenomeIdentifier [ : ] )
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
pair1GenomeIdentifier := [ 32 ] byte ( pair1GenomeIdentifierSlice )
offspringHasDiseaseProbabilityIsKnown , _ , genomePairOffspringProbabilityOfHavingDisease , _ , _ , _ , conflictExists , err := readGeneticAnalysis . GetOffspringMonogenicDiseaseInfoFromGeneticAnalysis ( coupleAnalysisObject , diseaseName , pair1GenomeIdentifier )
2024-04-11 15:51:56 +02:00
if ( err != nil ) { return nil , err }
getOffspringProbabilityOfHavingDiseaseText := func ( ) string {
2024-06-02 10:43:39 +02:00
if ( offspringHasDiseaseProbabilityIsKnown == false ) {
2024-04-11 15:51:56 +02:00
result := translate ( "Unknown" )
return result
}
return genomePairOffspringProbabilityOfHavingDisease
}
offspringProbabilityOfHavingDiseaseText := getOffspringProbabilityOfHavingDiseaseText ( )
diseaseNameText := getBoldLabelCentered ( diseaseName )
diseaseNameColumn . Add ( diseaseNameText )
offspringProbabilityOfHavingDiseaseLabel := getBoldLabelCentered ( offspringProbabilityOfHavingDiseaseText )
offspringProbabilityOfHavingDiseaseColumn . Add ( offspringProbabilityOfHavingDiseaseLabel )
conflictExistsString := helpers . ConvertBoolToYesOrNoString ( conflictExists )
conflictExistsLabel := getBoldLabelCentered ( conflictExistsString )
conflictExistsColumn . Add ( conflictExistsLabel )
viewDetailsButton := getWidgetCentered ( widget . NewButtonWithIcon ( "" , theme . VisibilityIcon ( ) , func ( ) {
2024-06-02 10:43:39 +02:00
setViewCoupleGeneticAnalysisMonogenicDiseaseDetailsPage ( window , person1Name , person2Name , person1AnalysisObject , person2AnalysisObject , coupleAnalysisObject , diseaseName , currentPage )
2024-04-11 15:51:56 +02:00
} ) )
viewButtonsColumn . Add ( viewDetailsButton )
diseaseNameColumn . Add ( widget . NewSeparator ( ) )
offspringProbabilityOfHavingDiseaseColumn . Add ( widget . NewSeparator ( ) )
conflictExistsColumn . Add ( widget . NewSeparator ( ) )
viewButtonsColumn . Add ( widget . NewSeparator ( ) )
}
offspringProbabilityOfHavingDiseaseHelpButton := widget . NewButtonWithIcon ( "" , theme . QuestionIcon ( ) , func ( ) {
setOffspringProbabilityOfHavingMonogenicDiseaseExplainerPage ( window , currentPage )
} )
offspringProbabilityOfHavingDiseaseColumn . Add ( offspringProbabilityOfHavingDiseaseHelpButton )
diseasesGrid := container . NewHBox ( layout . NewSpacer ( ) , diseaseNameColumn , offspringProbabilityOfHavingDiseaseColumn )
if ( secondGenomePairExists == true ) {
conflictExistsHelpButton := widget . NewButtonWithIcon ( "" , theme . QuestionIcon ( ) , func ( ) {
setCoupleGeneticAnalysisConflictExistsExplainerPage ( window , currentPage )
} )
conflictExistsColumn . Add ( conflictExistsHelpButton )
diseasesGrid . Add ( conflictExistsColumn )
}
diseasesGrid . Add ( viewButtonsColumn )
diseasesGrid . Add ( layout . NewSpacer ( ) )
return diseasesGrid , nil
}
monogenicDiseasesContainer , err := getMonogenicDiseasesGrid ( )
if ( err != nil ) {
setErrorEncounteredPage ( window , err , previousPage )
return
}
page := container . NewVBox ( title , backButton , widget . NewSeparator ( ) , description , widget . NewSeparator ( ) , monogenicDiseasesContainer )
setPageContent ( page , window )
}
2024-06-02 10:43:39 +02:00
func setViewCoupleGeneticAnalysisMonogenicDiseaseDetailsPage ( window fyne . Window , person1Name string , person2Name string , person1AnalysisObject geneticAnalysis . PersonAnalysis , person2AnalysisObject geneticAnalysis . PersonAnalysis , coupleAnalysisObject geneticAnalysis . CoupleAnalysis , diseaseName string , previousPage func ( ) ) {
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
currentPage := func ( ) { setViewCoupleGeneticAnalysisMonogenicDiseaseDetailsPage ( window , person1Name , person2Name , person1AnalysisObject , person2AnalysisObject , coupleAnalysisObject , diseaseName , previousPage ) }
2024-04-11 15:51:56 +02:00
title := getPageTitleCentered ( "Viewing Couple Analysis - " + diseaseName )
backButton := getBackButtonCentered ( previousPage )
2024-06-02 10:43:39 +02:00
pair1Person1GenomeIdentifier , pair1Person2GenomeIdentifier , secondGenomePairExists , pair2Person1GenomeIdentifier , pair2Person2GenomeIdentifier , _ , _ , _ , _ , _ , _ , err := readGeneticAnalysis . GetMetadataFromCoupleGeneticAnalysis ( coupleAnalysisObject )
2024-04-11 15:51:56 +02:00
if ( err != nil ) {
setErrorEncounteredPage ( window , err , previousPage )
return
}
getDescriptionSection := func ( ) * fyne . Container {
if ( secondGenomePairExists == false ) {
description := getLabelCentered ( "Below are the disease probabilities for the couple's offspring." )
return description
}
description1 := getLabelCentered ( "Below are the disease probabilities for the couple's offspring." )
description2 := getLabelCentered ( "Each genome pair combines different genomes from each person." )
descriptionsSection := container . NewVBox ( description1 , description2 )
return descriptionsSection
}
descriptionSection := getDescriptionSection ( )
diseaseNameLabel := widget . NewLabel ( "Disease:" )
diseaseNameText := getBoldLabel ( diseaseName )
diseaseNameInfoButton := widget . NewButtonWithIcon ( "" , theme . InfoIcon ( ) , func ( ) {
setViewMonogenicDiseaseDetailsPage ( window , diseaseName , currentPage )
} )
diseaseNameRow := container . NewHBox ( layout . NewSpacer ( ) , diseaseNameLabel , diseaseNameText , diseaseNameInfoButton , layout . NewSpacer ( ) )
emptyLabel1 := widget . NewLabel ( "" )
emptyLabel2 := widget . NewLabel ( "" )
emptyLabel3 := widget . NewLabel ( "" )
emptyLabel4 := widget . NewLabel ( "" )
offspringProbabilityOfLabel1 := getItalicLabelCentered ( "Offspring Probability Of" )
havingDiseaseLabel := getItalicLabelCentered ( "Having Disease" )
offspringProbabilityOfLabel2 := getItalicLabelCentered ( "Offspring Probability Of" )
havingVariantLabel := getItalicLabelCentered ( "Having Variant" )
emptyLabel5 := widget . NewLabel ( "" )
emptyLabel6 := widget . NewLabel ( "" )
viewGenomePairButtonsColumn := container . NewVBox ( emptyLabel1 , emptyLabel2 , widget . NewSeparator ( ) )
pairNameColumn := container . NewVBox ( emptyLabel3 , emptyLabel4 , widget . NewSeparator ( ) )
offspringProbabilityOfHavingDiseaseColumn := container . NewVBox ( offspringProbabilityOfLabel1 , havingDiseaseLabel , widget . NewSeparator ( ) )
offspringProbabilityOfHavingVariantColumn := container . NewVBox ( offspringProbabilityOfLabel2 , havingVariantLabel , widget . NewSeparator ( ) )
viewOffspringVariantButtonsColumn := container . NewVBox ( emptyLabel5 , emptyLabel6 , widget . NewSeparator ( ) )
2024-06-02 10:43:39 +02:00
addGenomePairRow := func ( genomePairName string , person1GenomeIdentifier [ 16 ] byte , person2GenomeIdentifier [ 16 ] byte ) error {
genomePairIdentifierSlice := slices . Concat ( person1GenomeIdentifier [ : ] , person2GenomeIdentifier [ : ] )
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
genomePairIdentifier := [ 32 ] byte ( genomePairIdentifierSlice )
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
offspringProbabilityOfHavingDiseaseIsKnown , _ , genomePairOffspringProbabilityOfHavingDisease , offspringProbabilityOfHavingAVariantIsKnown , _ , genomePairOffspringProbabilityOfHavingAVariant , _ , err := readGeneticAnalysis . GetOffspringMonogenicDiseaseInfoFromGeneticAnalysis ( coupleAnalysisObject , diseaseName , genomePairIdentifier )
2024-04-11 15:51:56 +02:00
if ( err != nil ) { return err }
getOffspringProbabilityOfHavingDiseaseText := func ( ) string {
2024-06-02 10:43:39 +02:00
if ( offspringProbabilityOfHavingDiseaseIsKnown == false ) {
2024-04-11 15:51:56 +02:00
result := translate ( "Unknown" )
return result
}
return genomePairOffspringProbabilityOfHavingDisease
}
offspringProbabilityOfHavingDiseaseText := getOffspringProbabilityOfHavingDiseaseText ( )
getOffspringProbabilityOfHavingAVariantText := func ( ) string {
2024-06-02 10:43:39 +02:00
if ( offspringProbabilityOfHavingAVariantIsKnown == false ) {
2024-04-11 15:51:56 +02:00
result := translate ( "Unknown" )
return result
}
return genomePairOffspringProbabilityOfHavingAVariant
}
offspringProbabilityOfHavingAVariantText := getOffspringProbabilityOfHavingAVariantText ( )
genomePairNameLabel := getBoldLabelCentered ( genomePairName )
offspringProbabilityOfHavingDiseaseLabel := getBoldLabelCentered ( offspringProbabilityOfHavingDiseaseText )
offspringProbabilityOfHavingAVariantLabel := getBoldLabelCentered ( offspringProbabilityOfHavingAVariantText )
viewGenomePairButton := widget . NewButtonWithIcon ( "" , theme . InfoIcon ( ) , func ( ) {
2024-06-02 10:43:39 +02:00
setViewCoupleGeneticAnalysisMonogenicDiseaseGenomePairDetailsPage ( window , person1Name , person2Name , person1AnalysisObject , person2AnalysisObject , coupleAnalysisObject , diseaseName , genomePairIdentifier , genomePairName , currentPage )
2024-04-11 15:51:56 +02:00
} )
viewOffspringVariantsButton := widget . NewButtonWithIcon ( "" , theme . VisibilityIcon ( ) , func ( ) {
2024-06-02 10:43:39 +02:00
setViewCoupleMonogenicDiseaseVariantsPage ( window , person1Name , person2Name , person1AnalysisObject , person2AnalysisObject , coupleAnalysisObject , diseaseName , genomePairIdentifier , genomePairName , currentPage )
2024-04-11 15:51:56 +02:00
} )
viewGenomePairButtonsColumn . Add ( viewGenomePairButton )
pairNameColumn . Add ( genomePairNameLabel )
offspringProbabilityOfHavingDiseaseColumn . Add ( offspringProbabilityOfHavingDiseaseLabel )
offspringProbabilityOfHavingVariantColumn . Add ( offspringProbabilityOfHavingAVariantLabel )
viewOffspringVariantButtonsColumn . Add ( viewOffspringVariantsButton )
viewGenomePairButtonsColumn . Add ( widget . NewSeparator ( ) )
pairNameColumn . Add ( widget . NewSeparator ( ) )
offspringProbabilityOfHavingDiseaseColumn . Add ( widget . NewSeparator ( ) )
offspringProbabilityOfHavingVariantColumn . Add ( widget . NewSeparator ( ) )
viewOffspringVariantButtonsColumn . Add ( widget . NewSeparator ( ) )
return nil
}
2024-06-02 10:43:39 +02:00
err = addGenomePairRow ( "Pair 1" , pair1Person1GenomeIdentifier , pair1Person2GenomeIdentifier )
2024-04-11 15:51:56 +02:00
if ( err != nil ) {
setErrorEncounteredPage ( window , err , previousPage )
return
}
if ( secondGenomePairExists == true ) {
2024-06-02 10:43:39 +02:00
err := addGenomePairRow ( "Pair 2" , pair2Person1GenomeIdentifier , pair2Person2GenomeIdentifier )
2024-04-11 15:51:56 +02:00
if ( err != nil ) {
setErrorEncounteredPage ( window , err , previousPage )
return
}
}
offspringProbabilityOfHavingDiseaseHelpButton := widget . NewButtonWithIcon ( "" , theme . QuestionIcon ( ) , func ( ) {
setOffspringProbabilityOfHavingMonogenicDiseaseExplainerPage ( window , currentPage )
} )
offspringProbabilityOfHavingVariantHelpButton := widget . NewButtonWithIcon ( "" , theme . QuestionIcon ( ) , func ( ) {
setOffspringProbabilityOfHavingVariantExplainerPage ( window , currentPage )
} )
offspringProbabilityOfHavingDiseaseColumn . Add ( offspringProbabilityOfHavingDiseaseHelpButton )
offspringProbabilityOfHavingVariantColumn . Add ( offspringProbabilityOfHavingVariantHelpButton )
genomesContainer := container . NewHBox ( layout . NewSpacer ( ) , viewGenomePairButtonsColumn , pairNameColumn , offspringProbabilityOfHavingDiseaseColumn , offspringProbabilityOfHavingVariantColumn , viewOffspringVariantButtonsColumn , layout . NewSpacer ( ) )
page := container . NewVBox ( title , backButton , widget . NewSeparator ( ) , descriptionSection , widget . NewSeparator ( ) , diseaseNameRow , widget . NewSeparator ( ) , genomesContainer )
setPageContent ( page , window )
}
2024-06-02 10:43:39 +02:00
func setViewCoupleGeneticAnalysisMonogenicDiseaseGenomePairDetailsPage ( window fyne . Window , person1Name string , person2Name string , person1AnalysisObject geneticAnalysis . PersonAnalysis , person2AnalysisObject geneticAnalysis . PersonAnalysis , coupleAnalysisObject geneticAnalysis . CoupleAnalysis , diseaseName string , genomePairIdentifier [ 32 ] byte , genomePairName string , previousPage func ( ) ) {
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
currentPage := func ( ) { setViewCoupleGeneticAnalysisMonogenicDiseaseGenomePairDetailsPage ( window , person1Name , person2Name , person1AnalysisObject , person2AnalysisObject , coupleAnalysisObject , diseaseName , genomePairIdentifier , genomePairName , previousPage ) }
2024-04-11 15:51:56 +02:00
title := getPageTitleCentered ( "Viewing Couple Genome Pair Info" )
backButton := getBackButtonCentered ( previousPage )
description := getLabelCentered ( "Below is the disease information for both genomes in the genome pair." )
diseaseNameLabel := widget . NewLabel ( "Disease:" )
diseaseNameText := getBoldLabel ( diseaseName )
diseaseNameInfoButton := widget . NewButtonWithIcon ( "" , theme . InfoIcon ( ) , func ( ) {
setViewMonogenicDiseaseDetailsPage ( window , diseaseName , currentPage )
} )
diseaseNameRow := container . NewHBox ( layout . NewSpacer ( ) , diseaseNameLabel , diseaseNameText , diseaseNameInfoButton , layout . NewSpacer ( ) )
genomePairLabel := widget . NewLabel ( "Genome Pair:" )
genomePairNameLabel := getBoldLabel ( genomePairName )
genomePairHelpButton := widget . NewButtonWithIcon ( "" , theme . QuestionIcon ( ) , func ( ) {
setCoupleGenomePairExplainerPage ( window , currentPage )
} )
genomePairRow := container . NewHBox ( layout . NewSpacer ( ) , genomePairLabel , genomePairNameLabel , genomePairHelpButton , layout . NewSpacer ( ) )
2024-06-02 10:43:39 +02:00
diseaseVariantsMap , err := monogenicDiseases . GetMonogenicDiseaseVariantsMap ( diseaseName )
if ( err != nil ) {
setErrorEncounteredPage ( window , err , previousPage )
return
}
totalNumberOfVariants := len ( diseaseVariantsMap )
totalNumberOfVariantsString := helpers . ConvertIntToString ( totalNumberOfVariants )
2024-04-11 15:51:56 +02:00
emptyLabelA := widget . NewLabel ( "" )
personNameLabel := getItalicLabelCentered ( "Person Name" )
emptyLabelB := widget . NewLabel ( "" )
genomeNameLabel := getItalicLabelCentered ( "Genome Name" )
probabilityOfLabel := getItalicLabelCentered ( "Probability Of" )
passingAVariantLabel := getItalicLabelCentered ( "Passing A Variant" )
numberOfLabel := getItalicLabelCentered ( "Number Of" )
variantsTestedLabel := getItalicLabelCentered ( "Variants Tested" )
emptyLabelC := widget . NewLabel ( "" )
emptyLabelD := widget . NewLabel ( "" )
personNameColumn := container . NewVBox ( emptyLabelA , personNameLabel , widget . NewSeparator ( ) )
genomeNameColumn := container . NewVBox ( emptyLabelB , genomeNameLabel , widget . NewSeparator ( ) )
probabilityOfPassingAVariantColumn := container . NewVBox ( probabilityOfLabel , passingAVariantLabel , widget . NewSeparator ( ) )
numberOfVariantsTestedColumn := container . NewVBox ( numberOfLabel , variantsTestedLabel , widget . NewSeparator ( ) )
viewGenomeButtonsColumn := container . NewVBox ( emptyLabelC , emptyLabelD , widget . NewSeparator ( ) )
2024-06-02 10:43:39 +02:00
addGenomeRow := func ( isPerson1 bool , personName string , inputGenomeIdentifier [ 16 ] byte ) error {
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
personAnalysisGenomeIdentifier , _ , genomeIsCombined , combinedType , err := readGeneticAnalysis . GetMatchingPersonAnalysisGenomeIdentifierFromCoupleAnalysis ( isPerson1 , person1AnalysisObject , person2AnalysisObject , coupleAnalysisObject , inputGenomeIdentifier )
2024-04-11 15:51:56 +02:00
if ( err != nil ) { return err }
personNameTrimmed , _ , err := helpers . TrimAndFlattenString ( personName , 10 )
if ( err != nil ) { return err }
personNameLabel := getBoldLabelCentered ( personNameTrimmed )
2024-06-02 10:43:39 +02:00
getPersonAnalysisObject := func ( ) geneticAnalysis . PersonAnalysis {
if ( isPerson1 == true ) {
return person1AnalysisObject
2024-04-11 15:51:56 +02:00
}
2024-06-02 10:43:39 +02:00
return person2AnalysisObject
2024-04-11 15:51:56 +02:00
}
2024-06-02 10:43:39 +02:00
personAnalysisObject := getPersonAnalysisObject ( )
2024-04-11 15:51:56 +02:00
getGenomeName := func ( ) ( string , error ) {
if ( genomeIsCombined == false ) {
2024-06-02 10:43:39 +02:00
2024-04-11 15:51:56 +02:00
genomeFound , _ , _ , _ , _ , _ , companyName , _ , _ , err := myGenomes . GetMyRawGenomeMetadata ( personAnalysisGenomeIdentifier )
if ( err != nil ) { return "" , err }
if ( genomeFound == false ) {
2024-06-02 10:43:39 +02:00
return "" , errors . New ( "MyGenomeInfo for genome from analysisObject not found." )
2024-04-11 15:51:56 +02:00
}
return companyName , nil
}
return combinedType , nil
}
genomeName , err := getGenomeName ( )
if ( err != nil ) { return err }
genomeNameLabel := getBoldLabelCentered ( genomeName )
2024-06-02 10:43:39 +02:00
probabilitiesKnown , _ , _ , probabilityOfPassingAVariantFormatted , personNumberOfVariantsTested , _ , _ , _ , err := readGeneticAnalysis . GetPersonMonogenicDiseaseInfoFromGeneticAnalysis ( personAnalysisObject , diseaseName , personAnalysisGenomeIdentifier )
2024-04-11 15:51:56 +02:00
if ( err != nil ) { return err }
getProbabilityOfPassingAVariantText := func ( ) string {
if ( probabilitiesKnown == false ) {
result := translate ( "Unknown" )
return result
}
return probabilityOfPassingAVariantFormatted
}
genomeProbabilityOfPassingAVariantText := getProbabilityOfPassingAVariantText ( )
2024-06-02 10:43:39 +02:00
2024-04-11 15:51:56 +02:00
genomeProbabilityOfPassingAVariantLabel := getBoldLabelCentered ( genomeProbabilityOfPassingAVariantText )
personNumberOfVariantsTestedString := helpers . ConvertIntToString ( personNumberOfVariantsTested )
2024-06-02 10:43:39 +02:00
genomeNumberOfVariantsTestedLabel := getBoldLabelCentered ( personNumberOfVariantsTestedString + "/" + totalNumberOfVariantsString )
2024-04-11 15:51:56 +02:00
viewGenomeButton := widget . NewButtonWithIcon ( "" , theme . VisibilityIcon ( ) , func ( ) {
2024-06-02 10:43:39 +02:00
setViewPersonGenomeMonogenicDiseaseVariantsPage ( window , personAnalysisObject , personAnalysisGenomeIdentifier , genomeName , diseaseName , currentPage )
2024-04-11 15:51:56 +02:00
} )
personNameColumn . Add ( personNameLabel )
genomeNameColumn . Add ( genomeNameLabel )
probabilityOfPassingAVariantColumn . Add ( genomeProbabilityOfPassingAVariantLabel )
numberOfVariantsTestedColumn . Add ( genomeNumberOfVariantsTestedLabel )
viewGenomeButtonsColumn . Add ( viewGenomeButton )
personNameColumn . Add ( widget . NewSeparator ( ) )
genomeNameColumn . Add ( widget . NewSeparator ( ) )
probabilityOfPassingAVariantColumn . Add ( widget . NewSeparator ( ) )
numberOfVariantsTestedColumn . Add ( widget . NewSeparator ( ) )
viewGenomeButtonsColumn . Add ( widget . NewSeparator ( ) )
return nil
}
2024-06-02 10:43:39 +02:00
person1GenomeIdentifier , person2GenomeIdentifier := helpers . Split32ByteArrayInHalf ( genomePairIdentifier )
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
err = addGenomeRow ( true , person1Name , person1GenomeIdentifier )
2024-04-11 15:51:56 +02:00
if ( err != nil ) {
setErrorEncounteredPage ( window , err , previousPage )
return
}
2024-06-02 10:43:39 +02:00
err = addGenomeRow ( false , person2Name , person2GenomeIdentifier )
2024-04-11 15:51:56 +02:00
if ( err != nil ) {
setErrorEncounteredPage ( window , err , previousPage )
return
}
probabilityOfPassingAVariantHelpButton := widget . NewButtonWithIcon ( "" , theme . QuestionIcon ( ) , func ( ) {
setPersonProbabilityOfPassingVariantExplainerPage ( window , currentPage )
} )
numberOfVariantsTestedHelpButton := widget . NewButtonWithIcon ( "" , theme . QuestionIcon ( ) , func ( ) {
setNumberOfTestedVariantsExplainerPage ( window , currentPage )
} )
probabilityOfPassingAVariantColumn . Add ( probabilityOfPassingAVariantHelpButton )
numberOfVariantsTestedColumn . Add ( numberOfVariantsTestedHelpButton )
genomesGrid := container . NewHBox ( layout . NewSpacer ( ) , personNameColumn , genomeNameColumn , probabilityOfPassingAVariantColumn , numberOfVariantsTestedColumn , viewGenomeButtonsColumn , layout . NewSpacer ( ) )
page := container . NewVBox ( title , backButton , widget . NewSeparator ( ) , description , diseaseNameRow , genomePairRow , widget . NewSeparator ( ) , genomesGrid )
setPageContent ( page , window )
}
// This function provides a page to view the offspring disease variant probabilities for a particular genome pair from a couple genetic analysis
2024-06-02 10:43:39 +02:00
func setViewCoupleMonogenicDiseaseVariantsPage ( window fyne . Window , person1Name string , person2Name string , person1AnalysisObject geneticAnalysis . PersonAnalysis , person2AnalysisObject geneticAnalysis . PersonAnalysis , coupleAnalysisObject geneticAnalysis . CoupleAnalysis , diseaseName string , genomePairIdentifier [ 32 ] byte , genomePairName string , previousPage func ( ) ) {
2024-04-11 15:51:56 +02:00
setLoadingScreen ( window , "Loading Disease Variants" , "Loading disease variants..." )
2024-06-02 10:43:39 +02:00
currentPage := func ( ) { setViewCoupleMonogenicDiseaseVariantsPage ( window , person1Name , person2Name , person1AnalysisObject , person2AnalysisObject , coupleAnalysisObject , diseaseName , genomePairIdentifier , genomePairName , previousPage ) }
2024-04-11 15:51:56 +02:00
title := getPageTitleCentered ( "View Offspring Disease Variants - " + diseaseName )
backButton := getBackButtonCentered ( previousPage )
description1 := widget . NewLabel ( "Below are the disease variant probabilities for offspring from this genome pair." )
variantsHelpButton := widget . NewButtonWithIcon ( "" , theme . QuestionIcon ( ) , func ( ) {
setMonogenicDiseaseVariantsExplainerPage ( window , currentPage )
} )
description1Row := container . NewHBox ( layout . NewSpacer ( ) , description1 , variantsHelpButton , layout . NewSpacer ( ) )
genomePairLabel := widget . NewLabel ( "Genome Pair:" )
genomePairNameLabel := getBoldLabel ( genomePairName )
viewGenomePairInfoButton := widget . NewButtonWithIcon ( "" , theme . InfoIcon ( ) , func ( ) {
2024-06-02 10:43:39 +02:00
setViewCoupleGeneticAnalysisMonogenicDiseaseGenomePairDetailsPage ( window , person1Name , person2Name , person1AnalysisObject , person2AnalysisObject , coupleAnalysisObject , diseaseName , genomePairIdentifier , genomePairName , currentPage )
2024-04-11 15:51:56 +02:00
} )
genomePairRow := container . NewHBox ( layout . NewSpacer ( ) , genomePairLabel , genomePairNameLabel , viewGenomePairInfoButton , layout . NewSpacer ( ) )
2024-06-02 10:43:39 +02:00
//Outputs:
// -int: Number of variants tested
// -int: Number of loci tested
// -int: Number of phased loci
getVariantAndLociInfo := func ( ) ( int , int , int , error ) {
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
person1GenomeIdentifier , person2GenomeIdentifier := helpers . Split32ByteArrayInHalf ( genomePairIdentifier )
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
person1AnalysisGenomeIdentifier , _ , _ , _ , err := readGeneticAnalysis . GetMatchingPersonAnalysisGenomeIdentifierFromCoupleAnalysis ( true , person1AnalysisObject , person2AnalysisObject , coupleAnalysisObject , person1GenomeIdentifier )
if ( err != nil ) { return 0 , 0 , 0 , err }
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
_ , _ , _ , _ , person1NumberOfVariantsTested , person1NumberOfLociTested , person1NumberOfPhasedLoci , _ , err := readGeneticAnalysis . GetPersonMonogenicDiseaseInfoFromGeneticAnalysis ( person1AnalysisObject , diseaseName , person1AnalysisGenomeIdentifier )
if ( err != nil ) { return 0 , 0 , 0 , err }
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
person2AnalysisGenomeIdentifier , _ , _ , _ , err := readGeneticAnalysis . GetMatchingPersonAnalysisGenomeIdentifierFromCoupleAnalysis ( false , person1AnalysisObject , person2AnalysisObject , coupleAnalysisObject , person2GenomeIdentifier )
if ( err != nil ) { return 0 , 0 , 0 , err }
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
_ , _ , _ , _ , person2NumberOfVariantsTested , person2NumberOfLociTested , person2NumberOfPhasedLoci , _ , err := readGeneticAnalysis . GetPersonMonogenicDiseaseInfoFromGeneticAnalysis ( person2AnalysisObject , diseaseName , person2AnalysisGenomeIdentifier )
if ( err != nil ) { return 0 , 0 , 0 , err }
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
numberOfVariantsTested := person1NumberOfVariantsTested + person2NumberOfVariantsTested
numberOfLociTested := person1NumberOfLociTested + person2NumberOfLociTested
numberOfPhasedLoci := person1NumberOfPhasedLoci + person2NumberOfPhasedLoci
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
return numberOfVariantsTested , numberOfLociTested , numberOfPhasedLoci , nil
2024-04-11 15:51:56 +02:00
}
2024-06-02 10:43:39 +02:00
numberOfVariantsTested , numberOfLociTested , numberOfPhasedLoci , err := getVariantAndLociInfo ( )
2024-04-11 15:51:56 +02:00
if ( err != nil ) {
setErrorEncounteredPage ( window , err , previousPage )
return
}
diseaseVariantsMap , err := monogenicDiseases . GetMonogenicDiseaseVariantsMap ( diseaseName )
if ( err != nil ) {
setErrorEncounteredPage ( window , err , previousPage )
return
}
totalNumberOfVariants := len ( diseaseVariantsMap ) * 2
totalNumberOfVariantsString := helpers . ConvertIntToString ( totalNumberOfVariants )
numberOfVariantsTestedString := helpers . ConvertIntToString ( numberOfVariantsTested )
variantsTestedLabel := widget . NewLabel ( "Variants Tested:" )
variantsTestedText := getBoldLabel ( numberOfVariantsTestedString + "/" + totalNumberOfVariantsString )
variantsTestedHelpButton := widget . NewButtonWithIcon ( "" , theme . QuestionIcon ( ) , func ( ) {
setNumberOfTestedVariantsExplainerPage ( window , currentPage )
} )
variantsTestedRow := container . NewHBox ( layout . NewSpacer ( ) , variantsTestedLabel , variantsTestedText , variantsTestedHelpButton , layout . NewSpacer ( ) )
2024-06-02 10:43:39 +02:00
numberOfLociTestedString := helpers . ConvertIntToString ( numberOfLociTested )
numberOfPhasedLociString := helpers . ConvertIntToString ( numberOfPhasedLoci )
phasedLociLabel := widget . NewLabel ( "Phased Loci:" )
phasedLociText := getBoldLabel ( numberOfPhasedLociString + "/" + numberOfLociTestedString )
phasedLociHelpButton := widget . NewButtonWithIcon ( "" , theme . QuestionIcon ( ) , func ( ) {
setNumberOfPhasedLociExplainerPage ( window , currentPage )
} )
phasedLociRow := container . NewHBox ( layout . NewSpacer ( ) , phasedLociLabel , phasedLociText , phasedLociHelpButton , layout . NewSpacer ( ) )
2024-04-11 15:51:56 +02:00
//TODO: Add navigation with pages
getVariantsGrid := func ( ) ( * fyne . Container , error ) {
emptyLabelA := widget . NewLabel ( "" )
variantNameLabel := getItalicLabelCentered ( "Variant Name" )
probabilityOfLabelA := getItalicLabelCentered ( "Probability Of" )
zeroMutationsLabel := getItalicLabelCentered ( "0 Mutations" )
probabilityOfLabelB := getItalicLabelCentered ( "Probability Of" )
oneMutationLabel := getItalicLabelCentered ( "1 Mutation" )
probabilityOfLabelC := getItalicLabelCentered ( "Probability Of" )
twoMutationsLabel := getItalicLabelCentered ( "2 Mutations" )
emptyLabelB := widget . NewLabel ( "" )
emptyLabelC := widget . NewLabel ( "" )
variantNameColumn := container . NewVBox ( emptyLabelA , variantNameLabel , widget . NewSeparator ( ) )
probabilityOf0MutationsColumn := container . NewVBox ( probabilityOfLabelA , zeroMutationsLabel , widget . NewSeparator ( ) )
probabilityOf1MutationColumn := container . NewVBox ( probabilityOfLabelB , oneMutationLabel , widget . NewSeparator ( ) )
probabilityOf2MutationsColumn := container . NewVBox ( probabilityOfLabelC , twoMutationsLabel , widget . NewSeparator ( ) )
variantInfoButtonsColumn := container . NewVBox ( emptyLabelB , emptyLabelC , widget . NewSeparator ( ) )
2024-06-02 10:43:39 +02:00
addVariantRow := func ( variantIdentifierHex string ) error {
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
variantObject , exists := diseaseVariantsMap [ variantIdentifierHex ]
2024-04-11 15:51:56 +02:00
if ( exists == false ) {
return errors . New ( "Cannot add variant row: Variant missing from diseaseVariantsMap" )
}
2024-06-02 10:43:39 +02:00
variantIdentifier , err := encoding . DecodeHexStringTo3ByteArray ( variantIdentifierHex )
if ( err != nil ) {
return errors . New ( "addVariantRow called with invalid variantIdentifier: " + variantIdentifierHex )
}
2024-04-11 15:51:56 +02:00
variantName := variantObject . VariantNames [ 0 ]
2024-06-02 10:43:39 +02:00
offspringProbabilitiesKnown , probabilityOf0MutationsLowerBound , probabilityOf0MutationsUpperBound , probabilityOf0MutationsFormatted , probabilityOf1MutationLowerBound , probabilityOf1MutationUpperBound , probabilityOf1MutationFormatted , probabilityOf2MutationsLowerBound , probabilityOf2MutationsUpperBound , probabilityOf2MutationsFormatted , err := readGeneticAnalysis . GetOffspringMonogenicDiseaseVariantInfoFromGeneticAnalysis ( coupleAnalysisObject , diseaseName , variantIdentifier , genomePairIdentifier )
2024-04-11 15:51:56 +02:00
if ( err != nil ) { return err }
getProbabilityOf0MutationsText := func ( ) string {
if ( offspringProbabilitiesKnown == false ) {
result := translate ( "Unknown" )
return result
}
if ( probabilityOf0MutationsLowerBound == 0 && probabilityOf0MutationsUpperBound == 100 ) {
result := translate ( "Unknown" )
return result
}
return probabilityOf0MutationsFormatted
}
probabilityOf0MutationsText := getProbabilityOf0MutationsText ( )
getProbabilityOf1MutationText := func ( ) string {
if ( offspringProbabilitiesKnown == false ) {
result := translate ( "Unknown" )
return result
}
if ( probabilityOf1MutationLowerBound == 0 && probabilityOf1MutationUpperBound == 100 ) {
result := translate ( "Unknown" )
return result
}
return probabilityOf1MutationFormatted
}
probabilityOf1MutationText := getProbabilityOf1MutationText ( )
getProbabilityOf2MutationsText := func ( ) string {
if ( offspringProbabilitiesKnown == false ) {
result := translate ( "Unknown" )
return result
}
if ( probabilityOf2MutationsLowerBound == 0 && probabilityOf2MutationsUpperBound == 100 ) {
result := translate ( "Unknown" )
return result
}
return probabilityOf2MutationsFormatted
}
probabilityOf2MutationsText := getProbabilityOf2MutationsText ( )
variantNameLabel := getBoldLabelCentered ( variantName )
probabilityOf0MutationsLabel := getBoldLabelCentered ( probabilityOf0MutationsText )
probabilityOf1MutationLabel := getBoldLabelCentered ( probabilityOf1MutationText )
probabilityOf2MutationsLabel := getBoldLabelCentered ( probabilityOf2MutationsText )
viewVariantDetailsButton := widget . NewButtonWithIcon ( "" , theme . VisibilityIcon ( ) , func ( ) {
2024-06-02 10:43:39 +02:00
setViewCoupleGeneticAnalysisMonogenicDiseaseVariantDetailsPage ( window , person1Name , person2Name , person1AnalysisObject , person2AnalysisObject , coupleAnalysisObject , diseaseName , variantIdentifier , currentPage )
2024-04-11 15:51:56 +02:00
} )
variantNameColumn . Add ( variantNameLabel )
probabilityOf0MutationsColumn . Add ( probabilityOf0MutationsLabel )
probabilityOf1MutationColumn . Add ( probabilityOf1MutationLabel )
probabilityOf2MutationsColumn . Add ( probabilityOf2MutationsLabel )
variantInfoButtonsColumn . Add ( viewVariantDetailsButton )
variantNameColumn . Add ( widget . NewSeparator ( ) )
probabilityOf0MutationsColumn . Add ( widget . NewSeparator ( ) )
probabilityOf1MutationColumn . Add ( widget . NewSeparator ( ) )
probabilityOf2MutationsColumn . Add ( widget . NewSeparator ( ) )
variantInfoButtonsColumn . Add ( widget . NewSeparator ( ) )
return nil
}
variantsWithNonZeroRiskList := make ( [ ] string , 0 )
variantsWithZeroRiskFullyKnownList := make ( [ ] string , 0 )
variantsWithZeroRiskPartiallyKnownList := make ( [ ] string , 0 )
variantsWithUnknownRiskList := make ( [ ] string , 0 )
2024-06-02 10:43:39 +02:00
for variantIdentifierHex , _ := range diseaseVariantsMap {
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
variantIdentifier , err := encoding . DecodeHexStringTo3ByteArray ( variantIdentifierHex )
if ( err != nil ) {
return nil , errors . New ( "diseaseVariantsMap contains invalid variantIdentifier: " + variantIdentifierHex )
}
probabilitesKnown , probabilityOf0MutationsLowerBound , probabilityOf0MutationsUpperBound , _ , probabilityOf1MutationLowerBound , probabilityOf1MutationUpperBound , _ , probabilityOf2MutationsLowerBound , probabilityOf2MutationsUpperBound , _ , err := readGeneticAnalysis . GetOffspringMonogenicDiseaseVariantInfoFromGeneticAnalysis ( coupleAnalysisObject , diseaseName , variantIdentifier , genomePairIdentifier )
2024-04-11 15:51:56 +02:00
if ( err != nil ) { return nil , err }
if ( probabilitesKnown == false ) {
2024-06-02 10:43:39 +02:00
variantsWithUnknownRiskList = append ( variantsWithUnknownRiskList , variantIdentifierHex )
2024-04-11 15:51:56 +02:00
continue
}
2024-06-02 10:43:39 +02:00
2024-04-11 15:51:56 +02:00
if ( probabilityOf1MutationLowerBound != 0 || probabilityOf2MutationsLowerBound != 0 ) {
2024-06-02 10:43:39 +02:00
variantsWithNonZeroRiskList = append ( variantsWithNonZeroRiskList , variantIdentifierHex )
2024-04-11 15:51:56 +02:00
continue
}
// Risk is either 0 or partially unknown
if ( probabilityOf0MutationsLowerBound == 100 && probabilityOf0MutationsUpperBound == 100 && probabilityOf1MutationLowerBound == 0 && probabilityOf1MutationUpperBound == 0 && probabilityOf2MutationsLowerBound == 0 && probabilityOf2MutationsUpperBound == 0 ) {
2024-06-02 10:43:39 +02:00
variantsWithZeroRiskFullyKnownList = append ( variantsWithZeroRiskFullyKnownList , variantIdentifierHex )
2024-04-11 15:51:56 +02:00
continue
}
2024-06-02 10:43:39 +02:00
variantsWithZeroRiskPartiallyKnownList = append ( variantsWithZeroRiskPartiallyKnownList , variantIdentifierHex )
2024-04-11 15:51:56 +02:00
}
// We sort each list so the variants show up in the same order each time
helpers . SortStringListToUnicodeOrder ( variantsWithNonZeroRiskList )
helpers . SortStringListToUnicodeOrder ( variantsWithZeroRiskFullyKnownList )
helpers . SortStringListToUnicodeOrder ( variantsWithZeroRiskPartiallyKnownList )
helpers . SortStringListToUnicodeOrder ( variantsWithUnknownRiskList )
for _ , variantIdentifier := range variantsWithNonZeroRiskList {
err = addVariantRow ( variantIdentifier )
if ( err != nil ) { return nil , err }
}
for _ , variantIdentifier := range variantsWithZeroRiskFullyKnownList {
err = addVariantRow ( variantIdentifier )
if ( err != nil ) { return nil , err }
}
for _ , variantIdentifier := range variantsWithZeroRiskPartiallyKnownList {
err = addVariantRow ( variantIdentifier )
if ( err != nil ) { return nil , err }
}
for _ , variantIdentifier := range variantsWithUnknownRiskList {
err = addVariantRow ( variantIdentifier )
if ( err != nil ) { return nil , err }
}
variantsGrid := container . NewHBox ( layout . NewSpacer ( ) , variantNameColumn , probabilityOf0MutationsColumn , probabilityOf1MutationColumn , probabilityOf2MutationsColumn , variantInfoButtonsColumn , layout . NewSpacer ( ) )
return variantsGrid , nil
}
variantsGrid , err := getVariantsGrid ( )
if ( err != nil ) {
setErrorEncounteredPage ( window , err , previousPage )
return
}
2024-06-02 10:43:39 +02:00
page := container . NewVBox ( title , backButton , widget . NewSeparator ( ) , description1Row , widget . NewSeparator ( ) , genomePairRow , widget . NewSeparator ( ) , variantsTestedRow , widget . NewSeparator ( ) , phasedLociRow , widget . NewSeparator ( ) , variantsGrid )
2024-04-11 15:51:56 +02:00
setPageContent ( page , window )
}
// This function provides a page to view the details of a specific variant from a genetic analysis
// It will show the variant details for all of the couple's genome pairs
2024-06-02 10:43:39 +02:00
func setViewCoupleGeneticAnalysisMonogenicDiseaseVariantDetailsPage ( window fyne . Window , person1Name string , person2Name string , person1AnalysisObject geneticAnalysis . PersonAnalysis , person2AnalysisObject geneticAnalysis . PersonAnalysis , coupleAnalysisObject geneticAnalysis . CoupleAnalysis , diseaseName string , variantIdentifier [ 3 ] byte , previousPage func ( ) ) {
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
currentPage := func ( ) { setViewCoupleGeneticAnalysisMonogenicDiseaseVariantDetailsPage ( window , person1Name , person2Name , person1AnalysisObject , person2AnalysisObject , coupleAnalysisObject , diseaseName , variantIdentifier , previousPage ) }
2024-04-11 15:51:56 +02:00
title := getPageTitleCentered ( "Disease Variant Details - " + diseaseName )
backButton := getBackButtonCentered ( previousPage )
2024-06-02 10:43:39 +02:00
variantIdentifierHex := encoding . EncodeBytesToHexString ( variantIdentifier [ : ] )
variantObject , err := monogenicDiseases . GetMonogenicDiseaseVariantObject ( diseaseName , variantIdentifierHex )
2024-04-11 15:51:56 +02:00
if ( err != nil ) {
setErrorEncounteredPage ( window , err , previousPage )
return
}
variantName := variantObject . VariantNames [ 0 ]
description := getLabelCentered ( "Below is the disease variant analysis for the couple." )
variantNameLabel := widget . NewLabel ( "Variant Name:" )
variantNameText := getBoldLabel ( variantName )
variantInfoButton := widget . NewButtonWithIcon ( "" , theme . InfoIcon ( ) , func ( ) {
2024-06-02 10:43:39 +02:00
setViewMonogenicDiseaseVariantDetailsPage ( window , diseaseName , variantIdentifierHex , currentPage )
2024-04-11 15:51:56 +02:00
} )
variantNameRow := container . NewHBox ( layout . NewSpacer ( ) , variantNameLabel , variantNameText , variantInfoButton , layout . NewSpacer ( ) )
getGenomePairsHaveVariantGrid := func ( ) ( * fyne . Container , error ) {
emptyLabelA := widget . NewLabel ( "" )
emptyLabelB := widget . NewLabel ( "" )
emptyLabelC := widget . NewLabel ( "" )
genomePairLabel := getItalicLabelCentered ( "Genome Pair" )
probabilityOfLabelA := getItalicLabelCentered ( "Probability Of" )
zeroMutationsLabel := getItalicLabelCentered ( "0 Mutations" )
probabilityOfLabelB := getItalicLabelCentered ( "Probability Of" )
oneMutationLabel := getItalicLabelCentered ( "1 Mutation" )
probabilityOfLabelC := getItalicLabelCentered ( "Probability Of" )
twoMutationsLabel := getItalicLabelCentered ( "2 Mutations" )
viewGenomePairInfoButtonsColumn := container . NewVBox ( emptyLabelA , emptyLabelB , widget . NewSeparator ( ) )
genomePairNameColumn := container . NewVBox ( emptyLabelC , genomePairLabel , widget . NewSeparator ( ) )
probabilityOf0MutationsColumn := container . NewVBox ( probabilityOfLabelA , zeroMutationsLabel , widget . NewSeparator ( ) )
probabilityOf1MutationColumn := container . NewVBox ( probabilityOfLabelB , oneMutationLabel , widget . NewSeparator ( ) )
probablityOf2MutationsColumn := container . NewVBox ( probabilityOfLabelC , twoMutationsLabel , widget . NewSeparator ( ) )
2024-06-02 10:43:39 +02:00
addGenomePairRow := func ( genomePairName string , genomePairIdentifier [ 32 ] byte ) error {
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
probabilitiesKnown , probabilityOf0MutationsLowerBound , probabilityOf0MutationsUpperBound , probabilityOf0MutationsFormatted , probabilityOf1MutationLowerBound , probabilityOf1MutationUpperBound , probabilityOf1MutationFormatted , probabilityOf2MutationsLowerBound , probabilityOf2MutationsUpperBound , probabilityOf2MutationsFormatted , err := readGeneticAnalysis . GetOffspringMonogenicDiseaseVariantInfoFromGeneticAnalysis ( coupleAnalysisObject , diseaseName , variantIdentifier , genomePairIdentifier )
2024-04-11 15:51:56 +02:00
if ( err != nil ) { return err }
getProbabilityOf0MutationsText := func ( ) string {
if ( probabilitiesKnown == false ) {
result := translate ( "Unknown" )
return result
}
if ( probabilityOf0MutationsLowerBound == 0 && probabilityOf0MutationsUpperBound == 100 ) {
result := translate ( "Unknown" )
return result
}
return probabilityOf0MutationsFormatted
}
probabilityOf0MutationsText := getProbabilityOf0MutationsText ( )
getProbabilityOf1MutationText := func ( ) string {
if ( probabilitiesKnown == false ) {
result := translate ( "Unknown" )
return result
}
if ( probabilityOf1MutationLowerBound == 0 && probabilityOf1MutationUpperBound == 100 ) {
result := translate ( "Unknown" )
return result
}
return probabilityOf1MutationFormatted
}
probabilityOf1MutationText := getProbabilityOf1MutationText ( )
getProbabilityOf2MutationsText := func ( ) string {
if ( probabilitiesKnown == false ) {
result := translate ( "Unknown" )
return result
}
if ( probabilityOf2MutationsLowerBound == 0 && probabilityOf2MutationsUpperBound == 100 ) {
result := translate ( "Unknown" )
return result
}
return probabilityOf2MutationsFormatted
}
probabilityOf2MutationsText := getProbabilityOf2MutationsText ( )
viewGenomePairInfoButton := widget . NewButtonWithIcon ( "" , theme . InfoIcon ( ) , func ( ) {
2024-06-02 10:43:39 +02:00
setViewCoupleGeneticAnalysisMonogenicDiseaseGenomePairDetailsPage ( window , person1Name , person2Name , person1AnalysisObject , person2AnalysisObject , coupleAnalysisObject , diseaseName , genomePairIdentifier , genomePairName , currentPage )
2024-04-11 15:51:56 +02:00
} )
genomePairNameLabel := getBoldLabelCentered ( genomePairName )
probabilityOf0MutationsLabel := getBoldLabelCentered ( probabilityOf0MutationsText )
probabilityOf1MutationLabel := getBoldLabelCentered ( probabilityOf1MutationText )
probabilityOf2MutationsLabel := getBoldLabelCentered ( probabilityOf2MutationsText )
viewGenomePairInfoButtonsColumn . Add ( viewGenomePairInfoButton )
genomePairNameColumn . Add ( genomePairNameLabel )
probabilityOf0MutationsColumn . Add ( probabilityOf0MutationsLabel )
probabilityOf1MutationColumn . Add ( probabilityOf1MutationLabel )
probablityOf2MutationsColumn . Add ( probabilityOf2MutationsLabel )
viewGenomePairInfoButtonsColumn . Add ( widget . NewSeparator ( ) )
genomePairNameColumn . Add ( widget . NewSeparator ( ) )
probabilityOf0MutationsColumn . Add ( widget . NewSeparator ( ) )
probabilityOf1MutationColumn . Add ( widget . NewSeparator ( ) )
probablityOf2MutationsColumn . Add ( widget . NewSeparator ( ) )
return nil
}
2024-06-02 10:43:39 +02:00
pair1Person1GenomeIdentifier , pair1Person2GenomeIdentifier , secondGenomePairExists , pair2Person1GenomeIdentifier , pair2Person2GenomeIdentifier , _ , _ , _ , _ , _ , _ , err := readGeneticAnalysis . GetMetadataFromCoupleGeneticAnalysis ( coupleAnalysisObject )
2024-04-11 15:51:56 +02:00
if ( err != nil ) { return nil , err }
2024-06-02 10:43:39 +02:00
genomePair1Identifier := helpers . JoinTwo16ByteArrays ( pair1Person1GenomeIdentifier , pair1Person2GenomeIdentifier )
2024-04-11 15:51:56 +02:00
err = addGenomePairRow ( "Pair 1" , genomePair1Identifier )
if ( err != nil ) { return nil , err }
if ( secondGenomePairExists == true ) {
2024-06-02 10:43:39 +02:00
genomePair2Identifier := helpers . JoinTwo16ByteArrays ( pair2Person1GenomeIdentifier , pair2Person2GenomeIdentifier )
2024-04-11 15:51:56 +02:00
err := addGenomePairRow ( "Pair 2" , genomePair2Identifier )
if ( err != nil ) { return nil , err }
}
genomesContainer := container . NewHBox ( layout . NewSpacer ( ) , viewGenomePairInfoButtonsColumn , genomePairNameColumn , probabilityOf0MutationsColumn , probabilityOf1MutationColumn , probablityOf2MutationsColumn , layout . NewSpacer ( ) )
return genomesContainer , nil
}
genomePairsHaveVariantGrid , err := getGenomePairsHaveVariantGrid ( )
if ( err != nil ) {
setErrorEncounteredPage ( window , err , previousPage )
return
}
page := container . NewVBox ( title , backButton , widget . NewSeparator ( ) , description , widget . NewSeparator ( ) , variantNameRow , widget . NewSeparator ( ) , genomePairsHaveVariantGrid )
setPageContent ( page , window )
}
2024-06-02 10:43:39 +02:00
func setViewCoupleGeneticAnalysisPolygenicDiseasesPage ( window fyne . Window , person1Name string , person2Name string , person1AnalysisObject geneticAnalysis . PersonAnalysis , person2AnalysisObject geneticAnalysis . PersonAnalysis , coupleAnalysisObject geneticAnalysis . CoupleAnalysis , previousPage func ( ) ) {
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
currentPage := func ( ) { setViewCoupleGeneticAnalysisPolygenicDiseasesPage ( window , person1Name , person2Name , person1AnalysisObject , person2AnalysisObject , coupleAnalysisObject , previousPage ) }
2024-04-11 15:51:56 +02:00
title := getPageTitleCentered ( "Viewing Genetic Analysis - Polygenic Diseases" )
backButton := getBackButtonCentered ( previousPage )
description := getLabelCentered ( "Below is an analysis of the polygenic disease risk probabilities for the couple's offspring." )
getDiseasesGrid := func ( ) ( * fyne . Container , error ) {
2024-06-02 10:43:39 +02:00
pair1Person1GenomeIdentifier , pair1Person2GenomeIdentifier , secondGenomePairExists , _ , _ , _ , _ , _ , _ , _ , _ , err := readGeneticAnalysis . GetMetadataFromCoupleGeneticAnalysis ( coupleAnalysisObject )
2024-04-11 15:51:56 +02:00
if ( err != nil ) { return nil , err }
diseaseNameLabel := getItalicLabelCentered ( "Disease Name" )
offspringRiskScoreLabel := getItalicLabelCentered ( "Offspring Risk Score" )
conflictExistsLabel := getItalicLabelCentered ( "Conflict Exists?" )
emptyLabel := widget . NewLabel ( "" )
diseaseNameColumn := container . NewVBox ( diseaseNameLabel , widget . NewSeparator ( ) )
offspringRiskScoreColumn := container . NewVBox ( offspringRiskScoreLabel , widget . NewSeparator ( ) )
conflictExistsColumn := container . NewVBox ( conflictExistsLabel , widget . NewSeparator ( ) )
viewButtonsColumn := container . NewVBox ( emptyLabel , widget . NewSeparator ( ) )
diseaseNamesList , err := polygenicDiseases . GetPolygenicDiseaseNamesList ( )
if ( err != nil ) { return nil , err }
for _ , diseaseName := range diseaseNamesList {
2024-06-02 10:43:39 +02:00
mainGenomePairIdentifier := helpers . JoinTwo16ByteArrays ( pair1Person1GenomeIdentifier , pair1Person2GenomeIdentifier )
2024-04-11 15:51:56 +02:00
2024-06-07 02:04:13 +02:00
offspringRiskScoreKnown , _ , offspringRiskScoreFormatted , _ , _ , conflictExists , err := readGeneticAnalysis . GetOffspringPolygenicDiseaseInfoFromGeneticAnalysis ( coupleAnalysisObject , diseaseName , mainGenomePairIdentifier )
2024-04-11 15:51:56 +02:00
if ( err != nil ) { return nil , err }
getRiskScoreLabelText := func ( ) string {
2024-06-02 10:43:39 +02:00
if ( offspringRiskScoreKnown == false ) {
2024-04-11 15:51:56 +02:00
result := translate ( "Unknown" )
return result
}
return offspringRiskScoreFormatted
}
offspringRiskScoreLabelText := getRiskScoreLabelText ( )
diseaseNameText := getBoldLabelCentered ( diseaseName )
diseaseNameColumn . Add ( diseaseNameText )
offspringRiskScoreText := getBoldLabelCentered ( offspringRiskScoreLabelText )
offspringRiskScoreColumn . Add ( offspringRiskScoreText )
conflictExistsString := helpers . ConvertBoolToYesOrNoString ( conflictExists )
conflictExistsLabel := getBoldLabelCentered ( conflictExistsString )
conflictExistsColumn . Add ( conflictExistsLabel )
viewDetailsButton := getWidgetCentered ( widget . NewButtonWithIcon ( "" , theme . VisibilityIcon ( ) , func ( ) {
2024-06-02 10:43:39 +02:00
setViewCoupleGeneticAnalysisPolygenicDiseaseDetailsPage ( window , person1Name , person2Name , person1AnalysisObject , person2AnalysisObject , coupleAnalysisObject , diseaseName , currentPage )
2024-04-11 15:51:56 +02:00
} ) )
viewButtonsColumn . Add ( viewDetailsButton )
diseaseNameColumn . Add ( widget . NewSeparator ( ) )
offspringRiskScoreColumn . Add ( widget . NewSeparator ( ) )
conflictExistsColumn . Add ( widget . NewSeparator ( ) )
viewButtonsColumn . Add ( widget . NewSeparator ( ) )
}
offspringRiskScoreHelpButton := widget . NewButtonWithIcon ( "" , theme . QuestionIcon ( ) , func ( ) {
setOffspringPolygenicDiseaseRiskScoreExplainerPage ( window , currentPage )
} )
offspringRiskScoreColumn . Add ( offspringRiskScoreHelpButton )
diseasesGrid := container . NewHBox ( layout . NewSpacer ( ) , diseaseNameColumn , offspringRiskScoreColumn )
if ( secondGenomePairExists == true ) {
conflictExistsHelpButton := widget . NewButtonWithIcon ( "" , theme . QuestionIcon ( ) , func ( ) {
setCoupleGeneticAnalysisConflictExistsExplainerPage ( window , currentPage )
} )
conflictExistsColumn . Add ( conflictExistsHelpButton )
diseasesGrid . Add ( conflictExistsColumn )
}
diseasesGrid . Add ( viewButtonsColumn )
diseasesGrid . Add ( layout . NewSpacer ( ) )
return diseasesGrid , nil
}
diseasesGrid , err := getDiseasesGrid ( )
if ( err != nil ) {
setErrorEncounteredPage ( window , err , previousPage )
return
}
page := container . NewVBox ( title , backButton , widget . NewSeparator ( ) , description , widget . NewSeparator ( ) , diseasesGrid )
setPageContent ( page , window )
}
2024-06-02 10:43:39 +02:00
func setViewCoupleGeneticAnalysisPolygenicDiseaseDetailsPage ( window fyne . Window , person1Name string , person2Name string , person1AnalysisObject geneticAnalysis . PersonAnalysis , person2AnalysisObject geneticAnalysis . PersonAnalysis , coupleAnalysisObject geneticAnalysis . CoupleAnalysis , diseaseName string , previousPage func ( ) ) {
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
currentPage := func ( ) { setViewCoupleGeneticAnalysisPolygenicDiseaseDetailsPage ( window , person1Name , person2Name , person1AnalysisObject , person2AnalysisObject , coupleAnalysisObject , diseaseName , previousPage ) }
2024-04-11 15:51:56 +02:00
title := getPageTitleCentered ( "Viewing Couple Analysis - " + diseaseName )
backButton := getBackButtonCentered ( previousPage )
2024-06-02 10:43:39 +02:00
pair1Person1GenomeIdentifier , pair1Person2GenomeIdentifier , secondGenomePairExists , pair2Person1GenomeIdentifier , pair2Person2GenomeIdentifier , _ , _ , _ , _ , _ , _ , err := readGeneticAnalysis . GetMetadataFromCoupleGeneticAnalysis ( coupleAnalysisObject )
2024-04-11 15:51:56 +02:00
if ( err != nil ) {
setErrorEncounteredPage ( window , err , previousPage )
return
}
getDescriptionSection := func ( ) * fyne . Container {
if ( secondGenomePairExists == false ) {
description := getLabelCentered ( "Below is the disease analysis for the couple's offspring." )
return description
}
description1 := getLabelCentered ( "Below is the disease analysis for the couple's offspring." )
description2 := getLabelCentered ( "Each genome pair combines different genomes from each person." )
descriptionsSection := container . NewVBox ( description1 , description2 )
return descriptionsSection
}
descriptionSection := getDescriptionSection ( )
diseaseNameLabel := widget . NewLabel ( "Disease:" )
diseaseNameText := getBoldLabel ( diseaseName )
diseaseNameInfoButton := widget . NewButtonWithIcon ( "" , theme . InfoIcon ( ) , func ( ) {
setViewPolygenicDiseaseDetailsPage ( window , diseaseName , currentPage )
} )
diseaseNameRow := container . NewHBox ( layout . NewSpacer ( ) , diseaseNameLabel , diseaseNameText , diseaseNameInfoButton , layout . NewSpacer ( ) )
2024-06-07 02:04:13 +02:00
emptyLabel1 := widget . NewLabel ( "" )
emptyLabel2 := widget . NewLabel ( "" )
2024-04-11 15:51:56 +02:00
offspringRiskScoreLabel := getItalicLabelCentered ( "Offspring Risk Score" )
2024-06-07 02:04:13 +02:00
emptyLabel3 := widget . NewLabel ( "" )
emptyLabel4 := widget . NewLabel ( "" )
emptyLabel5 := widget . NewLabel ( "" )
2024-04-11 15:51:56 +02:00
2024-06-07 02:04:13 +02:00
viewGenomePairButtonsColumn := container . NewVBox ( emptyLabel1 , widget . NewSeparator ( ) )
pairNameColumn := container . NewVBox ( emptyLabel2 , widget . NewSeparator ( ) )
2024-04-11 15:51:56 +02:00
offspringRiskScoreColumn := container . NewVBox ( offspringRiskScoreLabel , widget . NewSeparator ( ) )
2024-06-07 02:04:13 +02:00
viewSampleOffspringsChartButtonsColumn := container . NewVBox ( emptyLabel3 , widget . NewSeparator ( ) )
viewLifetimeRiskButtonsColumn := container . NewVBox ( emptyLabel4 , widget . NewSeparator ( ) )
viewOffspringLociButtonsColumn := container . NewVBox ( emptyLabel5 , widget . NewSeparator ( ) )
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
addGenomePairRow := func ( genomePairName string , person1GenomeIdentifier [ 16 ] byte , person2GenomeIdentifier [ 16 ] byte ) error {
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
genomePairIdentifier := helpers . JoinTwo16ByteArrays ( person1GenomeIdentifier , person2GenomeIdentifier )
2024-04-11 15:51:56 +02:00
2024-06-07 02:04:13 +02:00
offspringRiskScoreKnown , _ , offspringRiskScoreFormatted , sampleOffspringRiskScoresList , numberOfLociTested , _ , err := readGeneticAnalysis . GetOffspringPolygenicDiseaseInfoFromGeneticAnalysis ( coupleAnalysisObject , diseaseName , genomePairIdentifier )
2024-04-11 15:51:56 +02:00
if ( err != nil ) { return err }
getRiskScoreLabelText := func ( ) string {
if ( offspringRiskScoreKnown == false ) {
result := translate ( "Unknown" )
return result
}
return offspringRiskScoreFormatted
}
riskScoreLabelText := getRiskScoreLabelText ( )
genomePairNameLabel := getBoldLabelCentered ( genomePairName )
offspringRiskScoreLabel := getBoldLabelCentered ( riskScoreLabelText )
viewGenomePairButton := widget . NewButtonWithIcon ( "" , theme . InfoIcon ( ) , func ( ) {
2024-06-02 10:43:39 +02:00
setViewCoupleGeneticAnalysisPolygenicDiseaseGenomePairDetailsPage ( window , person1Name , person2Name , person1AnalysisObject , person2AnalysisObject , coupleAnalysisObject , diseaseName , genomePairIdentifier , genomePairName , currentPage )
2024-04-11 15:51:56 +02:00
} )
2024-06-07 02:04:13 +02:00
viewSampleOffspringsChartButton := widget . NewButtonWithIcon ( "" , theme . InfoIcon ( ) , func ( ) {
setViewPolygenicDiseaseSampleOffspringRiskScoresChart ( window , diseaseName , sampleOffspringRiskScoresList , numberOfLociTested , currentPage )
} )
2024-04-11 15:51:56 +02:00
viewOffspringLifetimeRiskButton := widget . NewButtonWithIcon ( "" , theme . HistoryIcon ( ) , func ( ) {
diseaseObject , err := polygenicDiseases . GetPolygenicDiseaseObject ( diseaseName )
if ( err != nil ) {
setErrorEncounteredPage ( window , err , currentPage )
return
}
getPageMaleOrFemale := func ( ) string {
//TODO: Get user sex from myLocalProfiles
diseaseEffectedSex := diseaseObject . EffectedSex
if ( diseaseEffectedSex == "Both" ) {
return "Male"
}
return diseaseEffectedSex
}
pageMaleOrFemale := getPageMaleOrFemale ( )
setViewPersonPolygenicDiseaseLifetimeProbabilitiesPage ( window , diseaseName , genomePairName , pageMaleOrFemale , currentPage )
} )
viewOffspringLociButton := widget . NewButtonWithIcon ( "" , theme . VisibilityIcon ( ) , func ( ) {
2024-06-02 10:43:39 +02:00
setViewCouplePolygenicDiseaseLociPage ( window , person1Name , person2Name , person1AnalysisObject , person2AnalysisObject , coupleAnalysisObject , diseaseName , genomePairIdentifier , genomePairName , currentPage )
2024-04-11 15:51:56 +02:00
} )
viewGenomePairButtonsColumn . Add ( viewGenomePairButton )
pairNameColumn . Add ( genomePairNameLabel )
offspringRiskScoreColumn . Add ( offspringRiskScoreLabel )
2024-06-07 02:04:13 +02:00
viewSampleOffspringsChartButtonsColumn . Add ( viewSampleOffspringsChartButton )
2024-04-11 15:51:56 +02:00
viewLifetimeRiskButtonsColumn . Add ( viewOffspringLifetimeRiskButton )
viewOffspringLociButtonsColumn . Add ( viewOffspringLociButton )
viewGenomePairButtonsColumn . Add ( widget . NewSeparator ( ) )
pairNameColumn . Add ( widget . NewSeparator ( ) )
offspringRiskScoreColumn . Add ( widget . NewSeparator ( ) )
2024-06-07 02:04:13 +02:00
viewSampleOffspringsChartButtonsColumn . Add ( widget . NewSeparator ( ) )
viewLifetimeRiskButtonsColumn . Add ( widget . NewSeparator ( ) )
2024-04-11 15:51:56 +02:00
viewOffspringLociButtonsColumn . Add ( widget . NewSeparator ( ) )
return nil
}
2024-06-02 10:43:39 +02:00
err = addGenomePairRow ( "Pair 1" , pair1Person1GenomeIdentifier , pair1Person2GenomeIdentifier )
2024-04-11 15:51:56 +02:00
if ( err != nil ) {
setErrorEncounteredPage ( window , err , previousPage )
return
}
if ( secondGenomePairExists == true ) {
2024-06-02 10:43:39 +02:00
err := addGenomePairRow ( "Pair 2" , pair2Person1GenomeIdentifier , pair2Person2GenomeIdentifier )
2024-04-11 15:51:56 +02:00
if ( err != nil ) {
setErrorEncounteredPage ( window , err , previousPage )
return
}
}
offspringRiskScoreHelpButton := widget . NewButtonWithIcon ( "" , theme . QuestionIcon ( ) , func ( ) {
setOffspringPolygenicDiseaseRiskScoreExplainerPage ( window , currentPage )
} )
offspringRiskScoreColumn . Add ( offspringRiskScoreHelpButton )
2024-06-07 02:04:13 +02:00
genomesContainer := container . NewHBox ( layout . NewSpacer ( ) , viewGenomePairButtonsColumn , pairNameColumn , offspringRiskScoreColumn , viewSampleOffspringsChartButtonsColumn , viewLifetimeRiskButtonsColumn , viewOffspringLociButtonsColumn , layout . NewSpacer ( ) )
2024-04-11 15:51:56 +02:00
page := container . NewVBox ( title , backButton , widget . NewSeparator ( ) , descriptionSection , widget . NewSeparator ( ) , diseaseNameRow , widget . NewSeparator ( ) , genomesContainer )
setPageContent ( page , window )
}
2024-06-02 10:43:39 +02:00
func setViewCoupleGeneticAnalysisPolygenicDiseaseGenomePairDetailsPage ( window fyne . Window , person1Name string , person2Name string , person1AnalysisObject geneticAnalysis . PersonAnalysis , person2AnalysisObject geneticAnalysis . PersonAnalysis , coupleAnalysisObject geneticAnalysis . CoupleAnalysis , diseaseName string , genomePairIdentifier [ 32 ] byte , genomePairName string , previousPage func ( ) ) {
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
currentPage := func ( ) { setViewCoupleGeneticAnalysisPolygenicDiseaseGenomePairDetailsPage ( window , person1Name , person2Name , person1AnalysisObject , person2AnalysisObject , coupleAnalysisObject , diseaseName , genomePairIdentifier , genomePairName , previousPage ) }
2024-04-11 15:51:56 +02:00
title := getPageTitleCentered ( "Viewing Couple Genome Pair Info" )
backButton := getBackButtonCentered ( previousPage )
description := getLabelCentered ( "Below is the disease information for both genomes in the genome pair." )
diseaseNameLabel := widget . NewLabel ( "Disease:" )
diseaseNameText := getBoldLabel ( diseaseName )
diseaseNameInfoButton := widget . NewButtonWithIcon ( "" , theme . InfoIcon ( ) , func ( ) {
setViewPolygenicDiseaseDetailsPage ( window , diseaseName , currentPage )
} )
diseaseNameRow := container . NewHBox ( layout . NewSpacer ( ) , diseaseNameLabel , diseaseNameText , diseaseNameInfoButton , layout . NewSpacer ( ) )
genomePairLabel := widget . NewLabel ( "Genome Pair:" )
genomePairNameLabel := getBoldLabel ( genomePairName )
genomePairHelpButton := widget . NewButtonWithIcon ( "" , theme . QuestionIcon ( ) , func ( ) {
setCoupleGenomePairExplainerPage ( window , currentPage )
} )
genomePairRow := container . NewHBox ( layout . NewSpacer ( ) , genomePairLabel , genomePairNameLabel , genomePairHelpButton , layout . NewSpacer ( ) )
emptyLabelA := widget . NewLabel ( "" )
personNameLabel := getItalicLabelCentered ( "Person Name" )
emptyLabelB := widget . NewLabel ( "" )
genomeNameLabel := getItalicLabelCentered ( "Genome Name" )
emptyLabelC := widget . NewLabel ( "" )
riskScoreLabel := getItalicLabelCentered ( "Risk Score" )
numberOfLabel := getItalicLabelCentered ( "Number Of" )
lociTestedLabel := getItalicLabelCentered ( "Loci Tested" )
emptyLabelD := widget . NewLabel ( "" )
emptyLabelE := widget . NewLabel ( "" )
personNameColumn := container . NewVBox ( emptyLabelA , personNameLabel , widget . NewSeparator ( ) )
genomeNameColumn := container . NewVBox ( emptyLabelB , genomeNameLabel , widget . NewSeparator ( ) )
riskScoreColumn := container . NewVBox ( emptyLabelC , riskScoreLabel , widget . NewSeparator ( ) )
numberOfLociTestedColumn := container . NewVBox ( numberOfLabel , lociTestedLabel , widget . NewSeparator ( ) )
viewGenomeButtonsColumn := container . NewVBox ( emptyLabelD , emptyLabelE , widget . NewSeparator ( ) )
2024-06-02 10:43:39 +02:00
addGenomeRow := func ( isPerson1 bool , personName string , inputGenomeIdentifier [ 16 ] byte ) error {
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
personAnalysisGenomeIdentifier , _ , genomeIsCombined , combinedType , err := readGeneticAnalysis . GetMatchingPersonAnalysisGenomeIdentifierFromCoupleAnalysis ( isPerson1 , person1AnalysisObject , person2AnalysisObject , coupleAnalysisObject , inputGenomeIdentifier )
2024-04-11 15:51:56 +02:00
if ( err != nil ) { return err }
personNameTrimmed , _ , err := helpers . TrimAndFlattenString ( personName , 10 )
if ( err != nil ) { return err }
personNameLabel := getBoldLabelCentered ( personNameTrimmed )
2024-06-02 10:43:39 +02:00
getPersonAnalysisObject := func ( ) geneticAnalysis . PersonAnalysis {
if ( isPerson1 == true ) {
return person1AnalysisObject
2024-04-11 15:51:56 +02:00
}
2024-06-02 10:43:39 +02:00
return person2AnalysisObject
2024-04-11 15:51:56 +02:00
}
2024-06-02 10:43:39 +02:00
personAnalysisObject := getPersonAnalysisObject ( )
2024-04-11 15:51:56 +02:00
getGenomeName := func ( ) ( string , error ) {
if ( genomeIsCombined == false ) {
2024-06-02 10:43:39 +02:00
2024-04-11 15:51:56 +02:00
genomeFound , _ , _ , _ , _ , _ , companyName , _ , _ , err := myGenomes . GetMyRawGenomeMetadata ( personAnalysisGenomeIdentifier )
if ( err != nil ) { return "" , err }
if ( genomeFound == false ) {
2024-06-02 10:43:39 +02:00
return "" , errors . New ( "MyGenomeInfo for genome from analysisObject not found." )
2024-04-11 15:51:56 +02:00
}
return companyName , nil
}
return combinedType , nil
}
genomeName , err := getGenomeName ( )
if ( err != nil ) { return err }
genomeNameLabel := getBoldLabelCentered ( genomeName )
2024-07-19 19:16:28 +02:00
personRiskScoreKnown , _ , personRiskScoreFormatted , numberOfLociTested , _ , err := readGeneticAnalysis . GetPersonPolygenicDiseaseInfoFromGeneticAnalysis ( personAnalysisObject , diseaseName , personAnalysisGenomeIdentifier )
2024-04-11 15:51:56 +02:00
if ( err != nil ) { return err }
getPersonRiskScoreLabelText := func ( ) string {
if ( personRiskScoreKnown == false ) {
result := translate ( "Unknown" )
return result
}
return personRiskScoreFormatted
}
personRiskScoreLabelText := getPersonRiskScoreLabelText ( )
genomeRiskScoreLabel := getBoldLabelCentered ( personRiskScoreLabelText )
numberOfLociTestedString := helpers . ConvertIntToString ( numberOfLociTested )
numberOfLociTestedText := getBoldLabelCentered ( numberOfLociTestedString )
viewGenomeButton := widget . NewButtonWithIcon ( "" , theme . VisibilityIcon ( ) , func ( ) {
2024-06-02 10:43:39 +02:00
setViewPersonGenomePolygenicDiseaseLociPage ( window , personAnalysisObject , diseaseName , personAnalysisGenomeIdentifier , genomeName , currentPage )
2024-04-11 15:51:56 +02:00
} )
personNameColumn . Add ( personNameLabel )
genomeNameColumn . Add ( genomeNameLabel )
riskScoreColumn . Add ( genomeRiskScoreLabel )
numberOfLociTestedColumn . Add ( numberOfLociTestedText )
viewGenomeButtonsColumn . Add ( viewGenomeButton )
personNameColumn . Add ( widget . NewSeparator ( ) )
genomeNameColumn . Add ( widget . NewSeparator ( ) )
riskScoreColumn . Add ( widget . NewSeparator ( ) )
numberOfLociTestedColumn . Add ( widget . NewSeparator ( ) )
viewGenomeButtonsColumn . Add ( widget . NewSeparator ( ) )
return nil
}
2024-06-02 10:43:39 +02:00
person1GenomeIdentifier , person2GenomeIdentifier := helpers . Split32ByteArrayInHalf ( genomePairIdentifier )
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
err := addGenomeRow ( true , person1Name , person1GenomeIdentifier )
2024-04-11 15:51:56 +02:00
if ( err != nil ) {
setErrorEncounteredPage ( window , err , previousPage )
return
}
2024-06-02 10:43:39 +02:00
err = addGenomeRow ( false , person2Name , person2GenomeIdentifier )
2024-04-11 15:51:56 +02:00
if ( err != nil ) {
setErrorEncounteredPage ( window , err , previousPage )
return
}
riskScoreHelpButton := widget . NewButtonWithIcon ( "" , theme . QuestionIcon ( ) , func ( ) {
setPolygenicDiseaseRiskScoreExplainerPage ( window , currentPage )
} )
riskScoreColumn . Add ( riskScoreHelpButton )
numberOfLociTestedHelpButton := widget . NewButtonWithIcon ( "" , theme . QuestionIcon ( ) , func ( ) {
setPolygenicDiseaseNumberOfLociTestedExplainerPage ( window , currentPage )
} )
numberOfLociTestedColumn . Add ( numberOfLociTestedHelpButton )
genomesGrid := container . NewHBox ( layout . NewSpacer ( ) , personNameColumn , genomeNameColumn , riskScoreColumn , numberOfLociTestedColumn , viewGenomeButtonsColumn , layout . NewSpacer ( ) )
page := container . NewVBox ( title , backButton , widget . NewSeparator ( ) , description , widget . NewSeparator ( ) , diseaseNameRow , widget . NewSeparator ( ) , genomePairRow , widget . NewSeparator ( ) , genomesGrid )
setPageContent ( page , window )
}
// This function provides a page to view the couple offspring locus probabilities for a particular genome pair
2024-06-02 10:43:39 +02:00
func setViewCouplePolygenicDiseaseLociPage ( window fyne . Window , person1Name string , person2Name string , person1AnalysisObject geneticAnalysis . PersonAnalysis , person2AnalysisObject geneticAnalysis . PersonAnalysis , coupleAnalysisObject geneticAnalysis . CoupleAnalysis , diseaseName string , genomePairIdentifier [ 32 ] byte , genomePairName string , previousPage func ( ) ) {
2024-04-11 15:51:56 +02:00
setLoadingScreen ( window , "Loading Polygenic Disease Loci" , "Loading disease loci..." )
2024-06-02 10:43:39 +02:00
currentPage := func ( ) { setViewCouplePolygenicDiseaseLociPage ( window , person1Name , person2Name , person1AnalysisObject , person2AnalysisObject , coupleAnalysisObject , diseaseName , genomePairIdentifier , genomePairName , previousPage ) }
2024-04-11 15:51:56 +02:00
title := getPageTitleCentered ( "View Offspring Disease Loci - " + diseaseName )
backButton := getBackButtonCentered ( previousPage )
description1 := widget . NewLabel ( "Below are the disease loci probabilities for offspring from this genome pair." )
diseaseLociHelpButton := widget . NewButtonWithIcon ( "" , theme . QuestionIcon ( ) , func ( ) {
setPolygenicDiseaseLociExplainerPage ( window , currentPage )
} )
description1Row := container . NewHBox ( layout . NewSpacer ( ) , description1 , diseaseLociHelpButton , layout . NewSpacer ( ) )
genomePairLabel := widget . NewLabel ( "Genome Pair:" )
genomePairNameLabel := getBoldLabel ( genomePairName )
viewGenomePairInfoButton := widget . NewButtonWithIcon ( "" , theme . InfoIcon ( ) , func ( ) {
2024-06-02 10:43:39 +02:00
setViewCoupleGeneticAnalysisPolygenicDiseaseGenomePairDetailsPage ( window , person1Name , person2Name , person1AnalysisObject , person2AnalysisObject , coupleAnalysisObject , diseaseName , genomePairIdentifier , genomePairName , currentPage )
2024-04-11 15:51:56 +02:00
} )
genomePairRow := container . NewHBox ( layout . NewSpacer ( ) , genomePairLabel , genomePairNameLabel , viewGenomePairInfoButton , layout . NewSpacer ( ) )
2024-06-07 02:04:13 +02:00
_ , _ , _ , _ , numberOfLociTested , _ , err := readGeneticAnalysis . GetOffspringPolygenicDiseaseInfoFromGeneticAnalysis ( coupleAnalysisObject , diseaseName , genomePairIdentifier )
2024-04-11 15:51:56 +02:00
if ( err != nil ) {
setErrorEncounteredPage ( window , err , previousPage )
return
}
2024-06-07 02:04:13 +02:00
2024-04-11 15:51:56 +02:00
numberOfLociTestedString := helpers . ConvertIntToString ( numberOfLociTested )
diseaseLociMap , err := polygenicDiseases . GetPolygenicDiseaseLociMap ( diseaseName )
if ( err != nil ) {
setErrorEncounteredPage ( window , err , previousPage )
return
}
totalNumberOfLoci := len ( diseaseLociMap )
totalNumberOfLociString := helpers . ConvertIntToString ( totalNumberOfLoci )
lociTestedLabel := widget . NewLabel ( "Loci Tested:" )
lociTestedText := getBoldLabel ( numberOfLociTestedString + "/" + totalNumberOfLociString )
lociTestedHelpButton := widget . NewButtonWithIcon ( "" , theme . QuestionIcon ( ) , func ( ) {
setOffspringPolygenicDiseaseNumberOfLociTestedExplainerPage ( window , currentPage )
} )
lociTestedRow := container . NewHBox ( layout . NewSpacer ( ) , lociTestedLabel , lociTestedText , lociTestedHelpButton , layout . NewSpacer ( ) )
getLociGrid := func ( ) ( * fyne . Container , error ) {
locusNameLabel := getItalicLabelCentered ( "Locus Name" )
offspringRiskWeightLabel := getItalicLabelCentered ( "Offspring Risk Weight" )
offspringOddsRatioLabel := getItalicLabelCentered ( "Offspring Odds Ratio" )
emptyLabel := widget . NewLabel ( "" )
locusNameColumn := container . NewVBox ( locusNameLabel , widget . NewSeparator ( ) )
offspringRiskWeightColumn := container . NewVBox ( offspringRiskWeightLabel , widget . NewSeparator ( ) )
offspringOddsRatioColumn := container . NewVBox ( offspringOddsRatioLabel , widget . NewSeparator ( ) )
lociInfoButtonsColumn := container . NewVBox ( emptyLabel , widget . NewSeparator ( ) )
2024-06-02 10:43:39 +02:00
addLocusRow := func ( locusIdentifierHex string ) error {
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
locusObject , exists := diseaseLociMap [ locusIdentifierHex ]
2024-04-11 15:51:56 +02:00
if ( exists == false ) {
2024-06-02 10:43:39 +02:00
return errors . New ( "Cannot add locus row: Locus not found in diseaseLociMap: " + locusIdentifierHex )
2024-04-11 15:51:56 +02:00
}
2024-06-02 10:43:39 +02:00
locusIdentifier , err := encoding . DecodeHexStringTo3ByteArray ( locusIdentifierHex )
if ( err != nil ) { return err }
2024-04-11 15:51:56 +02:00
locusRSID := locusObject . LocusRSID
locusRSIDString := helpers . ConvertInt64ToString ( locusRSID )
locusName := "rs" + locusRSIDString
2024-06-02 10:43:39 +02:00
offspringRiskWeightKnown , offspringRiskWeight , offspringOddsRatioKnown , _ , offspringOddsRatioFormatted , err := readGeneticAnalysis . GetOffspringPolygenicDiseaseLocusInfoFromGeneticAnalysis ( coupleAnalysisObject , diseaseName , locusIdentifier , genomePairIdentifier )
2024-04-11 15:51:56 +02:00
if ( err != nil ) { return err }
getOffspringRiskWeightText := func ( ) string {
if ( offspringRiskWeightKnown == false ) {
unknownTextTranslated := translate ( "Unknown" )
return unknownTextTranslated
}
offspringRiskWeightString := helpers . ConvertIntToString ( offspringRiskWeight )
return offspringRiskWeightString
}
offspringRiskWeightText := getOffspringRiskWeightText ( )
getOffspringOddsRatioText := func ( ) string {
if ( offspringOddsRatioKnown == false ) {
unknownTextTranslated := translate ( "Unknown" )
return unknownTextTranslated
}
return offspringOddsRatioFormatted
}
offspringOddsRatioText := getOffspringOddsRatioText ( )
locusNameLabel := getBoldLabelCentered ( locusName )
locusRiskWeightLabel := getBoldLabelCentered ( offspringRiskWeightText )
locusOddsRatioLabel := getBoldLabelCentered ( offspringOddsRatioText )
viewLocusDetailsButton := widget . NewButtonWithIcon ( "" , theme . VisibilityIcon ( ) , func ( ) {
2024-06-02 10:43:39 +02:00
setViewCoupleGeneticAnalysisPolygenicDiseaseLocusDetailsPage ( window , person1Name , person2Name , person1AnalysisObject , person2AnalysisObject , coupleAnalysisObject , diseaseName , locusIdentifier , currentPage )
2024-04-11 15:51:56 +02:00
} )
locusNameColumn . Add ( locusNameLabel )
offspringRiskWeightColumn . Add ( locusRiskWeightLabel )
offspringOddsRatioColumn . Add ( locusOddsRatioLabel )
lociInfoButtonsColumn . Add ( viewLocusDetailsButton )
locusNameColumn . Add ( widget . NewSeparator ( ) )
offspringRiskWeightColumn . Add ( widget . NewSeparator ( ) )
offspringOddsRatioColumn . Add ( widget . NewSeparator ( ) )
lociInfoButtonsColumn . Add ( widget . NewSeparator ( ) )
return nil
}
lociWithKnownRiskWeightList := make ( [ ] string , 0 )
lociWithUnknownRiskWeightList := make ( [ ] string , 0 )
2024-06-02 10:43:39 +02:00
for locusIdentifierHex , _ := range diseaseLociMap {
locusIdentifier , err := encoding . DecodeHexStringTo3ByteArray ( locusIdentifierHex )
if ( err != nil ) { return nil , err }
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
offspringRiskWeightKnown , _ , _ , _ , _ , err := readGeneticAnalysis . GetOffspringPolygenicDiseaseLocusInfoFromGeneticAnalysis ( coupleAnalysisObject , diseaseName , locusIdentifier , genomePairIdentifier )
2024-04-11 15:51:56 +02:00
if ( err != nil ) { return nil , err }
if ( offspringRiskWeightKnown == true ) {
2024-06-02 10:43:39 +02:00
lociWithKnownRiskWeightList = append ( lociWithKnownRiskWeightList , locusIdentifierHex )
2024-04-11 15:51:56 +02:00
} else {
2024-06-02 10:43:39 +02:00
lociWithUnknownRiskWeightList = append ( lociWithUnknownRiskWeightList , locusIdentifierHex )
2024-04-11 15:51:56 +02:00
}
}
// We sort the lists so loci show up in the same order whenever page is refreshed
helpers . SortStringListToUnicodeOrder ( lociWithKnownRiskWeightList )
helpers . SortStringListToUnicodeOrder ( lociWithUnknownRiskWeightList )
for _ , locusIdentifier := range lociWithKnownRiskWeightList {
err = addLocusRow ( locusIdentifier )
if ( err != nil ) { return nil , err }
}
for _ , locusIdentifier := range lociWithUnknownRiskWeightList {
err = addLocusRow ( locusIdentifier )
if ( err != nil ) { return nil , err }
}
offspringRiskWeightHelpButton := widget . NewButtonWithIcon ( "" , theme . QuestionIcon ( ) , func ( ) {
setOffspringPolygenicDiseaseLocusRiskWeightExplainerPage ( window , currentPage )
} )
offspringRiskWeightColumn . Add ( offspringRiskWeightHelpButton )
offspringOddsRatioHelpButton := widget . NewButtonWithIcon ( "" , theme . QuestionIcon ( ) , func ( ) {
//TODO
showUnderConstructionDialog ( window )
} )
offspringOddsRatioColumn . Add ( offspringOddsRatioHelpButton )
lociGrid := container . NewHBox ( layout . NewSpacer ( ) , locusNameColumn , offspringRiskWeightColumn , offspringOddsRatioColumn , lociInfoButtonsColumn , layout . NewSpacer ( ) )
return lociGrid , nil
}
lociGrid , err := getLociGrid ( )
if ( err != nil ) {
setErrorEncounteredPage ( window , err , previousPage )
return
}
page := container . NewVBox ( title , backButton , widget . NewSeparator ( ) , description1Row , widget . NewSeparator ( ) , genomePairRow , widget . NewSeparator ( ) , lociTestedRow , widget . NewSeparator ( ) , lociGrid )
setPageContent ( page , window )
}
// This function provides a page to view the details of a specific locus from a genetic analysis
// It will show the locus details for all of the couple's genome pairs
2024-06-02 10:43:39 +02:00
func setViewCoupleGeneticAnalysisPolygenicDiseaseLocusDetailsPage ( window fyne . Window , person1Name string , person2Name string , person1AnalysisObject geneticAnalysis . PersonAnalysis , person2AnalysisObject geneticAnalysis . PersonAnalysis , coupleAnalysisObject geneticAnalysis . CoupleAnalysis , diseaseName string , locusIdentifier [ 3 ] byte , previousPage func ( ) ) {
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
currentPage := func ( ) { setViewCoupleGeneticAnalysisPolygenicDiseaseLocusDetailsPage ( window , person1Name , person2Name , person1AnalysisObject , person2AnalysisObject , coupleAnalysisObject , diseaseName , locusIdentifier , previousPage ) }
2024-04-11 15:51:56 +02:00
title := getPageTitleCentered ( "Disease Locus Details - " + diseaseName )
backButton := getBackButtonCentered ( previousPage )
2024-06-02 10:43:39 +02:00
locusIdentifierHex := encoding . EncodeBytesToHexString ( locusIdentifier [ : ] )
locusObject , err := polygenicDiseases . GetPolygenicDiseaseLocusObject ( diseaseName , locusIdentifierHex )
2024-04-11 15:51:56 +02:00
if ( err != nil ) {
setErrorEncounteredPage ( window , err , previousPage )
return
}
locusRSID := locusObject . LocusRSID
locusRSIDString := helpers . ConvertInt64ToString ( locusRSID )
locusName := "rs" + locusRSIDString
description := getLabelCentered ( "Below is the locus analysis for the couple." )
2024-06-02 10:43:39 +02:00
2024-04-11 15:51:56 +02:00
locusNameLabel := widget . NewLabel ( "Locus Name:" )
locusNameText := getBoldLabel ( locusName )
locusInfoButton := widget . NewButtonWithIcon ( "" , theme . InfoIcon ( ) , func ( ) {
2024-06-02 10:43:39 +02:00
setViewPolygenicDiseaseLocusDetailsPage ( window , diseaseName , locusIdentifierHex , currentPage )
2024-04-11 15:51:56 +02:00
} )
locusNameRow := container . NewHBox ( layout . NewSpacer ( ) , locusNameLabel , locusNameText , locusInfoButton , layout . NewSpacer ( ) )
getGenomePairsLocusInfoGrid := func ( ) ( * fyne . Container , error ) {
emptyLabel := widget . NewLabel ( "" )
genomePairLabel := getItalicLabelCentered ( "Genome Pair" )
offspringRiskWeightLabel := getItalicLabelCentered ( "Offspring Risk Weight" )
offspringOddsRatioLabel := getItalicLabelCentered ( "Offspring Odds Ratio" )
viewGenomePairInfoButtonsColumn := container . NewVBox ( emptyLabel , widget . NewSeparator ( ) )
genomePairNameColumn := container . NewVBox ( genomePairLabel , widget . NewSeparator ( ) )
offspringRiskWeightColumn := container . NewVBox ( offspringRiskWeightLabel , widget . NewSeparator ( ) )
offspringOddsRatioColumn := container . NewVBox ( offspringOddsRatioLabel , widget . NewSeparator ( ) )
2024-06-02 10:43:39 +02:00
addGenomePairRow := func ( genomePairName string , genomePairIdentifier [ 32 ] byte ) error {
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
offspringRiskWeightKnown , offspringRiskWeight , offspringOddsRatioKnown , _ , offspringOddsRatioFormatted , err := readGeneticAnalysis . GetOffspringPolygenicDiseaseLocusInfoFromGeneticAnalysis ( coupleAnalysisObject , diseaseName , locusIdentifier , genomePairIdentifier )
2024-04-11 15:51:56 +02:00
if ( err != nil ) { return err }
getOffspringRiskWeightText := func ( ) string {
if ( offspringRiskWeightKnown == false ) {
result := translate ( "Unknown" )
return result
}
offspringRiskWeightString := helpers . ConvertIntToString ( offspringRiskWeight )
return offspringRiskWeightString
}
offspringRiskWeightText := getOffspringRiskWeightText ( )
getOffspringOddsRatioText := func ( ) string {
if ( offspringOddsRatioKnown == false ) {
result := translate ( "Unknown" )
return result
}
return offspringOddsRatioFormatted
}
offspringOddsRatioText := getOffspringOddsRatioText ( )
viewGenomePairInfoButton := widget . NewButtonWithIcon ( "" , theme . InfoIcon ( ) , func ( ) {
2024-06-02 10:43:39 +02:00
setViewCoupleGeneticAnalysisPolygenicDiseaseGenomePairDetailsPage ( window , person1Name , person2Name , person1AnalysisObject , person2AnalysisObject , coupleAnalysisObject , diseaseName , genomePairIdentifier , genomePairName , currentPage )
2024-04-11 15:51:56 +02:00
} )
genomePairNameLabel := getBoldLabelCentered ( genomePairName )
offspringRiskWeightLabel := getBoldLabelCentered ( offspringRiskWeightText )
offspringOddsRatioLabel := getBoldLabelCentered ( offspringOddsRatioText )
viewGenomePairInfoButtonsColumn . Add ( viewGenomePairInfoButton )
genomePairNameColumn . Add ( genomePairNameLabel )
offspringRiskWeightColumn . Add ( offspringRiskWeightLabel )
offspringOddsRatioColumn . Add ( offspringOddsRatioLabel )
viewGenomePairInfoButtonsColumn . Add ( widget . NewSeparator ( ) )
genomePairNameColumn . Add ( widget . NewSeparator ( ) )
offspringRiskWeightColumn . Add ( widget . NewSeparator ( ) )
offspringOddsRatioColumn . Add ( widget . NewSeparator ( ) )
return nil
}
2024-06-02 10:43:39 +02:00
pair1Person1GenomeIdentifier , pair1Person2GenomeIdentifier , secondGenomePairExists , pair2Person1GenomeIdentifier , pair2Person2GenomeIdentifier , _ , _ , _ , _ , _ , _ , err := readGeneticAnalysis . GetMetadataFromCoupleGeneticAnalysis ( coupleAnalysisObject )
2024-04-11 15:51:56 +02:00
if ( err != nil ) { return nil , err }
2024-06-02 10:43:39 +02:00
genomePair1Identifier := helpers . JoinTwo16ByteArrays ( pair1Person1GenomeIdentifier , pair1Person2GenomeIdentifier )
2024-04-11 15:51:56 +02:00
err = addGenomePairRow ( "Pair 1" , genomePair1Identifier )
if ( err != nil ) { return nil , err }
if ( secondGenomePairExists == true ) {
2024-06-02 10:43:39 +02:00
genomePair2Identifier := helpers . JoinTwo16ByteArrays ( pair2Person1GenomeIdentifier , pair2Person2GenomeIdentifier )
2024-04-11 15:51:56 +02:00
err := addGenomePairRow ( "Pair 2" , genomePair2Identifier )
if ( err != nil ) { return nil , err }
}
offspringRiskWeightHelpButton := widget . NewButtonWithIcon ( "" , theme . QuestionIcon ( ) , func ( ) {
setOffspringPolygenicDiseaseLocusRiskWeightExplainerPage ( window , currentPage )
} )
offspringOddsRatioHelpButton := widget . NewButtonWithIcon ( "" , theme . QuestionIcon ( ) , func ( ) {
//TODO
showUnderConstructionDialog ( window )
} )
offspringRiskWeightColumn . Add ( offspringRiskWeightHelpButton )
offspringOddsRatioColumn . Add ( offspringOddsRatioHelpButton )
2024-06-02 10:43:39 +02:00
2024-04-11 15:51:56 +02:00
genomesContainer := container . NewHBox ( layout . NewSpacer ( ) , viewGenomePairInfoButtonsColumn , genomePairNameColumn , offspringRiskWeightColumn , offspringOddsRatioColumn , layout . NewSpacer ( ) )
return genomesContainer , nil
}
genomePairsLocusInfoGrid , err := getGenomePairsLocusInfoGrid ( )
if ( err != nil ) {
setErrorEncounteredPage ( window , err , previousPage )
return
}
page := container . NewVBox ( title , backButton , widget . NewSeparator ( ) , description , widget . NewSeparator ( ) , locusNameRow , widget . NewSeparator ( ) , genomePairsLocusInfoGrid )
setPageContent ( page , window )
}
2024-06-07 02:04:13 +02:00
// This is a page that shows the user 100 sample offspring polygenic disease risk scores on a bar chart
// This helps users to visualize the standard deviation of their offspring's disease risk with this user
func setViewPolygenicDiseaseSampleOffspringRiskScoresChart ( window fyne . Window , diseaseName string , sampleOffspringRiskScoresList [ ] int , numberOfLociTested int , previousPage func ( ) ) {
currentPage := func ( ) { setViewPolygenicDiseaseSampleOffspringRiskScoresChart ( window , diseaseName , sampleOffspringRiskScoresList , numberOfLociTested , previousPage ) }
title := getPageTitleCentered ( "Viewing Sample Offspring Risk Scores Chart" )
backButton := getBackButtonCentered ( previousPage )
description := widget . NewLabel ( "Below is a chart of 100 sample offspring risk scores for this disease." )
descriptionHelpButton := widget . NewButtonWithIcon ( "" , theme . QuestionIcon ( ) , func ( ) {
//TODO
showUnderConstructionDialog ( window )
} )
descriptionRow := container . NewHBox ( layout . NewSpacer ( ) , description , descriptionHelpButton , layout . NewSpacer ( ) )
diseaseNameTitle := widget . NewLabel ( "Disease Name:" )
diseaseNameLabel := getBoldLabel ( diseaseName )
diseaseNameRow := container . NewHBox ( layout . NewSpacer ( ) , diseaseNameTitle , diseaseNameLabel , layout . NewSpacer ( ) )
if ( len ( sampleOffspringRiskScoresList ) == 0 ) {
description2 := getBoldLabelCentered ( "There is no offspring information available for this disease." )
description3 := getBoldLabelCentered ( "This is because there were no disease loci for which both prospective parents had information." )
page := container . NewVBox ( title , backButton , widget . NewSeparator ( ) , descriptionRow , widget . NewSeparator ( ) , diseaseNameRow , widget . NewSeparator ( ) , description2 , description3 )
setPageContent ( page , window )
return
}
diseaseLociMap , err := polygenicDiseases . GetPolygenicDiseaseLociMap ( diseaseName )
if ( err != nil ) {
setErrorEncounteredPage ( window , err , previousPage )
return
}
totalNumberOfLoci := len ( diseaseLociMap )
totalNumberOfLociString := helpers . ConvertIntToString ( totalNumberOfLoci )
numberOfLociTestedTitle := widget . NewLabel ( "Number Of Loci Tested:" )
numberOfLociTestedString := helpers . ConvertIntToString ( numberOfLociTested )
numberOfLociTestedLabel := getBoldLabel ( numberOfLociTestedString + "/" + totalNumberOfLociString )
lociTestedHelpButton := widget . NewButtonWithIcon ( "" , theme . QuestionIcon ( ) , func ( ) {
setOffspringPolygenicDiseaseNumberOfLociTestedExplainerPage ( window , currentPage )
} )
numberOfLociTestedRow := container . NewHBox ( layout . NewSpacer ( ) , numberOfLociTestedTitle , numberOfLociTestedLabel , lociTestedHelpButton , layout . NewSpacer ( ) )
getOffspringSampleRiskScoresChartImage := func ( ) ( image . Image , error ) {
// Map Structure: Risk Score -> Number of offspring with that risk score
offspringRiskScoreCountsMap := make ( map [ int ] int )
for _ , offspringRiskScore := range sampleOffspringRiskScoresList {
offspringRiskScoreCountsMap [ offspringRiskScore ] += 1
}
//TODO: Move StatisticsDatum to its own package, because we are using it for non-user purposes, and will continue to do so
offspringStatisticsDatumsList := make ( [ ] statisticsDatum . StatisticsDatum , 0 )
for riskScore := 0 ; riskScore <= 10 ; riskScore += 1 {
getOffspringCount := func ( ) int {
offspringCount , exists := offspringRiskScoreCountsMap [ riskScore ]
if ( exists == false ) {
return 0
}
return offspringCount
}
offspringCount := getOffspringCount ( )
riskScoreString := helpers . ConvertIntToString ( riskScore )
offspringCountString := helpers . ConvertIntToString ( offspringCount )
newStatisticsDatum := statisticsDatum . StatisticsDatum {
Label : riskScoreString + "/10" ,
LabelFormatted : riskScoreString + "/10" ,
Value : float64 ( offspringCount ) ,
ValueFormatted : offspringCountString ,
}
offspringStatisticsDatumsList = append ( offspringStatisticsDatumsList , newStatisticsDatum )
}
chartTitle := diseaseName + ": 100 Prospective Offspring Risk Scores"
formatYAxisValuesFunction := func ( inputRiskScore float64 ) ( string , error ) {
inputRiskScoreInt , err := helpers . FloorFloat64ToInt ( inputRiskScore )
if ( err != nil ) { return "" , err }
inputRiskScoreString := helpers . ConvertIntToString ( inputRiskScoreInt )
return inputRiskScoreString , nil
}
offspringsChart , err := createCharts . CreateBarChart ( chartTitle , offspringStatisticsDatumsList , formatYAxisValuesFunction , true , " Offspring" )
if ( err != nil ) { return nil , err }
return offspringsChart , nil
}
offspringRiskScoresChartImage , err := getOffspringSampleRiskScoresChartImage ( )
if ( err != nil ) {
setErrorEncounteredPage ( window , err , previousPage )
return
}
viewChartFullscreenButton := getWidgetCentered ( widget . NewButtonWithIcon ( "View Fullscreen" , theme . ZoomInIcon ( ) , func ( ) {
setViewFullpageImagePage ( window , offspringRiskScoresChartImage , currentPage )
} ) )
pageHeader := container . NewVBox ( title , backButton , widget . NewSeparator ( ) , descriptionRow , widget . NewSeparator ( ) , diseaseNameRow , widget . NewSeparator ( ) , numberOfLociTestedRow , widget . NewSeparator ( ) )
chartFyneImage := canvas . NewImageFromImage ( offspringRiskScoresChartImage )
chartFyneImage . FillMode = canvas . ImageFillContain
page := container . NewBorder ( pageHeader , viewChartFullscreenButton , nil , nil , chartFyneImage )
setPageContent ( page , window )
}
2024-04-11 15:51:56 +02:00
2024-07-19 19:16:28 +02:00
func setViewCoupleGeneticAnalysisDiscreteTraitsPage ( window fyne . Window , person1Name string , person2Name string , person1AnalysisObject geneticAnalysis . PersonAnalysis , person2AnalysisObject geneticAnalysis . PersonAnalysis , coupleAnalysisObject geneticAnalysis . CoupleAnalysis , previousPage func ( ) ) {
2024-04-11 15:51:56 +02:00
2024-07-19 19:16:28 +02:00
currentPage := func ( ) { setViewCoupleGeneticAnalysisDiscreteTraitsPage ( window , person1Name , person2Name , person1AnalysisObject , person2AnalysisObject , coupleAnalysisObject , previousPage ) }
2024-04-11 15:51:56 +02:00
2024-07-19 19:16:28 +02:00
title := getPageTitleCentered ( "Viewing Genetic Analysis - Discrete Traits" )
2024-04-11 15:51:56 +02:00
backButton := getBackButtonCentered ( previousPage )
2024-07-19 19:16:28 +02:00
description := getLabelCentered ( "Below is an analysis of the average discrete trait outcomes for the couple's offspring." )
2024-04-11 15:51:56 +02:00
getTraitsGrid := func ( ) ( * fyne . Container , error ) {
2024-06-02 10:43:39 +02:00
pair1Person1GenomeIdentifier , pair1Person2GenomeIdentifier , secondGenomePairExists , _ , _ , _ , _ , _ , _ , _ , _ , err := readGeneticAnalysis . GetMetadataFromCoupleGeneticAnalysis ( coupleAnalysisObject )
2024-04-11 15:51:56 +02:00
if ( err != nil ) { return nil , err }
2024-06-02 10:43:39 +02:00
2024-07-19 19:16:28 +02:00
mainGenomePairIdentifier := helpers . JoinTwo16ByteArrays ( pair1Person1GenomeIdentifier , pair1Person2GenomeIdentifier )
emptyLabel1 := widget . NewLabel ( "" )
2024-04-11 15:51:56 +02:00
traitNameLabel := getItalicLabelCentered ( "Trait Name" )
2024-07-19 19:16:28 +02:00
emptyLabel2 := widget . NewLabel ( "" )
predictedProbabilitiesLabel := getItalicLabelCentered ( "Predicted Probabilities" )
2024-04-11 15:51:56 +02:00
2024-07-19 19:16:28 +02:00
quantityOfLabel := getItalicLabelCentered ( "Quantity Of" )
lociKnownLabel := getItalicLabelCentered ( "Loci Known" )
emptyLabel3 := widget . NewLabel ( "" )
2024-04-11 15:51:56 +02:00
conflictExistsLabel := getItalicLabelCentered ( "Conflict Exists?" )
2024-07-19 19:16:28 +02:00
emptyLabel4 := widget . NewLabel ( "" )
emptyLabel5 := widget . NewLabel ( "" )
2024-04-11 15:51:56 +02:00
2024-07-19 19:16:28 +02:00
traitNameColumn := container . NewVBox ( emptyLabel1 , traitNameLabel , widget . NewSeparator ( ) )
predictedProbabilitiesColumn := container . NewVBox ( emptyLabel2 , predictedProbabilitiesLabel , widget . NewSeparator ( ) )
quantityOfLociKnownColumn := container . NewVBox ( quantityOfLabel , lociKnownLabel , widget . NewSeparator ( ) )
conflictExistsColumn := container . NewVBox ( emptyLabel3 , conflictExistsLabel , widget . NewSeparator ( ) )
viewDetailsButtonsColumn := container . NewVBox ( emptyLabel4 , emptyLabel5 , widget . NewSeparator ( ) )
2024-04-11 15:51:56 +02:00
traitObjectsList , err := traits . GetTraitObjectsList ( )
if ( err != nil ) { return nil , err }
for _ , traitObject := range traitObjectsList {
2024-07-19 19:16:28 +02:00
traitIsDiscreteOrNumeric := traitObject . DiscreteOrNumeric
if ( traitIsDiscreteOrNumeric != "Discrete" ) {
continue
}
2024-04-11 15:51:56 +02:00
2024-07-19 19:16:28 +02:00
traitLociList := traitObject . LociList
2024-04-11 15:51:56 +02:00
traitRulesList := traitObject . RulesList
2024-07-19 19:16:28 +02:00
if ( len ( traitLociList ) == 0 && len ( traitRulesList ) == 0 ) {
2024-04-11 15:51:56 +02:00
// This trait does not have any rules
// We cannot analyze it yet
// We will add neural network prediction so we can predict these traits
continue
}
2024-07-19 19:16:28 +02:00
traitName := traitObject . TraitName
2024-06-02 10:43:39 +02:00
2024-07-19 19:16:28 +02:00
neuralNetworkExists , neuralNetworkAnalysisExists , offspringOutcomeProbabilitiesMap_NeuralNetwork , _ , quantityOfLociKnown_NeuralNetwork , _ , anyRulesExist , rulesAnalysisExists , offspringOutcomeProbabilitiesMap_Rules , _ , _ , quantityOfLociKnown_Rules , conflictExists , err := readGeneticAnalysis . GetOffspringDiscreteTraitInfoFromGeneticAnalysis ( coupleAnalysisObject , traitName , mainGenomePairIdentifier )
2024-04-11 15:51:56 +02:00
if ( err != nil ) { return nil , err }
2024-07-19 19:16:28 +02:00
if ( neuralNetworkExists == false && anyRulesExist == false ) {
// We cannot analyze this trait
continue
}
2024-04-11 15:51:56 +02:00
2024-07-19 19:16:28 +02:00
getQuantityOfLociKnown := func ( ) int {
if ( neuralNetworkExists == true ) {
return quantityOfLociKnown_NeuralNetwork
}
return quantityOfLociKnown_Rules
}
quantityOfLociKnown := getQuantityOfLociKnown ( )
getTotalQuantityOfLoci := func ( ) int {
if ( neuralNetworkExists == true ) {
totalQuantityOfLoci := len ( traitLociList )
return totalQuantityOfLoci
}
traitLociList_Rules := traitObject . LociList_Rules
totalQuantityOfLoci := len ( traitLociList_Rules )
return totalQuantityOfLoci
}
totalQuantityOfLoci := getTotalQuantityOfLoci ( )
quantityOfLociKnownString := helpers . ConvertIntToString ( quantityOfLociKnown )
totalQuantityOfLociString := helpers . ConvertIntToString ( totalQuantityOfLoci )
quantityOfLociKnownFormatted := quantityOfLociKnownString + "/" + totalQuantityOfLociString
quantityOfLociKnownLabel := getBoldLabelCentered ( quantityOfLociKnownFormatted )
// We add each row except for the outcome rows
// The outcome grid cell can be multiple rows tall
traitNameLabel := getBoldLabelCentered ( traitName )
2024-04-11 15:51:56 +02:00
conflictExistsString := helpers . ConvertBoolToYesOrNoString ( conflictExists )
conflictExistsLabel := getBoldLabelCentered ( conflictExistsString )
2024-07-19 19:16:28 +02:00
2024-04-11 15:51:56 +02:00
viewDetailsButton := getWidgetCentered ( widget . NewButtonWithIcon ( "" , theme . VisibilityIcon ( ) , func ( ) {
2024-07-19 19:16:28 +02:00
setViewCoupleGeneticAnalysisDiscreteTraitDetailsPage ( window , person1Name , person2Name , person1AnalysisObject , person2AnalysisObject , coupleAnalysisObject , traitName , currentPage )
2024-04-11 15:51:56 +02:00
} ) )
2024-07-19 19:16:28 +02:00
traitNameColumn . Add ( traitNameLabel )
quantityOfLociKnownColumn . Add ( quantityOfLociKnownLabel )
2024-04-11 15:51:56 +02:00
conflictExistsColumn . Add ( conflictExistsLabel )
2024-07-19 19:16:28 +02:00
viewDetailsButtonsColumn . Add ( viewDetailsButton )
2024-04-11 15:51:56 +02:00
2024-07-19 19:16:28 +02:00
// Outputs:
// -bool: Outcome probabilities exist
// -map[string]int: Outcome Name -> Probability of outcome (0-100)
getOutcomeProbabilitiesMap := func ( ) ( bool , map [ string ] int ) {
if ( neuralNetworkExists == true ) {
if ( neuralNetworkAnalysisExists == false ) {
return false , nil
}
return true , offspringOutcomeProbabilitiesMap_NeuralNetwork
}
//anyRulesExist must be true
if ( rulesAnalysisExists == false ) {
return false , nil
}
return true , offspringOutcomeProbabilitiesMap_Rules
}
2024-04-11 15:51:56 +02:00
2024-07-19 19:16:28 +02:00
outcomeProbabilitiesExist , outcomeProbabilitiesMap := getOutcomeProbabilitiesMap ( )
if ( outcomeProbabilitiesExist == false ) {
unknownLabel := getItalicLabelCentered ( "Unknown" )
predictedProbabilitiesColumn . Add ( unknownLabel )
2024-04-11 15:51:56 +02:00
} else {
2024-07-19 19:16:28 +02:00
outcomeNamesList := traitObject . OutcomesList
outcomeNamesListSorted := helpers . CopyAndSortStringListToUnicodeOrder ( outcomeNamesList )
2024-04-11 15:51:56 +02:00
2024-07-19 19:16:28 +02:00
addedItems := 0
2024-04-11 15:51:56 +02:00
2024-07-19 19:16:28 +02:00
for _ , outcomeName := range outcomeNamesListSorted {
2024-04-11 15:51:56 +02:00
2024-07-19 19:16:28 +02:00
outcomeProbability , exists := outcomeProbabilitiesMap [ outcomeName ]
2024-04-11 15:51:56 +02:00
if ( exists == false ) {
2024-07-19 19:16:28 +02:00
continue
}
if ( outcomeProbability == 0 ) {
continue
2024-04-11 15:51:56 +02:00
}
2024-07-19 19:16:28 +02:00
outcomeProbabilityString := helpers . ConvertIntToString ( outcomeProbability )
2024-04-11 15:51:56 +02:00
2024-07-19 19:16:28 +02:00
outcomeRowLabel := getBoldLabel ( outcomeName + ": " + outcomeProbabilityString + "%" )
2024-04-11 15:51:56 +02:00
2024-07-19 19:16:28 +02:00
predictedProbabilitiesColumn . Add ( outcomeRowLabel )
2024-04-11 15:51:56 +02:00
2024-07-19 19:16:28 +02:00
addedItems += 1
2024-04-11 15:51:56 +02:00
2024-07-19 19:16:28 +02:00
if ( addedItems != 1 ) {
// We have to add whitespace to the other columns
traitNameColumn . Add ( widget . NewLabel ( "" ) )
quantityOfLociKnownColumn . Add ( widget . NewLabel ( "" ) )
conflictExistsColumn . Add ( widget . NewLabel ( "" ) )
viewDetailsButtonsColumn . Add ( widget . NewLabel ( "" ) )
2024-04-11 15:51:56 +02:00
}
}
}
traitNameColumn . Add ( widget . NewSeparator ( ) )
2024-07-19 19:16:28 +02:00
predictedProbabilitiesColumn . Add ( widget . NewSeparator ( ) )
quantityOfLociKnownColumn . Add ( widget . NewSeparator ( ) )
2024-04-11 15:51:56 +02:00
conflictExistsColumn . Add ( widget . NewSeparator ( ) )
2024-07-19 19:16:28 +02:00
viewDetailsButtonsColumn . Add ( widget . NewSeparator ( ) )
2024-04-11 15:51:56 +02:00
}
2024-07-19 19:16:28 +02:00
predictedProbabilitiesHelpButton := widget . NewButtonWithIcon ( "" , theme . QuestionIcon ( ) , func ( ) {
//TODO
showUnderConstructionDialog ( window )
2024-04-11 15:51:56 +02:00
} )
2024-07-19 19:16:28 +02:00
predictedProbabilitiesColumn . Add ( predictedProbabilitiesHelpButton )
2024-04-11 15:51:56 +02:00
2024-07-19 19:16:28 +02:00
quantityOfLociKnownHelpButton := widget . NewButtonWithIcon ( "" , theme . QuestionIcon ( ) , func ( ) {
//TODO
showUnderConstructionDialog ( window )
} )
quantityOfLociKnownColumn . Add ( quantityOfLociKnownHelpButton )
traitsGrid := container . NewHBox ( layout . NewSpacer ( ) , traitNameColumn , predictedProbabilitiesColumn , quantityOfLociKnownColumn )
2024-04-11 15:51:56 +02:00
if ( secondGenomePairExists == true ) {
conflictExistsHelpButton := widget . NewButtonWithIcon ( "" , theme . QuestionIcon ( ) , func ( ) {
setCoupleGeneticAnalysisConflictExistsExplainerPage ( window , currentPage )
} )
conflictExistsColumn . Add ( conflictExistsHelpButton )
traitsGrid . Add ( conflictExistsColumn )
}
2024-07-19 19:16:28 +02:00
traitsGrid . Add ( viewDetailsButtonsColumn )
2024-04-11 15:51:56 +02:00
traitsGrid . Add ( layout . NewSpacer ( ) )
return traitsGrid , nil
}
traitsGrid , err := getTraitsGrid ( )
if ( err != nil ) {
setErrorEncounteredPage ( window , err , previousPage )
return
}
page := container . NewVBox ( title , backButton , widget . NewSeparator ( ) , description , widget . NewSeparator ( ) , traitsGrid )
setPageContent ( page , window )
}
2024-07-19 19:16:28 +02:00
func setViewCoupleGeneticAnalysisDiscreteTraitDetailsPage ( window fyne . Window , person1Name string , person2Name string , person1AnalysisObject geneticAnalysis . PersonAnalysis , person2AnalysisObject geneticAnalysis . PersonAnalysis , coupleAnalysisObject geneticAnalysis . CoupleAnalysis , traitName string , previousPage func ( ) ) {
2024-04-11 15:51:56 +02:00
2024-07-19 19:16:28 +02:00
currentPage := func ( ) { setViewCoupleGeneticAnalysisDiscreteTraitDetailsPage ( window , person1Name , person2Name , person1AnalysisObject , person2AnalysisObject , coupleAnalysisObject , traitName , previousPage ) }
2024-04-11 15:51:56 +02:00
title := getPageTitleCentered ( "Viewing Couple Analysis - " + traitName )
backButton := getBackButtonCentered ( previousPage )
2024-07-19 19:16:28 +02:00
2024-06-02 10:43:39 +02:00
pair1Person1GenomeIdentifier , pair1Person2GenomeIdentifier , secondGenomePairExists , pair2Person1GenomeIdentifier , pair2Person2GenomeIdentifier , _ , _ , _ , _ , _ , _ , err := readGeneticAnalysis . GetMetadataFromCoupleGeneticAnalysis ( coupleAnalysisObject )
2024-04-11 15:51:56 +02:00
if ( err != nil ) {
setErrorEncounteredPage ( window , err , previousPage )
return
}
getDescriptionSection := func ( ) * fyne . Container {
if ( secondGenomePairExists == false ) {
description := getLabelCentered ( "Below is the trait analysis for the couple's offspring." )
return description
}
description1 := getLabelCentered ( "Below is the trait analysis for the couple's offspring." )
description2 := getLabelCentered ( "Each genome pair combines different genomes from each person." )
descriptionsSection := container . NewVBox ( description1 , description2 )
return descriptionsSection
}
descriptionSection := getDescriptionSection ( )
traitNameLabel := widget . NewLabel ( "Trait:" )
traitNameText := getBoldLabel ( traitName )
traitNameInfoButton := widget . NewButtonWithIcon ( "" , theme . InfoIcon ( ) , func ( ) {
setViewTraitDetailsPage ( window , traitName , currentPage )
} )
traitNameRow := container . NewHBox ( layout . NewSpacer ( ) , traitNameLabel , traitNameText , traitNameInfoButton , layout . NewSpacer ( ) )
2024-07-19 19:16:28 +02:00
neuralNetworkExists , _ := geneticPredictionModels . GetGeneticPredictionModelBytes ( traitName )
2024-04-11 15:51:56 +02:00
2024-07-19 19:16:28 +02:00
emptyLabel1 := widget . NewLabel ( "" )
emptyLabel2 := widget . NewLabel ( "" )
emptyLabel3 := widget . NewLabel ( "" )
genomePairLabel := getItalicLabelCentered ( "Genome Pair" )
emptyLabel4 := widget . NewLabel ( "" )
predictedProbabilitiesLabel := getItalicLabelCentered ( "Predicted Probabilities" )
predictionLabel := getItalicLabelCentered ( "Prediction" )
confidenceLabel := getItalicLabelCentered ( "Confidence" )
quantityOfLabel := getItalicLabelCentered ( "Quantity Of" )
rulesTestedLabel := getItalicLabelCentered ( "Rules Tested" )
emptyLabel5 := widget . NewLabel ( "" )
emptyLabel6 := widget . NewLabel ( "" )
2024-04-11 15:51:56 +02:00
2024-07-19 19:16:28 +02:00
viewGenomePairButtonsColumn := container . NewVBox ( emptyLabel1 , emptyLabel2 , widget . NewSeparator ( ) )
pairNameColumn := container . NewVBox ( emptyLabel3 , genomePairLabel , widget . NewSeparator ( ) )
predictedProbabilitiesColumn := container . NewVBox ( emptyLabel4 , predictedProbabilitiesLabel , widget . NewSeparator ( ) )
neuralNetworkPredictionConfidenceColumn := container . NewVBox ( predictionLabel , confidenceLabel , widget . NewSeparator ( ) )
quantityOfRulesTestedColumn := container . NewVBox ( quantityOfLabel , rulesTestedLabel , widget . NewSeparator ( ) )
viewDetailsButtonsColumn := container . NewVBox ( emptyLabel5 , emptyLabel6 , widget . NewSeparator ( ) )
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
addGenomePairRow := func ( genomePairName string , person1GenomeIdentifier [ 16 ] byte , person2GenomeIdentifier [ 16 ] byte ) error {
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
genomePairIdentifier := helpers . JoinTwo16ByteArrays ( person1GenomeIdentifier , person2GenomeIdentifier )
2024-04-11 15:51:56 +02:00
genomePairNameLabel := getBoldLabelCentered ( genomePairName )
viewGenomePairButton := widget . NewButtonWithIcon ( "" , theme . InfoIcon ( ) , func ( ) {
2024-07-19 19:16:28 +02:00
setViewCoupleGeneticAnalysisDiscreteTraitGenomePairDetailsPage ( window , person1Name , person2Name , person1AnalysisObject , person2AnalysisObject , coupleAnalysisObject , traitName , genomePairIdentifier , genomePairName , currentPage )
2024-04-11 15:51:56 +02:00
} )
2024-07-19 19:16:28 +02:00
viewAnalysisDetailsButton := widget . NewButtonWithIcon ( "" , theme . VisibilityIcon ( ) , func ( ) {
if ( neuralNetworkExists == true ) {
//TODO
showUnderConstructionDialog ( window )
} else {
setViewCoupleDiscreteTraitRulesPage ( window , person1Name , person2Name , person1AnalysisObject , person2AnalysisObject , coupleAnalysisObject , traitName , genomePairIdentifier , genomePairName , currentPage )
}
2024-04-11 15:51:56 +02:00
} )
viewGenomePairButtonsColumn . Add ( viewGenomePairButton )
pairNameColumn . Add ( genomePairNameLabel )
2024-07-19 19:16:28 +02:00
viewDetailsButtonsColumn . Add ( viewAnalysisDetailsButton )
traitObject , err := traits . GetTraitObject ( traitName )
if ( err != nil ) { return err }
traitIsDiscreteOrNumeric := traitObject . DiscreteOrNumeric
if ( traitIsDiscreteOrNumeric != "Discrete" ) {
return errors . New ( "setViewCoupleGeneticAnalysisDiscreteTraitDetailsPage called with non-discrete trait: " + traitName )
}
2024-04-11 15:51:56 +02:00
2024-07-19 19:16:28 +02:00
neuralNetworkExists , neuralNetworkAnalysisExists , offspringOutcomeProbabilitiesMap_NeuralNetwork , neuralNetworkPredictionConfidence , _ , _ , anyRulesExist , rulesAnalysisExists , offspringOutcomeProbabilitiesMap_Rules , _ , quantityOfRulesTested , _ , _ , err := readGeneticAnalysis . GetOffspringDiscreteTraitInfoFromGeneticAnalysis ( coupleAnalysisObject , traitName , genomePairIdentifier )
2024-04-11 15:51:56 +02:00
if ( err != nil ) { return err }
2024-07-19 19:16:28 +02:00
if ( neuralNetworkExists == false && anyRulesExist == false ) {
return errors . New ( "setViewCoupleGeneticAnalysisDiscreteTraitDetailsPage called with trait that is not analyzable." )
}
// First we add analysis details to their respective column
if ( neuralNetworkExists == true ) {
if ( neuralNetworkAnalysisExists == false ) {
neuralNetworkPredictionConfidenceColumn . Add ( getLabelCentered ( "-" ) )
} else {
predictionConfidenceString := helpers . ConvertIntToString ( neuralNetworkPredictionConfidence )
2024-04-11 15:51:56 +02:00
2024-07-19 19:16:28 +02:00
predictionConfidenceLabel := getBoldLabelCentered ( predictionConfidenceString + "%" )
2024-04-11 15:51:56 +02:00
2024-07-19 19:16:28 +02:00
neuralNetworkPredictionConfidenceColumn . Add ( predictionConfidenceLabel )
}
2024-04-11 15:51:56 +02:00
} else {
2024-07-19 19:16:28 +02:00
if ( anyRulesExist == false ) {
return errors . New ( "setViewCoupleGeneticAnalysisDiscreteTraitDetailsPage called with analysis which is missing " )
}
2024-04-11 15:51:56 +02:00
2024-07-19 19:16:28 +02:00
traitRulesList := traitObject . RulesList
2024-04-11 15:51:56 +02:00
2024-07-19 19:16:28 +02:00
totalNumberOfRules := len ( traitRulesList )
2024-04-11 15:51:56 +02:00
2024-07-19 19:16:28 +02:00
totalNumberOfRulesString := helpers . ConvertIntToString ( totalNumberOfRules )
quantityOfRulesTestedString := helpers . ConvertIntToString ( quantityOfRulesTested )
quantityOfRulesTestedFormatted := quantityOfRulesTestedString + "/" + totalNumberOfRulesString
quantityOfRulesTestedLabel := getBoldLabelCentered ( quantityOfRulesTestedFormatted )
quantityOfRulesTestedColumn . Add ( quantityOfRulesTestedLabel )
}
// Now we add the outcome probabilities cell
// Outputs:
// -bool: Outcome probabilities exist
// -map[string]int: Outcome Name -> Probability of outcome (0-100)
getOutcomeProbabilitiesMap := func ( ) ( bool , map [ string ] int ) {
if ( neuralNetworkExists == true ) {
if ( neuralNetworkAnalysisExists == false ) {
return false , nil
}
return true , offspringOutcomeProbabilitiesMap_NeuralNetwork
}
//anyRulesExist must be true
if ( rulesAnalysisExists == false ) {
return false , nil
}
return true , offspringOutcomeProbabilitiesMap_Rules
}
outcomeProbabilitiesExist , outcomeProbabilitiesMap := getOutcomeProbabilitiesMap ( )
if ( outcomeProbabilitiesExist == false ) {
unknownLabel := getItalicLabelCentered ( "Unknown" )
predictedProbabilitiesColumn . Add ( unknownLabel )
} else {
2024-04-11 15:51:56 +02:00
2024-07-19 19:16:28 +02:00
outcomeNamesList := traitObject . OutcomesList
outcomeNamesListSorted := helpers . CopyAndSortStringListToUnicodeOrder ( outcomeNamesList )
addedItems := 0
for _ , outcomeName := range outcomeNamesListSorted {
outcomeProbability , exists := outcomeProbabilitiesMap [ outcomeName ]
2024-04-11 15:51:56 +02:00
if ( exists == false ) {
2024-07-19 19:16:28 +02:00
continue
2024-04-11 15:51:56 +02:00
}
2024-07-19 19:16:28 +02:00
if ( outcomeProbability == 0 ) {
continue
}
2024-04-11 15:51:56 +02:00
2024-07-19 19:16:28 +02:00
outcomeProbabilityString := helpers . ConvertIntToString ( outcomeProbability )
outcomeRowLabel := getBoldLabel ( outcomeName + ": " + outcomeProbabilityString + "%" )
2024-04-11 15:51:56 +02:00
2024-07-19 19:16:28 +02:00
predictedProbabilitiesColumn . Add ( outcomeRowLabel )
addedItems += 1
if ( addedItems > 1 ) {
// We have to add whitespace to the other columns
viewGenomePairButtonsColumn . Add ( widget . NewLabel ( "" ) )
pairNameColumn . Add ( widget . NewLabel ( "" ) )
neuralNetworkPredictionConfidenceColumn . Add ( widget . NewLabel ( "" ) )
quantityOfRulesTestedColumn . Add ( widget . NewLabel ( "" ) )
viewDetailsButtonsColumn . Add ( widget . NewLabel ( "" ) )
2024-04-11 15:51:56 +02:00
}
}
}
viewGenomePairButtonsColumn . Add ( widget . NewSeparator ( ) )
pairNameColumn . Add ( widget . NewSeparator ( ) )
2024-07-19 19:16:28 +02:00
predictedProbabilitiesColumn . Add ( widget . NewSeparator ( ) )
neuralNetworkPredictionConfidenceColumn . Add ( widget . NewSeparator ( ) )
quantityOfRulesTestedColumn . Add ( widget . NewSeparator ( ) )
viewDetailsButtonsColumn . Add ( widget . NewSeparator ( ) )
2024-04-11 15:51:56 +02:00
return nil
}
2024-06-02 10:43:39 +02:00
err = addGenomePairRow ( "Pair 1" , pair1Person1GenomeIdentifier , pair1Person2GenomeIdentifier )
2024-04-11 15:51:56 +02:00
if ( err != nil ) {
setErrorEncounteredPage ( window , err , previousPage )
return
}
if ( secondGenomePairExists == true ) {
2024-06-02 10:43:39 +02:00
err := addGenomePairRow ( "Pair 2" , pair2Person1GenomeIdentifier , pair2Person2GenomeIdentifier )
2024-04-11 15:51:56 +02:00
if ( err != nil ) {
setErrorEncounteredPage ( window , err , previousPage )
return
}
}
2024-07-19 19:16:28 +02:00
predictedProbabilitiesHelpButton := widget . NewButtonWithIcon ( "" , theme . QuestionIcon ( ) , func ( ) {
//TODO
showUnderConstructionDialog ( window )
2024-04-11 15:51:56 +02:00
} )
2024-07-19 19:16:28 +02:00
predictedProbabilitiesColumn . Add ( predictedProbabilitiesHelpButton )
if ( neuralNetworkExists == true ) {
neuralNetworkPredictionConfidenceHelpButton := widget . NewButtonWithIcon ( "" , theme . QuestionIcon ( ) , func ( ) {
setOffspringDiscreteTraitNeuralNetworkPredictionExplainerPage ( window , currentPage )
} )
neuralNetworkPredictionConfidenceColumn . Add ( neuralNetworkPredictionConfidenceHelpButton )
} else {
quantityOfRulesTestedHelpButton := widget . NewButtonWithIcon ( "" , theme . QuestionIcon ( ) , func ( ) {
setOffspringDiscreteTraitQuantityOfRulesTestedExplainerPage ( window , currentPage )
} )
quantityOfRulesTestedColumn . Add ( quantityOfRulesTestedHelpButton )
}
genomesContainer := container . NewHBox ( layout . NewSpacer ( ) , viewGenomePairButtonsColumn , pairNameColumn , predictedProbabilitiesColumn )
if ( neuralNetworkExists == true ) {
genomesContainer . Add ( neuralNetworkPredictionConfidenceColumn )
} else {
genomesContainer . Add ( quantityOfRulesTestedColumn )
}
2024-04-11 15:51:56 +02:00
2024-07-19 19:16:28 +02:00
genomesContainer . Add ( viewDetailsButtonsColumn )
genomesContainer . Add ( layout . NewSpacer ( ) )
2024-04-11 15:51:56 +02:00
page := container . NewVBox ( title , backButton , widget . NewSeparator ( ) , descriptionSection , widget . NewSeparator ( ) , traitNameRow , widget . NewSeparator ( ) , genomesContainer )
2024-07-19 19:16:28 +02:00
2024-04-11 15:51:56 +02:00
setPageContent ( page , window )
}
2024-07-19 19:16:28 +02:00
func setViewCoupleGeneticAnalysisDiscreteTraitGenomePairDetailsPage ( window fyne . Window , person1Name string , person2Name string , person1AnalysisObject geneticAnalysis . PersonAnalysis , person2AnalysisObject geneticAnalysis . PersonAnalysis , coupleAnalysisObject geneticAnalysis . CoupleAnalysis , traitName string , genomePairIdentifier [ 32 ] byte , genomePairName string , previousPage func ( ) ) {
2024-04-11 15:51:56 +02:00
2024-07-19 19:16:28 +02:00
currentPage := func ( ) { setViewCoupleGeneticAnalysisDiscreteTraitGenomePairDetailsPage ( window , person1Name , person2Name , person1AnalysisObject , person2AnalysisObject , coupleAnalysisObject , traitName , genomePairIdentifier , genomePairName , previousPage ) }
2024-04-11 15:51:56 +02:00
title := getPageTitleCentered ( "Viewing Couple Genome Pair Info" )
backButton := getBackButtonCentered ( previousPage )
description := getLabelCentered ( "Below is the trait information for both genomes in the genome pair." )
traitNameLabel := widget . NewLabel ( "Trait:" )
traitNameText := getBoldLabel ( traitName )
traitNameInfoButton := widget . NewButtonWithIcon ( "" , theme . InfoIcon ( ) , func ( ) {
setViewTraitDetailsPage ( window , traitName , currentPage )
} )
traitNameRow := container . NewHBox ( layout . NewSpacer ( ) , traitNameLabel , traitNameText , traitNameInfoButton , layout . NewSpacer ( ) )
genomePairLabel := widget . NewLabel ( "Genome Pair:" )
genomePairNameLabel := getBoldLabel ( genomePairName )
genomePairHelpButton := widget . NewButtonWithIcon ( "" , theme . QuestionIcon ( ) , func ( ) {
setCoupleGenomePairExplainerPage ( window , currentPage )
} )
genomePairRow := container . NewHBox ( layout . NewSpacer ( ) , genomePairLabel , genomePairNameLabel , genomePairHelpButton , layout . NewSpacer ( ) )
2024-07-19 19:16:28 +02:00
emptyLabel1 := widget . NewLabel ( "" )
2024-04-11 15:51:56 +02:00
personNameLabel := getItalicLabelCentered ( "Person Name" )
2024-07-19 19:16:28 +02:00
emptyLabel2 := widget . NewLabel ( "" )
2024-04-11 15:51:56 +02:00
genomeNameLabel := getItalicLabelCentered ( "Genome Name" )
2024-07-19 19:16:28 +02:00
emptyLabel3 := widget . NewLabel ( "" )
predictedOutcomeLabel := getItalicLabelCentered ( "Predicted Outcome" )
2024-04-11 15:51:56 +02:00
2024-07-19 19:16:28 +02:00
quantityOfLabel1 := getItalicLabelCentered ( "Quantity Of" )
lociKnownLabel := getItalicLabelCentered ( "Loci Known" )
quantityOfLabel2 := getItalicLabelCentered ( "Quantity Of" )
2024-04-11 15:51:56 +02:00
rulesTestedLabel := getItalicLabelCentered ( "Rules Tested" )
2024-07-19 19:16:28 +02:00
emptyLabel4 := widget . NewLabel ( "" )
emptyLabel5 := widget . NewLabel ( "" )
2024-04-11 15:51:56 +02:00
2024-07-19 19:16:28 +02:00
personNameColumn := container . NewVBox ( emptyLabel1 , personNameLabel , widget . NewSeparator ( ) )
genomeNameColumn := container . NewVBox ( emptyLabel2 , genomeNameLabel , widget . NewSeparator ( ) )
predictedOutcomeColumn := container . NewVBox ( emptyLabel3 , predictedOutcomeLabel , widget . NewSeparator ( ) )
quantityOfLociKnownColumn := container . NewVBox ( quantityOfLabel1 , lociKnownLabel , widget . NewSeparator ( ) )
quantityOfRulesTestedColumn := container . NewVBox ( quantityOfLabel2 , rulesTestedLabel , widget . NewSeparator ( ) )
viewGenomeButtonsColumn := container . NewVBox ( emptyLabel4 , emptyLabel5 , widget . NewSeparator ( ) )
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
addGenomeRow := func ( isPerson1 bool , personName string , inputGenomeIdentifier [ 16 ] byte ) error {
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
personAnalysisGenomeIdentifier , _ , genomeIsCombined , combinedType , err := readGeneticAnalysis . GetMatchingPersonAnalysisGenomeIdentifierFromCoupleAnalysis ( isPerson1 , person1AnalysisObject , person2AnalysisObject , coupleAnalysisObject , inputGenomeIdentifier )
2024-04-11 15:51:56 +02:00
if ( err != nil ) { return err }
personNameTrimmed , _ , err := helpers . TrimAndFlattenString ( personName , 10 )
if ( err != nil ) { return err }
personNameLabel := getBoldLabelCentered ( personNameTrimmed )
2024-06-02 10:43:39 +02:00
getPersonAnalysisObject := func ( ) geneticAnalysis . PersonAnalysis {
if ( isPerson1 == true ) {
return person1AnalysisObject
2024-04-11 15:51:56 +02:00
}
2024-06-02 10:43:39 +02:00
return person2AnalysisObject
2024-04-11 15:51:56 +02:00
}
2024-06-02 10:43:39 +02:00
personAnalysisObject := getPersonAnalysisObject ( )
2024-04-11 15:51:56 +02:00
getGenomeName := func ( ) ( string , error ) {
if ( genomeIsCombined == false ) {
genomeFound , _ , _ , _ , _ , _ , companyName , _ , _ , err := myGenomes . GetMyRawGenomeMetadata ( personAnalysisGenomeIdentifier )
if ( err != nil ) { return "" , err }
if ( genomeFound == false ) {
2024-06-02 10:43:39 +02:00
return "" , errors . New ( "MyGenomeInfo for genome from analysisObject not found." )
2024-04-11 15:51:56 +02:00
}
return companyName , nil
}
return combinedType , nil
}
genomeName , err := getGenomeName ( )
if ( err != nil ) { return err }
genomeNameLabel := getBoldLabelCentered ( genomeName )
2024-07-19 19:16:28 +02:00
neuralNetworkExists , neuralNetworkAnalysisExists , neuralNetworkPredictedOutcome , _ , neuralNetworkQuantityOfLociTested , _ , _ , rulesAnalysisExists , _ , rulesPredictedOutcomeExists , rulesPredictedOutcome , quantityOfRulesTested , _ , _ , err := readGeneticAnalysis . GetPersonDiscreteTraitInfoFromGeneticAnalysis ( personAnalysisObject , traitName , personAnalysisGenomeIdentifier )
2024-04-11 15:51:56 +02:00
if ( err != nil ) { return err }
personNameColumn . Add ( personNameLabel )
genomeNameColumn . Add ( genomeNameLabel )
2024-07-19 19:16:28 +02:00
//Outputs:
// -bool: Outcome is known
// -string: Prediction outcome
getPredictedOutcome := func ( ) ( bool , string ) {
if ( neuralNetworkExists == true ) {
if ( neuralNetworkAnalysisExists == false ) {
return false , ""
}
return true , neuralNetworkPredictedOutcome
}
// Analysis must be rule-based
if ( rulesAnalysisExists == false || rulesPredictedOutcomeExists == false ) {
return false , ""
}
2024-04-11 15:51:56 +02:00
2024-07-19 19:16:28 +02:00
return true , rulesPredictedOutcome
}
2024-04-11 15:51:56 +02:00
2024-07-19 19:16:28 +02:00
predictedOutcomeExists , predictedOutcome := getPredictedOutcome ( )
if ( predictedOutcomeExists == false ) {
unknownLabel := getItalicLabelCentered ( translate ( "Unknown" ) )
predictedOutcomeColumn . Add ( unknownLabel )
2024-04-11 15:51:56 +02:00
} else {
2024-07-19 19:16:28 +02:00
predictedOutcomeLabel := getBoldLabelCentered ( predictedOutcome )
predictedOutcomeColumn . Add ( predictedOutcomeLabel )
}
2024-04-11 15:51:56 +02:00
2024-07-19 19:16:28 +02:00
// Now we add outcome details
2024-04-11 15:51:56 +02:00
2024-07-19 19:16:28 +02:00
traitObject , err := traits . GetTraitObject ( traitName )
if ( err != nil ) { return err }
2024-04-11 15:51:56 +02:00
2024-07-19 19:16:28 +02:00
traitIsDiscreteOrNumeric := traitObject . DiscreteOrNumeric
if ( traitIsDiscreteOrNumeric != "Discrete" ) {
return errors . New ( "setViewCoupleGeneticAnalysisDiscreteTraitGenomePairDetailsPage called with non-discrete trait: " + traitName )
}
2024-04-11 15:51:56 +02:00
2024-07-19 19:16:28 +02:00
if ( neuralNetworkExists == true ) {
2024-06-02 10:43:39 +02:00
2024-07-19 19:16:28 +02:00
traitLociList := traitObject . LociList
2024-04-11 15:51:56 +02:00
2024-07-19 19:16:28 +02:00
totalQuantityOfLoci := len ( traitLociList )
2024-04-11 15:51:56 +02:00
2024-07-19 19:16:28 +02:00
quantityOfLociKnownString := helpers . ConvertIntToString ( neuralNetworkQuantityOfLociTested )
totalQuantityOfLociString := helpers . ConvertIntToString ( totalQuantityOfLoci )
2024-04-11 15:51:56 +02:00
2024-07-19 19:16:28 +02:00
quantityOfLociKnownFormatted := quantityOfLociKnownString + "/" + totalQuantityOfLociString
quantityOfLociKnownLabel := getBoldLabelCentered ( quantityOfLociKnownFormatted )
quantityOfLociKnownColumn . Add ( quantityOfLociKnownLabel )
} else {
// Analysis is rule-based
traitRulesList := traitObject . RulesList
totalQuantityOfRules := len ( traitRulesList )
quantityOfRulesTestedString := helpers . ConvertIntToString ( quantityOfRulesTested )
totalQuantityOfRulesString := helpers . ConvertIntToString ( totalQuantityOfRules )
quantityOfRulesTestedFormatted := quantityOfRulesTestedString + "/" + totalQuantityOfRulesString
quantityOfRulesTestedLabel := getBoldLabelCentered ( quantityOfRulesTestedFormatted )
quantityOfRulesTestedColumn . Add ( quantityOfRulesTestedLabel )
2024-04-11 15:51:56 +02:00
}
2024-07-19 19:16:28 +02:00
viewGenomeButton := widget . NewButtonWithIcon ( "" , theme . VisibilityIcon ( ) , func ( ) {
if ( neuralNetworkExists == true ) {
//TODO
showUnderConstructionDialog ( window )
} else {
setViewPersonGenomeDiscreteTraitRulesPage ( window , personAnalysisObject , traitName , personAnalysisGenomeIdentifier , genomeName , currentPage )
}
} )
viewGenomeButtonsColumn . Add ( viewGenomeButton )
2024-04-11 15:51:56 +02:00
personNameColumn . Add ( widget . NewSeparator ( ) )
genomeNameColumn . Add ( widget . NewSeparator ( ) )
2024-07-19 19:16:28 +02:00
predictedOutcomeColumn . Add ( widget . NewSeparator ( ) )
quantityOfLociKnownColumn . Add ( widget . NewSeparator ( ) )
quantityOfRulesTestedColumn . Add ( widget . NewSeparator ( ) )
2024-04-11 15:51:56 +02:00
viewGenomeButtonsColumn . Add ( widget . NewSeparator ( ) )
return nil
}
2024-06-02 10:43:39 +02:00
person1GenomeIdentifier , person2GenomeIdentifier := helpers . Split32ByteArrayInHalf ( genomePairIdentifier )
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
err := addGenomeRow ( true , person1Name , person1GenomeIdentifier )
2024-04-11 15:51:56 +02:00
if ( err != nil ) {
setErrorEncounteredPage ( window , err , previousPage )
return
}
2024-06-02 10:43:39 +02:00
err = addGenomeRow ( false , person2Name , person2GenomeIdentifier )
2024-04-11 15:51:56 +02:00
if ( err != nil ) {
setErrorEncounteredPage ( window , err , previousPage )
return
}
2024-07-19 19:16:28 +02:00
neuralNetworkExists , _ := geneticPredictionModels . GetGeneticPredictionModelBytes ( traitName )
predictedOutcomeHelpButton := widget . NewButtonWithIcon ( "" , theme . QuestionIcon ( ) , func ( ) {
if ( neuralNetworkExists == true ) {
setDiscreteTraitNeuralNetworkPredictionExplainerPage ( window , currentPage )
} else {
setOffspringDiscreteTraitNeuralNetworkPredictionExplainerPage ( window , currentPage )
}
2024-04-11 15:51:56 +02:00
} )
2024-07-19 19:16:28 +02:00
predictedOutcomeColumn . Add ( predictedOutcomeHelpButton )
quantityOfLociKnownHelpButton := widget . NewButtonWithIcon ( "" , theme . QuestionIcon ( ) , func ( ) {
//TODO
showUnderConstructionDialog ( window )
} )
quantityOfLociKnownColumn . Add ( quantityOfLociKnownHelpButton )
2024-04-11 15:51:56 +02:00
numberOfRulesTestedHelpButton := widget . NewButtonWithIcon ( "" , theme . QuestionIcon ( ) , func ( ) {
2024-07-19 19:16:28 +02:00
setOffspringDiscreteTraitQuantityOfRulesTestedExplainerPage ( window , currentPage )
2024-04-11 15:51:56 +02:00
} )
2024-07-19 19:16:28 +02:00
quantityOfRulesTestedColumn . Add ( numberOfRulesTestedHelpButton )
2024-04-11 15:51:56 +02:00
2024-07-19 19:16:28 +02:00
genomesGrid := container . NewHBox ( layout . NewSpacer ( ) , personNameColumn , genomeNameColumn , predictedOutcomeColumn )
if ( neuralNetworkExists == true ) {
genomesGrid . Add ( quantityOfLociKnownColumn )
} else {
genomesGrid . Add ( quantityOfRulesTestedColumn )
}
genomesGrid . Add ( viewGenomeButtonsColumn )
genomesGrid . Add ( layout . NewSpacer ( ) )
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
page := container . NewVBox ( title , backButton , widget . NewSeparator ( ) , description , widget . NewSeparator ( ) , traitNameRow , widget . NewSeparator ( ) , genomePairRow , widget . NewSeparator ( ) , genomesGrid )
2024-04-11 15:51:56 +02:00
setPageContent ( page , window )
}
// This function provides a page to view the couple offspring rule probabilities for a particular genome pair
2024-07-19 19:16:28 +02:00
func setViewCoupleDiscreteTraitRulesPage ( window fyne . Window , person1Name string , person2Name string , person1AnalysisObject geneticAnalysis . PersonAnalysis , person2AnalysisObject geneticAnalysis . PersonAnalysis , coupleAnalysisObject geneticAnalysis . CoupleAnalysis , traitName string , genomePairIdentifier [ 32 ] byte , genomePairName string , previousPage func ( ) ) {
2024-04-11 15:51:56 +02:00
setLoadingScreen ( window , "Loading Trait Rules" , "Loading trait rules..." )
2024-07-19 19:16:28 +02:00
currentPage := func ( ) { setViewCoupleDiscreteTraitRulesPage ( window , person1Name , person2Name , person1AnalysisObject , person2AnalysisObject , coupleAnalysisObject , traitName , genomePairIdentifier , genomePairName , previousPage ) }
2024-04-11 15:51:56 +02:00
title := getPageTitleCentered ( "View Offspring Trait Rules - " + traitName )
backButton := getBackButtonCentered ( previousPage )
description1 := widget . NewLabel ( "Below are the trait rule probabilities for offspring from this genome pair." )
traitRulesHelpButton := widget . NewButtonWithIcon ( "" , theme . QuestionIcon ( ) , func ( ) {
2024-07-19 19:16:28 +02:00
setOffspringDiscreteTraitRulesExplainerPage ( window , currentPage )
2024-04-11 15:51:56 +02:00
} )
description1Row := container . NewHBox ( layout . NewSpacer ( ) , description1 , traitRulesHelpButton , layout . NewSpacer ( ) )
genomePairLabel := widget . NewLabel ( "Genome Pair:" )
genomePairNameLabel := getBoldLabel ( genomePairName )
viewGenomePairInfoButton := widget . NewButtonWithIcon ( "" , theme . InfoIcon ( ) , func ( ) {
2024-07-19 19:16:28 +02:00
setViewCoupleGeneticAnalysisDiscreteTraitGenomePairDetailsPage ( window , person1Name , person2Name , person1AnalysisObject , person2AnalysisObject , coupleAnalysisObject , traitName , genomePairIdentifier , genomePairName , currentPage )
2024-04-11 15:51:56 +02:00
} )
genomePairRow := container . NewHBox ( layout . NewSpacer ( ) , genomePairLabel , genomePairNameLabel , viewGenomePairInfoButton , layout . NewSpacer ( ) )
2024-07-19 19:16:28 +02:00
neuralNetworkExists , _ , _ , _ , _ , _ , anyRulesExist , rulesAnalysisExists , _ , _ , quantityOfRulesTested , _ , _ , err := readGeneticAnalysis . GetOffspringDiscreteTraitInfoFromGeneticAnalysis ( coupleAnalysisObject , traitName , genomePairIdentifier )
2024-04-11 15:51:56 +02:00
if ( err != nil ) {
setErrorEncounteredPage ( window , err , previousPage )
return
}
2024-07-19 19:16:28 +02:00
if ( neuralNetworkExists == true ) {
setErrorEncounteredPage ( window , errors . New ( "setViewCoupleTraitRulesPage called when neural network analysis for trait exists." ) , previousPage )
return
}
if ( anyRulesExist == false ) {
setErrorEncounteredPage ( window , errors . New ( "GetOffspringTraitInfoFromGeneticAnalysis claiming that no analysis method exists for triat: " + traitName ) , previousPage )
return
}
quantityOfRulesTestedString := helpers . ConvertIntToString ( quantityOfRulesTested )
2024-04-11 15:51:56 +02:00
traitRulesMap , err := traits . GetTraitRulesMap ( traitName )
if ( err != nil ) {
setErrorEncounteredPage ( window , err , previousPage )
return
}
totalNumberOfRules := len ( traitRulesMap )
totalNumberOfRulesString := helpers . ConvertIntToString ( totalNumberOfRules )
rulesTestedLabel := widget . NewLabel ( "Rules Tested:" )
2024-07-19 19:16:28 +02:00
rulesTestedText := getBoldLabel ( quantityOfRulesTestedString + "/" + totalNumberOfRulesString )
2024-04-11 15:51:56 +02:00
rulesTestedHelpButton := widget . NewButtonWithIcon ( "" , theme . QuestionIcon ( ) , func ( ) {
2024-07-19 19:16:28 +02:00
setOffspringDiscreteTraitQuantityOfRulesTestedExplainerPage ( window , currentPage )
2024-04-11 15:51:56 +02:00
} )
rulesTestedRow := container . NewHBox ( layout . NewSpacer ( ) , rulesTestedLabel , rulesTestedText , rulesTestedHelpButton , layout . NewSpacer ( ) )
getRulesGrid := func ( ) ( * fyne . Container , error ) {
emptyLabelA := widget . NewLabel ( "" )
ruleIdentifierLabel := getItalicLabelCentered ( "Rule Identifier" )
emptyLabelB := widget . NewLabel ( "" )
ruleEffectsLabel := getItalicLabelCentered ( "Rule Effects" )
offspringProbabilityOfLabel := getItalicLabelCentered ( "Offspring Probability Of" )
passingRuleLabel := getItalicLabelCentered ( "Passing Rule" )
emptyLabelC := widget . NewLabel ( "" )
emptyLabelD := widget . NewLabel ( "" )
ruleIdentifierColumn := container . NewVBox ( emptyLabelA , ruleIdentifierLabel , widget . NewSeparator ( ) )
ruleEffectsColumn := container . NewVBox ( emptyLabelB , ruleEffectsLabel , widget . NewSeparator ( ) )
offspringProbabilityOfPassingRuleColumn := container . NewVBox ( offspringProbabilityOfLabel , passingRuleLabel , widget . NewSeparator ( ) )
ruleInfoButtonsColumn := container . NewVBox ( emptyLabelC , emptyLabelD , widget . NewSeparator ( ) )
2024-06-02 10:43:39 +02:00
addRuleRow := func ( ruleIdentifierHex string ) error {
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
ruleIdentifierLabel := getBoldLabelCentered ( ruleIdentifierHex )
ruleIdentifier , err := encoding . DecodeHexStringTo3ByteArray ( ruleIdentifierHex )
if ( err != nil ) { return err }
2024-07-19 19:16:28 +02:00
getProbabilityOfPassingRuleText := func ( ) ( string , error ) {
2024-04-11 15:51:56 +02:00
2024-07-19 19:16:28 +02:00
if ( rulesAnalysisExists == false ) {
// No rules were tested
result := translate ( "Unknown" )
return result , nil
}
2024-04-11 15:51:56 +02:00
2024-07-19 19:16:28 +02:00
offspringRuleProbabilityKnown , _ , offspringProbabilityOfPassingRuleFormatted , err := readGeneticAnalysis . GetOffspringDiscreteTraitRuleInfoFromGeneticAnalysis ( coupleAnalysisObject , traitName , ruleIdentifier , genomePairIdentifier )
if ( err != nil ) { return "" , err }
2024-04-11 15:51:56 +02:00
if ( offspringRuleProbabilityKnown == false ) {
result := translate ( "Unknown" )
2024-07-19 19:16:28 +02:00
return result , nil
2024-04-11 15:51:56 +02:00
}
2024-07-19 19:16:28 +02:00
return offspringProbabilityOfPassingRuleFormatted , nil
2024-04-11 15:51:56 +02:00
}
2024-07-19 19:16:28 +02:00
probabilityOfPassingRuleText , err := getProbabilityOfPassingRuleText ( )
if ( err != nil ) { return err }
2024-04-11 15:51:56 +02:00
probabilityOfPassingRuleTextLabel := getBoldLabelCentered ( probabilityOfPassingRuleText )
2024-07-19 19:16:28 +02:00
viewRuleDetailsButton := widget . NewButtonWithIcon ( "" , theme . VisibilityIcon ( ) , func ( ) {
setViewCoupleGeneticAnalysisDiscreteTraitRuleDetailsPage ( window , person1Name , person2Name , person1AnalysisObject , person2AnalysisObject , coupleAnalysisObject , traitName , ruleIdentifier , currentPage )
} )
2024-04-11 15:51:56 +02:00
// We add all of the columns except for the rule effects column
// We do this because the rule effects column may be multiple rows tall
ruleIdentifierColumn . Add ( ruleIdentifierLabel )
offspringProbabilityOfPassingRuleColumn . Add ( probabilityOfPassingRuleTextLabel )
ruleInfoButtonsColumn . Add ( viewRuleDetailsButton )
2024-06-02 10:43:39 +02:00
traitRuleObject , exists := traitRulesMap [ ruleIdentifierHex ]
2024-04-11 15:51:56 +02:00
if ( exists == false ) {
2024-06-02 10:43:39 +02:00
return errors . New ( "Trait rule not found after being found already: " + ruleIdentifierHex )
2024-04-11 15:51:56 +02:00
}
ruleOutcomePointsMap := traitRuleObject . OutcomePointsMap
outcomeNamesList := helpers . GetListOfMapKeys ( ruleOutcomePointsMap )
// We have to sort the outcome names so they always show up in the same order
helpers . SortStringListToUnicodeOrder ( outcomeNamesList )
for index , outcomeName := range outcomeNamesList {
outcomeChange , exists := ruleOutcomePointsMap [ outcomeName ]
if ( exists == false ) {
return errors . New ( "OutcomeName not found in ruleOutcomePointsMap after being found already: " + outcomeName )
}
getOutcomeEffectString := func ( ) string {
outcomeChangeString := helpers . ConvertIntToString ( outcomeChange )
if ( outcomeChange < 0 ) {
return outcomeChangeString
}
outcomeEffect := "+" + outcomeChangeString
return outcomeEffect
}
outcomeEffect := getOutcomeEffectString ( )
outcomeRow := getBoldLabelCentered ( outcomeName + ": " + outcomeEffect )
ruleEffectsColumn . Add ( outcomeRow )
if ( index > 0 ) {
2024-07-19 19:16:28 +02:00
2024-04-11 15:51:56 +02:00
emptyLabelA := widget . NewLabel ( "" )
emptyLabelB := widget . NewLabel ( "" )
emptyLabelC := widget . NewLabel ( "" )
ruleIdentifierColumn . Add ( emptyLabelA )
offspringProbabilityOfPassingRuleColumn . Add ( emptyLabelB )
ruleInfoButtonsColumn . Add ( emptyLabelC )
}
}
ruleIdentifierColumn . Add ( widget . NewSeparator ( ) )
ruleEffectsColumn . Add ( widget . NewSeparator ( ) )
offspringProbabilityOfPassingRuleColumn . Add ( widget . NewSeparator ( ) )
ruleInfoButtonsColumn . Add ( widget . NewSeparator ( ) )
return nil
}
rulesWithKnownProbabilityList := make ( [ ] string , 0 )
rulesWithUnknownProbabilityList := make ( [ ] string , 0 )
2024-06-02 10:43:39 +02:00
for ruleIdentifierHex , _ := range traitRulesMap {
2024-04-11 15:51:56 +02:00
2024-06-02 10:43:39 +02:00
ruleIdentifier , err := encoding . DecodeHexStringTo3ByteArray ( ruleIdentifierHex )
if ( err != nil ) { return nil , err }
2024-07-19 19:16:28 +02:00
offspringRuleProbabilityKnown , _ , _ , err := readGeneticAnalysis . GetOffspringDiscreteTraitRuleInfoFromGeneticAnalysis ( coupleAnalysisObject , traitName , ruleIdentifier , genomePairIdentifier )
2024-04-11 15:51:56 +02:00
if ( err != nil ) { return nil , err }
if ( offspringRuleProbabilityKnown == true ) {
2024-06-02 10:43:39 +02:00
rulesWithKnownProbabilityList = append ( rulesWithKnownProbabilityList , ruleIdentifierHex )
2024-04-11 15:51:56 +02:00
} else {
2024-06-02 10:43:39 +02:00
rulesWithUnknownProbabilityList = append ( rulesWithUnknownProbabilityList , ruleIdentifierHex )
2024-04-11 15:51:56 +02:00
}
}
// Now we sort rules so they show up in the same order each time
helpers . SortStringListToUnicodeOrder ( rulesWithKnownProbabilityList )
helpers . SortStringListToUnicodeOrder ( rulesWithUnknownProbabilityList )
for _ , ruleIdentifier := range rulesWithKnownProbabilityList {
err = addRuleRow ( ruleIdentifier )
if ( err != nil ) { return nil , err }
}
for _ , ruleIdentifier := range rulesWithUnknownProbabilityList {
err = addRuleRow ( ruleIdentifier )
if ( err != nil ) { return nil , err }
}
ruleEffectsHelpButton := widget . NewButtonWithIcon ( "" , theme . QuestionIcon ( ) , func ( ) {
2024-07-19 19:16:28 +02:00
setDiscreteTraitRuleOutcomeEffectsExplainerPage ( window , currentPage )
2024-04-11 15:51:56 +02:00
} )
ruleEffectsColumn . Add ( ruleEffectsHelpButton )
offspringProbabilityOfPassingRuleHelpButton := widget . NewButtonWithIcon ( "" , theme . QuestionIcon ( ) , func ( ) {
setOffspringProbabilityOfPassingTraitRuleExplainerPage ( window , currentPage )
} )
offspringProbabilityOfPassingRuleColumn . Add ( offspringProbabilityOfPassingRuleHelpButton )
2024-07-19 19:16:28 +02:00
2024-04-11 15:51:56 +02:00
rulesGrid := container . NewHBox ( layout . NewSpacer ( ) , ruleIdentifierColumn , ruleEffectsColumn , offspringProbabilityOfPassingRuleColumn , ruleInfoButtonsColumn , layout . NewSpacer ( ) )
return rulesGrid , nil
}
rulesGrid , err := getRulesGrid ( )
if ( err != nil ) {
setErrorEncounteredPage ( window , err , previousPage )
return
}
page := container . NewVBox ( title , backButton , widget . NewSeparator ( ) , description1Row , widget . NewSeparator ( ) , genomePairRow , widget . NewSeparator ( ) , rulesTestedRow , widget . NewSeparator ( ) , rulesGrid )
setPageContent ( page , window )
}
// This function implements a page to view the details of a specific rule from a genetic analysis
// It will show the rule details for all of the couple's genome pairs
2024-07-19 19:16:28 +02:00
func setViewCoupleGeneticAnalysisDiscreteTraitRuleDetailsPage ( window fyne . Window , person1Name string , person2Name string , person1AnalysisObject geneticAnalysis . PersonAnalysis , person2AnalysisObject geneticAnalysis . PersonAnalysis , coupleAnalysisObject geneticAnalysis . CoupleAnalysis , traitName string , ruleIdentifier [ 3 ] byte , previousPage func ( ) ) {
2024-04-11 15:51:56 +02:00
2024-07-19 19:16:28 +02:00
currentPage := func ( ) { setViewCoupleGeneticAnalysisDiscreteTraitRuleDetailsPage ( window , person1Name , person2Name , person1AnalysisObject , person2AnalysisObject , coupleAnalysisObject , traitName , ruleIdentifier , previousPage ) }
2024-04-11 15:51:56 +02:00
title := getPageTitleCentered ( "Trait Rule Details - " + traitName )
backButton := getBackButtonCentered ( previousPage )
description := getLabelCentered ( "Below is the trait rule analysis for the couple." )
2024-06-02 10:43:39 +02:00
ruleIdentifierHex := encoding . EncodeBytesToHexString ( ruleIdentifier [ : ] )
2024-04-11 15:51:56 +02:00
ruleIdentifierLabel := widget . NewLabel ( "Rule Identifier:" )
2024-06-02 10:43:39 +02:00
ruleIdentifierText := getBoldLabel ( ruleIdentifierHex )
2024-04-11 15:51:56 +02:00
ruleInfoButton := widget . NewButtonWithIcon ( "" , theme . InfoIcon ( ) , func ( ) {
2024-07-19 19:16:28 +02:00
setViewDiscreteTraitRuleDetailsPage ( window , traitName , ruleIdentifierHex , currentPage )
2024-04-11 15:51:56 +02:00
} )
ruleIdentifierRow := container . NewHBox ( layout . NewSpacer ( ) , ruleIdentifierLabel , ruleIdentifierText , ruleInfoButton , layout . NewSpacer ( ) )
getGenomePairsRuleInfoGrid := func ( ) ( * fyne . Container , error ) {
emptyLabelA := widget . NewLabel ( "" )
emptyLabelB := widget . NewLabel ( "" )
emptyLabelC := widget . NewLabel ( "" )
genomePairLabel := getItalicLabelCentered ( "Genome Pair" )
offspringProbabilityOfLabel := getItalicLabelCentered ( "Offspring Probability Of" )
passingRuleLabel := getItalicLabelCentered ( "Passing Rule" )
viewGenomePairInfoButtonsColumn := container . NewVBox ( emptyLabelA , emptyLabelB , widget . NewSeparator ( ) )
genomePairNameColumn := container . NewVBox ( emptyLabelC , genomePairLabel , widget . NewSeparator ( ) )
offspringProbabilityOfPassingRuleColumn := container . NewVBox ( offspringProbabilityOfLabel , passingRuleLabel , widget . NewSeparator ( ) )
2024-06-02 10:43:39 +02:00
addGenomePairRow := func ( genomePairName string , genomePairIdentifier [ 32 ] byte ) error {
2024-04-11 15:51:56 +02:00
2024-07-19 19:16:28 +02:00
offspringRuleProbabilityKnown , _ , offspringProbabilityOfPassingRuleFormatted , err := readGeneticAnalysis . GetOffspringDiscreteTraitRuleInfoFromGeneticAnalysis ( coupleAnalysisObject , traitName , ruleIdentifier , genomePairIdentifier )
2024-04-11 15:51:56 +02:00
if ( err != nil ) { return err }
getOffspringProbabilityOfPassingRuleText := func ( ) string {
if ( offspringRuleProbabilityKnown == false ) {
result := translate ( "Unknown" )
return result
}
return offspringProbabilityOfPassingRuleFormatted
}
2024-07-19 19:16:28 +02:00
2024-04-11 15:51:56 +02:00
offspringProbabilityOfPassingRuleText := getOffspringProbabilityOfPassingRuleText ( )
viewGenomePairInfoButton := widget . NewButtonWithIcon ( "" , theme . InfoIcon ( ) , func ( ) {
2024-07-19 19:16:28 +02:00
setViewCoupleGeneticAnalysisDiscreteTraitGenomePairDetailsPage ( window , person1Name , person2Name , person1AnalysisObject , person2AnalysisObject , coupleAnalysisObject , traitName , genomePairIdentifier , genomePairName , currentPage )
2024-04-11 15:51:56 +02:00
} )
genomePairNameLabel := getBoldLabelCentered ( genomePairName )
offspringProbabilityOfPassingRuleLabel := getBoldLabelCentered ( offspringProbabilityOfPassingRuleText )
viewGenomePairInfoButtonsColumn . Add ( viewGenomePairInfoButton )
genomePairNameColumn . Add ( genomePairNameLabel )
offspringProbabilityOfPassingRuleColumn . Add ( offspringProbabilityOfPassingRuleLabel )
viewGenomePairInfoButtonsColumn . Add ( widget . NewSeparator ( ) )
genomePairNameColumn . Add ( widget . NewSeparator ( ) )
offspringProbabilityOfPassingRuleColumn . Add ( widget . NewSeparator ( ) )
return nil
}
2024-06-02 10:43:39 +02:00
pair1Person1GenomeIdentifier , pair1Person2GenomeIdentifier , secondGenomePairExists , pair2Person1GenomeIdentifier , pair2Person2GenomeIdentifier , _ , _ , _ , _ , _ , _ , err := readGeneticAnalysis . GetMetadataFromCoupleGeneticAnalysis ( coupleAnalysisObject )
2024-04-11 15:51:56 +02:00
if ( err != nil ) { return nil , err }
2024-06-02 10:43:39 +02:00
genomePair1Identifier := helpers . JoinTwo16ByteArrays ( pair1Person1GenomeIdentifier , pair1Person2GenomeIdentifier )
2024-04-11 15:51:56 +02:00
err = addGenomePairRow ( "Pair 1" , genomePair1Identifier )
if ( err != nil ) { return nil , err }
if ( secondGenomePairExists == true ) {
2024-06-02 10:43:39 +02:00
genomePair2Identifier := helpers . JoinTwo16ByteArrays ( pair2Person1GenomeIdentifier , pair2Person2GenomeIdentifier )
2024-04-11 15:51:56 +02:00
err := addGenomePairRow ( "Pair 2" , genomePair2Identifier )
if ( err != nil ) { return nil , err }
}
2024-06-02 10:43:39 +02:00
2024-04-11 15:51:56 +02:00
genomesContainer := container . NewHBox ( layout . NewSpacer ( ) , viewGenomePairInfoButtonsColumn , genomePairNameColumn , offspringProbabilityOfPassingRuleColumn , layout . NewSpacer ( ) )
return genomesContainer , nil
}
genomePairsRuleInfoGrid , err := getGenomePairsRuleInfoGrid ( )
if ( err != nil ) {
setErrorEncounteredPage ( window , err , previousPage )
return
}
page := container . NewVBox ( title , backButton , widget . NewSeparator ( ) , description , widget . NewSeparator ( ) , ruleIdentifierRow , widget . NewSeparator ( ) , genomePairsRuleInfoGrid )
setPageContent ( page , window )
}