seekia/gui/viewAnalysisGui_Couple.go

2495 lines
107 KiB
Go
Raw Normal View History

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"
import "seekia/resources/geneticReferences/monogenicDiseases"
import "seekia/resources/geneticReferences/polygenicDiseases"
import "seekia/resources/geneticReferences/traits"
import "seekia/internal/appMemory"
import "seekia/internal/genetics/myGenomes"
import "seekia/internal/genetics/myPeople"
import "seekia/internal/genetics/readGeneticAnalysis"
import "seekia/internal/helpers"
import "strings"
import "errors"
func setViewCoupleGeneticAnalysisPage(window fyne.Window, personAIdentifier string, personBIdentifier string, personAAnalysisMapList []map[string]string, personBAnalysisMapList []map[string]string, coupleAnalysisMapList []map[string]string, numberOfPersonAGenomesAnalyzed int, numberOfPersonBGenomesAnalyzed int, previousPage func()){
appMemory.SetMemoryEntry("CurrentViewedPage", "ViewCoupleGeneticAnalysisPage")
currentPage := func(){setViewCoupleGeneticAnalysisPage(window, personAIdentifier, personBIdentifier, personAAnalysisMapList, personBAnalysisMapList, coupleAnalysisMapList, numberOfPersonAGenomesAnalyzed, numberOfPersonBGenomesAnalyzed, previousPage)}
title := getPageTitleCentered("Viewing Genetic Analysis")
backButton := getBackButtonCentered(previousPage)
warningLabel := getBoldLabelCentered("WARNING: Results are not accurate!")
personAFound, personAName, _, _, err := myPeople.GetPersonInfo(personAIdentifier)
if (err != nil) {
setErrorEncounteredPage(window, err, previousPage)
return
}
if (personAFound == false){
setErrorEncounteredPage(window, errors.New("Couple person A not found."), previousPage)
return
}
personBFound, personBName, _, _, err := myPeople.GetPersonInfo(personBIdentifier)
if (err != nil) {
setErrorEncounteredPage(window, err, previousPage)
return
}
if (personBFound == false){
setErrorEncounteredPage(window, errors.New("Couple person B not found."), previousPage)
return
}
coupleNameLabel := widget.NewLabel("Couple Name:")
coupleNameText := getBoldLabel(personAName + " + " + personBName)
coupleNameRow := container.NewHBox(layout.NewSpacer(), coupleNameLabel, coupleNameText, layout.NewSpacer())
numberOfAnalyzedGenomesLabel := getLabelCentered("Number of Analyzed Genomes:")
personANameLabel := widget.NewLabel(personAName + ":")
personANumberOfGenomesAnalyzedString := helpers.ConvertIntToString(numberOfPersonAGenomesAnalyzed)
personANumberOfGenomesAnalyzedLabel := getBoldLabel(personANumberOfGenomesAnalyzedString)
personANumberOfAnalyzedGenomesRow := container.NewHBox(layout.NewSpacer(), personANameLabel, personANumberOfGenomesAnalyzedLabel, layout.NewSpacer())
personBNameLabel := widget.NewLabel(personBName + ":")
personBNumberOfGenomesAnalyzedString := helpers.ConvertIntToString(numberOfPersonBGenomesAnalyzed)
personBNumberOfGenomesAnalyzedLabel := getBoldLabel(personBNumberOfGenomesAnalyzedString)
personBNumberOfAnalyzedGenomesRow := container.NewHBox(layout.NewSpacer(), personBNameLabel, personBNumberOfGenomesAnalyzedLabel, layout.NewSpacer())
generalButton := widget.NewButton("General", func(){
//TODO: Offspring inbred rating (kinship of parents), ancestry
showUnderConstructionDialog(window)
})
monogenicDiseasesButton := widget.NewButton("Monogenic Diseases", func(){
setViewCoupleGeneticAnalysisMonogenicDiseasesPage(window, personAName, personBName, personAAnalysisMapList, personBAnalysisMapList, coupleAnalysisMapList, currentPage)
})
polygenicDiseasesButton := widget.NewButton("Polygenic Diseases", func(){
setViewCoupleGeneticAnalysisPolygenicDiseasesPage(window, personAName, personBName, personAAnalysisMapList, personBAnalysisMapList, coupleAnalysisMapList, currentPage)
})
traitsButton := widget.NewButton("Traits", func(){
setViewCoupleGeneticAnalysisTraitsPage(window, personAName, personBName, personAAnalysisMapList, personBAnalysisMapList, coupleAnalysisMapList, currentPage)
})
categoryButtonsGrid := getContainerCentered(container.NewGridWithColumns(1, generalButton, monogenicDiseasesButton, polygenicDiseasesButton, traitsButton))
page := container.NewVBox(title, backButton, widget.NewSeparator(), warningLabel, widget.NewSeparator(), coupleNameRow, widget.NewSeparator(), numberOfAnalyzedGenomesLabel, personANumberOfAnalyzedGenomesRow, personBNumberOfAnalyzedGenomesRow, widget.NewSeparator(), categoryButtonsGrid)
setPageContent(page, window)
}
func setViewCoupleGeneticAnalysisMonogenicDiseasesPage(window fyne.Window, personAName string, personBName string, personAAnalysisMapList []map[string]string, personBAnalysisMapList []map[string]string, coupleAnalysisMapList []map[string]string, previousPage func()){
currentPage := func(){setViewCoupleGeneticAnalysisMonogenicDiseasesPage(window, personAName, personBName, personAAnalysisMapList, personBAnalysisMapList, coupleAnalysisMapList, previousPage)}
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){
pair1PersonAGenomeIdentifier, pair1PersonBGenomeIdentifier, secondGenomePairExists, _, _, _, _, _, _, _, _, err := readGeneticAnalysis.GetMetadataFromCoupleGeneticAnalysis(coupleAnalysisMapList)
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{
pair1GenomeIdentifier := pair1PersonAGenomeIdentifier + "+" + pair1PersonBGenomeIdentifier
genomeProbabilitiesKnown, _, genomePairOffspringProbabilityOfHavingDisease, _, _, conflictExists, err := readGeneticAnalysis.GetOffspringMonogenicDiseaseInfoFromGeneticAnalysis(coupleAnalysisMapList, diseaseName, pair1GenomeIdentifier, secondGenomePairExists)
if (err != nil) { return nil, err }
getOffspringProbabilityOfHavingDiseaseText := func()string{
if (genomeProbabilitiesKnown == false){
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(){
setViewCoupleGeneticAnalysisMonogenicDiseaseDetailsPage(window, personAName, personBName, personAAnalysisMapList, personBAnalysisMapList, coupleAnalysisMapList, diseaseName, currentPage)
}))
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)
}
func setViewCoupleGeneticAnalysisMonogenicDiseaseDetailsPage(window fyne.Window, personAName string, personBName string, personAAnalysisMapList []map[string]string, personBAnalysisMapList []map[string]string, coupleAnalysisMapList []map[string]string, diseaseName string, previousPage func()){
currentPage := func(){setViewCoupleGeneticAnalysisMonogenicDiseaseDetailsPage(window, personAName, personBName, personAAnalysisMapList, personBAnalysisMapList, coupleAnalysisMapList, diseaseName, previousPage)}
title := getPageTitleCentered("Viewing Couple Analysis - " + diseaseName)
backButton := getBackButtonCentered(previousPage)
pair1PersonAGenomeIdentifier, pair1PersonBGenomeIdentifier, secondGenomePairExists, pair2PersonAGenomeIdentifier, pair2PersonBGenomeIdentifier, _, _, _, _, _, _, err := readGeneticAnalysis.GetMetadataFromCoupleGeneticAnalysis(coupleAnalysisMapList)
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())
addGenomePairRow := func(genomePairName string, personAGenomeIdentifier string, personBGenomeIdentifier string)error{
genomePairIdentifier := personAGenomeIdentifier + "+" + personBGenomeIdentifier
genomeProbabilitiesKnown, _, genomePairOffspringProbabilityOfHavingDisease, _, genomePairOffspringProbabilityOfHavingAVariant, _, err := readGeneticAnalysis.GetOffspringMonogenicDiseaseInfoFromGeneticAnalysis(coupleAnalysisMapList, diseaseName, genomePairIdentifier, secondGenomePairExists)
if (err != nil) { return err }
getOffspringProbabilityOfHavingDiseaseText := func()string{
if (genomeProbabilitiesKnown == false){
result := translate("Unknown")
return result
}
return genomePairOffspringProbabilityOfHavingDisease
}
offspringProbabilityOfHavingDiseaseText := getOffspringProbabilityOfHavingDiseaseText()
getOffspringProbabilityOfHavingAVariantText := func()string{
if (genomeProbabilitiesKnown == false){
result := translate("Unknown")
return result
}
return genomePairOffspringProbabilityOfHavingAVariant
}
offspringProbabilityOfHavingAVariantText := getOffspringProbabilityOfHavingAVariantText()
genomePairNameLabel := getBoldLabelCentered(genomePairName)
offspringProbabilityOfHavingDiseaseLabel := getBoldLabelCentered(offspringProbabilityOfHavingDiseaseText)
offspringProbabilityOfHavingAVariantLabel := getBoldLabelCentered(offspringProbabilityOfHavingAVariantText)
viewGenomePairButton := widget.NewButtonWithIcon("", theme.InfoIcon(), func(){
setViewCoupleGeneticAnalysisMonogenicDiseaseGenomePairDetailsPage(window, personAName, personBName, personAAnalysisMapList, personBAnalysisMapList, coupleAnalysisMapList, diseaseName, genomePairIdentifier, genomePairName, currentPage)
})
viewOffspringVariantsButton := widget.NewButtonWithIcon("", theme.VisibilityIcon(), func(){
setViewCoupleMonogenicDiseaseVariantsPage(window, personAName, personBName, personAAnalysisMapList, personBAnalysisMapList, coupleAnalysisMapList, diseaseName, genomePairIdentifier, genomePairName, currentPage)
})
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
}
err = addGenomePairRow("Pair 1", pair1PersonAGenomeIdentifier, pair1PersonBGenomeIdentifier)
if (err != nil) {
setErrorEncounteredPage(window, err, previousPage)
return
}
if (secondGenomePairExists == true){
err := addGenomePairRow("Pair 2", pair2PersonAGenomeIdentifier, pair2PersonBGenomeIdentifier)
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)
}
func setViewCoupleGeneticAnalysisMonogenicDiseaseGenomePairDetailsPage(window fyne.Window, personAName string, personBName string, personAAnalysisMapList []map[string]string, personBAnalysisMapList []map[string]string, coupleAnalysisMapList []map[string]string, diseaseName string, genomePairIdentifier string, genomePairName string, previousPage func()){
currentPage := func(){setViewCoupleGeneticAnalysisMonogenicDiseaseGenomePairDetailsPage(window, personAName, personBName, personAAnalysisMapList, personBAnalysisMapList, coupleAnalysisMapList, diseaseName, genomePairIdentifier, genomePairName, previousPage)}
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())
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())
addGenomeRow := func(isPersonA bool, personName string, inputGenomeIdentifier string)error{
personAnalysisGenomeIdentifier, personHasMultipleGenomes, genomeIsCombined, combinedType, err := readGeneticAnalysis.GetMatchingPersonAnalysisGenomeIdentifierFromCoupleAnalysis(isPersonA, personAAnalysisMapList, personBAnalysisMapList, coupleAnalysisMapList, inputGenomeIdentifier)
if (err != nil) { return err }
personNameTrimmed, _, err := helpers.TrimAndFlattenString(personName, 10)
if (err != nil) { return err }
personNameLabel := getBoldLabelCentered(personNameTrimmed)
getPersonAnalysisMapList := func()[]map[string]string{
if (isPersonA == true){
return personAAnalysisMapList
}
return personBAnalysisMapList
}
personAnalysisMapList := getPersonAnalysisMapList()
getGenomeName := func()(string, error){
if (genomeIsCombined == false){
genomeFound, _, _, _, _, _, companyName, _, _, err := myGenomes.GetMyRawGenomeMetadata(personAnalysisGenomeIdentifier)
if (err != nil) { return "", err }
if (genomeFound == false){
return "", errors.New("MyGenomeInfo for genome from analysisMapList not found.")
}
return companyName, nil
}
return combinedType, nil
}
genomeName, err := getGenomeName()
if (err != nil) { return err }
genomeNameLabel := getBoldLabelCentered(genomeName)
probabilitiesKnown, _, _, _, probabilityOfPassingAVariantFormatted, personNumberOfVariantsTested, _, err := readGeneticAnalysis.GetPersonMonogenicDiseaseInfoFromGeneticAnalysis(personAnalysisMapList, diseaseName, personAnalysisGenomeIdentifier, personHasMultipleGenomes)
if (err != nil) { return err }
getProbabilityOfPassingAVariantText := func()string{
if (probabilitiesKnown == false){
result := translate("Unknown")
return result
}
return probabilityOfPassingAVariantFormatted
}
genomeProbabilityOfPassingAVariantText := getProbabilityOfPassingAVariantText()
genomeProbabilityOfPassingAVariantLabel := getBoldLabelCentered(genomeProbabilityOfPassingAVariantText)
personNumberOfVariantsTestedString := helpers.ConvertIntToString(personNumberOfVariantsTested)
genomeNumberOfVariantsTestedLabel := getBoldLabelCentered(personNumberOfVariantsTestedString)
viewGenomeButton := widget.NewButtonWithIcon("", theme.VisibilityIcon(), func(){
setViewPersonGenomeMonogenicDiseaseVariantsPage(window, personAnalysisMapList, personAnalysisGenomeIdentifier, genomeName, diseaseName, currentPage)
})
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
}
personAGenomeIdentifier, personBGenomeIdentifier, found := strings.Cut(genomePairIdentifier, "+")
if (found == false){
setErrorEncounteredPage(window, errors.New("setViewCoupleGeneticAnalysisMonogenicDiseaseGenomePairDetailsPage called with invalid genomePairIdentifier"), previousPage)
return
}
err := addGenomeRow(true, personAName, personAGenomeIdentifier)
if (err != nil){
setErrorEncounteredPage(window, err, previousPage)
return
}
err = addGenomeRow(false, personBName, personBGenomeIdentifier)
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
func setViewCoupleMonogenicDiseaseVariantsPage(window fyne.Window, personAName string, personBName string, personAAnalysisMapList []map[string]string, personBAnalysisMapList []map[string]string, coupleAnalysisMapList []map[string]string, diseaseName string, genomePairIdentifier string, genomePairName string, previousPage func()){
setLoadingScreen(window, "Loading Disease Variants", "Loading disease variants...")
currentPage := func(){setViewCoupleMonogenicDiseaseVariantsPage(window, personAName, personBName, personAAnalysisMapList, personBAnalysisMapList, coupleAnalysisMapList, diseaseName, genomePairIdentifier, genomePairName, previousPage)}
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(){
setViewCoupleGeneticAnalysisMonogenicDiseaseGenomePairDetailsPage(window, personAName, personBName, personAAnalysisMapList, personBAnalysisMapList, coupleAnalysisMapList, diseaseName, genomePairIdentifier, genomePairName, currentPage)
})
genomePairRow := container.NewHBox(layout.NewSpacer(), genomePairLabel, genomePairNameLabel, viewGenomePairInfoButton, layout.NewSpacer())
getNumberOfVariantsTested := func()(int, error){
personAGenomeIdentifier, personBGenomeIdentifier, found := strings.Cut(genomePairIdentifier, "+")
if (found == false){
return 0, errors.New("setViewCoupleMonogenicDiseaseVariantsPage called with invalid genomePairIdentifier: " + genomePairIdentifier)
}
personAAnalysisGenomeIdentifier, personAHasMultipleGenomes, _, _, err := readGeneticAnalysis.GetMatchingPersonAnalysisGenomeIdentifierFromCoupleAnalysis(true, personAAnalysisMapList, personBAnalysisMapList, coupleAnalysisMapList, personAGenomeIdentifier)
if (err != nil) { return 0, err }
_, _, _, _, _, personANumberOfVariantsTested, _, err := readGeneticAnalysis.GetPersonMonogenicDiseaseInfoFromGeneticAnalysis(personAAnalysisMapList, diseaseName, personAAnalysisGenomeIdentifier, personAHasMultipleGenomes)
if (err != nil) { return 0, err }
personBAnalysisGenomeIdentifier, personBHasMultipleGenomes, _, _, err := readGeneticAnalysis.GetMatchingPersonAnalysisGenomeIdentifierFromCoupleAnalysis(false, personAAnalysisMapList, personBAnalysisMapList, coupleAnalysisMapList, personBGenomeIdentifier)
if (err != nil) { return 0, err }
_, _, _, _, _, personBNumberOfVariantsTested, _, err := readGeneticAnalysis.GetPersonMonogenicDiseaseInfoFromGeneticAnalysis(personBAnalysisMapList, diseaseName, personBAnalysisGenomeIdentifier, personBHasMultipleGenomes)
if (err != nil) { return 0, err }
numberOfVariantsTested := personANumberOfVariantsTested + personBNumberOfVariantsTested
return numberOfVariantsTested, nil
}
numberOfVariantsTested, err := getNumberOfVariantsTested()
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())
//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())
addVariantRow := func(variantIdentifier string)error{
variantObject, exists := diseaseVariantsMap[variantIdentifier]
if (exists == false){
return errors.New("Cannot add variant row: Variant missing from diseaseVariantsMap")
}
variantName := variantObject.VariantNames[0]
offspringProbabilitiesKnown, probabilityOf0MutationsLowerBound, probabilityOf0MutationsUpperBound, probabilityOf0MutationsFormatted, probabilityOf1MutationLowerBound, probabilityOf1MutationUpperBound, probabilityOf1MutationFormatted, probabilityOf2MutationsLowerBound, probabilityOf2MutationsUpperBound, probabilityOf2MutationsFormatted, err := readGeneticAnalysis.GetOffspringMonogenicDiseaseVariantInfoFromGeneticAnalysis(coupleAnalysisMapList, diseaseName, variantIdentifier, genomePairIdentifier)
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(){
setViewCoupleGeneticAnalysisMonogenicDiseaseVariantDetailsPage(window, personAName, personBName, personAAnalysisMapList, personBAnalysisMapList, coupleAnalysisMapList, diseaseName, variantIdentifier, currentPage)
})
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)
for variantIdentifier, _ := range diseaseVariantsMap{
probabilitesKnown, probabilityOf0MutationsLowerBound, probabilityOf0MutationsUpperBound, _, probabilityOf1MutationLowerBound, probabilityOf1MutationUpperBound, _, probabilityOf2MutationsLowerBound, probabilityOf2MutationsUpperBound, _, err := readGeneticAnalysis.GetOffspringMonogenicDiseaseVariantInfoFromGeneticAnalysis(coupleAnalysisMapList, diseaseName, variantIdentifier, genomePairIdentifier)
if (err != nil) { return nil, err }
if (probabilitesKnown == false){
variantsWithUnknownRiskList = append(variantsWithUnknownRiskList, variantIdentifier)
continue
}
if (probabilityOf1MutationLowerBound != 0 || probabilityOf2MutationsLowerBound != 0){
variantsWithNonZeroRiskList = append(variantsWithNonZeroRiskList, variantIdentifier)
continue
}
// Risk is either 0 or partially unknown
if (probabilityOf0MutationsLowerBound == 100 && probabilityOf0MutationsUpperBound == 100 && probabilityOf1MutationLowerBound == 0 && probabilityOf1MutationUpperBound == 0 && probabilityOf2MutationsLowerBound == 0 && probabilityOf2MutationsUpperBound == 0){
variantsWithZeroRiskFullyKnownList = append(variantsWithZeroRiskFullyKnownList, variantIdentifier)
continue
}
variantsWithZeroRiskPartiallyKnownList = append(variantsWithZeroRiskPartiallyKnownList, variantIdentifier)
}
// 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
}
page := container.NewVBox(title, backButton, widget.NewSeparator(), description1Row, widget.NewSeparator(), genomePairRow, widget.NewSeparator(), variantsTestedRow, widget.NewSeparator(), variantsGrid)
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
func setViewCoupleGeneticAnalysisMonogenicDiseaseVariantDetailsPage(window fyne.Window, personAName string, personBName string, personAAnalysisMapList []map[string]string, personBAnalysisMapList []map[string]string, coupleAnalysisMapList []map[string]string, diseaseName string, variantIdentifier string, previousPage func()){
currentPage := func(){setViewCoupleGeneticAnalysisMonogenicDiseaseVariantDetailsPage(window, personAName, personBName, personAAnalysisMapList, personBAnalysisMapList, coupleAnalysisMapList, diseaseName, variantIdentifier, previousPage)}
title := getPageTitleCentered("Disease Variant Details - " + diseaseName)
backButton := getBackButtonCentered(previousPage)
variantObject, err := monogenicDiseases.GetMonogenicDiseaseVariantObject(diseaseName, variantIdentifier)
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(){
setViewMonogenicDiseaseVariantDetailsPage(window, diseaseName, variantIdentifier, currentPage)
})
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())
addGenomePairRow := func(genomePairName string, genomePairIdentifier string)error{
probabilitiesKnown, probabilityOf0MutationsLowerBound, probabilityOf0MutationsUpperBound, probabilityOf0MutationsFormatted, probabilityOf1MutationLowerBound, probabilityOf1MutationUpperBound, probabilityOf1MutationFormatted, probabilityOf2MutationsLowerBound, probabilityOf2MutationsUpperBound, probabilityOf2MutationsFormatted, err := readGeneticAnalysis.GetOffspringMonogenicDiseaseVariantInfoFromGeneticAnalysis(coupleAnalysisMapList, diseaseName, variantIdentifier, genomePairIdentifier)
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(){
setViewCoupleGeneticAnalysisMonogenicDiseaseGenomePairDetailsPage(window, personAName, personBName, personAAnalysisMapList, personBAnalysisMapList, coupleAnalysisMapList, diseaseName, genomePairIdentifier, genomePairName, currentPage)
})
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
}
pair1PersonAGenomeIdentifier, pair1PersonBGenomeIdentifier, secondGenomePairExists, pair2PersonAGenomeIdentifier, pair2PersonBGenomeIdentifier, _, _, _, _, _, _, err := readGeneticAnalysis.GetMetadataFromCoupleGeneticAnalysis(coupleAnalysisMapList)
if (err != nil){ return nil, err }
genomePair1Identifier := pair1PersonAGenomeIdentifier + "+" + pair1PersonBGenomeIdentifier
err = addGenomePairRow("Pair 1", genomePair1Identifier)
if (err != nil) { return nil, err }
if (secondGenomePairExists == true){
genomePair2Identifier := pair2PersonAGenomeIdentifier + "+" + pair2PersonBGenomeIdentifier
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)
}
func setViewCoupleGeneticAnalysisPolygenicDiseasesPage(window fyne.Window, personAName string, personBName string, personAAnalysisMapList []map[string]string, personBAnalysisMapList []map[string]string, coupleAnalysisMapList []map[string]string, previousPage func()){
currentPage := func(){setViewCoupleGeneticAnalysisPolygenicDiseasesPage(window, personAName, personBName, personAAnalysisMapList, personBAnalysisMapList, coupleAnalysisMapList, previousPage)}
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){
pair1PersonAGenomeIdentifier, pair1PersonBGenomeIdentifier, secondGenomePairExists, _, _, _, _, _, _, _, _, err := readGeneticAnalysis.GetMetadataFromCoupleGeneticAnalysis(coupleAnalysisMapList)
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{
mainGenomePairIdentifier := pair1PersonAGenomeIdentifier + "+" + pair1PersonBGenomeIdentifier
offspringRiskScoreKnown, _, offspringRiskScoreFormatted, _, conflictExists, err := readGeneticAnalysis.GetOffspringPolygenicDiseaseInfoFromGeneticAnalysis(coupleAnalysisMapList, diseaseName, mainGenomePairIdentifier, secondGenomePairExists)
if (err != nil) { return nil, err }
getRiskScoreLabelText := func()string{
if (offspringRiskScoreKnown == false){
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(){
setViewCoupleGeneticAnalysisPolygenicDiseaseDetailsPage(window, personAName, personBName, personAAnalysisMapList, personBAnalysisMapList, coupleAnalysisMapList, diseaseName, currentPage)
}))
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)
}
func setViewCoupleGeneticAnalysisPolygenicDiseaseDetailsPage(window fyne.Window, personAName string, personBName string, personAAnalysisMapList []map[string]string, personBAnalysisMapList []map[string]string, coupleAnalysisMapList []map[string]string, diseaseName string, previousPage func()){
currentPage := func(){setViewCoupleGeneticAnalysisPolygenicDiseaseDetailsPage(window, personAName, personBName, personAAnalysisMapList, personBAnalysisMapList, coupleAnalysisMapList, diseaseName, previousPage)}
title := getPageTitleCentered("Viewing Couple Analysis - " + diseaseName)
backButton := getBackButtonCentered(previousPage)
pair1PersonAGenomeIdentifier, pair1PersonBGenomeIdentifier, secondGenomePairExists, pair2PersonAGenomeIdentifier, pair2PersonBGenomeIdentifier, _, _, _, _, _, _, err := readGeneticAnalysis.GetMetadataFromCoupleGeneticAnalysis(coupleAnalysisMapList)
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())
emptyLabelA := widget.NewLabel("")
emptyLabelB := widget.NewLabel("")
offspringRiskScoreLabel := getItalicLabelCentered("Offspring Risk Score")
emptyLabelC := widget.NewLabel("")
emptyLabelD := widget.NewLabel("")
viewGenomePairButtonsColumn := container.NewVBox(emptyLabelA, widget.NewSeparator())
pairNameColumn := container.NewVBox(emptyLabelB, widget.NewSeparator())
offspringRiskScoreColumn := container.NewVBox(offspringRiskScoreLabel, widget.NewSeparator())
viewLifetimeRiskButtonsColumn := container.NewVBox(emptyLabelC, widget.NewSeparator())
viewOffspringLociButtonsColumn := container.NewVBox(emptyLabelD, widget.NewSeparator())
addGenomePairRow := func(genomePairName string, personAGenomeIdentifier string, personBGenomeIdentifier string)error{
genomePairIdentifier := personAGenomeIdentifier + "+" + personBGenomeIdentifier
offspringRiskScoreKnown, _, offspringRiskScoreFormatted, _, _, err := readGeneticAnalysis.GetOffspringPolygenicDiseaseInfoFromGeneticAnalysis(coupleAnalysisMapList, diseaseName, genomePairIdentifier, secondGenomePairExists)
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(){
setViewCoupleGeneticAnalysisPolygenicDiseaseGenomePairDetailsPage(window, personAName, personBName, personAAnalysisMapList, personBAnalysisMapList, coupleAnalysisMapList, diseaseName, genomePairIdentifier, genomePairName, currentPage)
})
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(){
setViewCouplePolygenicDiseaseLociPage(window, personAName, personBName, personAAnalysisMapList, personBAnalysisMapList, coupleAnalysisMapList, diseaseName, genomePairIdentifier, genomePairName, currentPage)
})
viewGenomePairButtonsColumn.Add(viewGenomePairButton)
pairNameColumn.Add(genomePairNameLabel)
offspringRiskScoreColumn.Add(offspringRiskScoreLabel)
viewLifetimeRiskButtonsColumn.Add(viewOffspringLifetimeRiskButton)
viewOffspringLociButtonsColumn.Add(viewOffspringLociButton)
viewGenomePairButtonsColumn.Add(widget.NewSeparator())
pairNameColumn.Add(widget.NewSeparator())
offspringRiskScoreColumn.Add(widget.NewSeparator())
viewOffspringLociButtonsColumn.Add(widget.NewSeparator())
return nil
}
err = addGenomePairRow("Pair 1", pair1PersonAGenomeIdentifier, pair1PersonBGenomeIdentifier)
if (err != nil) {
setErrorEncounteredPage(window, err, previousPage)
return
}
if (secondGenomePairExists == true){
err := addGenomePairRow("Pair 2", pair2PersonAGenomeIdentifier, pair2PersonBGenomeIdentifier)
if (err != nil) {
setErrorEncounteredPage(window, err, previousPage)
return
}
}
offspringRiskScoreHelpButton := widget.NewButtonWithIcon("", theme.QuestionIcon(), func(){
setOffspringPolygenicDiseaseRiskScoreExplainerPage(window, currentPage)
})
offspringRiskScoreColumn.Add(offspringRiskScoreHelpButton)
genomesContainer := container.NewHBox(layout.NewSpacer(), viewGenomePairButtonsColumn, pairNameColumn, offspringRiskScoreColumn, viewOffspringLociButtonsColumn, layout.NewSpacer())
page := container.NewVBox(title, backButton, widget.NewSeparator(), descriptionSection, widget.NewSeparator(), diseaseNameRow, widget.NewSeparator(), genomesContainer)
setPageContent(page, window)
}
func setViewCoupleGeneticAnalysisPolygenicDiseaseGenomePairDetailsPage(window fyne.Window, personAName string, personBName string, personAAnalysisMapList []map[string]string, personBAnalysisMapList []map[string]string, coupleAnalysisMapList []map[string]string, diseaseName string, genomePairIdentifier string, genomePairName string, previousPage func()){
currentPage := func(){setViewCoupleGeneticAnalysisPolygenicDiseaseGenomePairDetailsPage(window, personAName, personBName, personAAnalysisMapList, personBAnalysisMapList, coupleAnalysisMapList, diseaseName, genomePairIdentifier, genomePairName, previousPage)}
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())
addGenomeRow := func(isPersonA bool, personName string, inputGenomeIdentifier string)error{
personAnalysisGenomeIdentifier, personHasMultipleGenomes, genomeIsCombined, combinedType, err := readGeneticAnalysis.GetMatchingPersonAnalysisGenomeIdentifierFromCoupleAnalysis(isPersonA, personAAnalysisMapList, personBAnalysisMapList, coupleAnalysisMapList, inputGenomeIdentifier)
if (err != nil) { return err }
personNameTrimmed, _, err := helpers.TrimAndFlattenString(personName, 10)
if (err != nil) { return err }
personNameLabel := getBoldLabelCentered(personNameTrimmed)
getPersonAnalysisMapList := func()[]map[string]string{
if (isPersonA == true){
return personAAnalysisMapList
}
return personBAnalysisMapList
}
personAnalysisMapList := getPersonAnalysisMapList()
getGenomeName := func()(string, error){
if (genomeIsCombined == false){
genomeFound, _, _, _, _, _, companyName, _, _, err := myGenomes.GetMyRawGenomeMetadata(personAnalysisGenomeIdentifier)
if (err != nil) { return "", err }
if (genomeFound == false){
return "", errors.New("MyGenomeInfo for genome from analysisMapList not found.")
}
return companyName, nil
}
return combinedType, nil
}
genomeName, err := getGenomeName()
if (err != nil) { return err }
genomeNameLabel := getBoldLabelCentered(genomeName)
personRiskScoreKnown, _, personRiskScoreFormatted, numberOfLociTested, _, err := readGeneticAnalysis.GetPersonPolygenicDiseaseInfoFromGeneticAnalysis(personAnalysisMapList, diseaseName, personAnalysisGenomeIdentifier, personHasMultipleGenomes)
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(){
setViewPersonGenomePolygenicDiseaseLociPage(window, personAnalysisMapList, diseaseName, personAnalysisGenomeIdentifier, genomeName, currentPage)
})
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
}
personAGenomeIdentifier, personBGenomeIdentifier, found := strings.Cut(genomePairIdentifier, "+")
if (found == false){
setErrorEncounteredPage(window, errors.New("setViewCoupleGeneticAnalysisPolygenicDiseaseGenomePairDetailsPage called with invalid genomePairIdentifier"), previousPage)
return
}
err := addGenomeRow(true, personAName, personAGenomeIdentifier)
if (err != nil){
setErrorEncounteredPage(window, err, previousPage)
return
}
err = addGenomeRow(false, personBName, personBGenomeIdentifier)
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
func setViewCouplePolygenicDiseaseLociPage(window fyne.Window, personAName string, personBName string, personAAnalysisMapList []map[string]string, personBAnalysisMapList []map[string]string, coupleAnalysisMapList []map[string]string, diseaseName string, genomePairIdentifier string, genomePairName string, previousPage func()){
setLoadingScreen(window, "Loading Polygenic Disease Loci", "Loading disease loci...")
currentPage := func(){setViewCouplePolygenicDiseaseLociPage(window, personAName, personBName, personAAnalysisMapList, personBAnalysisMapList, coupleAnalysisMapList, diseaseName, genomePairIdentifier, genomePairName, previousPage)}
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(){
setViewCoupleGeneticAnalysisPolygenicDiseaseGenomePairDetailsPage(window, personAName, personBName, personAAnalysisMapList, personBAnalysisMapList, coupleAnalysisMapList, diseaseName, genomePairIdentifier, genomePairName, currentPage)
})
genomePairRow := container.NewHBox(layout.NewSpacer(), genomePairLabel, genomePairNameLabel, viewGenomePairInfoButton, layout.NewSpacer())
_, _, secondGenomePairExists, _, _, _, _, _, _, _, _, err := readGeneticAnalysis.GetMetadataFromCoupleGeneticAnalysis(coupleAnalysisMapList)
if (err != nil){
setErrorEncounteredPage(window, err, previousPage)
return
}
_, _, _, numberOfLociTested, _, err := readGeneticAnalysis.GetOffspringPolygenicDiseaseInfoFromGeneticAnalysis(coupleAnalysisMapList, diseaseName, genomePairIdentifier, secondGenomePairExists)
if (err != nil){
setErrorEncounteredPage(window, err, previousPage)
return
}
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())
addLocusRow := func(locusIdentifier string)error{
locusObject, exists := diseaseLociMap[locusIdentifier]
if (exists == false) {
return errors.New("Cannot add locus row: Locus not found in diseaseLociMap: " + locusIdentifier)
}
locusRSID := locusObject.LocusRSID
locusRSIDString := helpers.ConvertInt64ToString(locusRSID)
locusName := "rs" + locusRSIDString
offspringRiskWeightKnown, offspringRiskWeight, offspringOddsRatioKnown, _, offspringOddsRatioFormatted, err := readGeneticAnalysis.GetOffspringPolygenicDiseaseLocusInfoFromGeneticAnalysis(coupleAnalysisMapList, diseaseName, locusIdentifier, genomePairIdentifier)
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(){
setViewCoupleGeneticAnalysisPolygenicDiseaseLocusDetailsPage(window, personAName, personBName, personAAnalysisMapList, personBAnalysisMapList, coupleAnalysisMapList, diseaseName, locusIdentifier, currentPage)
})
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)
for locusIdentifier, _ := range diseaseLociMap{
offspringRiskWeightKnown, _, _, _, _, err := readGeneticAnalysis.GetOffspringPolygenicDiseaseLocusInfoFromGeneticAnalysis(coupleAnalysisMapList, diseaseName, locusIdentifier, genomePairIdentifier)
if (err != nil) { return nil, err }
if (offspringRiskWeightKnown == true){
lociWithKnownRiskWeightList = append(lociWithKnownRiskWeightList, locusIdentifier)
} else {
lociWithUnknownRiskWeightList = append(lociWithUnknownRiskWeightList, locusIdentifier)
}
}
// 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
func setViewCoupleGeneticAnalysisPolygenicDiseaseLocusDetailsPage(window fyne.Window, personAName string, personBName string, personAAnalysisMapList []map[string]string, personBAnalysisMapList []map[string]string, coupleAnalysisMapList []map[string]string, diseaseName string, locusIdentifier string, previousPage func()){
currentPage := func(){setViewCoupleGeneticAnalysisPolygenicDiseaseLocusDetailsPage(window, personAName, personBName, personAAnalysisMapList, personBAnalysisMapList, coupleAnalysisMapList, diseaseName, locusIdentifier, previousPage)}
title := getPageTitleCentered("Disease Locus Details - " + diseaseName)
backButton := getBackButtonCentered(previousPage)
locusObject, err := polygenicDiseases.GetPolygenicDiseaseLocusObject(diseaseName, locusIdentifier)
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.")
locusNameLabel := widget.NewLabel("Locus Name:")
locusNameText := getBoldLabel(locusName)
locusInfoButton := widget.NewButtonWithIcon("", theme.InfoIcon(), func(){
setViewPolygenicDiseaseLocusDetailsPage(window, diseaseName, locusIdentifier, currentPage)
})
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())
addGenomePairRow := func(genomePairName string, genomePairIdentifier string)error{
offspringRiskWeightKnown, offspringRiskWeight, offspringOddsRatioKnown, _, offspringOddsRatioFormatted, err := readGeneticAnalysis.GetOffspringPolygenicDiseaseLocusInfoFromGeneticAnalysis(coupleAnalysisMapList, diseaseName, locusIdentifier, genomePairIdentifier)
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(){
setViewCoupleGeneticAnalysisPolygenicDiseaseGenomePairDetailsPage(window, personAName, personBName, personAAnalysisMapList, personBAnalysisMapList, coupleAnalysisMapList, diseaseName, genomePairIdentifier, genomePairName, currentPage)
})
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
}
pair1PersonAGenomeIdentifier, pair1PersonBGenomeIdentifier, secondGenomePairExists, pair2PersonAGenomeIdentifier, pair2PersonBGenomeIdentifier, _, _, _, _, _, _, err := readGeneticAnalysis.GetMetadataFromCoupleGeneticAnalysis(coupleAnalysisMapList)
if (err != nil){ return nil, err }
genomePair1Identifier := pair1PersonAGenomeIdentifier + "+" + pair1PersonBGenomeIdentifier
err = addGenomePairRow("Pair 1", genomePair1Identifier)
if (err != nil) { return nil, err }
if (secondGenomePairExists == true){
genomePair2Identifier := pair2PersonAGenomeIdentifier + "+" + pair2PersonBGenomeIdentifier
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)
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)
}
func setViewCoupleGeneticAnalysisTraitsPage(window fyne.Window, personAName string, personBName string, personAAnalysisMapList []map[string]string, personBAnalysisMapList []map[string]string, coupleAnalysisMapList []map[string]string, previousPage func()){
currentPage := func(){setViewCoupleGeneticAnalysisTraitsPage(window, personAName, personBName, personAAnalysisMapList, personBAnalysisMapList, coupleAnalysisMapList, previousPage)}
title := getPageTitleCentered("Viewing Genetic Analysis - Traits")
backButton := getBackButtonCentered(previousPage)
description := getLabelCentered("Below is an analysis of the average trait scores for the couple's offspring.")
getTraitsGrid := func()(*fyne.Container, error){
pair1PersonAGenomeIdentifier, pair1PersonBGenomeIdentifier, secondGenomePairExists, _, _, _, _, _, _, _, _, err := readGeneticAnalysis.GetMetadataFromCoupleGeneticAnalysis(coupleAnalysisMapList)
if (err != nil){ return nil, err }
traitNameLabel := getItalicLabelCentered("Trait Name")
offspringOutcomeScoresLabel := getItalicLabelCentered("Offspring Outcome Scores")
conflictExistsLabel := getItalicLabelCentered("Conflict Exists?")
emptyLabel := widget.NewLabel("")
traitNameColumn := container.NewVBox(traitNameLabel, widget.NewSeparator())
offspringOutcomeScoresColumn := container.NewVBox(offspringOutcomeScoresLabel, widget.NewSeparator())
conflictExistsColumn := container.NewVBox(conflictExistsLabel, widget.NewSeparator())
viewButtonsColumn := container.NewVBox(emptyLabel, widget.NewSeparator())
traitObjectsList, err := traits.GetTraitObjectsList()
if (err != nil) { return nil, err }
for _, traitObject := range traitObjectsList{
traitName := traitObject.TraitName
traitRulesList := traitObject.RulesList
if (len(traitRulesList) == 0){
// 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
}
mainGenomePairIdentifier := pair1PersonAGenomeIdentifier + "+" + pair1PersonBGenomeIdentifier
offspringOutcomeScoresKnown, offspringAverageOutcomeScoresMap, _, conflictExists, err := readGeneticAnalysis.GetOffspringTraitInfoFromGeneticAnalysis(coupleAnalysisMapList, traitName, mainGenomePairIdentifier, secondGenomePairExists)
if (err != nil) { return nil, err }
// We add all of the columns except for the trait outcomes column, which may be multiple rows high
traitNameText := getBoldLabelCentered(traitName)
conflictExistsString := helpers.ConvertBoolToYesOrNoString(conflictExists)
conflictExistsLabel := getBoldLabelCentered(conflictExistsString)
viewDetailsButton := getWidgetCentered(widget.NewButtonWithIcon("", theme.VisibilityIcon(), func(){
setViewCoupleGeneticAnalysisTraitDetailsPage(window, personAName, personBName, personAAnalysisMapList, personBAnalysisMapList, coupleAnalysisMapList, traitName, previousPage)
}))
traitNameColumn.Add(traitNameText)
conflictExistsColumn.Add(conflictExistsLabel)
viewButtonsColumn.Add(viewDetailsButton)
if (offspringOutcomeScoresKnown == false){
unknownTranslated := translate("Unknown")
unknownLabel := getBoldLabelCentered(unknownTranslated)
offspringOutcomeScoresColumn.Add(unknownLabel)
} else {
outcomeNamesList := helpers.GetListOfMapKeys(offspringAverageOutcomeScoresMap)
// We have to sort outcome names so they always show up in the same order
helpers.SortStringListToUnicodeOrder(outcomeNamesList)
for index, outcomeName := range outcomeNamesList{
outcomeScore, exists := offspringAverageOutcomeScoresMap[outcomeName]
if (exists == false){
return nil, errors.New("Outcome name not found in outcomeScoresMap after being found already.")
}
outcomeScoreString := helpers.ConvertFloat64ToStringRounded(outcomeScore, 2)
outcomeRow := getBoldLabelCentered(outcomeName + ": " + outcomeScoreString)
offspringOutcomeScoresColumn.Add(outcomeRow)
if (index > 0){
emptyLabelA := widget.NewLabel("")
emptyLabelB := widget.NewLabel("")
emptyLabelC := widget.NewLabel("")
traitNameColumn.Add(emptyLabelA)
conflictExistsColumn.Add(emptyLabelB)
viewButtonsColumn.Add(emptyLabelC)
}
}
}
traitNameColumn.Add(widget.NewSeparator())
offspringOutcomeScoresColumn.Add(widget.NewSeparator())
conflictExistsColumn.Add(widget.NewSeparator())
viewButtonsColumn.Add(widget.NewSeparator())
}
offspringOutcomeScoresHelpButton := widget.NewButtonWithIcon("", theme.QuestionIcon(), func(){
setOffspringTraitOutcomeScoresExplainerPage(window, currentPage)
})
offspringOutcomeScoresColumn.Add(offspringOutcomeScoresHelpButton)
traitsGrid := container.NewHBox(layout.NewSpacer(), traitNameColumn, offspringOutcomeScoresColumn)
if (secondGenomePairExists == true){
conflictExistsHelpButton := widget.NewButtonWithIcon("", theme.QuestionIcon(), func(){
setCoupleGeneticAnalysisConflictExistsExplainerPage(window, currentPage)
})
conflictExistsColumn.Add(conflictExistsHelpButton)
traitsGrid.Add(conflictExistsColumn)
}
traitsGrid.Add(viewButtonsColumn)
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)
}
func setViewCoupleGeneticAnalysisTraitDetailsPage(window fyne.Window, personAName string, personBName string, personAAnalysisMapList []map[string]string, personBAnalysisMapList []map[string]string, coupleAnalysisMapList []map[string]string, traitName string, previousPage func()){
currentPage := func(){setViewCoupleGeneticAnalysisTraitDetailsPage(window, personAName, personBName, personAAnalysisMapList, personBAnalysisMapList, coupleAnalysisMapList, traitName, previousPage)}
title := getPageTitleCentered("Viewing Couple Analysis - " + traitName)
backButton := getBackButtonCentered(previousPage)
pair1PersonAGenomeIdentifier, pair1PersonBGenomeIdentifier, secondGenomePairExists, pair2PersonAGenomeIdentifier, pair2PersonBGenomeIdentifier, _, _, _, _, _, _, err := readGeneticAnalysis.GetMetadataFromCoupleGeneticAnalysis(coupleAnalysisMapList)
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())
emptyLabelA := widget.NewLabel("")
emptyLabelB := widget.NewLabel("")
offspringOutcomeScoresLabel := getItalicLabelCentered("Offspring Outcome Scores")
emptyLabelC := widget.NewLabel("")
viewGenomePairButtonsColumn := container.NewVBox(emptyLabelA, widget.NewSeparator())
pairNameColumn := container.NewVBox(emptyLabelB, widget.NewSeparator())
offspringOutcomeScoresColumn := container.NewVBox(offspringOutcomeScoresLabel, widget.NewSeparator())
viewOffspringRulesButtonsColumn := container.NewVBox(emptyLabelC, widget.NewSeparator())
addGenomePairRow := func(genomePairName string, personAGenomeIdentifier string, personBGenomeIdentifier string)error{
genomePairIdentifier := personAGenomeIdentifier + "+" + personBGenomeIdentifier
genomePairNameLabel := getBoldLabelCentered(genomePairName)
viewGenomePairButton := widget.NewButtonWithIcon("", theme.InfoIcon(), func(){
setViewCoupleGeneticAnalysisTraitGenomePairDetailsPage(window, personAName, personBName, personAAnalysisMapList, personBAnalysisMapList, coupleAnalysisMapList, traitName, genomePairIdentifier, genomePairName, currentPage)
})
viewOffspringRulesButton := widget.NewButtonWithIcon("", theme.VisibilityIcon(), func(){
setViewCoupleTraitRulesPage(window, personAName, personBName, personAAnalysisMapList, personBAnalysisMapList, coupleAnalysisMapList, traitName, genomePairIdentifier, genomePairName, currentPage)
})
// We add all of the columns except for the trait rule column, which may be multiple rows high
viewGenomePairButtonsColumn.Add(viewGenomePairButton)
pairNameColumn.Add(genomePairNameLabel)
viewOffspringRulesButtonsColumn.Add(viewOffspringRulesButton)
offspringOutcomeScoresKnown, offspringOutcomeScoresMap, _, _, err := readGeneticAnalysis.GetOffspringTraitInfoFromGeneticAnalysis(coupleAnalysisMapList, traitName, genomePairIdentifier, secondGenomePairExists)
if (err != nil) { return err }
if (offspringOutcomeScoresKnown == false){
unknownTranslated := translate("Unknown")
unknownLabel := getBoldLabelCentered(unknownTranslated)
offspringOutcomeScoresColumn.Add(unknownLabel)
} else {
outcomeNamesList := helpers.GetListOfMapKeys(offspringOutcomeScoresMap)
// We have to sort the outcome names so they always show up in the same order
helpers.SortStringListToUnicodeOrder(outcomeNamesList)
for index, outcomeName := range outcomeNamesList{
outcomeScore, exists := offspringOutcomeScoresMap[outcomeName]
if (exists == false){
return errors.New("Outcome name not found in outcome scores map after being found already.")
}
outcomeScoreString := helpers.ConvertFloat64ToStringRounded(outcomeScore, 2)
outcomeRow := getBoldLabelCentered(outcomeName + ": " + outcomeScoreString)
offspringOutcomeScoresColumn.Add(outcomeRow)
if (index > 0){
emptyLabelA := widget.NewLabel("")
emptyLabelB := widget.NewLabel("")
emptyLabelC := widget.NewLabel("")
pairNameColumn.Add(emptyLabelA)
viewGenomePairButtonsColumn.Add(emptyLabelB)
viewOffspringRulesButtonsColumn.Add(emptyLabelC)
}
}
}
viewGenomePairButtonsColumn.Add(widget.NewSeparator())
pairNameColumn.Add(widget.NewSeparator())
offspringOutcomeScoresColumn.Add(widget.NewSeparator())
viewOffspringRulesButtonsColumn.Add(widget.NewSeparator())
return nil
}
err = addGenomePairRow("Pair 1", pair1PersonAGenomeIdentifier, pair1PersonBGenomeIdentifier)
if (err != nil) {
setErrorEncounteredPage(window, err, previousPage)
return
}
if (secondGenomePairExists == true){
err := addGenomePairRow("Pair 2", pair2PersonAGenomeIdentifier, pair2PersonBGenomeIdentifier)
if (err != nil) {
setErrorEncounteredPage(window, err, previousPage)
return
}
}
offspringOutcomeScoresHelpButton := widget.NewButtonWithIcon("", theme.QuestionIcon(), func(){
setOffspringTraitOutcomeScoresExplainerPage(window, currentPage)
})
offspringOutcomeScoresColumn.Add(offspringOutcomeScoresHelpButton)
genomesContainer := container.NewHBox(layout.NewSpacer(), viewGenomePairButtonsColumn, pairNameColumn, offspringOutcomeScoresColumn, viewOffspringRulesButtonsColumn, layout.NewSpacer())
page := container.NewVBox(title, backButton, widget.NewSeparator(), descriptionSection, widget.NewSeparator(), traitNameRow, widget.NewSeparator(), genomesContainer)
setPageContent(page, window)
}
func setViewCoupleGeneticAnalysisTraitGenomePairDetailsPage(window fyne.Window, personAName string, personBName string, personAAnalysisMapList []map[string]string, personBAnalysisMapList []map[string]string, coupleAnalysisMapList []map[string]string, traitName string, genomePairIdentifier string, genomePairName string, previousPage func()){
currentPage := func(){setViewCoupleGeneticAnalysisTraitGenomePairDetailsPage(window, personAName, personBName, personAAnalysisMapList, personBAnalysisMapList, coupleAnalysisMapList, traitName, genomePairIdentifier, genomePairName, previousPage)}
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())
emptyLabelA := widget.NewLabel("")
personNameLabel := getItalicLabelCentered("Person Name")
emptyLabelB := widget.NewLabel("")
genomeNameLabel := getItalicLabelCentered("Genome Name")
emptyLabelC := widget.NewLabel("")
outcomeScoresLabel := getItalicLabelCentered("Outcome Scores")
numberOfLabel := getItalicLabelCentered("Number Of")
rulesTestedLabel := getItalicLabelCentered("Rules Tested")
emptyLabelD := widget.NewLabel("")
emptyLabelE := widget.NewLabel("")
personNameColumn := container.NewVBox(emptyLabelA, personNameLabel, widget.NewSeparator())
genomeNameColumn := container.NewVBox(emptyLabelB, genomeNameLabel, widget.NewSeparator())
outcomeScoresColumn := container.NewVBox(emptyLabelC, outcomeScoresLabel, widget.NewSeparator())
numberOfRulesTestedColumn := container.NewVBox(numberOfLabel, rulesTestedLabel, widget.NewSeparator())
viewGenomeButtonsColumn := container.NewVBox(emptyLabelD, emptyLabelE, widget.NewSeparator())
addGenomeRow := func(isPersonA bool, personName string, inputGenomeIdentifier string)error{
personAnalysisGenomeIdentifier, personHasMultipleGenomes, genomeIsCombined, combinedType, err := readGeneticAnalysis.GetMatchingPersonAnalysisGenomeIdentifierFromCoupleAnalysis(isPersonA, personAAnalysisMapList, personBAnalysisMapList, coupleAnalysisMapList, inputGenomeIdentifier)
if (err != nil) { return err }
personNameTrimmed, _, err := helpers.TrimAndFlattenString(personName, 10)
if (err != nil) { return err }
personNameLabel := getBoldLabelCentered(personNameTrimmed)
getPersonAnalysisMapList := func()[]map[string]string{
if (isPersonA == true){
return personAAnalysisMapList
}
return personBAnalysisMapList
}
personAnalysisMapList := getPersonAnalysisMapList()
getGenomeName := func()(string, error){
if (genomeIsCombined == false){
genomeFound, _, _, _, _, _, companyName, _, _, err := myGenomes.GetMyRawGenomeMetadata(personAnalysisGenomeIdentifier)
if (err != nil) { return "", err }
if (genomeFound == false){
return "", errors.New("MyGenomeInfo for genome from analysisMapList not found.")
}
return companyName, nil
}
return combinedType, nil
}
genomeName, err := getGenomeName()
if (err != nil) { return err }
genomeNameLabel := getBoldLabelCentered(genomeName)
// We add all of the columns except for the trait rule column, which may be multiple rows high
_, anyTraitRuleTested, outcomeScoresMap, numberOfRulesTested, _, err := readGeneticAnalysis.GetPersonTraitInfoFromGeneticAnalysis(personAnalysisMapList, traitName, personAnalysisGenomeIdentifier, personHasMultipleGenomes)
if (err != nil) { return err }
numberOfRulesTestedString := helpers.ConvertIntToString(numberOfRulesTested)
numberOfRulesTestedText := getBoldLabelCentered(numberOfRulesTestedString)
viewGenomeButton := widget.NewButtonWithIcon("", theme.VisibilityIcon(), func(){
setViewPersonGenomeTraitRulesPage(window, personAnalysisMapList, traitName, personAnalysisGenomeIdentifier, genomeName, currentPage)
})
personNameColumn.Add(personNameLabel)
genomeNameColumn.Add(genomeNameLabel)
numberOfRulesTestedColumn.Add(numberOfRulesTestedText)
viewGenomeButtonsColumn.Add(viewGenomeButton)
if (anyTraitRuleTested == false){
unknownTranslated := translate("Unknown")
unknownLabel := getBoldLabelCentered(unknownTranslated)
outcomeScoresColumn.Add(unknownLabel)
} else {
outcomeNamesList := helpers.GetListOfMapKeys(outcomeScoresMap)
// We have to sort the outcome names so they always show up in the same order
helpers.SortStringListToUnicodeOrder(outcomeNamesList)
for index, outcomeName := range outcomeNamesList{
outcomeScore, exists := outcomeScoresMap[outcomeName]
if (exists == false){
return errors.New("Outcome name not found in outcome scores map after being found already.")
}
outcomeScoreString := helpers.ConvertIntToString(outcomeScore)
outcomeRow := getBoldLabelCentered(outcomeName + ": " + outcomeScoreString)
outcomeScoresColumn.Add(outcomeRow)
if (index > 0){
emptyLabelA := widget.NewLabel("")
emptyLabelB := widget.NewLabel("")
emptyLabelC := widget.NewLabel("")
emptyLabelD := widget.NewLabel("")
personNameColumn.Add(emptyLabelA)
genomeNameColumn.Add(emptyLabelB)
numberOfRulesTestedColumn.Add(emptyLabelC)
viewGenomeButtonsColumn.Add(emptyLabelD)
}
}
}
personNameColumn.Add(widget.NewSeparator())
genomeNameColumn.Add(widget.NewSeparator())
outcomeScoresColumn.Add(widget.NewSeparator())
numberOfRulesTestedColumn.Add(widget.NewSeparator())
viewGenomeButtonsColumn.Add(widget.NewSeparator())
return nil
}
personAGenomeIdentifier, personBGenomeIdentifier, found := strings.Cut(genomePairIdentifier, "+")
if (found == false){
setErrorEncounteredPage(window, errors.New("setViewCoupleGeneticAnalysisTraitGenomePairDetailsPage called with invalid genomePairIdentifier"), previousPage)
return
}
err := addGenomeRow(true, personAName, personAGenomeIdentifier)
if (err != nil){
setErrorEncounteredPage(window, err, previousPage)
return
}
err = addGenomeRow(false, personBName, personBGenomeIdentifier)
if (err != nil){
setErrorEncounteredPage(window, err, previousPage)
return
}
outcomeScoresHelpButton := widget.NewButtonWithIcon("", theme.QuestionIcon(), func(){
setOffspringTraitOutcomeScoresExplainerPage(window, currentPage)
})
outcomeScoresColumn.Add(outcomeScoresHelpButton)
numberOfRulesTestedHelpButton := widget.NewButtonWithIcon("", theme.QuestionIcon(), func(){
setOffspringTraitNumberOfRulesTestedExplainerPage(window, currentPage)
})
numberOfRulesTestedColumn.Add(numberOfRulesTestedHelpButton)
genomesGrid := container.NewHBox(layout.NewSpacer(), personNameColumn, genomeNameColumn, outcomeScoresColumn, numberOfRulesTestedColumn, viewGenomeButtonsColumn, layout.NewSpacer())
page := container.NewVBox(title, backButton, widget.NewSeparator(), description, traitNameRow, genomePairRow, widget.NewSeparator(), genomesGrid)
setPageContent(page, window)
}
// This function provides a page to view the couple offspring rule probabilities for a particular genome pair
func setViewCoupleTraitRulesPage(window fyne.Window, personAName string, personBName string, personAAnalysisMapList []map[string]string, personBAnalysisMapList []map[string]string, coupleAnalysisMapList []map[string]string, traitName string, genomePairIdentifier string, genomePairName string, previousPage func()){
setLoadingScreen(window, "Loading Trait Rules", "Loading trait rules...")
currentPage := func(){setViewCoupleTraitRulesPage(window, personAName, personBName, personAAnalysisMapList, personBAnalysisMapList, coupleAnalysisMapList, traitName, genomePairIdentifier, genomePairName, previousPage)}
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(){
setOffspringTraitRulesExplainerPage(window, currentPage)
})
description1Row := container.NewHBox(layout.NewSpacer(), description1, traitRulesHelpButton, layout.NewSpacer())
genomePairLabel := widget.NewLabel("Genome Pair:")
genomePairNameLabel := getBoldLabel(genomePairName)
viewGenomePairInfoButton := widget.NewButtonWithIcon("", theme.InfoIcon(), func(){
setViewCoupleGeneticAnalysisTraitGenomePairDetailsPage(window, personAName, personBName, personAAnalysisMapList, personBAnalysisMapList, coupleAnalysisMapList, traitName, genomePairIdentifier, genomePairName, currentPage)
})
genomePairRow := container.NewHBox(layout.NewSpacer(), genomePairLabel, genomePairNameLabel, viewGenomePairInfoButton, layout.NewSpacer())
_, _, secondGenomePairExists, _, _, _, _, _, _, _, _, err := readGeneticAnalysis.GetMetadataFromCoupleGeneticAnalysis(coupleAnalysisMapList)
if (err != nil){
setErrorEncounteredPage(window, err, previousPage)
return
}
_, _, numberOfRulesTested, _, err := readGeneticAnalysis.GetOffspringTraitInfoFromGeneticAnalysis(coupleAnalysisMapList, traitName, genomePairIdentifier, secondGenomePairExists)
if (err != nil){
setErrorEncounteredPage(window, err, previousPage)
return
}
numberOfRulesTestedString := helpers.ConvertIntToString(numberOfRulesTested)
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:")
rulesTestedText := getBoldLabel(numberOfRulesTestedString + "/" + totalNumberOfRulesString)
rulesTestedHelpButton := widget.NewButtonWithIcon("", theme.QuestionIcon(), func(){
setOffspringTraitNumberOfRulesTestedExplainerPage(window, currentPage)
})
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())
addRuleRow := func(ruleIdentifier string)error{
ruleIdentifierLabel := getBoldLabelCentered(ruleIdentifier)
offspringRuleProbabilityKnown, _, offspringProbabilityOfPassingRuleFormatted, err := readGeneticAnalysis.GetOffspringTraitRuleInfoFromGeneticAnalysis(coupleAnalysisMapList, traitName, ruleIdentifier, genomePairIdentifier)
if (err != nil) { return err }
viewRuleDetailsButton := widget.NewButtonWithIcon("", theme.VisibilityIcon(), func(){
setViewCoupleGeneticAnalysisTraitRuleDetailsPage(window, personAName, personBName, personAAnalysisMapList, personBAnalysisMapList, coupleAnalysisMapList, traitName, ruleIdentifier, currentPage)
})
getProbabilityOfPassingRuleText := func()string{
if (offspringRuleProbabilityKnown == false){
result := translate("Unknown")
return result
}
return offspringProbabilityOfPassingRuleFormatted
}
probabilityOfPassingRuleText := getProbabilityOfPassingRuleText()
probabilityOfPassingRuleTextLabel := getBoldLabelCentered(probabilityOfPassingRuleText)
// 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)
traitRuleObject, exists := traitRulesMap[ruleIdentifier]
if (exists == false){
return errors.New("Trait rule not found after being found already: " + ruleIdentifier)
}
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){
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)
for ruleIdentifier, _ := range traitRulesMap{
offspringRuleProbabilityKnown, _, _, err := readGeneticAnalysis.GetOffspringTraitRuleInfoFromGeneticAnalysis(coupleAnalysisMapList, traitName, ruleIdentifier, genomePairIdentifier)
if (err != nil) { return nil, err }
if (offspringRuleProbabilityKnown == true){
rulesWithKnownProbabilityList = append(rulesWithKnownProbabilityList, ruleIdentifier)
} else {
rulesWithUnknownProbabilityList = append(rulesWithUnknownProbabilityList, ruleIdentifier)
}
}
// 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(){
setTraitRuleOutcomeEffectsExplainerPage(window, currentPage)
})
ruleEffectsColumn.Add(ruleEffectsHelpButton)
offspringProbabilityOfPassingRuleHelpButton := widget.NewButtonWithIcon("", theme.QuestionIcon(), func(){
setOffspringProbabilityOfPassingTraitRuleExplainerPage(window, currentPage)
})
offspringProbabilityOfPassingRuleColumn.Add(offspringProbabilityOfPassingRuleHelpButton)
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
func setViewCoupleGeneticAnalysisTraitRuleDetailsPage(window fyne.Window, personAName string, personBName string, personAAnalysisMapList []map[string]string, personBAnalysisMapList []map[string]string, coupleAnalysisMapList []map[string]string, traitName string, ruleIdentifier string, previousPage func()){
currentPage := func(){setViewCoupleGeneticAnalysisTraitRuleDetailsPage(window, personAName, personBName, personAAnalysisMapList, personBAnalysisMapList, coupleAnalysisMapList, traitName, ruleIdentifier, previousPage)}
title := getPageTitleCentered("Trait Rule Details - " + traitName)
backButton := getBackButtonCentered(previousPage)
description := getLabelCentered("Below is the trait rule analysis for the couple.")
ruleIdentifierLabel := widget.NewLabel("Rule Identifier:")
ruleIdentifierText := getBoldLabel(ruleIdentifier)
ruleInfoButton := widget.NewButtonWithIcon("", theme.InfoIcon(), func(){
setViewTraitRuleDetailsPage(window, traitName, ruleIdentifier, currentPage)
})
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())
addGenomePairRow := func(genomePairName string, genomePairIdentifier string)error{
offspringRuleProbabilityKnown, _, offspringProbabilityOfPassingRuleFormatted, err := readGeneticAnalysis.GetOffspringTraitRuleInfoFromGeneticAnalysis(coupleAnalysisMapList, traitName, ruleIdentifier, genomePairIdentifier)
if (err != nil) { return err }
getOffspringProbabilityOfPassingRuleText := func()string{
if (offspringRuleProbabilityKnown == false){
result := translate("Unknown")
return result
}
return offspringProbabilityOfPassingRuleFormatted
}
offspringProbabilityOfPassingRuleText := getOffspringProbabilityOfPassingRuleText()
viewGenomePairInfoButton := widget.NewButtonWithIcon("", theme.InfoIcon(), func(){
setViewCoupleGeneticAnalysisTraitGenomePairDetailsPage(window, personAName, personBName, personAAnalysisMapList, personBAnalysisMapList, coupleAnalysisMapList, traitName, genomePairIdentifier, genomePairName, currentPage)
})
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
}
pair1PersonAGenomeIdentifier, pair1PersonBGenomeIdentifier, secondGenomePairExists, pair2PersonAGenomeIdentifier, pair2PersonBGenomeIdentifier, _, _, _, _, _, _, err := readGeneticAnalysis.GetMetadataFromCoupleGeneticAnalysis(coupleAnalysisMapList)
if (err != nil){ return nil, err }
genomePair1Identifier := pair1PersonAGenomeIdentifier + "+" + pair1PersonBGenomeIdentifier
err = addGenomePairRow("Pair 1", genomePair1Identifier)
if (err != nil) { return nil, err }
if (secondGenomePairExists == true){
genomePair2Identifier := pair2PersonAGenomeIdentifier + "+" + pair2PersonBGenomeIdentifier
err := addGenomePairRow("Pair 2", genomePair2Identifier)
if (err != nil) { return nil, err }
}
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)
}