Improved the creation procedures, encoding format, and graphical presentation of genetic analyses. Map lists have been replaced by custom objects.

This commit is contained in:
Simon Sarasova 2024-06-02 08:43:39 +00:00
parent 10fd477026
commit 35cda50ad7
No known key found for this signature in database
GPG key ID: EEDA4103C9C36944
38 changed files with 3376 additions and 6227 deletions

View file

@ -6,6 +6,7 @@ Small and insignificant changes may not be included in this log.
## Unversioned Changes
* Improved the creation procedures, encoding format, and graphical presentation of genetic analyses. Map lists have been replaced by custom objects. - *Simon Sarasova*
* Upgraded Circl to version 1.3.8. - *Simon Sarasova*
## Version 0.60

View file

@ -9,4 +9,4 @@ Many other people have written code for modules which are imported by Seekia. Th
Name | Date Of First Commit | Number Of Commits
--- | --- | ---
Simon Sarasova | June 13, 2023 | 247
Simon Sarasova | June 13, 2023 | 248

View file

@ -232,7 +232,7 @@ If two people who have the same recessive monogenic disease breed, their offspri
In order to prevent people with recessive monogenic diseases from being conceived, we must prevent people who have any defects in genes for the same diseases from breeding with each other. This practice only requires reducing each person's pool of potential mates by a small amount (~5% in 2024), but will result in a drastic reduction in the prevalence of recessive monogenic disorders within the human species.
A Person analysis describes a persons probability of having each monogenic disease and their probability of passing a disease variant for each disease. A Couple analysis will report on the offspring's probability of having each monogenic disease. Users can share their monogenic disease probabilities on their profiles, and users can filter and sort users by their offspring's probability of having a monogenic disease.
A Person analysis describes if a person has each monogenic disease and their probability of passing a disease variant for each disease. A Couple analysis will report on the offspring's probability of having each monogenic disease. Users can share their monogenic disease probabilities on their profiles, and users can filter and sort users by their offspring's probability of having a monogenic disease.
Users have 2 options for filtering their offspring's monogenic disease probability: 0% and <100%.

View file

@ -338,6 +338,33 @@ func setNumberOfTestedVariantsExplainerPage(window fyne.Window, previousPage fun
setPageContent(page, window)
}
func setNumberOfPhasedLociExplainerPage(window fyne.Window, previousPage func()){
title := getPageTitleCentered("Help - Phased Loci")
backButton := getBackButtonCentered(previousPage)
subtitle := getPageSubtitleCentered("Number of Phased Loci")
description1 := getLabelCentered("Each monogenic disease has a set of variants Seekia tests for.")
description2 := getLabelCentered("These variants are specific mutations that cause each monogenic disease.")
description3 := getLabelCentered("Each variant effects a specific locus of the genome.")
description4 := getLabelCentered("Each genome file reports the values of loci.")
description5 := getLabelCentered("A reported value can either be phased or unphased.")
description6 := getLabelCentered("Phased values provide more information than unphased values.")
description7 := getLabelCentered("The greater the number of phased loci is, the more accurate a genetic analysis will be.")
description8 := getLabelCentered("Import a phased genome for the most accurate genetic analysis results.")
description9 := getLabelCentered("Use a genome sequencing provider which produces phased genome files.")
//TODO: Explain that phased genomes don't always increase accuracy, and the results may still be fully accurate
// For example, if you have no mutations or if you only have 1 mutation on 1 locus,
// a phased sequence has no impact on your disease analysis results.
page := container.NewVBox(title, backButton, widget.NewSeparator(), subtitle, widget.NewSeparator(), description1, description2, description3, description4, description5, description6, description7, description8, description9)
setPageContent(page, window)
}
func setCoupleGenomePairExplainerPage(window fyne.Window, previousPage func()){
@ -378,20 +405,21 @@ func setPersonProbabilityOfPassingVariantExplainerPage(window fyne.Window, previ
setPageContent(page, window)
}
func setPersonProbabilityOfHavingMonogenicDiseaseExplainerPage(window fyne.Window, previousPage func()){
func setPersonHasMonogenicDiseaseExplainerPage(window fyne.Window, previousPage func()){
title := getPageTitleCentered("Help - Person Monogenic Disease Probability")
title := getPageTitleCentered("Help - Person Has Monogenic Disease")
backButton := getBackButtonCentered(previousPage)
subtitle := getPageSubtitleCentered("Probability Of Having Monogenic Disease")
subtitle := getPageSubtitleCentered("Person Has Monogenic Disease")
description1 := getLabelCentered("This is the probability that the analyzed person has this monogenic disease.")
description2 := getLabelCentered("This probability becomes more accurate if more variants are tested.")
description3 := getLabelCentered("The person's imported genomes may not contain locations for some variants.")
description4 := getLabelCentered("Seekia also does not test for many rare disease variants.")
description1 := getLabelCentered("This describes if the analyzed person has this monogenic disease.")
description2 := getLabelCentered("This result becomes more accurate if more variants are tested.")
description3 := getLabelCentered("It also become more accurate in certain circumstances if the tested loci are phased.")
description4 := getLabelCentered("The person's imported genomes may not contain locations for some variants.")
description5 := getLabelCentered("Seekia also does not test for many rare disease variants.")
page := container.NewVBox(title, backButton, widget.NewSeparator(), subtitle, widget.NewSeparator(), description1, description2, description3, description4)
page := container.NewVBox(title, backButton, widget.NewSeparator(), subtitle, widget.NewSeparator(), description1, description2, description3, description4, description5)
setPageContent(page, window)
}

View file

@ -12,6 +12,8 @@ import "fyne.io/fyne/v2/layout"
import "fyne.io/fyne/v2/dialog"
import "fyne.io/fyne/v2/data/binding"
import "seekia/internal/appMemory"
import "seekia/internal/encoding"
import "seekia/internal/genetics/myGenomes"
import "seekia/internal/genetics/myPeople"
import "seekia/internal/genetics/myCouples"
@ -19,7 +21,6 @@ import "seekia/internal/genetics/myAnalyses"
import "seekia/internal/genetics/readRawGenomes"
import "seekia/internal/genetics/sampleAnalyses"
import "seekia/internal/helpers"
import "seekia/internal/appMemory"
import "seekia/internal/localFilesystem"
import "time"
@ -94,13 +95,13 @@ func setViewSampleGeneticAnalysesPage(window fyne.Window, previousPage func()){
personIdentifier := "111111111111111111111111111111"
analysisMapList, err := sampleAnalyses.GetSamplePerson1Analysis()
analysisObject, err := sampleAnalyses.GetSamplePerson1Analysis()
if (err != nil) {
setErrorEncounteredPage(window, err, currentPage)
return
}
setViewPersonGeneticAnalysisPage(window, personIdentifier, analysisMapList, 1, currentPage)
setViewPersonGeneticAnalysisPage(window, personIdentifier, analysisObject, 1, currentPage)
})
personAnalysisButtonWithIcon := container.NewGridWithColumns(1, personIcon, personAnalysisButton)
@ -112,28 +113,28 @@ func setViewSampleGeneticAnalysesPage(window fyne.Window, previousPage func()){
}
coupleAnalysisButton := widget.NewButton("Couple Analysis", func(){
personAIdentifier := "111111111111111111111111111111"
personBIdentifier := "222222222222222222222222222222"
person1Identifier := "111111111111111111111111111111"
person2Identifier := "222222222222222222222222222222"
person1AnalysisMapList, err := sampleAnalyses.GetSamplePerson1Analysis()
person1AnalysisObject, err := sampleAnalyses.GetSamplePerson1Analysis()
if (err != nil) {
setErrorEncounteredPage(window, err, currentPage)
return
}
person2AnalysisMapList, err := sampleAnalyses.GetSamplePerson2Analysis()
person2AnalysisObject, err := sampleAnalyses.GetSamplePerson2Analysis()
if (err != nil) {
setErrorEncounteredPage(window, err, currentPage)
return
}
coupleAnalysisMapList, err := sampleAnalyses.GetSampleCoupleAnalysis()
coupleAnalysisObject, err := sampleAnalyses.GetSampleCoupleAnalysis()
if (err != nil) {
setErrorEncounteredPage(window, err, currentPage)
return
}
setViewCoupleGeneticAnalysisPage(window, personAIdentifier, personBIdentifier, person1AnalysisMapList, person2AnalysisMapList, coupleAnalysisMapList, 1, 1, currentPage)
setViewCoupleGeneticAnalysisPage(window, person1Identifier, person2Identifier, person1AnalysisObject, person2AnalysisObject, coupleAnalysisObject, 1, 1, currentPage)
})
coupleAnalysisButtonWithIcon := container.NewGridWithColumns(1, coupleIcon, coupleAnalysisButton)
@ -597,11 +598,16 @@ func setManagePersonGenomesPage(window fyne.Window, personIdentifier string, pre
companyNameLabel := widget.NewLabel(companyName)
genomeIdentifier, exists := genomeMap["GenomeIdentifier"]
genomeIdentifierHex, exists := genomeMap["GenomeIdentifier"]
if (exists == false){
return nil, errors.New("Malformed myGenomesMapList: Item missing GenomeIdentifier")
}
genomeIdentifier, err := encoding.DecodeHexStringTo16ByteArray(genomeIdentifierHex)
if (err != nil){
return nil, errors.New("Malformed myGenomesMapList: Item contains invalid GenomeIdentifier: " + genomeIdentifierHex)
}
manageButton := widget.NewButtonWithIcon("Manage", theme.VisibilityIcon(), func(){
setManageGenomePage(window, genomeIdentifier, currentPage)
})
@ -709,7 +715,7 @@ func setImportRawGenomePage(window fyne.Window, personIdentifier string, previou
}
// This provides a page to manage a person's Genome
func setManageGenomePage(window fyne.Window, genomeIdentifier string, previousPage func()){
func setManageGenomePage(window fyne.Window, genomeIdentifier [16]byte, previousPage func()){
currentPage := func(){setManageGenomePage(window, genomeIdentifier, previousPage)}
@ -791,7 +797,7 @@ func setManageGenomePage(window fyne.Window, genomeIdentifier string, previousPa
return
}
importedTimeLabel := getItalicLabelCentered("Imported " + importedTimeAgo + ".")
deleteGenomeButton := getWidgetCentered(widget.NewButtonWithIcon("Delete Genome", theme.DeleteIcon(), func(){
setConfirmDeletePersonGenomePage(window, personIdentifier, genomeIdentifier, currentPage, previousPage)
}))
@ -801,7 +807,7 @@ func setManageGenomePage(window fyne.Window, genomeIdentifier string, previousPa
setPageContent(page, window)
}
func setConfirmDeletePersonGenomePage(window fyne.Window, personIdentifier string, genomeIdentifier string, previousPage func(), nextPage func()){
func setConfirmDeletePersonGenomePage(window fyne.Window, personIdentifier string, genomeIdentifier [16]byte, previousPage func(), nextPage func()){
currentPage := func(){setConfirmDeletePersonGenomePage(window, personIdentifier, genomeIdentifier, previousPage, nextPage)}
@ -972,7 +978,7 @@ func setAnalyzePersonGeneticsPage(window fyne.Window, personIdentifier string, p
viewAnalysisButton := getWidgetCentered(widget.NewButtonWithIcon("View Analysis", theme.VisibilityIcon(), func(){
analysisFound, analysisMapList, err := myAnalyses.GetGeneticAnalysis(newestAnalysisIdentifier)
analysisFound, analysisObject, err := myAnalyses.GetPersonGeneticAnalysis(newestAnalysisIdentifier)
if (err != nil){
setErrorEncounteredPage(window, err, currentPage)
return
@ -982,7 +988,7 @@ func setAnalyzePersonGeneticsPage(window fyne.Window, personIdentifier string, p
return
}
setViewPersonGeneticAnalysisPage(window, personIdentifier, analysisMapList, numberOfGenomesInAnalysis, currentPage)
setViewPersonGeneticAnalysisPage(window, personIdentifier, analysisObject, numberOfGenomesInAnalysis, currentPage)
}))
page := container.NewVBox(title, backButton, widget.NewSeparator(), description, widget.NewSeparator(), analysisReadyLabel, personAnalyzedRow, numberOfGenomesInAnalysisRow, timeAgoPerformedLabel, viewAnalysisButton)
@ -1193,38 +1199,38 @@ func setManageCouplesPage(window fyne.Window, previousPage func()){
for _, coupleMap := range myCouplesMapList{
personAIdentifier, exists := coupleMap["PersonAIdentifier"]
person1Identifier, exists := coupleMap["Person1Identifier"]
if (exists == false) {
return nil, errors.New("Malformed myCoupleAnalysesMapList: Item missing personAIdentifier")
return nil, errors.New("Malformed myCoupleAnalysesMapList: Item missing Person1Identifier")
}
personBIdentifier, exists := coupleMap["PersonBIdentifier"]
person2Identifier, exists := coupleMap["Person2Identifier"]
if (exists == false) {
return nil, errors.New("Malformed myCoupleAnalysesMapList: Item missing personBIdentifier")
return nil, errors.New("Malformed myCoupleAnalysesMapList: Item missing Person2Identifier")
}
personFound, personAName, _, _, err := myPeople.GetPersonInfo(personAIdentifier)
personFound, person1Name, _, _, err := myPeople.GetPersonInfo(person1Identifier)
if (err != nil) { return nil, err }
if (personFound == false){
return nil, errors.New("Couple person not found.")
}
personFound, personBName, _, _, err := myPeople.GetPersonInfo(personBIdentifier)
personFound, person2Name, _, _, err := myPeople.GetPersonInfo(person2Identifier)
if (err != nil) { return nil, err }
if (personFound == false){
return nil, errors.New("Couple person not found.")
}
personANameTrimmed, _, err := helpers.TrimAndFlattenString(personAName, 15)
person1NameTrimmed, _, err := helpers.TrimAndFlattenString(person1Name, 15)
if (err != nil) { return nil, err }
personBNameTrimmed, _, err := helpers.TrimAndFlattenString(personBName, 15)
person2NameTrimmed, _, err := helpers.TrimAndFlattenString(person2Name, 15)
if (err != nil) { return nil, err }
coupleName := personANameTrimmed + " + " + personBNameTrimmed
coupleName := person1NameTrimmed + " + " + person2NameTrimmed
manageCoupleButton := widget.NewButton(coupleName, func(){
setManageCouplePage(window, personAIdentifier, personBIdentifier, currentPage)
setManageCouplePage(window, person1Identifier, person2Identifier, currentPage)
})
manageButtonsGrid.Add(manageCoupleButton)
@ -1374,16 +1380,16 @@ func setCreateCouplePage(window fyne.Window, previousPage func()){
return
}
personAIdentifier := selectedPeopleList[0]
personBIdentifier := selectedPeopleList[1]
person1Identifier := selectedPeopleList[0]
person2Identifier := selectedPeopleList[1]
_, err = myCouples.AddCouple(personAIdentifier, personBIdentifier)
_, err = myCouples.AddCouple(person1Identifier, person2Identifier)
if (err != nil) {
setErrorEncounteredPage(window, err, previousPage)
return
}
setManageCouplePage(window, personAIdentifier, personBIdentifier, previousPage)
setManageCouplePage(window, person1Identifier, person2Identifier, previousPage)
}))
page := container.NewVBox(title, backButton, widget.NewSeparator(), description1, description2, widget.NewSeparator(), choosePeopleGrid, createCoupleButton)
@ -1392,36 +1398,36 @@ func setCreateCouplePage(window fyne.Window, previousPage func()){
}
func setManageCouplePage(window fyne.Window, personAIdentifier string, personBIdentifier string, previousPage func()){
func setManageCouplePage(window fyne.Window, person1Identifier string, person2Identifier string, previousPage func()){
currentPage := func(){setManageCouplePage(window, personAIdentifier, personBIdentifier, previousPage)}
currentPage := func(){setManageCouplePage(window, person1Identifier, person2Identifier, previousPage)}
title := getPageTitleCentered("Genetics - Manage Couple")
backButton := getBackButtonCentered(previousPage)
personAFound, personAName, _, _, err := myPeople.GetPersonInfo(personAIdentifier)
person1Found, person1Name, _, _, err := myPeople.GetPersonInfo(person1Identifier)
if (err != nil){
setErrorEncounteredPage(window, err, previousPage)
return
}
if (personAFound == false){
setErrorEncounteredPage(window, errors.New("setManageCouplePage called with unknown personAIdentifier"), previousPage)
if (person1Found == false){
setErrorEncounteredPage(window, errors.New("setManageCouplePage called with unknown person1Identifier"), previousPage)
return
}
personBFound, personBName, _, _, err := myPeople.GetPersonInfo(personBIdentifier)
person2Found, person2Name, _, _, err := myPeople.GetPersonInfo(person2Identifier)
if (err != nil){
setErrorEncounteredPage(window, err, previousPage)
return
}
if (personBFound == false){
setErrorEncounteredPage(window, errors.New("setManageCouplePage called with unknown personBIdentifier"), previousPage)
if (person2Found == false){
setErrorEncounteredPage(window, errors.New("setManageCouplePage called with unknown person2Identifier"), previousPage)
return
}
coupleNameLabel := getLabelCentered("Couple Name:")
coupleNameText := getBoldLabelCentered(personAName + " + " + personBName)
coupleNameText := getBoldLabelCentered(person1Name + " + " + person2Name)
analyzeIcon, err := getFyneImageIcon("Stats")
if (err != nil){
@ -1429,12 +1435,12 @@ func setManageCouplePage(window fyne.Window, personAIdentifier string, personBId
return
}
analyzeGeneticsButton := widget.NewButton("Analyze Genetics", func(){
setAnalyzeCoupleGeneticsPage(window, personAIdentifier, personBIdentifier, currentPage)
setAnalyzeCoupleGeneticsPage(window, person1Identifier, person2Identifier, currentPage)
})
analyzeGeneticsButtonWithIcon := getContainerCentered(container.NewGridWithColumns(1, analyzeIcon, analyzeGeneticsButton))
deleteCoupleButton := getWidgetCentered(widget.NewButtonWithIcon("Delete Couple", theme.DeleteIcon(), func(){
setDeleteCouplePage(window, personAIdentifier, personBIdentifier, currentPage, previousPage)
setDeleteCouplePage(window, person1Identifier, person2Identifier, currentPage, previousPage)
}))
page := container.NewVBox(title, backButton, widget.NewSeparator(), coupleNameLabel, coupleNameText, widget.NewSeparator(), analyzeGeneticsButtonWithIcon, widget.NewSeparator(), deleteCoupleButton)
@ -1442,9 +1448,9 @@ func setManageCouplePage(window fyne.Window, personAIdentifier string, personBId
setPageContent(page, window)
}
func setDeleteCouplePage(window fyne.Window, personAIdentifier string, personBIdentifier string, previousPage func(), nextPage func()){
func setDeleteCouplePage(window fyne.Window, person1Identifier string, person2Identifier string, previousPage func(), nextPage func()){
currentPage := func(){setDeleteCouplePage(window, personAIdentifier, personBIdentifier, previousPage, nextPage)}
currentPage := func(){setDeleteCouplePage(window, person1Identifier, person2Identifier, previousPage, nextPage)}
title := getPageTitleCentered("Genetics - Delete Couple")
@ -1452,29 +1458,29 @@ func setDeleteCouplePage(window fyne.Window, personAIdentifier string, personBId
subtitle := getPageSubtitleCentered("Delete Couple")
personAFound, personAName, _, _, err := myPeople.GetPersonInfo(personAIdentifier)
person1Found, person1Name, _, _, err := myPeople.GetPersonInfo(person1Identifier)
if (err != nil){
setErrorEncounteredPage(window, err, previousPage)
return
}
if (personAFound == false){
setErrorEncounteredPage(window, errors.New("setDeleteGenomeCouplePage called with unknown personAIdentifier"), previousPage)
if (person1Found == false){
setErrorEncounteredPage(window, errors.New("setDeleteGenomeCouplePage called with unknown person1Identifier"), previousPage)
return
}
personBFound, personBName, _, _, err := myPeople.GetPersonInfo(personBIdentifier)
person2Found, person2Name, _, _, err := myPeople.GetPersonInfo(person2Identifier)
if (err != nil){
setErrorEncounteredPage(window, err, previousPage)
return
}
if (personBFound == false){
setErrorEncounteredPage(window, errors.New("setDeleteGenomeCouplePage called with unknown personBIdentifier"), previousPage)
if (person2Found == false){
setErrorEncounteredPage(window, errors.New("setDeleteGenomeCouplePage called with unknown person2Identifier"), previousPage)
return
}
description := getLabelCentered("Confirm to delete this couple?")
coupleName := personAName + " + " + personBName
coupleName := person1Name + " + " + person2Name
coupleNameLabel := widget.NewLabel("Couple Name:")
coupleNameText := getBoldLabel(coupleName)
@ -1483,7 +1489,7 @@ func setDeleteCouplePage(window fyne.Window, personAIdentifier string, personBId
deleteButton := getWidgetCentered(widget.NewButtonWithIcon("Delete", theme.DeleteIcon(), func(){
err := myCouples.DeleteCouple(personAIdentifier, personBIdentifier)
err := myCouples.DeleteCouple(person1Identifier, person2Identifier)
if (err != nil){
setErrorEncounteredPage(window, err, currentPage)
return
@ -1498,15 +1504,15 @@ func setDeleteCouplePage(window fyne.Window, personAIdentifier string, personBId
}
func setAnalyzeCoupleGeneticsPage(window fyne.Window, inputPersonAIdentifier string, inputPersonBIdentifier string, previousPage func()){
func setAnalyzeCoupleGeneticsPage(window fyne.Window, inputPerson1Identifier string, inputPerson2Identifier string, previousPage func()){
appMemory.SetMemoryEntry("CurrentViewedPage", "AnalyzeCoupleGeneticsPage")
currentPage := func(){setAnalyzeCoupleGeneticsPage(window, inputPersonAIdentifier, inputPersonBIdentifier, previousPage)}
currentPage := func(){setAnalyzeCoupleGeneticsPage(window, inputPerson1Identifier, inputPerson2Identifier, previousPage)}
// We have to sort the person identifiers so they are in the same order as they exist in the couple analysis
personAIdentifier, personBIdentifier, err := myAnalyses.GetPeopleIdentifiersSortedForCouple(inputPersonAIdentifier, inputPersonBIdentifier)
person1Identifier, person2Identifier, err := myAnalyses.GetPeopleIdentifiersSortedForCouple(inputPerson1Identifier, inputPerson2Identifier)
if (err != nil){
setErrorEncounteredPage(window, err, previousPage)
return
@ -1518,54 +1524,54 @@ func setAnalyzeCoupleGeneticsPage(window fyne.Window, inputPersonAIdentifier str
description := getLabelCentered("Analyze this couple's genetics.")
personAFound, personAName, _, _, err := myPeople.GetPersonInfo(personAIdentifier)
person1Found, person1Name, _, _, err := myPeople.GetPersonInfo(person1Identifier)
if (err != nil){
setErrorEncounteredPage(window, err, previousPage)
return
}
if (personAFound == false){
if (person1Found == false){
setErrorEncounteredPage(window, errors.New("setAnalyzeCoupleGeneticsPage called with missing person"), previousPage)
return
}
personBFound, personBName, _, _, err := myPeople.GetPersonInfo(personBIdentifier)
person2Found, person2Name, _, _, err := myPeople.GetPersonInfo(person2Identifier)
if (err != nil){
setErrorEncounteredPage(window, err, previousPage)
return
}
if (personBFound == false){
if (person2Found == false){
setErrorEncounteredPage(window, errors.New("setAnalyzeCoupleGeneticsPage called with missing person"), previousPage)
return
}
allPersonARawGenomeIdentifiersList, err := myGenomes.GetAllPersonRawGenomeIdentifiersList(personAIdentifier)
allPerson1RawGenomeIdentifiersList, err := myGenomes.GetAllPersonRawGenomeIdentifiersList(person1Identifier)
if (err != nil) {
setErrorEncounteredPage(window, err, previousPage)
return
}
allPersonBRawGenomeIdentifiersList, err := myGenomes.GetAllPersonRawGenomeIdentifiersList(personBIdentifier)
allPerson2RawGenomeIdentifiersList, err := myGenomes.GetAllPersonRawGenomeIdentifiersList(person2Identifier)
if (err != nil) {
setErrorEncounteredPage(window, err, previousPage)
return
}
if (len(allPersonARawGenomeIdentifiersList) == 0 || len(allPersonBRawGenomeIdentifiersList) == 0){
if (len(allPerson1RawGenomeIdentifiersList) == 0 || len(allPerson2RawGenomeIdentifiersList) == 0){
// At least one of the people is missing genomes
getGenomesMissingText := func()string{
if (len(allPersonARawGenomeIdentifiersList) == 0 && len(allPersonBRawGenomeIdentifiersList) == 0){
missingLabelText := personAName + " and " + personBName + " have no genomes."
if (len(allPerson1RawGenomeIdentifiersList) == 0 && len(allPerson2RawGenomeIdentifiersList) == 0){
missingLabelText := person1Name + " and " + person2Name + " have no genomes."
return missingLabelText
}
if (len(allPersonARawGenomeIdentifiersList) == 0 && len(allPersonBRawGenomeIdentifiersList) != 0){
if (len(allPerson1RawGenomeIdentifiersList) == 0 && len(allPerson2RawGenomeIdentifiersList) != 0){
missingLabelText := personAName + " has no genomes."
missingLabelText := person1Name + " has no genomes."
return missingLabelText
}
// len(allPersonARawGenomeIdentifiersList) != 0 && len(allPersonBRawGenomeIdentifiersList) == 0){
// len(allPerson1RawGenomeIdentifiersList) != 0 && len(allPerson2RawGenomeIdentifiersList) == 0){
missingLabelText := personBName + " has no genomes."
missingLabelText := person2Name + " has no genomes."
return missingLabelText
}
@ -1579,35 +1585,35 @@ func setAnalyzeCoupleGeneticsPage(window fyne.Window, inputPersonAIdentifier str
return
}
anyPersonAAnalysisFound, newestPersonAAnalysisIdentifier, _, newestPersonAAnalysisListOfGenomesAnalyzed, newerPersonAAnalysisVersionAvailable, err := myAnalyses.GetPersonNewestGeneticAnalysisInfo(personAIdentifier)
anyPerson1AnalysisFound, newestPerson1AnalysisIdentifier, _, newestPerson1AnalysisListOfGenomesAnalyzed, newerPerson1AnalysisVersionAvailable, err := myAnalyses.GetPersonNewestGeneticAnalysisInfo(person1Identifier)
if (err != nil){
setErrorEncounteredPage(window, err, previousPage)
return
}
anyPersonBAnalysisFound, newestPersonBAnalysisIdentifier, _, newestPersonBAnalysisListOfGenomesAnalyzed, newerPersonBAnalysisVersionAvailable, err := myAnalyses.GetPersonNewestGeneticAnalysisInfo(personBIdentifier)
anyPerson2AnalysisFound, newestPerson2AnalysisIdentifier, _, newestPerson2AnalysisListOfGenomesAnalyzed, newerPerson2AnalysisVersionAvailable, err := myAnalyses.GetPersonNewestGeneticAnalysisInfo(person2Identifier)
if (err != nil){
setErrorEncounteredPage(window, err, previousPage)
return
}
anyCoupleAnalysisFound, newestCoupleAnalysisIdentifier, timeOfNewestAnalysis, newestCoupleAnalysisListOfGenomesAnalyzed_PersonA, newestCoupleAnalysisListOfGenomesAnalyzed_PersonB, newerCoupleAnalysisVersionAvailable, err := myAnalyses.GetCoupleNewestGeneticAnalysisInfo(personAIdentifier, personBIdentifier)
anyCoupleAnalysisFound, newestCoupleAnalysisIdentifier, timeOfNewestAnalysis, newestCoupleAnalysisListOfGenomesAnalyzed_Person1, newestCoupleAnalysisListOfGenomesAnalyzed_Person2, newerCoupleAnalysisVersionAvailable, err := myAnalyses.GetCoupleNewestGeneticAnalysisInfo(person1Identifier, person2Identifier)
if (err != nil){
setErrorEncounteredPage(window, err, previousPage)
return
}
if (anyCoupleAnalysisFound == false || anyPersonAAnalysisFound == false || anyPersonBAnalysisFound == false){
if (anyCoupleAnalysisFound == false || anyPerson1AnalysisFound == false || anyPerson2AnalysisFound == false){
// We will skip to the ConfirmPerformAnalysis page
setConfirmPerformCoupleAnalysisPage(window, personAIdentifier, personBIdentifier, previousPage, currentPage)
setConfirmPerformCoupleAnalysisPage(window, person1Identifier, person2Identifier, previousPage, currentPage)
return
}
if (newerPersonAAnalysisVersionAvailable == true || newerPersonBAnalysisVersionAvailable == true || newerCoupleAnalysisVersionAvailable == true){
if (newerPerson1AnalysisVersionAvailable == true || newerPerson2AnalysisVersionAvailable == true || newerCoupleAnalysisVersionAvailable == true){
description1 := getLabelCentered("A new analysis method is available!")
description2 := getLabelCentered("You must perform a new analysis to see the couple's new results.")
performNewAnalysisButton := getWidgetCentered(widget.NewButtonWithIcon("Perform New Analysis", theme.NavigateNextIcon(), func(){
setConfirmPerformCoupleAnalysisPage(window, personAIdentifier, personBIdentifier, currentPage, currentPage)
setConfirmPerformCoupleAnalysisPage(window, person1Identifier, person2Identifier, currentPage, currentPage)
}))
page := container.NewVBox(title, backButton, widget.NewSeparator(), description, widget.NewSeparator(), description1, description2, performNewAnalysisButton)
@ -1619,22 +1625,22 @@ func setAnalyzeCoupleGeneticsPage(window fyne.Window, inputPersonAIdentifier str
// This will return true if a newer analysis can be performed using newly imported genomes
getAnalysisIsMissingGenomesBool := func()(bool, error){
genomesAreIdentical := helpers.CheckIfTwoListsContainIdenticalItems(allPersonARawGenomeIdentifiersList, newestPersonAAnalysisListOfGenomesAnalyzed)
genomesAreIdentical := helpers.CheckIfTwoListsContainIdenticalItems(allPerson1RawGenomeIdentifiersList, newestPerson1AnalysisListOfGenomesAnalyzed)
if (genomesAreIdentical == false){
return true, nil
}
genomesAreIdentical = helpers.CheckIfTwoListsContainIdenticalItems(allPersonBRawGenomeIdentifiersList, newestPersonBAnalysisListOfGenomesAnalyzed)
genomesAreIdentical = helpers.CheckIfTwoListsContainIdenticalItems(allPerson2RawGenomeIdentifiersList, newestPerson2AnalysisListOfGenomesAnalyzed)
if (genomesAreIdentical == false){
return true, nil
}
genomesAreIdentical = helpers.CheckIfTwoListsContainIdenticalItems(allPersonARawGenomeIdentifiersList, newestCoupleAnalysisListOfGenomesAnalyzed_PersonA)
genomesAreIdentical = helpers.CheckIfTwoListsContainIdenticalItems(allPerson1RawGenomeIdentifiersList, newestCoupleAnalysisListOfGenomesAnalyzed_Person1)
if (genomesAreIdentical == false){
return true, nil
}
genomesAreIdentical = helpers.CheckIfTwoListsContainIdenticalItems(allPersonBRawGenomeIdentifiersList, newestCoupleAnalysisListOfGenomesAnalyzed_PersonB)
genomesAreIdentical = helpers.CheckIfTwoListsContainIdenticalItems(allPerson2RawGenomeIdentifiersList, newestCoupleAnalysisListOfGenomesAnalyzed_Person2)
if (genomesAreIdentical == false){
return true, nil
}
@ -1652,7 +1658,7 @@ func setAnalyzeCoupleGeneticsPage(window fyne.Window, inputPersonAIdentifier str
description1 := getLabelCentered("At least 1 person in the couple has imported/deleted a genome.")
description2 := getLabelCentered("A new analysis must be performed.")
performAnalysisButton := getWidgetCentered(widget.NewButtonWithIcon("Perform Analysis", theme.NavigateNextIcon(), func(){
setConfirmPerformCoupleAnalysisPage(window, personAIdentifier, personBIdentifier, currentPage, currentPage)
setConfirmPerformCoupleAnalysisPage(window, person1Identifier, person2Identifier, currentPage, currentPage)
}))
page := container.NewVBox(title, backButton, widget.NewSeparator(), description, widget.NewSeparator(), description1, description2, performAnalysisButton)
@ -1664,12 +1670,12 @@ func setAnalyzeCoupleGeneticsPage(window fyne.Window, inputPersonAIdentifier str
analysisReadyLabel := getBoldLabelCentered("Genetic Analysis Complete!")
coupleAnalyzedLabel := widget.NewLabel("Couple Analyzed:")
coupleName := personAName + " + " + personBName
coupleName := person1Name + " + " + person2Name
coupleNameLabel := getBoldLabel(coupleName)
personAnalyzedRow := container.NewHBox(layout.NewSpacer(), coupleAnalyzedLabel, coupleNameLabel, layout.NewSpacer())
numberOfPersonAGenomesInAnalysis := len(newestPersonAAnalysisListOfGenomesAnalyzed)
numberOfPersonBGenomesInAnalysis := len(newestPersonBAnalysisListOfGenomesAnalyzed)
numberOfPerson1GenomesInAnalysis := len(newestPerson1AnalysisListOfGenomesAnalyzed)
numberOfPerson2GenomesInAnalysis := len(newestPerson2AnalysisListOfGenomesAnalyzed)
timeAgoPerformed, err := helpers.ConvertUnixTimeToTimeAgoTranslated(timeOfNewestAnalysis, false)
if (err != nil){
@ -1681,27 +1687,27 @@ func setAnalyzeCoupleGeneticsPage(window fyne.Window, inputPersonAIdentifier str
viewAnalysisButton := getWidgetCentered(widget.NewButtonWithIcon("View Analysis", theme.VisibilityIcon(), func(){
personAAnalysisFound, personAAnalysisMapList, err := myAnalyses.GetGeneticAnalysis(newestPersonAAnalysisIdentifier)
person1AnalysisFound, person1AnalysisObject, err := myAnalyses.GetPersonGeneticAnalysis(newestPerson1AnalysisIdentifier)
if (err != nil){
setErrorEncounteredPage(window, err, currentPage)
return
}
if (personAAnalysisFound == false){
if (person1AnalysisFound == false){
setErrorEncounteredPage(window, errors.New("Person analysis not found after being found already."), currentPage)
return
}
personBAnalysisFound, personBAnalysisMapList, err := myAnalyses.GetGeneticAnalysis(newestPersonBAnalysisIdentifier)
person2AnalysisFound, person2AnalysisObject, err := myAnalyses.GetPersonGeneticAnalysis(newestPerson2AnalysisIdentifier)
if (err != nil){
setErrorEncounteredPage(window, err, currentPage)
return
}
if (personBAnalysisFound == false){
if (person2AnalysisFound == false){
setErrorEncounteredPage(window, errors.New("Person analysis not found after being found already."), currentPage)
return
}
coupleAnalysisFound, coupleAnalysisMapList, err := myAnalyses.GetGeneticAnalysis(newestCoupleAnalysisIdentifier)
coupleAnalysisFound, coupleAnalysisObject, err := myAnalyses.GetCoupleGeneticAnalysis(newestCoupleAnalysisIdentifier)
if (err != nil){
setErrorEncounteredPage(window, err, currentPage)
return
@ -1711,7 +1717,7 @@ func setAnalyzeCoupleGeneticsPage(window fyne.Window, inputPersonAIdentifier str
return
}
setViewCoupleGeneticAnalysisPage(window, personAIdentifier, personBIdentifier, personAAnalysisMapList, personBAnalysisMapList, coupleAnalysisMapList, numberOfPersonAGenomesInAnalysis, numberOfPersonBGenomesInAnalysis, currentPage)
setViewCoupleGeneticAnalysisPage(window, person1Identifier, person2Identifier, person1AnalysisObject, person2AnalysisObject, coupleAnalysisObject, numberOfPerson1GenomesInAnalysis, numberOfPerson2GenomesInAnalysis, currentPage)
}))
@ -1721,45 +1727,45 @@ func setAnalyzeCoupleGeneticsPage(window fyne.Window, inputPersonAIdentifier str
}
func setConfirmPerformCoupleAnalysisPage(window fyne.Window, personAIdentifier string, personBIdentifier string, previousPage func(), pageToVisitAfter func()){
func setConfirmPerformCoupleAnalysisPage(window fyne.Window, person1Identifier string, person2Identifier string, previousPage func(), pageToVisitAfter func()){
appMemory.SetMemoryEntry("CurrentViewedPage", "ConfirmPerformCoupleGeneticAnalysisPage")
currentPage := func(){setConfirmPerformCoupleAnalysisPage(window, personAIdentifier, personBIdentifier, previousPage, pageToVisitAfter)}
currentPage := func(){setConfirmPerformCoupleAnalysisPage(window, person1Identifier, person2Identifier, previousPage, pageToVisitAfter)}
title := getPageTitleCentered("Genetics - Perform Couple Analysis")
backButton := getBackButtonCentered(previousPage)
allPersonAGenomesMapList, err := myGenomes.GetAllPersonGenomesMapList(personAIdentifier)
allPerson1GenomesMapList, err := myGenomes.GetAllPersonGenomesMapList(person1Identifier)
if (err != nil){
setErrorEncounteredPage(window, err, previousPage)
return
}
numberOfPersonAGenomes := len(allPersonAGenomesMapList)
numberOfPerson1Genomes := len(allPerson1GenomesMapList)
if (numberOfPersonAGenomes == 0){
if (numberOfPerson1Genomes == 0){
setErrorEncounteredPage(window, errors.New("setConfirmPerformCoupleAnalysisPage called with person who has no genomes."), previousPage)
return
}
allPersonBGenomesMapList, err := myGenomes.GetAllPersonGenomesMapList(personBIdentifier)
allPerson2GenomesMapList, err := myGenomes.GetAllPersonGenomesMapList(person2Identifier)
if (err != nil){
setErrorEncounteredPage(window, err, previousPage)
return
}
numberOfPersonBGenomes := len(allPersonBGenomesMapList)
numberOfPerson2Genomes := len(allPerson2GenomesMapList)
if (numberOfPersonBGenomes == 0){
if (numberOfPerson2Genomes == 0){
setErrorEncounteredPage(window, errors.New("setConfirmPerformCoupleAnalysisPage called with person who has no genomes."), previousPage)
return
}
// Now we check if there is an analysis running
anyProcessFound, processIdentifier, err := myAnalyses.GetCoupleGeneticAnalysisProcessIdentifier(personAIdentifier, personBIdentifier)
anyProcessFound, processIdentifier, err := myAnalyses.GetCoupleGeneticAnalysisProcessIdentifier(person1Identifier, person2Identifier)
if (err != nil){
setErrorEncounteredPage(window, err, previousPage)
return
@ -1800,7 +1806,7 @@ func setConfirmPerformCoupleAnalysisPage(window fyne.Window, personAIdentifier s
startAnalysisFunction := func(){
newProcessIdentifier, err := myAnalyses.StartCreateNewCoupleGeneticAnalysis(personAIdentifier, personBIdentifier)
newProcessIdentifier, err := myAnalyses.StartCreateNewCoupleGeneticAnalysis(person1Identifier, person2Identifier)
if (err != nil){
setErrorEncounteredPage(window, err, previousPage)
return

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -2635,7 +2635,7 @@ func setViewMateProfilePage_MonogenicDiseases(window fyne.Window, userOrOffsprin
offspringProbabilityOfHavingAVariantColumn := container.NewVBox(offspringProbabilityOfLabelB, havingVariantLabel, widget.NewSeparator())
offspringNumberOfVariantsTestedColumn := container.NewVBox(offspringNumberOfLabel, variantsTestedLabelB, widget.NewSeparator())
myPersonChosen, myGenomesExist, myAnalysisIsReady, myAnalysisMapList, myGenomeIdentifier, iHaveMultipleGenomes, err := myChosenAnalysis.GetMyChosenMateGeneticAnalysis()
myPersonChosen, myGenomesExist, myAnalysisIsReady, myAnalysisObject, myGenomeIdentifier, _, err := myChosenAnalysis.GetMyChosenMateGeneticAnalysis()
if (err != nil) { return nil, err }
monogenicDiseaseObjectsList, err := monogenicDiseases.GetMonogenicDiseaseObjectsList()
@ -2699,9 +2699,9 @@ func setViewMateProfilePage_MonogenicDiseases(window fyne.Window, userOrOffsprin
return false, 0, 0, nil
}
probabilitiesKnown, _, _, probabilityOfPassingADiseaseVariant, _, numberOfVariantsTested, _, err := readGeneticAnalysis.GetPersonMonogenicDiseaseInfoFromGeneticAnalysis(myAnalysisMapList, monogenicDiseaseName, myGenomeIdentifier, iHaveMultipleGenomes)
diseaseInfoIsKnown, _, probabilityOfPassingADiseaseVariant, _, numberOfVariantsTested, _, _, _, err := readGeneticAnalysis.GetPersonMonogenicDiseaseInfoFromGeneticAnalysis(myAnalysisObject, monogenicDiseaseName, myGenomeIdentifier)
if (err != nil) { return false, 0, 0, err }
if (probabilitiesKnown == false){
if (diseaseInfoIsKnown == false){
return false, 0, 0, nil
}
@ -2711,61 +2711,8 @@ func setViewMateProfilePage_MonogenicDiseases(window fyne.Window, userOrOffsprin
myDiseaseInfoExists, myProbabilityOfPassingAVariant, myNumberOfVariantsTested, err := getMyDiseaseInfo()
if (err != nil) { return nil, err }
//Outputs:
// -bool: Disease info known
// -int: Offspring probability of having disease (0-100)
// -bool: Probability offspring has variant is known
// -int: Probability offspring has variant (0-100)
// -int: Number of variants tested
// -error
getOffspringDiseaseInfo := func()(bool, int, bool, int, int, error){
if (userDiseaseInfoExists == false && myDiseaseInfoExists == false){
return false, 0, false, 0, 0, nil
}
if (userDiseaseInfoExists == true && myDiseaseInfoExists == false){
if (diseaseIsDominantOrRecessive == "Dominant"){
if (userProbabilityOfPassingAVariant == 100){
// We know the offspring will have the disease
return true, 100, true, 100, userNumberOfVariantsTested, nil
}
return false, 0, false, 0, 0, nil
}
if (userProbabilityOfPassingAVariant == 0){
// We know the offspring will not have the disease
return true, 0, false, 0, userNumberOfVariantsTested, nil
}
return false, 0, false, 0, 0, nil
}
if (userDiseaseInfoExists == false && myDiseaseInfoExists == true){
if (diseaseIsDominantOrRecessive == "Dominant"){
if (myProbabilityOfPassingAVariant == 100){
// We know the offspring will have the disease
return true, 100, true, 100, myNumberOfVariantsTested, nil
}
return false, 0, false, 0, 0, nil
}
if (myProbabilityOfPassingAVariant == 0){
// We know the offspring will not have the disease
return true, 0, false, 0, myNumberOfVariantsTested, nil
}
return false, 0, false, 0, 0, nil
}
probabilityOffspringHasDisease, probabilityOffspringHasVariant, err := createGeneticAnalysis.GetOffspringMonogenicDiseaseProbabilities(diseaseIsDominantOrRecessive, userProbabilityOfPassingAVariant, myProbabilityOfPassingAVariant)
if (err != nil) { return false, 0, false, 0, 0, err }
offspringNumberOfVariantsTested := userNumberOfVariantsTested + myNumberOfVariantsTested
return true, probabilityOffspringHasDisease, true, probabilityOffspringHasVariant, offspringNumberOfVariantsTested, nil
}
offspringDiseaseInfoIsKnown, offspringProbabilityOfHavingDisease, offspringProbabilityOfHavingAVariantIsKnown, offspringProbabilityOfHavingAVariant, offspringNumberOfVariantsTested, err := getOffspringDiseaseInfo()
if (err != nil){ return nil, err }
probabilityOffspringHasDiseaseIsKnown, probabilityOffspringHasDisease, probabilityOffspringHasVariantIsKnown, probabilityOffspringHasVariant, err := createGeneticAnalysis.GetOffspringMonogenicDiseaseProbabilities(diseaseIsDominantOrRecessive, userDiseaseInfoExists, userProbabilityOfPassingAVariant, myDiseaseInfoExists, myProbabilityOfPassingAVariant)
if (err != nil) { return nil, err }
getUserProbabilityOfPassingAVariantString := func()string{
if (userDiseaseInfoExists == false){
@ -2794,41 +2741,37 @@ func setViewMateProfilePage_MonogenicDiseases(window fyne.Window, userOrOffsprin
getOffspringProbabilityOfHavingDiseaseString := func()string{
if (offspringDiseaseInfoIsKnown == false){
if (probabilityOffspringHasDiseaseIsKnown == false){
result := translate("Unknown")
return result
}
offspringProbabilityOfHavingDiseaseString := helpers.ConvertIntToString(offspringProbabilityOfHavingDisease)
offspringProbabilityOfHavingDiseaseString := helpers.ConvertIntToString(probabilityOffspringHasDisease)
resultFormatted := offspringProbabilityOfHavingDiseaseString + "%"
return resultFormatted
}
offspringProbabilityOfHavingDiseaseString := getOffspringProbabilityOfHavingDiseaseString()
getOffspringProbabilityOfHavingAVariantString := func()string{
getOffspringProbabilityOfHavingAVariantFormatted := func()string{
if (offspringDiseaseInfoIsKnown == false || offspringProbabilityOfHavingAVariantIsKnown == false){
if (probabilityOffspringHasVariantIsKnown == false){
result := translate("Unknown")
return result
}
offspringProbabilityOfHavingAVariantString := helpers.ConvertIntToString(offspringProbabilityOfHavingAVariant)
offspringProbabilityOfHavingAVariantString := helpers.ConvertIntToString(probabilityOffspringHasVariant)
resultFormatted := offspringProbabilityOfHavingAVariantString + "%"
return resultFormatted
}
offspringProbabilityOfHavingAVariantString := getOffspringProbabilityOfHavingAVariantString()
offspringProbabilityOfHavingAVariantFormatted := getOffspringProbabilityOfHavingAVariantFormatted()
getOffspringNumberOfVariantsTestedString := func()string{
totalNumberOfOffspringDiseaseVariantsString := helpers.ConvertIntToString(numberOfDiseaseVariants*2)
if (offspringDiseaseInfoIsKnown == false){
result := "0/" + totalNumberOfOffspringDiseaseVariantsString
return result
}
offspringNumberOfVariantsTestedString := helpers.ConvertIntToString(offspringNumberOfVariantsTested)
result := offspringNumberOfVariantsTestedString + "/" + totalNumberOfOffspringDiseaseVariantsString
return result
}
totalNumberOfOffspringDiseaseVariantsString := helpers.ConvertIntToString(numberOfDiseaseVariants*2)
offspringNumberOfVariantsTested := userNumberOfVariantsTested + myNumberOfVariantsTested
offspringNumberOfVariantsTestedString := helpers.ConvertIntToString(offspringNumberOfVariantsTested)
offspringNumberOfVariantsTestedFormatted := offspringNumberOfVariantsTestedString + "/" + totalNumberOfOffspringDiseaseVariantsString
viewDiseaseInfoButton := widget.NewButtonWithIcon("", theme.InfoIcon(), func(){
setViewMonogenicDiseaseDetailsPage(window, monogenicDiseaseName, currentPage)
@ -2836,14 +2779,12 @@ func setViewMateProfilePage_MonogenicDiseases(window fyne.Window, userOrOffsprin
diseaseNameLabel := getBoldLabelCentered(monogenicDiseaseName)
offspringNumberOfVariantsTestedString := getOffspringNumberOfVariantsTestedString()
userProbabilityOfPassingAVariantLabel := getBoldLabelCentered(userProbabilityOfPassingAVariantString)
userNumberOfVariantsTestedLabel := getBoldLabelCentered(userNumberOfVariantsTestedString)
offspringProbabilityOfHavingDiseaseLabel := getBoldLabelCentered(offspringProbabilityOfHavingDiseaseString)
offspringProbabilityOfHavingAVariantLabel := getBoldLabelCentered(offspringProbabilityOfHavingAVariantString)
offspringNumberOfVariantsTestedLabel := getBoldLabelCentered(offspringNumberOfVariantsTestedString)
offspringProbabilityOfHavingAVariantLabel := getBoldLabelCentered(offspringProbabilityOfHavingAVariantFormatted)
offspringNumberOfVariantsTestedLabel := getBoldLabelCentered(offspringNumberOfVariantsTestedFormatted)
diseaseInfoButtonsColumn.Add(viewDiseaseInfoButton)
diseaseNameColumn.Add(diseaseNameLabel)
@ -2959,7 +2900,7 @@ func setViewMateProfilePage_PolygenicDiseases(window fyne.Window, userOrOffsprin
offspringNumberOfLociTestedColumn := container.NewVBox(offspringNumberOfLabel, lociTestedLabelB, widget.NewSeparator())
viewDiseaseInfoButtonsColumn := container.NewVBox(emptyLabelD, emptyLabelE, widget.NewSeparator())
myPersonChosen, myGenomesExist, myAnalysisIsReady, myAnalysisMapList, myGenomeIdentifier, _, err := myChosenAnalysis.GetMyChosenMateGeneticAnalysis()
myPersonChosen, myGenomesExist, myAnalysisIsReady, myAnalysisObject, myGenomeIdentifier, _, err := myChosenAnalysis.GetMyChosenMateGeneticAnalysis()
if (err != nil) { return nil, err }
diseaseObjectsList, err := polygenicDiseases.GetPolygenicDiseaseObjectsList()
@ -2982,7 +2923,11 @@ func setViewMateProfilePage_PolygenicDiseases(window fyne.Window, userOrOffsprin
for _, locusObject := range diseaseLociList{
locusIdentifier := locusObject.LocusIdentifier
locusIdentifierHex := locusObject.LocusIdentifier
locusIdentifier, err := encoding.DecodeHexStringTo3ByteArray(locusIdentifierHex)
if (err != nil){ return nil, err }
locusRSID := locusObject.LocusRSID
locusRSIDString := helpers.ConvertInt64ToString(locusRSID)
@ -3014,27 +2959,33 @@ func setViewMateProfilePage_PolygenicDiseases(window fyne.Window, userOrOffsprin
//Outputs:
// -bool: My locus base pair exists
// -string: My locus base pair
// -string: My locus base 1
// -string: My locus base 2
// -error
getMyLocusInfo := func()(bool, string, error){
getMyLocusInfo := func()(bool, string, string, error){
if (myPersonChosen == false || myGenomesExist == false || myAnalysisIsReady == false){
return false, "", nil
return false, "", "", nil
}
locusInfoKnown, _, locusBasePair, _, _, _, err := readGeneticAnalysis.GetPersonPolygenicDiseaseLocusInfoFromGeneticAnalysis(myAnalysisMapList, diseaseName, locusIdentifier, myGenomeIdentifier)
if (err != nil){ return false, "", err }
locusInfoKnown, _, locusBase1, locusBase2, _, _, _, err := readGeneticAnalysis.GetPersonPolygenicDiseaseLocusInfoFromGeneticAnalysis(myAnalysisObject, diseaseName, locusIdentifier, myGenomeIdentifier)
if (err != nil){ return false, "", "", err }
if (locusInfoKnown == false){
return false, "", nil
return false, "", "", nil
}
return true, locusBasePair, nil
return true, locusBase1, locusBase2, nil
}
myLocusBasePairExists, myLocusBasePair, err := getMyLocusInfo()
myLocusBasePairExists, myLocusBase1, myLocusBase2, err := getMyLocusInfo()
if (err != nil) { return nil, err }
if (userLocusBasePairExists == true && myLocusBasePairExists == true){
offspringLocusRiskWeight, _, _, _, err := createGeneticAnalysis.GetOffspringPolygenicDiseaseLocusInfo(locusRiskWeightsMap, locusOddsRatiosMap, myLocusBasePair, userLocusBasePair)
userLocusBase1, userLocusBase2, semicolonFound := strings.Cut(userLocusBasePair, ";")
if (semicolonFound == false){
return nil, errors.New("Database contains profile containing invalid " + locusValueAttributeName + ": " + userLocusBasePair)
}
offspringLocusRiskWeight, _, _, _, err := createGeneticAnalysis.GetOffspringPolygenicDiseaseLocusInfo(locusRiskWeightsMap, locusOddsRatiosMap, myLocusBase1, myLocusBase2, userLocusBase1, userLocusBase2)
if (err != nil) { return nil, err }
offspringNumberOfLociTested += 1
@ -3196,7 +3147,7 @@ func setViewMateProfilePage_PolygenicDiseaseLoci(window fyne.Window, diseaseName
numberOfDiseaseLoci := len(diseaseLocusObjectsList)
myPersonChosen, myGenomesExist, myAnalysisIsReady, myAnalysisMapList, myGenomeIdentifier, _, err := myChosenAnalysis.GetMyChosenMateGeneticAnalysis()
myPersonChosen, myGenomesExist, myAnalysisIsReady, myAnalysisObject, myGenomeIdentifier, _, err := myChosenAnalysis.GetMyChosenMateGeneticAnalysis()
if (err != nil) {
setErrorEncounteredPage(window, err, previousPage)
return
@ -3242,19 +3193,23 @@ func setViewMateProfilePage_PolygenicDiseaseLoci(window fyne.Window, diseaseName
//Outputs:
// -bool: My locus Info is known
// -string: My locus base pair
// -string: My locus base 1
// -string: My locus base 2
// -error
getMyLocusInfo := func(locusIdentifier string)(bool, string, error){
getMyLocusInfo := func(locusIdentifierHex string)(bool, string, string, error){
if (myPersonChosen == false || myGenomesExist == false || myAnalysisIsReady == false){
return false, "", nil
return false, "", "", nil
}
locusInfoKnown, _, locusBasePair, _, _, _, err := readGeneticAnalysis.GetPersonPolygenicDiseaseLocusInfoFromGeneticAnalysis(myAnalysisMapList, diseaseName, locusIdentifier, myGenomeIdentifier)
if (err != nil){ return false, "", err }
locusIdentifier, err := encoding.DecodeHexStringTo3ByteArray(locusIdentifierHex)
if (err != nil) { return false, "", "", err }
locusInfoKnown, _, locusBase1, locusBase2, _, _, _, err := readGeneticAnalysis.GetPersonPolygenicDiseaseLocusInfoFromGeneticAnalysis(myAnalysisObject, diseaseName, locusIdentifier, myGenomeIdentifier)
if (err != nil){ return false, "", "", err }
if (locusInfoKnown == false){
return false, "", nil
return false, "", "", nil
}
return true, locusBasePair, nil
return true, locusBase1, locusBase2, nil
}
getNumberOfLociTested := func()(int, error){
@ -3282,7 +3237,7 @@ func setViewMateProfilePage_PolygenicDiseaseLoci(window fyne.Window, diseaseName
if (userOrOffspring == "Offspring") {
myLocusInfoKnown, _, err := getMyLocusInfo(locusIdentifier)
myLocusInfoKnown, _, _, err := getMyLocusInfo(locusIdentifier)
if (err != nil) { return 0, err }
if (myLocusInfoKnown == false){
continue
@ -3355,7 +3310,7 @@ func setViewMateProfilePage_PolygenicDiseaseLoci(window fyne.Window, diseaseName
userLocusInfoIsKnown, userLocusRiskWeight, userLocusBasePair, userLocusOddsRatioKnown, userLocusOddsRatioFormatted, err := getUserLocusInfo(locusRSID, locusRiskWeightsMap, locusOddsRatiosMap)
if (err != nil) { return nil, err }
myLocusInfoIsKnown, myLocusBasePair, err := getMyLocusInfo(locusIdentifier)
myLocusInfoIsKnown, myLocusBase1, myLocusBase2, err := getMyLocusInfo(locusIdentifier)
if (err != nil) { return nil, err }
getUserRiskWeightString := func()string{
@ -3393,7 +3348,12 @@ func setViewMateProfilePage_PolygenicDiseaseLoci(window fyne.Window, diseaseName
return false, 0, false, "", nil
}
offspringLocusRiskWeight, offspringOddsRatioIsKnown, offspringOddsRatio, unknownOddsRatiosWeightSum, err := createGeneticAnalysis.GetOffspringPolygenicDiseaseLocusInfo(locusRiskWeightsMap, locusOddsRatiosMap, myLocusBasePair, userLocusBasePair)
userLocusBase1, userLocusBase2, semicolonExists := strings.Cut(userLocusBasePair, ";")
if (semicolonExists == true){
return false, 0, false, "", errors.New("Database corrupt: Contains profile with invalid " + locusName + " value: " + userLocusBasePair)
}
offspringLocusRiskWeight, offspringOddsRatioIsKnown, offspringOddsRatio, unknownOddsRatiosWeightSum, err := createGeneticAnalysis.GetOffspringPolygenicDiseaseLocusInfo(locusRiskWeightsMap, locusOddsRatiosMap, myLocusBase1, myLocusBase2, userLocusBase1, userLocusBase2)
if (err != nil) { return false, 0, false, "", err }
if (offspringOddsRatioIsKnown == false){
@ -3557,7 +3517,7 @@ func setViewMateProfilePage_GeneticTraits(window fyne.Window, userOrOffspring st
offspringNumberOfRulesTestedColumn := container.NewVBox(numberOfLabelB, rulesTestedLabelB, widget.NewSeparator())
viewTraitDetailsButtonsColumn := container.NewVBox(emptyLabelD, emptyLabelE, widget.NewSeparator())
myPersonChosen, myGenomesExist, myAnalysisIsReady, myAnalysisMapList, myGenomeIdentifier, _, err := myChosenAnalysis.GetMyChosenMateGeneticAnalysis()
myPersonChosen, myGenomesExist, myAnalysisIsReady, myAnalysisObject, myGenomeIdentifier, _, err := myChosenAnalysis.GetMyChosenMateGeneticAnalysis()
if (err != nil) { return nil, err }
traitObjectsList, err := traits.GetTraitObjectsList()
@ -3691,21 +3651,19 @@ func setViewMateProfilePage_GeneticTraits(window fyne.Window, userOrOffspring st
// -error
getOffspringTraitOutcomeScoresMap := func()(bool, map[string]float64, int, error){
if (myPersonChosen == false || myGenomesExist == false || myAnalysisIsReady == false){
// Without my genome person chosen, all offspring rules and outcome scores are unknown
return false, nil, 0, nil
}
myTraitLocusValuesMap, _, _, _, _, err := readGeneticAnalysis.GetPersonTraitInfoFromGeneticAnalysis(myAnalysisObject, traitName, myGenomeIdentifier)
if (err != nil) { return false, nil, 0, err }
offspringTraitOutcomeScoresMap := make(map[string]float64)
offspringNumberOfRulesTested := 0
for _, traitRuleObject := range traitRulesList{
if (myPersonChosen == false || myGenomesExist == false || myAnalysisIsReady == false){
// Without my genome person chosen, all offspring rules and outcome scores are unknown
return false, nil, 0, nil
}
ruleIdentifier := traitRuleObject.RuleIdentifier
_, _, myRuleLociBasePairsMap, err := readGeneticAnalysis.GetPersonTraitRuleInfoFromGeneticAnalysis(myAnalysisMapList, traitName, ruleIdentifier, myGenomeIdentifier)
if (err != nil) { return false, nil, 0, err }
ruleLociList := traitRuleObject.LociList
//Outputs:
@ -3718,7 +3676,6 @@ func setViewMateProfilePage_GeneticTraits(window fyne.Window, userOrOffspring st
for _, ruleLocusObject := range ruleLociList{
locusIdentifier := ruleLocusObject.LocusIdentifier
locusRSID := ruleLocusObject.LocusRSID
locusRSIDString := helpers.ConvertInt64ToString(locusRSID)
@ -3732,15 +3689,23 @@ func setViewMateProfilePage_GeneticTraits(window fyne.Window, userOrOffspring st
return false, 0, nil
}
myLocusBasePair, myLocusBasePairIsKnown := myRuleLociBasePairsMap[locusIdentifier]
if (myLocusBasePairIsKnown == false){
userLocusBase1, userLocusBase2, semicolonExists := strings.Cut(userLocusBasePair, ";")
if (semicolonExists == false){
return false, 0, errors.New("Database corrupt: Contains profile with invalid " + userLocusValueAttributeName + ": " + userLocusBasePair)
}
myLocusValue, myLocusValueIsKnown := myTraitLocusValuesMap[locusRSID]
if (myLocusValueIsKnown == false){
// We must know all rule loci base pairs to determine offspring probability of passing rule
return false, 0, nil
}
myLocusBase1 := myLocusValue.Base1Value
myLocusBase2 := myLocusValue.Base2Value
locusRequiredBasePairsList := ruleLocusObject.BasePairsList
offspringProbabilityOfPassingRuleLocus, err := createGeneticAnalysis.GetOffspringTraitRuleLocusInfo(locusRequiredBasePairsList, userLocusBasePair, myLocusBasePair)
offspringProbabilityOfPassingRuleLocus, err := createGeneticAnalysis.GetOffspringTraitRuleLocusInfo(locusRequiredBasePairsList, userLocusBase1, userLocusBase2, myLocusBase1, myLocusBase2)
if (err != nil) { return false, 0, err }
offspringProbabilityOfPassingRule *= offspringProbabilityOfPassingRuleLocus
@ -3754,7 +3719,7 @@ func setViewMateProfilePage_GeneticTraits(window fyne.Window, userOrOffspring st
continue
}
offspringNumberOfRulesTested += 1
ruleOutcomePointsMap := traitRuleObject.OutcomePointsMap
for traitOutcome, pointsEffect := range ruleOutcomePointsMap{
@ -3807,7 +3772,7 @@ func setViewMateProfilePage_GeneticTraits(window fyne.Window, userOrOffspring st
if (exists == false){
return nil, errors.New("Outcome not found in userTraitOutcomeScoresMap.")
}
outcomeScoreString := helpers.ConvertIntToString(outcomeScore)
outcomeRow := getBoldLabelCentered(outcomeName + ": " + outcomeScoreString)
@ -3867,7 +3832,7 @@ func setViewMateProfilePage_GeneticTraits(window fyne.Window, userOrOffspring st
}
}
}
traitNameColumn.Add(widget.NewSeparator())
userOutcomeScoresColumn.Add(widget.NewSeparator())
offspringOutcomeScoresColumn.Add(widget.NewSeparator())
@ -3978,7 +3943,7 @@ func setViewMateProfilePage_TraitRules(window fyne.Window, traitName string, use
return true, true, nil
}
myPersonChosen, myGenomesExist, myAnalysisIsReady, myAnalysisMapList, myGenomeIdentifier, _, err := myChosenAnalysis.GetMyChosenMateGeneticAnalysis()
myPersonChosen, myGenomesExist, myAnalysisIsReady, myAnalysisObject, myGenomeIdentifier, _, err := myChosenAnalysis.GetMyChosenMateGeneticAnalysis()
if (err != nil) {
setErrorEncounteredPage(window, err, previousPage)
return
@ -3995,14 +3960,13 @@ func setViewMateProfilePage_TraitRules(window fyne.Window, traitName string, use
return false, 0, nil
}
_, _, myRuleLociBasePairsMap, err := readGeneticAnalysis.GetPersonTraitRuleInfoFromGeneticAnalysis(myAnalysisMapList, traitName, ruleIdentifier, myGenomeIdentifier)
myTraitLocusValuesMap, _, _, _, _, err := readGeneticAnalysis.GetPersonTraitInfoFromGeneticAnalysis(myAnalysisObject, traitName, myGenomeIdentifier)
if (err != nil) { return false, 0, err }
offspringProbabilityOfPassingRule := float64(1)
for _, ruleLocusObject := range ruleLociList{
locusIdentifier := ruleLocusObject.LocusIdentifier
locusRSID := ruleLocusObject.LocusRSID
locusRSIDString := helpers.ConvertInt64ToString(locusRSID)
@ -4016,15 +3980,23 @@ func setViewMateProfilePage_TraitRules(window fyne.Window, traitName string, use
return false, 0, nil
}
myLocusBasePair, myLocusBasePairIsKnown := myRuleLociBasePairsMap[locusIdentifier]
if (myLocusBasePairIsKnown == false){
userLocusBase1, userLocusBase2, semicolonExists := strings.Cut(userLocusBasePair, ";")
if (semicolonExists == false){
return false, 0, errors.New("Database corrupt: Contains profile with invalid: " + userLocusValueAttributeName + ": " + userLocusBasePair)
}
myLocusValue, myLocusValueIsKnown := myTraitLocusValuesMap[locusRSID]
if (myLocusValueIsKnown == false){
// We must know all rule loci base pairs to determine offspring probability of passing rule
return false, 0, nil
}
myLocusBase1 := myLocusValue.Base1Value
myLocusBase2 := myLocusValue.Base2Value
locusRequiredBasePairsList := ruleLocusObject.BasePairsList
offspringProbabilityOfPassingRuleLocus, err := createGeneticAnalysis.GetOffspringTraitRuleLocusInfo(locusRequiredBasePairsList, userLocusBasePair, myLocusBasePair)
offspringProbabilityOfPassingRuleLocus, err := createGeneticAnalysis.GetOffspringTraitRuleLocusInfo(locusRequiredBasePairsList, userLocusBase1, userLocusBase2, myLocusBase1, myLocusBase2)
if (err != nil) { return false, 0, err }
offspringProbabilityOfPassingRule *= offspringProbabilityOfPassingRuleLocus

View file

@ -23,6 +23,34 @@ func DecodeHexStringToBytes(hexInput string)([]byte, error){
return decodedBytes, nil
}
func DecodeHexStringTo3ByteArray(hexInput string)([3]byte, error){
decodedBytes, err := hex.DecodeString(hexInput)
if (err != nil) { return [3]byte{}, err }
if (len(decodedBytes) != 3){
return [3]byte{}, errors.New("DecodeHexStringTo3ByteArray called with invalid length hex string: " + hexInput)
}
result := [3]byte(decodedBytes)
return result, nil
}
func DecodeHexStringTo16ByteArray(hexInput string)([16]byte, error){
decodedBytes, err := hex.DecodeString(hexInput)
if (err != nil) { return [16]byte{}, err }
if (len(decodedBytes) != 16){
return [16]byte{}, errors.New("DecodeHexStringTo16ByteArray called with invalid length hex string: " + hexInput)
}
result := [16]byte(decodedBytes)
return result, nil
}
func EncodeBytesToHexString(input []byte)string{
result := hex.EncodeToString(input)
@ -127,7 +155,6 @@ func EncodeMessagePackBytes(input interface{}) ([]byte, error) {
return bytes, nil
}
func DecodeRawMessagePackToString(data messagepack.RawMessage)(string, error){
var outputString string

View file

@ -440,66 +440,66 @@ func AddMissingParentsToAncestryCompositionMaps_23andMe(inputContinentPercentage
// -map[string]float64: Region percentages map
// -map[string]float64: Subregion percentages map
// -error
func GetOffspringAncestryComposition_23andMe(personAAncestryCompositionAttribute string, personBAncestryCompositionAttribute string)(map[string]float64, map[string]float64, map[string]float64, error){
func GetOffspringAncestryComposition_23andMe(person1AncestryCompositionAttribute string, person2AncestryCompositionAttribute string)(map[string]float64, map[string]float64, map[string]float64, error){
personAAttributeIsValid, personAContinentPercentagesMap, personARegionPercentagesMap, personASubregionPercentagesMap, err := ReadAncestryCompositionAttribute_23andMe(true, personAAncestryCompositionAttribute)
person1AttributeIsValid, person1ContinentPercentagesMap, person1RegionPercentagesMap, person1SubregionPercentagesMap, err := ReadAncestryCompositionAttribute_23andMe(true, person1AncestryCompositionAttribute)
if (err != nil) { return nil, nil, nil, err }
if (personAAttributeIsValid == false){
return nil, nil, nil, errors.New("GetOffspringAncestryComposition_23andMe called with invalid person A ancestry composition attribute: " + personAAncestryCompositionAttribute)
if (person1AttributeIsValid == false){
return nil, nil, nil, errors.New("GetOffspringAncestryComposition_23andMe called with invalid person A ancestry composition attribute: " + person1AncestryCompositionAttribute)
}
personBAttributeIsValid, personBContinentPercentagesMap, personBRegionPercentagesMap, personBSubregionPercentagesMap, err := ReadAncestryCompositionAttribute_23andMe(true, personBAncestryCompositionAttribute)
person2AttributeIsValid, person2ContinentPercentagesMap, person2RegionPercentagesMap, person2SubregionPercentagesMap, err := ReadAncestryCompositionAttribute_23andMe(true, person2AncestryCompositionAttribute)
if (err != nil) { return nil, nil, nil, err }
if (personBAttributeIsValid == false){
return nil, nil, nil, errors.New("GetOffspringAncestryComposition_23andMe called with invalid person B ancestry composition attribute: " + personBAncestryCompositionAttribute)
if (person2AttributeIsValid == false){
return nil, nil, nil, errors.New("GetOffspringAncestryComposition_23andMe called with invalid person B ancestry composition attribute: " + person2AncestryCompositionAttribute)
}
offspringContinentPercentagesMap := make(map[string]float64)
for continentName, continentPercentage := range personAContinentPercentagesMap{
for continentName, continentPercentage := range person1ContinentPercentagesMap{
personAPercentage := continentPercentage/2
person1Percentage := continentPercentage/2
offspringContinentPercentagesMap[continentName] = personAPercentage
offspringContinentPercentagesMap[continentName] = person1Percentage
}
for continentName, continentPercentage := range personBContinentPercentagesMap{
for continentName, continentPercentage := range person2ContinentPercentagesMap{
personBPercentage := continentPercentage/2
person2Percentage := continentPercentage/2
offspringContinentPercentagesMap[continentName] += personBPercentage
offspringContinentPercentagesMap[continentName] += person2Percentage
}
offspringRegionPercentagesMap := make(map[string]float64)
for regionName, regionPercentage := range personARegionPercentagesMap{
for regionName, regionPercentage := range person1RegionPercentagesMap{
personAPercentage := regionPercentage/2
person1Percentage := regionPercentage/2
offspringRegionPercentagesMap[regionName] = personAPercentage
offspringRegionPercentagesMap[regionName] = person1Percentage
}
for regionName, regionPercentage := range personBRegionPercentagesMap{
for regionName, regionPercentage := range person2RegionPercentagesMap{
personBPercentage := regionPercentage/2
person2Percentage := regionPercentage/2
offspringRegionPercentagesMap[regionName] += personBPercentage
offspringRegionPercentagesMap[regionName] += person2Percentage
}
offspringSubregionPercentagesMap := make(map[string]float64)
for subregionName, subregionPercentage := range personASubregionPercentagesMap{
for subregionName, subregionPercentage := range person1SubregionPercentagesMap{
personAPercentage := subregionPercentage/2
person1Percentage := subregionPercentage/2
offspringSubregionPercentagesMap[subregionName] = personAPercentage
offspringSubregionPercentagesMap[subregionName] = person1Percentage
}
for subregionName, subregionPercentage := range personBSubregionPercentagesMap{
for subregionName, subregionPercentage := range person2SubregionPercentagesMap{
personBPercentage := subregionPercentage/2
person2Percentage := subregionPercentage/2
offspringSubregionPercentagesMap[subregionName] += personBPercentage
offspringSubregionPercentagesMap[subregionName] += person2Percentage
}
return offspringContinentPercentagesMap, offspringRegionPercentagesMap, offspringSubregionPercentagesMap, nil

View file

@ -27,9 +27,9 @@ func TestCreatePersonGeneticAnalysis_SingleGenome(t *testing.T){
polygenicDiseases.InitializePolygenicDiseaseVariables()
traits.InitializeTraitVariables()
genomeIdentifier, err := helpers.GetNewRandomHexString(16)
genomeIdentifier, err := helpers.GetNewRandom16ByteArray()
if (err != nil) {
t.Fatalf("Failed to get random hex string: " + err.Error())
t.Fatalf("Failed to get random 16 byte array: " + err.Error())
}
fakeRawGenome, _, _, _, err := createRawGenomes.CreateFakeRawGenome_AncestryDNA()
@ -63,12 +63,12 @@ func TestCreatePersonGeneticAnalysis_SingleGenome(t *testing.T){
t.Fatalf("Failed to create person genetic analysis: Process did not complete.")
}
personGeneticAnalysisMapList, err := readGeneticAnalysis.ReadGeneticAnalysisString(personGeneticAnalysis)
personGeneticAnalysisObject, err := readGeneticAnalysis.ReadPersonGeneticAnalysisString(personGeneticAnalysis)
if (err != nil){
t.Fatalf("Failed to read person genetic analysis string: " + err.Error())
}
err = readGeneticAnalysis.ReadPersonGeneticAnalysisForTests(personGeneticAnalysisMapList)
err = readGeneticAnalysis.VerifyPersonGeneticAnalysis(personGeneticAnalysisObject)
if (err != nil){
t.Fatalf("Failed to read person genetic analysis: " + err.Error())
}
@ -92,9 +92,9 @@ func TestCreatePersonGeneticAnalysis_MultipleGenomes(t *testing.T){
for i:=0; i < numberOfGenomesToAdd; i++{
genomeIdentifier, err := helpers.GetNewRandomHexString(16)
genomeIdentifier, err := helpers.GetNewRandom16ByteArray()
if (err != nil) {
t.Fatalf("Failed to get random hex string: " + err.Error())
t.Fatalf("Failed to get random 16 byte array: " + err.Error())
}
getFakeRawGenome := func()(string, error){
@ -149,12 +149,12 @@ func TestCreatePersonGeneticAnalysis_MultipleGenomes(t *testing.T){
t.Fatalf("Failed to create person genetic analysis: Process did not complete.")
}
personGeneticAnalysisMapList, err := readGeneticAnalysis.ReadGeneticAnalysisString(personGeneticAnalysis)
personGeneticAnalysisObject, err := readGeneticAnalysis.ReadPersonGeneticAnalysisString(personGeneticAnalysis)
if (err != nil){
t.Fatalf("Failed to read person genetic analysis string: " + err.Error())
}
err = readGeneticAnalysis.ReadPersonGeneticAnalysisForTests(personGeneticAnalysisMapList)
err = readGeneticAnalysis.VerifyPersonGeneticAnalysis(personGeneticAnalysisObject)
if (err != nil){
t.Fatalf("Failed to read person genetic analysis: " + err.Error())
}
@ -174,9 +174,9 @@ func TestCreateCoupleGeneticAnalysis_SingleGenomes(t *testing.T){
getPersonGenomesList := func()([]prepareRawGenomes.RawGenomeWithMetadata, error){
genomeIdentifier, err := helpers.GetNewRandomHexString(16)
genomeIdentifier, err := helpers.GetNewRandom16ByteArray()
if (err != nil) {
return nil, errors.New("Failed to get random hex string: " + err.Error())
return nil, errors.New("Failed to get random 16 byte array: " + err.Error())
}
fakeRawGenome, _, _, _, err := createRawGenomes.CreateFakeRawGenome_AncestryDNA()
@ -197,12 +197,12 @@ func TestCreateCoupleGeneticAnalysis_SingleGenomes(t *testing.T){
return personGenomesList, nil
}
personAGenomesList, err := getPersonGenomesList()
person1GenomesList, err := getPersonGenomesList()
if (err != nil){
t.Fatalf("getPersonGenomesList failed: " + err.Error())
}
personBGenomesList, err := getPersonGenomesList()
person2GenomesList, err := getPersonGenomesList()
if (err != nil){
t.Fatalf("getPersonGenomesList failed: " + err.Error())
}
@ -215,7 +215,7 @@ func TestCreateCoupleGeneticAnalysis_SingleGenomes(t *testing.T){
return false
}
processCompleted, coupleGeneticAnalysis, err := createGeneticAnalysis.CreateCoupleGeneticAnalysis(personAGenomesList, personBGenomesList, updateProgressFunction, checkIfProcessIsStoppedFunction)
processCompleted, coupleGeneticAnalysis, err := createGeneticAnalysis.CreateCoupleGeneticAnalysis(person1GenomesList, person2GenomesList, updateProgressFunction, checkIfProcessIsStoppedFunction)
if (err != nil){
t.Fatalf("Failed to create couple genetic analysis: " + err.Error())
}
@ -223,12 +223,12 @@ func TestCreateCoupleGeneticAnalysis_SingleGenomes(t *testing.T){
t.Fatalf("Failed to create couple genetic analysis: Process did not complete.")
}
coupleGeneticAnalysisMapList, err := readGeneticAnalysis.ReadGeneticAnalysisString(coupleGeneticAnalysis)
coupleGeneticAnalysisObject, err := readGeneticAnalysis.ReadCoupleGeneticAnalysisString(coupleGeneticAnalysis)
if (err != nil){
t.Fatalf("Failed to read couple genetic analysis string: " + err.Error())
}
err = readGeneticAnalysis.ReadCoupleGeneticAnalysisForTests(coupleGeneticAnalysisMapList)
err = readGeneticAnalysis.VerifyCoupleGeneticAnalysis(coupleGeneticAnalysisObject)
if (err != nil){
t.Fatalf("Failed to read couple genetic analysis: " + err.Error())
}
@ -249,9 +249,9 @@ func TestCreateCoupleGeneticAnalysis_SingleAndMultipleGenomes(t *testing.T){
getPersonGenomesList := func(addSecondGenome bool)([]prepareRawGenomes.RawGenomeWithMetadata, error){
genomeIdentifier1, err := helpers.GetNewRandomHexString(16)
genomeIdentifier1, err := helpers.GetNewRandom16ByteArray()
if (err != nil) {
return nil, errors.New("Failed to get random hex string: " + err.Error())
return nil, errors.New("Failed to get random 16 byte array: " + err.Error())
}
fakeRawGenome1, _, _, _, err := createRawGenomes.CreateFakeRawGenome_AncestryDNA()
@ -271,9 +271,9 @@ func TestCreateCoupleGeneticAnalysis_SingleAndMultipleGenomes(t *testing.T){
if (addSecondGenome == true){
genomeIdentifier2, err := helpers.GetNewRandomHexString(16)
genomeIdentifier2, err := helpers.GetNewRandom16ByteArray()
if (err != nil) {
return nil, errors.New("Failed to get random hex string: " + err.Error())
return nil, errors.New("Failed to get random 16 byte array: " + err.Error())
}
fakeRawGenome2, _, _, _, err := createRawGenomes.CreateFakeRawGenome_23andMe()
@ -295,12 +295,12 @@ func TestCreateCoupleGeneticAnalysis_SingleAndMultipleGenomes(t *testing.T){
return genomesList, nil
}
personAGenomesList, err := getPersonGenomesList(false)
person1GenomesList, err := getPersonGenomesList(false)
if (err != nil){
t.Fatalf("getPersonGenomesList failed: " + err.Error())
}
personBGenomesList, err := getPersonGenomesList(true)
person2GenomesList, err := getPersonGenomesList(true)
if (err != nil){
t.Fatalf("getPersonGenomesList failed: " + err.Error())
}
@ -313,7 +313,7 @@ func TestCreateCoupleGeneticAnalysis_SingleAndMultipleGenomes(t *testing.T){
return false
}
processCompleted, coupleGeneticAnalysis, err := createGeneticAnalysis.CreateCoupleGeneticAnalysis(personAGenomesList, personBGenomesList, updateProgressFunction, checkIfProcessIsStoppedFunction)
processCompleted, coupleGeneticAnalysis, err := createGeneticAnalysis.CreateCoupleGeneticAnalysis(person1GenomesList, person2GenomesList, updateProgressFunction, checkIfProcessIsStoppedFunction)
if (err != nil){
t.Fatalf("Failed to create couple genetic analysis: " + err.Error())
}
@ -321,12 +321,12 @@ func TestCreateCoupleGeneticAnalysis_SingleAndMultipleGenomes(t *testing.T){
t.Fatalf("Failed to create couple genetic analysis: Process did not complete.")
}
coupleGeneticAnalysisMapList, err := readGeneticAnalysis.ReadGeneticAnalysisString(coupleGeneticAnalysis)
coupleGeneticAnalysisObject, err := readGeneticAnalysis.ReadCoupleGeneticAnalysisString(coupleGeneticAnalysis)
if (err != nil){
t.Fatalf("Failed to read couple genetic analysis string: " + err.Error())
}
err = readGeneticAnalysis.ReadCoupleGeneticAnalysisForTests(coupleGeneticAnalysisMapList)
err = readGeneticAnalysis.VerifyCoupleGeneticAnalysis(coupleGeneticAnalysisObject)
if (err != nil){
t.Fatalf("Failed to read couple genetic analysis: " + err.Error())
}
@ -347,9 +347,9 @@ func TestCreateCoupleGeneticAnalysis_MultipleGenomes(t *testing.T){
getPersonGenomesList := func()([]prepareRawGenomes.RawGenomeWithMetadata, error){
genomeIdentifier1, err := helpers.GetNewRandomHexString(16)
genomeIdentifier1, err := helpers.GetNewRandom16ByteArray()
if (err != nil) {
return nil, errors.New("Failed to get random hex string: " + err.Error())
return nil, errors.New("Failed to get random 16 byte array: " + err.Error())
}
fakeRawGenome1, _, _, _, err := createRawGenomes.CreateFakeRawGenome_AncestryDNA()
@ -365,9 +365,9 @@ func TestCreateCoupleGeneticAnalysis_MultipleGenomes(t *testing.T){
return nil, errors.New("CreateRawGenomeWithMetadataObject failed: Genome is not valid.")
}
genomeIdentifier2, err := helpers.GetNewRandomHexString(16)
genomeIdentifier2, err := helpers.GetNewRandom16ByteArray()
if (err != nil) {
return nil, errors.New("Failed to get random hex string: " + err.Error())
return nil, errors.New("Failed to get random 16 byte array: " + err.Error())
}
fakeRawGenome2, _, _, _, err := createRawGenomes.CreateFakeRawGenome_23andMe()
@ -388,12 +388,12 @@ func TestCreateCoupleGeneticAnalysis_MultipleGenomes(t *testing.T){
return genomesList, nil
}
personAGenomesList, err := getPersonGenomesList()
person1GenomesList, err := getPersonGenomesList()
if (err != nil){
t.Fatalf("getPersonGenomesList failed: " + err.Error())
}
personBGenomesList, err := getPersonGenomesList()
person2GenomesList, err := getPersonGenomesList()
if (err != nil){
t.Fatalf("getPersonGenomesList failed: " + err.Error())
}
@ -406,7 +406,7 @@ func TestCreateCoupleGeneticAnalysis_MultipleGenomes(t *testing.T){
return false
}
processCompleted, coupleGeneticAnalysis, err := createGeneticAnalysis.CreateCoupleGeneticAnalysis(personAGenomesList, personBGenomesList, updateProgressFunction, checkIfProcessIsStoppedFunction)
processCompleted, coupleGeneticAnalysis, err := createGeneticAnalysis.CreateCoupleGeneticAnalysis(person1GenomesList, person2GenomesList, updateProgressFunction, checkIfProcessIsStoppedFunction)
if (err != nil){
t.Fatalf("Failed to create couple genetic analysis: " + err.Error())
}
@ -414,12 +414,12 @@ func TestCreateCoupleGeneticAnalysis_MultipleGenomes(t *testing.T){
t.Fatalf("Failed to create couple genetic analysis: Process did not complete.")
}
coupleGeneticAnalysisMapList, err := readGeneticAnalysis.ReadGeneticAnalysisString(coupleGeneticAnalysis)
coupleGeneticAnalysisObject, err := readGeneticAnalysis.ReadCoupleGeneticAnalysisString(coupleGeneticAnalysis)
if (err != nil){
t.Fatalf("Failed to read couple genetic analysis string: " + err.Error())
}
err = readGeneticAnalysis.ReadCoupleGeneticAnalysisForTests(coupleGeneticAnalysisMapList)
err = readGeneticAnalysis.VerifyCoupleGeneticAnalysis(coupleGeneticAnalysisObject)
if (err != nil){
t.Fatalf("Failed to read couple genetic analysis: " + err.Error())
}

View file

@ -0,0 +1,318 @@
// geneticAnalysis implements the geneticAnalysis objects
// There are 2 geneticAnalysis types: Person and Couple
package geneticAnalysis
import "seekia/internal/genetics/locusValue"
type PersonAnalysis struct{
AnalysisVersion int
// This is a list of each raw genome identifier (not including combined genomes)
AllRawGenomeIdentifiersList [][16]byte
// This is true if there is more than 1 raw genome
CombinedGenomesExist bool
// These are the identifiers for the combined genomes
// These only exist if CombinedGenomesExist == true
OnlyIncludeSharedGenomeIdentifier [16]byte
OnlyExcludeConflictsGenomeIdentifier [16]byte
// Map Structure: Disease Name -> PersonMonogenicDiseaseInfo
MonogenicDiseasesMap map[string]PersonMonogenicDiseaseInfo
// Map Structure: Disease Name -> PersonPolygenicDiseaseInfo
PolygenicDiseasesMap map[string]PersonPolygenicDiseaseInfo
// Map Structure: Trait Name -> Trait Info Object
TraitsMap map[string]PersonTraitInfo
}
type PersonMonogenicDiseaseInfo struct{
// This map gives information about each genome's monogenic disease risk
// If no map entries exist, then no disease info is known
// Map Structure: Genome Identifier -> PersonGenomeMonogenicDiseaseInfo
MonogenicDiseaseInfoMap map[[16]byte]PersonGenomeMonogenicDiseaseInfo
// This is true if there are multiple genomes and the results for each genome differ
ConflictExists bool
}
type PersonGenomeMonogenicDiseaseInfo struct{
// This describes if the person has the disease
PersonHasDisease bool
// This describes the number of variants that were tested for this disease
NumberOfVariantsTested int
// This describes the number of loci that were tested for this disease
// 1 locus can have multiple potential variants
NumberOfLociTested int
// This describes the number of loci which are phased
// This number will always be <= NumberOfLociTested
NumberOfPhasedLoci int
// This describes the probability that the person will pass a disease variant
// It is a value that represents a percentage between 0-100
ProbabilityOfPassingADiseaseVariant int
// This map contains info about all tested monogenic disease variants for the genome
// If the map does not contain an item for a disease variant, then the genome does not contain information for that variant
// Map Structure: Variant Identifier -> PersonGenomeMonogenicDiseaseVariantInfo
VariantsInfoMap map[[3]byte]PersonGenomeMonogenicDiseaseVariantInfo
}
type PersonGenomeMonogenicDiseaseVariantInfo struct{
// These bools describe if each base has the variant at the variant's locus
Base1HasVariant bool
Base2HasVariant bool
// This bool describes if the bases are phased or not
// If they are not phased, then Base1/2 are the same, the number carries no meaning
// If they are phased, then Base1 is inherited from the father? and Base2 was inherited from the mother?
LocusIsPhased bool
}
type PersonPolygenicDiseaseInfo struct{
// If no map entries exist, then no disease info is known
// Map Structure: Genome Identifier -> PersonGenomePolygenicDiseaseInfo
PolygenicDiseaseInfoMap map[[16]byte]PersonGenomePolygenicDiseaseInfo
// This is true if there are multiple genomes and the results from each genome differ
ConflictExists bool
}
type PersonGenomePolygenicDiseaseInfo struct{
// This describes the number of loci tested for this disease
// This should be len(LociInfoList)
NumberOfLociTested int
// This is total risk score for this disease for the person's genome
// This is a number between 1-10
RiskScore int
// This map contains info about all tested polygenic disease loci for this genome
// If a locus does not exist in the map, its values are unknown
// Map Structure: Locus Identifier -> PersonGenomePolygenicDiseaseLocusInfo
LociInfoMap map[[3]byte]PersonGenomePolygenicDiseaseLocusInfo
}
type PersonGenomePolygenicDiseaseLocusInfo struct{
// The person's genome locus base pair value for this variant's locus
// Example: "G", "C"
LocusBase1 string
LocusBase2 string
// This is the risk weight that this person's genome has for this variant
// A higher risk weight means more risk of getting the disease
RiskWeight int
// This is valse if the odds ratio is not known
OddsRatioIsKnown bool
// This is the person's genome odds ratio value for this variant's locus
// A ratio >1 means their risk is increased, a ratio <1 means their risk is decreased
OddsRatio float64
}
type PersonTraitInfo struct{
// This map contains the person's trait info for each genome
// If no map entries exist, then no trait info is known
// Map Structure: Genome Identifier -> PersonGenomeTraitInfo
TraitInfoMap map[[16]byte]PersonGenomeTraitInfo
// This is true if there are multiple genomes and the results from each genome differ
ConflictExists bool
}
type PersonGenomeTraitInfo struct{
// This should be len(RulesList)
NumberOfRulesTested int
// This map contains the locus values for the genome
// If an locus's entry doesn't exist, its value is unknown
// Map Structure: Locus rsID -> Locus Value
LocusValuesMap map[int64]locusValue.LocusValue
// This map contains the outcome scores for the genome
// Map Structure: Outcome Name -> Score
// Example: "Intolerant" -> 5
OutcomeScoresMap map[string]int
// Map Structure: Rule Identifier -> Genome Passes rule (true if the genome passes the rule)
GenomePassesRulesMap map[[3]byte]bool
}
type CoupleAnalysis struct{
AnalysisVersion int
Pair1Person1GenomeIdentifier [16]byte
Pair1Person2GenomeIdentifier [16]byte
// This is only true if at least 1 person has more than 1 genome
SecondPairExists bool
// These are empty unless SecondPairExists == true
Pair2Person1GenomeIdentifier [16]byte
Pair2Person2GenomeIdentifier [16]byte
Person1HasMultipleGenomes bool
Person2HasMultipleGenomes bool
// These are empty unless Person1HasMultipleGenomes == true
Person1OnlyExcludeConflictsGenomeIdentifier [16]byte
Person1OnlyIncludeSharedGenomeIdentifier [16]byte
// These are empty unless Person2HasMultipleGenomes == true
Person2OnlyExcludeConflictsGenomeIdentifier [16]byte
Person2OnlyIncludeSharedGenomeIdentifier [16]byte
// Map Structure: Disease Name -> OffspringMonogenicDiseaseInfo
MonogenicDiseasesMap map[string]OffspringMonogenicDiseaseInfo
// Map Structure: Disease Name -> OffspringPolygenicDiseaseInfo
PolygenicDiseasesMap map[string]OffspringPolygenicDiseaseInfo
// Map Structure: Trait Name -> Trait Info Object
TraitsMap map[string]OffspringTraitInfo
}
type OffspringMonogenicDiseaseInfo struct{
// This map stores the number of variants tested in each person's genome
// Map Structure: Genome Identifier -> Number of variants tested
NumberOfVariantsTestedMap map[[16]byte]int
// This map stores the offspring disease probabilities for each genome pair.
// A genome pair is a concatenation of two genome identifiers
// If a map entry doesn't exist, the probabilities are unknown for that genome pair
// Map Structure: Genome Pair Identifier -> OffspringGenomePairMonogenicDiseaseInfo
MonogenicDiseaseInfoMap map[[32]byte]OffspringGenomePairMonogenicDiseaseInfo
// This is true if there is more than 1 genome pair and the results from each genome pair differ
ConflictExists bool
}
type OffspringGenomePairMonogenicDiseaseInfo struct{
// At least 1 variant's information is needed from either person to include the diseaseInfo object in the MonogenicDiseaseInfoMap
ProbabilityOffspringHasDiseaseIsKnown bool
// This is the probability that the offspring will have the disease
// Is a number between 0-100%
ProbabilityOffspringHasDisease int
ProbabilityOffspringHasVariantIsKnown bool
// This is the probability that the offspring will have a variant
// Is a number between 0-100%
ProbabilityOffspringHasVariant int
// Map Structure: Variant Identifier -> OffspringMonogenicDiseaseVariantInfo
VariantsInfoMap map[[3]byte]OffspringMonogenicDiseaseVariantInfo
}
type OffspringMonogenicDiseaseVariantInfo struct{
// These are all numbers between 0-100%
ProbabilityOf0MutationsLowerBound int
ProbabilityOf0MutationsUpperBound int
ProbabilityOf1MutationLowerBound int
ProbabilityOf1MutationUpperBound int
ProbabilityOf2MutationsLowerBound int
ProbabilityOf2MutationsUpperBound int
}
type OffspringPolygenicDiseaseInfo struct{
// This map stores the polygenic disease info for each genome pair
// Map Structure: Genome Pair Identifier -> OffspringGenomePairPolygenicDiseaseInfo
PolygenicDiseaseInfoMap map[[32]byte]OffspringGenomePairPolygenicDiseaseInfo
// This is true if there is more than 1 genome pair and the results from each genome pair differ
ConflictExists bool
}
type OffspringGenomePairPolygenicDiseaseInfo struct{
// This should be len(DiseaseLociList)
NumberOfLociTested int
// A number between 1-10 representing the offspring's risk
// 1 == lowest risk, 10 == highest risk
OffspringRiskScore int
// A map of the offspring's locus information
// Map Structure: Locus Identifier -> OffspringPolygenicDiseaseLocusInfo
LociInfoMap map[[3]byte]OffspringPolygenicDiseaseLocusInfo
}
type OffspringPolygenicDiseaseLocusInfo struct{
// This is the offspring's risk weight for this locus value
// A higher weight means a higher risk of the disease
OffspringRiskWeight int
OffspringOddsRatioIsKnown bool
// This value represent's the offspring's average odds ratio for the disease locus
// A value <1 denotes a lesser risk, a value >1 denotes an increased risk
OffspringOddsRatio float64
// This is the sum of weights for the loci which have no odds ratios
// We do this to understand what effect those loci are having on the odds ratio
// If the sum is <0, we say the ratio is probably lower
// If the sum is >0, we say the ratio is probably higher
OffspringUnknownOddsRatiosWeightSum int
}
type OffspringTraitInfo struct{
// This map stores the trait info for each genome pair
// Map Structure: Genome Pair Identifier -> OffspringGenomePairTraitInfo
TraitInfoMap map[[32]byte]OffspringGenomePairTraitInfo
ConflictExists bool
}
type OffspringGenomePairTraitInfo struct{
// This should be len(TraitRulesList)
NumberOfRulesTested int
// Map Structure: Outcome Name -> Outcome Score
// Example: "Intolerant" -> 2.5
OffspringAverageOutcomeScoresMap map[string]float64
// Map Structure: Rule Identifier -> Offspring Probability Of Passing Rule
// The value stores the probability that the offspring will pass the rule
// This is a number between 0-100%
ProbabilityOfPassingRulesMap map[[3]byte]int
}

View file

@ -4,12 +4,14 @@
package myAnalyses
import "seekia/internal/helpers"
import "seekia/internal/appMemory"
import "seekia/internal/appValues"
import "seekia/internal/encoding"
import "seekia/internal/helpers"
import "seekia/internal/localFilesystem"
import "seekia/internal/myDatastores/myMapList"
import "seekia/internal/genetics/createGeneticAnalysis"
import "seekia/internal/genetics/geneticAnalysis"
import "seekia/internal/genetics/prepareRawGenomes"
import "seekia/internal/genetics/readGeneticAnalysis"
import "seekia/internal/genetics/myGenomes"
@ -84,14 +86,14 @@ func DeleteAllAnalysesForPerson(personIdentifier string)error{
if (err != nil) { return err }
mapToDelete = map[string]string{
"PersonAIdentifier": personIdentifier,
"Person1Identifier": personIdentifier,
}
err = myCoupleAnalysesMapListDatastore.DeleteMapListItems(mapToDelete)
if (err != nil) { return err }
mapToDelete = map[string]string{
"PersonBIdentifier": personIdentifier,
"Person2Identifier": personIdentifier,
}
err = myCoupleAnalysesMapListDatastore.DeleteMapListItems(mapToDelete)
@ -100,17 +102,17 @@ func DeleteAllAnalysesForPerson(personIdentifier string)error{
return nil
}
func DeleteAllAnalysesForCouple(inputPersonAIdentifier string, inputPersonBIdentifier string)error{
func DeleteAllAnalysesForCouple(inputPerson1Identifier string, inputPerson2Identifier string)error{
updatingMyAnalysesMutex.Lock()
defer updatingMyAnalysesMutex.Unlock()
personAIdentifier, personBIdentifier, err := GetPeopleIdentifiersSortedForCouple(inputPersonAIdentifier, inputPersonBIdentifier)
person1Identifier, person2Identifier, err := GetPeopleIdentifiersSortedForCouple(inputPerson1Identifier, inputPerson2Identifier)
if (err != nil) { return err }
mapToDelete := map[string]string{
"PersonAIdentifier": personAIdentifier,
"PersonBIdentifier": personBIdentifier,
"Person1Identifier": person1Identifier,
"Person2Identifier": person2Identifier,
}
err = myCoupleAnalysesMapListDatastore.DeleteMapListItems(mapToDelete)
@ -120,18 +122,18 @@ func DeleteAllAnalysesForCouple(inputPersonAIdentifier string, inputPersonBIdent
}
// This function is used to sort the person identifiers, so that each pair of identifiers will only map to a single couple
// PersonA and PersonB will always follow this order within a couple analysis
// Person1 and Person2 will always follow this order within a couple analysis
// The sorting method has no significance
func GetPeopleIdentifiersSortedForCouple(personAIdentifier string, personBIdentifier string)(string, string, error){
func GetPeopleIdentifiersSortedForCouple(person1Identifier string, person2Identifier string)(string, string, error){
if (personAIdentifier == personBIdentifier){
return "", "", errors.New("GetPeopleIdentifiersSortedForCouple called with identical person identifiers: " + personAIdentifier)
if (person1Identifier == person2Identifier){
return "", "", errors.New("GetPeopleIdentifiersSortedForCouple called with identical person identifiers: " + person1Identifier)
}
if (personAIdentifier < personBIdentifier){
return personAIdentifier, personBIdentifier, nil
if (person1Identifier < person2Identifier){
return person1Identifier, person2Identifier, nil
}
return personBIdentifier, personAIdentifier, nil
return person2Identifier, person1Identifier, nil
}
@ -139,12 +141,12 @@ func GetPeopleIdentifiersSortedForCouple(personAIdentifier string, personBIdenti
// -bool: Any analysis exists
// -string: Newest analysis identifier
// -int64: Time newest analysis was performed
// -[]string: List of genomes analyzed
// -[][16]byte: List of genomes analyzed
// -bool: Newer analysis version available
// -This is not the same as new genomes being available. New version can be for the same genomes.
// -To fully determine if the analysis is up to date, we must check if new (or less) genomes are available to analyse for the person
// -error
func GetPersonNewestGeneticAnalysisInfo(personIdentifier string)(bool, string, int64, []string, bool, error){
func GetPersonNewestGeneticAnalysisInfo(personIdentifier string)(bool, string, int64, [][16]byte, bool, error){
lookupMap := map[string]string{
"PersonIdentifier": personIdentifier,
@ -162,7 +164,7 @@ func GetPersonNewestGeneticAnalysisInfo(personIdentifier string)(bool, string, i
newestAnalysisFound := false
newestAnalysisCreatedTime := int64(0)
newestAnalysisIdentifier := ""
newestAnalysisAnalyzedGenomesList := []string{}
newestAnalysisAnalyzedGenomesList := make([][16]byte, 0)
newerAnalysisVersionAvailable := false
for _, analysisMap := range analysisItemsMapList{
@ -204,6 +206,18 @@ func GetPersonNewestGeneticAnalysisInfo(personIdentifier string)(bool, string, i
analyzedGenomesList := strings.Split(analyzedGenomes, "+")
analyzedGenomesArrayList := make([][16]byte, 0)
for _, genomeIdentifierHex := range analyzedGenomesList{
genomeIdentifier, err := encoding.DecodeHexStringTo16ByteArray(genomeIdentifierHex)
if (err != nil){
return false, "", 0, nil, false, errors.New("Malformed myAnalysesMapList: Item contains invalid AnalyzedGenomes: " + analyzedGenomes)
}
analyzedGenomesArrayList = append(analyzedGenomesArrayList, genomeIdentifier)
}
analysisVersion, exists := analysisMap["AnalysisVersion"]
if (exists == false) {
return false, "", 0, nil, false, errors.New("Malformed myAnalysesMapList: Item missing AnalysisVersion")
@ -224,7 +238,7 @@ func GetPersonNewestGeneticAnalysisInfo(personIdentifier string)(bool, string, i
newestAnalysisCreatedTime = timeCreatedInt64
newestAnalysisIdentifier = analysisIdentifier
newestAnalysisAnalyzedGenomesList = analyzedGenomesList
newestAnalysisAnalyzedGenomesList = analyzedGenomesArrayList
}
if (newestAnalysisFound == false){
@ -238,20 +252,20 @@ func GetPersonNewestGeneticAnalysisInfo(personIdentifier string)(bool, string, i
// -bool: Analysis exists
// -string: Newest analysis identifier
// -int64: Time newest analysis was performed
// -[]string: Person A list of genomes analyzed
// -[]string: Person B list of genomes analyzed
// -[][16]byte: Person A list of genomes analyzed
// -[][16]byte: Person B list of genomes analyzed
// -bool: Newer analysis version available
// -This is not the same as new genomes being available. New version can be for the same genomes.
// -To fully determine if the analysis is up to date, we must check if new (or less) genomes are available to analyse for the person
// -error
func GetCoupleNewestGeneticAnalysisInfo(inputPersonAIdentifier string, inputPersonBIdentifier string)(bool, string, int64, []string, []string, bool, error){
func GetCoupleNewestGeneticAnalysisInfo(inputPerson1Identifier string, inputPerson2Identifier string)(bool, string, int64, [][16]byte, [][16]byte, bool, error){
personAIdentifier, personBIdentifier, err := GetPeopleIdentifiersSortedForCouple(inputPersonAIdentifier, inputPersonBIdentifier)
person1Identifier, person2Identifier, err := GetPeopleIdentifiersSortedForCouple(inputPerson1Identifier, inputPerson2Identifier)
if (err != nil) { return false, "", 0, nil, nil, false, err }
lookupMap := map[string]string{
"PersonAIdentifier": personAIdentifier,
"PersonBIdentifier": personBIdentifier,
"Person1Identifier": person1Identifier,
"Person2Identifier": person2Identifier,
}
anyItemsFound, analysisItemsMapList, err := myCoupleAnalysesMapListDatastore.GetMapListItems(lookupMap)
@ -266,28 +280,28 @@ func GetCoupleNewestGeneticAnalysisInfo(inputPersonAIdentifier string, inputPers
newestAnalysisFound := false
newestAnalysisCreatedTime := int64(0)
newestAnalysisIdentifier := ""
newestAnalysisPersonAAnalyzedGenomesList := []string{}
newestAnalysisPersonBAnalyzedGenomesList := []string{}
newestAnalysisPerson1AnalyzedGenomesList := [][16]byte{}
newestAnalysisPerson2AnalyzedGenomesList := [][16]byte{}
newerAnalysisVersionAvailable := false
for _, analysisMap := range analysisItemsMapList{
currentPersonAIdentifier, exists := analysisMap["PersonAIdentifier"]
currentPerson1Identifier, exists := analysisMap["Person1Identifier"]
if (exists == false) {
return false, "", 0, nil, nil, false, errors.New("Malformed myAnalysesMapList: Item missing PersonAIdentifier")
return false, "", 0, nil, nil, false, errors.New("Malformed myAnalysesMapList: Item missing Person1Identifier")
}
if (personAIdentifier != currentPersonAIdentifier){
return false, "", 0, nil, nil, false, errors.New("GetMapListItems returning map with different personAIdentifier.")
if (person1Identifier != currentPerson1Identifier){
return false, "", 0, nil, nil, false, errors.New("GetMapListItems returning map with different person1Identifier.")
}
currentPersonBIdentifier, exists := analysisMap["PersonBIdentifier"]
currentPerson2Identifier, exists := analysisMap["Person2Identifier"]
if (exists == false) {
return false, "", 0, nil, nil, false, errors.New("Malformed myAnalysesMapList: Item missing PersonBIdentifier")
return false, "", 0, nil, nil, false, errors.New("Malformed myAnalysesMapList: Item missing Person2Identifier")
}
if (personBIdentifier != currentPersonBIdentifier){
return false, "", 0, nil, nil, false, errors.New("GetMapListItems returning map with different personBIdentifier.")
if (person2Identifier != currentPerson2Identifier){
return false, "", 0, nil, nil, false, errors.New("GetMapListItems returning map with different person2Identifier.")
}
timeCreated, exists := analysisMap["TimeCreated"]
@ -310,19 +324,41 @@ func GetCoupleNewestGeneticAnalysisInfo(inputPersonAIdentifier string, inputPers
return false, "", 0, nil, nil, false, errors.New("Malformed myAnalysesMapList: Item missing AnalysisIdentifier")
}
personAAnalyzedGenomes, exists := analysisMap["PersonAAnalyzedGenomes"]
person1AnalyzedGenomes, exists := analysisMap["Person1AnalyzedGenomes"]
if (exists == false) {
return false, "", 0, nil, nil, false, errors.New("Malformed myAnalysesMapList: Item missing PersonAAnalyzedGenomes")
return false, "", 0, nil, nil, false, errors.New("Malformed myAnalysesMapList: Item missing Person1AnalyzedGenomes")
}
personAAnalyzedGenomesList := strings.Split(personAAnalyzedGenomes, "+")
personBAnalyzedGenomes, exists := analysisMap["PersonBAnalyzedGenomes"]
person2AnalyzedGenomes, exists := analysisMap["Person2AnalyzedGenomes"]
if (exists == false) {
return false, "", 0, nil, nil, false, errors.New("Malformed myAnalysesMapList: Item missing PersonBAnalyzedGenomes")
return false, "", 0, nil, nil, false, errors.New("Malformed myAnalysesMapList: Item missing Person2AnalyzedGenomes")
}
personBAnalyzedGenomesList := strings.Split(personBAnalyzedGenomes, "+")
person1AnalyzedGenomesList := strings.Split(person1AnalyzedGenomes, "+")
person2AnalyzedGenomesList := strings.Split(person2AnalyzedGenomes, "+")
person1AnalyzedGenomesArrayList := make([][16]byte, 0)
person2AnalyzedGenomesArrayList := make([][16]byte, 0)
for _, genomeIdentifierHex := range person1AnalyzedGenomesList{
genomeIdentifier, err := encoding.DecodeHexStringTo16ByteArray(genomeIdentifierHex)
if (err != nil){
return false, "", 0, nil, nil, false, errors.New("Malformed myCoupleAnalysesMapListDatastore: Item contains invalid Person1AnalyzedGenomes: " + person1AnalyzedGenomes)
}
person1AnalyzedGenomesArrayList = append(person1AnalyzedGenomesArrayList, genomeIdentifier)
}
for _, genomeIdentifierHex := range person2AnalyzedGenomesList{
genomeIdentifier, err := encoding.DecodeHexStringTo16ByteArray(genomeIdentifierHex)
if (err != nil){
return false, "", 0, nil, nil, false, errors.New("Malformed myCoupleAnalysesMapListDatastore: Item contains invalid Person2AnalyzedGenomes: " + person1AnalyzedGenomes)
}
person2AnalyzedGenomesArrayList = append(person2AnalyzedGenomesArrayList, genomeIdentifier)
}
analysisVersion, exists := analysisMap["AnalysisVersion"]
if (exists == false) {
@ -344,54 +380,83 @@ func GetCoupleNewestGeneticAnalysisInfo(inputPersonAIdentifier string, inputPers
newestAnalysisCreatedTime = timeCreatedInt64
newestAnalysisIdentifier = analysisIdentifier
newestAnalysisPersonAAnalyzedGenomesList = personAAnalyzedGenomesList
newestAnalysisPersonBAnalyzedGenomesList = personBAnalyzedGenomesList
newestAnalysisPerson1AnalyzedGenomesList = person1AnalyzedGenomesArrayList
newestAnalysisPerson2AnalyzedGenomesList = person2AnalyzedGenomesArrayList
}
if (newestAnalysisFound == false){
return false, "", 0, nil, nil, false, errors.New("GetMapListItems not returning any items when anyItemsFound == true.")
}
// We have to return the personA/PersonB analyzed genomes list in the same order that they came in
// We have to return the person1/Person2 analyzed genomes list in the same order that they came in
if (inputPersonAIdentifier == personAIdentifier){
if (inputPerson1Identifier == person1Identifier){
// No swapping happened.
return true, newestAnalysisIdentifier, newestAnalysisCreatedTime, newestAnalysisPersonAAnalyzedGenomesList, newestAnalysisPersonBAnalyzedGenomesList, newerAnalysisVersionAvailable, nil
return true, newestAnalysisIdentifier, newestAnalysisCreatedTime, newestAnalysisPerson1AnalyzedGenomesList, newestAnalysisPerson2AnalyzedGenomesList, newerAnalysisVersionAvailable, nil
}
// We swap the personA/PersonB analyzed genomes lists
// We swap the person1/Person2 analyzed genomes lists
return true, newestAnalysisIdentifier, newestAnalysisCreatedTime, newestAnalysisPersonBAnalyzedGenomesList, newestAnalysisPersonAAnalyzedGenomesList, newerAnalysisVersionAvailable, nil
return true, newestAnalysisIdentifier, newestAnalysisCreatedTime, newestAnalysisPerson2AnalyzedGenomesList, newestAnalysisPerson1AnalyzedGenomesList, newerAnalysisVersionAvailable, nil
}
// This function should only be used to retrieve an existing analysis
// It can be used for person and couple genetic analyses
//Outputs:
// -bool: Analysis found
// -[]map[string]string: Analysis map list
// -geneticAnalysis.PersonAnalysis Analysis object
// -error
func GetGeneticAnalysis(analysisIdentifier string)(bool, []map[string]string, error){
func GetPersonGeneticAnalysis(analysisIdentifier string)(bool, geneticAnalysis.PersonAnalysis, error){
analysisFound, analysisFileString, err := getGeneticAnalysisFileString(analysisIdentifier)
if (err != nil) { return false, geneticAnalysis.PersonAnalysis{}, err }
if (analysisFound == false){
return false, geneticAnalysis.PersonAnalysis{}, nil
}
analysisObject, err := readGeneticAnalysis.ReadPersonGeneticAnalysisString(analysisFileString)
if (err != nil) { return false, geneticAnalysis.PersonAnalysis{}, err }
return true, analysisObject, nil
}
// This function should only be used to retrieve an existing analysis
//Outputs:
// -bool: Analysis found
// -geneticAnalysis.CoupleAnalysis Analysis object
// -error
func GetCoupleGeneticAnalysis(analysisIdentifier string)(bool, geneticAnalysis.CoupleAnalysis, error){
analysisFound, analysisFileString, err := getGeneticAnalysisFileString(analysisIdentifier)
if (err != nil) { return false, geneticAnalysis.CoupleAnalysis{}, err }
if (analysisFound == false){
return false, geneticAnalysis.CoupleAnalysis{}, nil
}
analysisObject, err := readGeneticAnalysis.ReadCoupleGeneticAnalysisString(analysisFileString)
if (err != nil) { return false, geneticAnalysis.CoupleAnalysis{}, err }
return true, analysisObject, nil
}
func getGeneticAnalysisFileString(analysisIdentifier string)(bool, string, error){
userDirectory, err := localFilesystem.GetAppUserFolderPath()
if (err != nil) { return false, nil, err }
if (err != nil) { return false, "", err }
analysisFileName := analysisIdentifier + ".json"
analysisFileName := analysisIdentifier + ".messagepack"
analysisFilePath := filepath.Join(userDirectory, "MyAnalyses", analysisFileName)
fileExists, fileBytes, err := localFilesystem.GetFileContents(analysisFilePath)
if (err != nil) { return false, nil, err }
if (err != nil) { return false, "", err }
if (fileExists == false){
return false, nil, nil
return false, "", nil
}
fileString := string(fileBytes)
analysisMapList, err := readGeneticAnalysis.ReadGeneticAnalysisString(fileString)
if (err != nil) { return false, nil, err }
return true, analysisMapList, nil
return true, fileString, nil
}
// This map keeps track of current person analyses being generated
@ -401,7 +466,7 @@ var personAnalysisProcessesMap map[string]string = make(map[string]string)
var personAnalysisProcessesMapMutex sync.RWMutex
// This map keeps track of current couple analyses being generated
// Map structure: PersonAIdentifier + "+" + PersonBIdentifier -> Process identifier
// Map structure: Person1Identifier + "+" + Person2Identifier -> Process identifier
var coupleAnalysisProcessesMap map[string]string = make(map[string]string)
var coupleAnalysisProcessesMapMutex sync.RWMutex
@ -429,12 +494,12 @@ func GetPersonGeneticAnalysisProcessIdentifier(personIdentifier string)(bool, st
// -bool: Any process found (The process may be complete)
// -string: Process identifier
// -error
func GetCoupleGeneticAnalysisProcessIdentifier(inputPersonAIdentifier string, inputPersonBIdentifier string)(bool, string, error){
func GetCoupleGeneticAnalysisProcessIdentifier(inputPerson1Identifier string, inputPerson2Identifier string)(bool, string, error){
personAIdentifier, personBIdentifier, err := GetPeopleIdentifiersSortedForCouple(inputPersonAIdentifier, inputPersonBIdentifier)
person1Identifier, person2Identifier, err := GetPeopleIdentifiersSortedForCouple(inputPerson1Identifier, inputPerson2Identifier)
if (err != nil) { return false, "", err }
coupleIdentifier := personAIdentifier + "+" + personBIdentifier
coupleIdentifier := person1Identifier + "+" + person2Identifier
coupleAnalysisProcessesMapMutex.RLock()
processIdentifier, exists := coupleAnalysisProcessesMap[coupleIdentifier]
@ -576,22 +641,25 @@ func StartCreateNewPersonGeneticAnalysis(personIdentifier string)(string, error)
return errors.New("GetAllPersonGenomesMapList returning genome for different person.")
}
genomeIdentifier, exists := genomeMap["GenomeIdentifier"]
genomeIdentifierHex, exists := genomeMap["GenomeIdentifier"]
if (exists == false) {
return errors.New("PersonGenomesMapList malformed: Item missing GenomeIdentifier")
}
genomeIdentifier, err := encoding.DecodeHexStringTo16ByteArray(genomeIdentifierHex)
if (err != nil) { return err }
genomeRawDataString, err := myGenomes.GetGenomeRawDataString(genomeIdentifier)
if (err != nil) { return err }
rawGenomeIsValid, rawGenomeWithMetadata, err := prepareRawGenomes.CreateRawGenomeWithMetadataObject(genomeIdentifier, genomeRawDataString)
if (err != nil) { return err }
if (rawGenomeIsValid == false){
return errors.New("myGenomes contains invalid rawGenomeDataString: " + genomeIdentifier)
return errors.New("myGenomes contains invalid rawGenomeDataString: " + genomeIdentifierHex)
}
genomesList = append(genomesList, rawGenomeWithMetadata)
genomeIdentifiersList = append(genomeIdentifiersList, genomeIdentifier)
genomeIdentifiersList = append(genomeIdentifiersList, genomeIdentifierHex)
}
analysisUpdatePercentageCompleteFunction := func(inputProgress int)error{
@ -642,7 +710,7 @@ func StartCreateNewPersonGeneticAnalysis(personIdentifier string)(string, error)
myAnalysesFolderPath := filepath.Join(userDirectory, "MyAnalyses")
analysisFileName := analysisIdentifier + ".json"
analysisFileName := analysisIdentifier + ".messagepack"
err = localFilesystem.CreateOrOverwriteFile([]byte(newGeneticAnalysisString), myAnalysesFolderPath, analysisFileName)
if (err != nil) { return err }
@ -677,12 +745,12 @@ func StartCreateNewPersonGeneticAnalysis(personIdentifier string)(string, error)
//Outputs:
// -string: New process identifier
// -error
func StartCreateNewCoupleGeneticAnalysis(inputPersonAIdentifier string, inputPersonBIdentifier string)(string, error){
func StartCreateNewCoupleGeneticAnalysis(inputPerson1Identifier string, inputPerson2Identifier string)(string, error){
personAIdentifier, personBIdentifier, err := GetPeopleIdentifiersSortedForCouple(inputPersonAIdentifier, inputPersonBIdentifier)
person1Identifier, person2Identifier, err := GetPeopleIdentifiersSortedForCouple(inputPerson1Identifier, inputPerson2Identifier)
if (err != nil) { return "", err }
coupleIdentifier := personAIdentifier + "+" + personBIdentifier
coupleIdentifier := person1Identifier + "+" + person2Identifier
coupleAnalysisProcessesMapMutex.Lock()
existingProcessIdentifier, exists := coupleAnalysisProcessesMap[coupleIdentifier]
@ -732,11 +800,11 @@ func StartCreateNewCoupleGeneticAnalysis(inputPersonAIdentifier string, inputPer
return false
}
// We need both personA and personB to have an analysis before performing the couple analysis
// We need both person1 and person2 to have an analysis before performing the couple analysis
// We will see if an analysis is already running for each person
// We will either start a new analysis for each person or monitor the existing one until it is done
personIdentifiersList := []string{personAIdentifier, personBIdentifier}
personIdentifiersList := []string{person1Identifier, person2Identifier}
for index, personIdentifier := range personIdentifiersList{
@ -777,7 +845,7 @@ func StartCreateNewCoupleGeneticAnalysis(inputPersonAIdentifier string, inputPer
return true, nil
}
allPersonRawGenomeIdentifiersList, err := myGenomes.GetAllPersonRawGenomeIdentifiersList(personAIdentifier)
allPersonRawGenomeIdentifiersList, err := myGenomes.GetAllPersonRawGenomeIdentifiersList(person1Identifier)
if (err != nil) { return false, err }
genomesAreIdentical := helpers.CheckIfTwoListsContainIdenticalItems(allPersonRawGenomeIdentifiersList, newestPersonAnalysisListOfGenomesAnalyzed)
@ -873,33 +941,36 @@ func StartCreateNewCoupleGeneticAnalysis(inputPersonAIdentifier string, inputPer
return nil, nil, errors.New("GetAllPersonGenomesMapList returning genome for different person.")
}
genomeIdentifier, exists := genomeMap["GenomeIdentifier"]
genomeIdentifierHex, exists := genomeMap["GenomeIdentifier"]
if (exists == false) {
return nil, nil, errors.New("PersonGenomesMapList malformed: Item missing GenomeIdentifier")
}
genomeIdentifier, err := encoding.DecodeHexStringTo16ByteArray(genomeIdentifierHex)
if (err != nil) { return nil, nil, err }
genomeRawDataString, err := myGenomes.GetGenomeRawDataString(genomeIdentifier)
if (err != nil) { return nil, nil, err }
rawGenomeIsValid, rawGenomeWithMetadata, err := prepareRawGenomes.CreateRawGenomeWithMetadataObject(genomeIdentifier, genomeRawDataString)
if (err != nil) { return nil, nil, err }
if (rawGenomeIsValid == false){
return nil, nil, errors.New("myGenomes contains invalid rawGenomeDataString: " + genomeIdentifier)
return nil, nil, errors.New("myGenomes contains invalid rawGenomeDataString: " + genomeIdentifierHex)
}
genomesList = append(genomesList, rawGenomeWithMetadata)
genomeIdentifiersList = append(genomeIdentifiersList, genomeIdentifier)
genomeIdentifiersList = append(genomeIdentifiersList, genomeIdentifierHex)
}
return genomesList, genomeIdentifiersList, nil
}
personAGenomesList, personARawGenomeIdentifiersList, err := getPersonGenomesList(personAIdentifier)
person1GenomesList, person1RawGenomeIdentifiersList, err := getPersonGenomesList(person1Identifier)
if (err != nil) { return err }
updatePercentageCompleteFunction(70)
personBGenomesList, personBRawGenomeIdentifiersList, err := getPersonGenomesList(personBIdentifier)
person2GenomesList, person2RawGenomeIdentifiersList, err := getPersonGenomesList(person2Identifier)
if (err != nil) { return err }
updatePercentageCompleteFunction(74)
@ -915,15 +986,15 @@ func StartCreateNewCoupleGeneticAnalysis(inputPersonAIdentifier string, inputPer
return nil
}
processCompleted, newGeneticAnalysisString, err := createGeneticAnalysis.CreateCoupleGeneticAnalysis(personAGenomesList, personBGenomesList, updateCoupleAnalysisPercentageCompleteFunction, checkIfProcessIsStopped)
processCompleted, newGeneticAnalysisString, err := createGeneticAnalysis.CreateCoupleGeneticAnalysis(person1GenomesList, person2GenomesList, updateCoupleAnalysisPercentageCompleteFunction, checkIfProcessIsStopped)
if (err != nil) { return err }
if (processCompleted == false){
// User stopped the analysis mid-way
return nil
}
personAAnalyzedGenomesListString := strings.Join(personARawGenomeIdentifiersList, "+")
personBAnalyzedGenomesListString := strings.Join(personBRawGenomeIdentifiersList, "+")
person1AnalyzedGenomesListString := strings.Join(person1RawGenomeIdentifiersList, "+")
person2AnalyzedGenomesListString := strings.Join(person2RawGenomeIdentifiersList, "+")
analysisIdentifier, err := helpers.GetNewRandomHexString(17)
if (err != nil) { return err }
@ -935,12 +1006,12 @@ func StartCreateNewCoupleGeneticAnalysis(inputPersonAIdentifier string, inputPer
currentAnalysisVersionString := helpers.ConvertIntToString(currentAnalysisVersion)
newAnalysisMap := map[string]string{
"PersonAIdentifier": personAIdentifier,
"PersonBIdentifier": personBIdentifier,
"Person1Identifier": person1Identifier,
"Person2Identifier": person2Identifier,
"AnalysisIdentifier": analysisIdentifier,
"TimeCreated": currentTimeString,
"PersonAAnalyzedGenomes": personAAnalyzedGenomesListString,
"PersonBAnalyzedGenomes": personBAnalyzedGenomesListString,
"Person1AnalyzedGenomes": person1AnalyzedGenomesListString,
"Person2AnalyzedGenomes": person2AnalyzedGenomesListString,
"AnalysisVersion": currentAnalysisVersionString,
}
@ -955,7 +1026,7 @@ func StartCreateNewCoupleGeneticAnalysis(inputPersonAIdentifier string, inputPer
myAnalysesFolderPath := filepath.Join(userDirectory, "MyAnalyses")
analysisFileName := analysisIdentifier + ".json"
analysisFileName := analysisIdentifier + ".messagepack"
err = localFilesystem.CreateOrOverwriteFile([]byte(newGeneticAnalysisString), myAnalysesFolderPath, analysisFileName)
if (err != nil) { return err }

View file

@ -8,11 +8,10 @@
package myChosenAnalysis
import "seekia/internal/genetics/geneticAnalysis"
import "seekia/internal/genetics/myAnalyses"
import "seekia/internal/genetics/myPeople"
import "seekia/internal/genetics/readGeneticAnalysis"
import "seekia/internal/helpers"
import "seekia/internal/profiles/myLocalProfiles"
import "errors"
@ -27,12 +26,12 @@ var myCacheChosenGeneticAnalysisMutex sync.RWMutex
var myCacheChosenGeneticAnalysisIdentifier string
// We use this variable to store the analysis in memory
// This prevents us from having to read and unmarshal the json file each time we want to retrieve the analysis
// This prevents us from having to read and unmarshal the messagepack file each time we want to retrieve the analysis
// TODO: Read attributes from the analysis into maps for faster retrieval
var myCacheChosenGeneticAnalysis []map[string]string
var myCacheChosenGeneticAnalysis geneticAnalysis.PersonAnalysis
// These variables store metadata about the cache genetic analysis
var myCacheChosenGeneticAnalysis_GenomeIdentifierToUse string
var myCacheChosenGeneticAnalysis_GenomeIdentifierToUse [16]byte
// This variable tells us if the current cache chosen genetic analysis contains multiple genomes
var myCacheChosenGeneticAnalysis_MultipleGenomesExist bool
@ -41,31 +40,35 @@ var myCacheChosenGeneticAnalysis_MultipleGenomesExist bool
// The user must choose a person to link to their mate profile/identity
// This genetic analysis is not shared on the person's profile publicly.
// Portions of the analysis may be shared if the user opts in.
// The analysis returned by this function is not a copy, so fields must not be edited
//Outputs:
// -bool: Person identifier chosen
// -bool: Any genomes exist
// -bool: Person analysis is ready
// -[]map[string]string: Genetic analysis map list
// -string: Genome identifier to use
// -geneticAnalysis.PersonAnalysis: My Chosen Genetic analysis
// -[16]byte: Genome identifier to use
// -bool: Multiple genomes exist
// -error
func GetMyChosenMateGeneticAnalysis()(bool, bool, bool, []map[string]string, string, bool, error){
func GetMyChosenMateGeneticAnalysis()(bool, bool, bool, geneticAnalysis.PersonAnalysis, [16]byte, bool, error){
// We use this when returning errors
emptyPersonAnalysis := geneticAnalysis.PersonAnalysis{}
// We check if the user has added a genome person, and add their genome info if necessary
myGenomePersonIdentifierExists, myGenomePersonIdentifier, err := myLocalProfiles.GetProfileData("Mate", "GenomePersonIdentifier")
if (err != nil){ return false, false, false, nil, "", false, err }
if (err != nil){ return false, false, false, emptyPersonAnalysis, [16]byte{}, false, err }
if (myGenomePersonIdentifierExists == false){
return false, false, false, nil, "", false, nil
return false, false, false, emptyPersonAnalysis, [16]byte{}, false, nil
}
anyGenomesExist, personAnalysisIsReady, personAnalysisIdentifier, err := myPeople.CheckIfPersonAnalysisIsReady(myGenomePersonIdentifier)
if (err != nil){ return false, false, false, nil, "", false, err }
if (err != nil){ return false, false, false, emptyPersonAnalysis, [16]byte{}, false, err }
if (anyGenomesExist == false){
return true, false, false, nil, "", false, nil
return true, false, false, emptyPersonAnalysis, [16]byte{}, false, nil
}
if (personAnalysisIsReady == false){
return true, true, false, nil, "", false, nil
return true, true, false, emptyPersonAnalysis, [16]byte{}, false, nil
}
myCacheChosenGeneticAnalysisMutex.RLock()
@ -78,7 +81,8 @@ func GetMyChosenMateGeneticAnalysis()(bool, bool, bool, []map[string]string, str
myCacheChosenGeneticAnalysisMutex.RLock()
myCacheChosenGeneticAnalysisCopy := helpers.DeepCopyStringToStringMapList(myCacheChosenGeneticAnalysis)
// This is a shallow copy, but it is all we need, because we never directly edit attributes of the returned object
myCacheChosenGeneticAnalysisCopy := myCacheChosenGeneticAnalysis
myCacheChosenGeneticAnalysis_GenomeIdentifierToUseCopy := myCacheChosenGeneticAnalysis_GenomeIdentifierToUse
myCacheChosenGeneticAnalysis_MultipleGenomesExistCopy := myCacheChosenGeneticAnalysis_MultipleGenomesExist
@ -89,18 +93,18 @@ func GetMyChosenMateGeneticAnalysis()(bool, bool, bool, []map[string]string, str
}
// The analysis and its metadata have not been read into the cache yet
// We will retrieve it from its .json file
// We will retrieve it from its .messagepack file
myAnalysisFound, myGeneticAnalysisMapList, err := myAnalyses.GetGeneticAnalysis(personAnalysisIdentifier)
if (err != nil){ return false, false, false, nil, "", false, err }
myAnalysisFound, myGeneticAnalysisObject, err := myAnalyses.GetPersonGeneticAnalysis(personAnalysisIdentifier)
if (err != nil){ return false, false, false, emptyPersonAnalysis, [16]byte{}, false, err }
if (myAnalysisFound == false){
return false, false, false, nil, "", false, errors.New("CheckIfPersonAnalysisIsReady returning missing genetic analysis.")
return false, false, false, emptyPersonAnalysis, [16]byte{}, false, errors.New("CheckIfPersonAnalysisIsReady returning missing genetic analysis.")
}
allRawGenomeIdentifiersList, multipleGenomesExist, onlyExcludeConflictsGenomeIdentifier, onlyIncludeSharedGenomeIdentifier, err := readGeneticAnalysis.GetMetadataFromPersonGeneticAnalysis(myGeneticAnalysisMapList)
if (err != nil) { return false, false, false, nil, "", false, err }
allRawGenomeIdentifiersList, multipleGenomesExist, onlyExcludeConflictsGenomeIdentifier, onlyIncludeSharedGenomeIdentifier, err := readGeneticAnalysis.GetMetadataFromPersonGeneticAnalysis(myGeneticAnalysisObject)
if (err != nil) { return false, false, false, emptyPersonAnalysis, [16]byte{}, false, err }
getGenomeIdentifierToUse := func()(string, error){
getGenomeIdentifierToUse := func()([16]byte, error){
if (multipleGenomesExist == false){
@ -111,7 +115,7 @@ func GetMyChosenMateGeneticAnalysis()(bool, bool, bool, []map[string]string, str
}
currentCombinedGenomeToUse, err := GetMyCombinedGenomeToUse()
if (err != nil){ return "", err }
if (err != nil){ return [16]byte{}, err }
if (currentCombinedGenomeToUse == "Only Exclude Conflicts"){
return onlyExcludeConflictsGenomeIdentifier, nil
@ -121,16 +125,16 @@ func GetMyChosenMateGeneticAnalysis()(bool, bool, bool, []map[string]string, str
}
genomeIdentifierToUse, err := getGenomeIdentifierToUse()
if (err != nil) { return false, false, false, nil, "", false, err }
if (err != nil) { return false, false, false, emptyPersonAnalysis, [16]byte{}, false, err }
myCacheChosenGeneticAnalysisMutex.Lock()
myCacheChosenGeneticAnalysisIdentifier = personAnalysisIdentifier
myCacheChosenGeneticAnalysis = myGeneticAnalysisMapList
myCacheChosenGeneticAnalysis = myGeneticAnalysisObject
myCacheChosenGeneticAnalysis_GenomeIdentifierToUse = genomeIdentifierToUse
myCacheChosenGeneticAnalysis_MultipleGenomesExist = multipleGenomesExist
myChosenGeneticAnalysisCopy := helpers.DeepCopyStringToStringMapList(myGeneticAnalysisMapList)
myChosenGeneticAnalysisCopy := myGeneticAnalysisObject
myCacheChosenGeneticAnalysisMutex.Unlock()
@ -170,8 +174,8 @@ func SetMyCombinedGenomeToUse(combinedGenomeToUse string)error{
myCacheChosenGeneticAnalysisMutex.Lock()
myCacheChosenGeneticAnalysisIdentifier = ""
myCacheChosenGeneticAnalysis = nil
myCacheChosenGeneticAnalysis_GenomeIdentifierToUse = ""
myCacheChosenGeneticAnalysis = geneticAnalysis.PersonAnalysis{}
myCacheChosenGeneticAnalysis_GenomeIdentifierToUse = [16]byte{}
myCacheChosenGeneticAnalysis_MultipleGenomesExist = false
myCacheChosenGeneticAnalysisMutex.Unlock()

View file

@ -31,8 +31,8 @@ func InitializeMyGenomeCouplesDatastore()error{
//Outputs:
// -[]map[string]string
// -PersonAIdentifier -> Person A Identifier
// -PersonBIdentifier -> Person B Identifier
// -Person1Identifier -> Person 1 Identifier
// -Person2Identifier -> Person 2 Identifier
// -error
func GetMyGenomeCouplesMapList()([]map[string]string, error){
@ -45,9 +45,9 @@ func GetMyGenomeCouplesMapList()([]map[string]string, error){
//Outputs:
// -bool: Couple already exists
// -error
func AddCouple(inputPersonAIdentifier string, inputPersonBIdentifier string)(bool, error){
personAIdentifier, personBIdentifier, err := getPeopleIdentifiersSortedForCouple(inputPersonAIdentifier, inputPersonBIdentifier)
func AddCouple(inputPerson1Identifier string, inputPerson2Identifier string)(bool, error){
person1Identifier, person2Identifier, err := getPeopleIdentifiersSortedForCouple(inputPerson1Identifier, inputPerson2Identifier)
if (err != nil) { return false, err }
updatingMyCouplesMutex.Lock()
@ -58,17 +58,17 @@ func AddCouple(inputPersonAIdentifier string, inputPersonBIdentifier string)(boo
for _, coupleMap := range couplesMapList{
currentPersonAIdentifier, exists := coupleMap["PersonAIdentifier"]
currentPerson1Identifier, exists := coupleMap["Person1Identifier"]
if (exists == false){
return false, errors.New("MyGenomeCouplesMapList malformed: Contains entry missing PersonAIdentifier")
return false, errors.New("MyGenomeCouplesMapList malformed: Contains entry missing Person1Identifier")
}
currentPersonBIdentifier, exists := coupleMap["PersonBIdentifier"]
currentPerson2Identifier, exists := coupleMap["Person2Identifier"]
if (exists == false){
return false, errors.New("MyGenomeCouplesMapList malformed: Contains entry missing PersonBIdentifier")
return false, errors.New("MyGenomeCouplesMapList malformed: Contains entry missing Person2Identifier")
}
if (currentPersonAIdentifier == personAIdentifier && currentPersonBIdentifier == personBIdentifier){
if (currentPerson1Identifier == person1Identifier && currentPerson2Identifier == person2Identifier){
return true, nil
}
}
@ -76,8 +76,8 @@ func AddCouple(inputPersonAIdentifier string, inputPersonBIdentifier string)(boo
// Couple does not exist. We add it.
newPersonMap := map[string]string{
"PersonAIdentifier": personAIdentifier,
"PersonBIdentifier": personBIdentifier,
"Person1Identifier": person1Identifier,
"Person2Identifier": person2Identifier,
}
newCouplesMapList := append(couplesMapList, newPersonMap)
@ -88,23 +88,23 @@ func AddCouple(inputPersonAIdentifier string, inputPersonBIdentifier string)(boo
return false, nil
}
func DeleteCouple(inputPersonAIdentifier string, inputPersonBIdentifier string)error{
func DeleteCouple(inputPerson1Identifier string, inputPerson2Identifier string)error{
personAIdentifier, personBIdentifier, err := getPeopleIdentifiersSortedForCouple(inputPersonAIdentifier, inputPersonBIdentifier)
person1Identifier, person2Identifier, err := getPeopleIdentifiersSortedForCouple(inputPerson1Identifier, inputPerson2Identifier)
if (err != nil) { return err }
updatingMyCouplesMutex.Lock()
defer updatingMyCouplesMutex.Unlock()
mapToDelete := map[string]string{
"PersonAIdentifier": personAIdentifier,
"PersonBIdentifier": personBIdentifier,
"Person1Identifier": person1Identifier,
"Person2Identifier": person2Identifier,
}
err = myGenomeCouplesMapListDatastore.DeleteMapListItems(mapToDelete)
if (err != nil) { return err }
err = myAnalyses.DeleteAllAnalysesForCouple(personAIdentifier, personBIdentifier)
err = myAnalyses.DeleteAllAnalysesForCouple(person1Identifier, person2Identifier)
if (err != nil) { return err }
return nil
@ -115,18 +115,18 @@ func DeleteAllCouplesForPerson(personIdentifier string)error{
updatingMyCouplesMutex.Lock()
defer updatingMyCouplesMutex.Unlock()
mapToDeleteA := map[string]string{
"PersonAIdentifier": personIdentifier,
mapToDelete1 := map[string]string{
"Person1Identifier": personIdentifier,
}
err := myGenomeCouplesMapListDatastore.DeleteMapListItems(mapToDeleteA)
err := myGenomeCouplesMapListDatastore.DeleteMapListItems(mapToDelete1)
if (err != nil) { return err }
mapToDeleteB := map[string]string{
"PersonBIdentifier": personIdentifier,
mapToDelete2 := map[string]string{
"Person2Identifier": personIdentifier,
}
err = myGenomeCouplesMapListDatastore.DeleteMapListItems(mapToDeleteB)
err = myGenomeCouplesMapListDatastore.DeleteMapListItems(mapToDelete2)
if (err != nil) { return err }
return nil
@ -137,24 +137,24 @@ func GetNumberOfCouplesForPerson(personIdentifier string)(int, error){
totalCouples := 0
lookupMapA := map[string]string{
"PersonAIdentifier": personIdentifier,
lookupMap1 := map[string]string{
"Person1Identifier": personIdentifier,
}
anyItemsFoundA, matchingItemsListA, err := myGenomeCouplesMapListDatastore.GetMapListItems(lookupMapA)
anyItemsFound1, matchingItemsList1, err := myGenomeCouplesMapListDatastore.GetMapListItems(lookupMap1)
if (err != nil){ return 0, err }
if (anyItemsFoundA == true){
totalCouples += len(matchingItemsListA)
if (anyItemsFound1 == true){
totalCouples += len(matchingItemsList1)
}
lookupMapB := map[string]string{
"PersonBIdentifier": personIdentifier,
lookupMap2 := map[string]string{
"Person2Identifier": personIdentifier,
}
anyItemsFoundB, matchingItemsListB, err := myGenomeCouplesMapListDatastore.GetMapListItems(lookupMapB)
anyItemsFound2, matchingItemsList2, err := myGenomeCouplesMapListDatastore.GetMapListItems(lookupMap2)
if (err != nil){ return 0, err }
if (anyItemsFoundB == true){
totalCouples += len(matchingItemsListB)
if (anyItemsFound2 == true){
totalCouples += len(matchingItemsList2)
}
return totalCouples, nil
@ -163,16 +163,16 @@ func GetNumberOfCouplesForPerson(personIdentifier string)(int, error){
// This function is used to sort the person identifiers, so that each pair of identifiers will always map to the same couple when added
// The sorting method has no significance
func getPeopleIdentifiersSortedForCouple(personAIdentifier string, personBIdentifier string)(string, string, error){
func getPeopleIdentifiersSortedForCouple(person1Identifier string, person2Identifier string)(string, string, error){
if (personAIdentifier == personBIdentifier){
return "", "", errors.New("getPeopleIdentifiersSortedForCouple called with identical person identifiers: " + personAIdentifier)
if (person1Identifier == person2Identifier){
return "", "", errors.New("getPeopleIdentifiersSortedForCouple called with identical person identifiers: " + person1Identifier)
}
if (personAIdentifier < personBIdentifier){
return personAIdentifier, personBIdentifier, nil
if (person1Identifier < person2Identifier){
return person1Identifier, person2Identifier, nil
}
return personBIdentifier, personAIdentifier, nil
return person2Identifier, person1Identifier, nil
}

View file

@ -4,11 +4,12 @@
package myGenomes
import "seekia/internal/myDatastores/myMapList"
import "seekia/internal/genetics/readRawGenomes"
import "seekia/internal/localFilesystem"
import "seekia/internal/helpers"
import "seekia/internal/cryptography/blake3"
import "seekia/internal/encoding"
import "seekia/internal/genetics/readRawGenomes"
import "seekia/internal/helpers"
import "seekia/internal/localFilesystem"
import "seekia/internal/myDatastores/myMapList"
import "path/filepath"
import "time"
@ -61,7 +62,7 @@ func InitializeMyGenomeDatastore()error{
// -SNPCount -> Number of readable SNPs in file
// -CompanyName -> Company name ("23andMe", "AncestryDNA")
// -ImportVersion -> Import version for the company from which the metadata was retrieved
// -FileHash -> 256 bits Blake3 hash of the genome file
// -FileHash -> 256 bits Blake3 hash of the genome file, encoded in Hex
// -error
func GetMyRawGenomesMetadataMapList()([]map[string]string, error){
@ -152,18 +153,15 @@ func AddRawGenome(personIdentifier string, rawGenomeString string)(bool, bool, e
return true, false, nil
}
func DeleteMyRawGenome(genomeIdentifier string)error{
isValid := helpers.VerifyHexString(16, genomeIdentifier)
if (isValid == false){
return errors.New("DeleteMyRawGenome called with invalid genomeIdentifier: " + genomeIdentifier)
}
func DeleteMyRawGenome(genomeIdentifier [16]byte)error{
updatingMyGenomesMutex.Lock()
defer updatingMyGenomesMutex.Unlock()
genomeIdentifierHex := encoding.EncodeBytesToHexString(genomeIdentifier[:])
mapToDelete := map[string]string{
"GenomeIdentifier": genomeIdentifier,
"GenomeIdentifier": genomeIdentifierHex,
}
err := myGenomesMapListDatastore.DeleteMapListItems(mapToDelete)
@ -172,7 +170,7 @@ func DeleteMyRawGenome(genomeIdentifier string)error{
userDirectory, err := localFilesystem.GetAppUserFolderPath()
if (err != nil) { return err }
genomeFileName := genomeIdentifier + ".txt"
genomeFileName := genomeIdentifierHex + ".txt"
genomeFilePath := filepath.Join(userDirectory, "MyGenomes", genomeFileName)
@ -193,15 +191,17 @@ func DeleteMyRawGenome(genomeIdentifier string)error{
// -int: Import version
// -string: FileHash
// -error
func GetMyRawGenomeMetadata(genomeIdentifier string)(bool, string, int64, int64, bool, int64, string, int, string, error){
func GetMyRawGenomeMetadata(genomeIdentifier [16]byte)(bool, string, int64, int64, bool, int64, string, int, string, error){
if (genomeIdentifier == "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" || genomeIdentifier == "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"){
genomeIdentifierHex := encoding.EncodeBytesToHexString(genomeIdentifier[:])
if (genomeIdentifierHex == "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" || genomeIdentifierHex == "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"){
// These are the genome identifiers we use for example reports
// These are used to show the user what a genetic analysis would look like
getPersonIdentifier := func()string{
if (genomeIdentifier == "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"){
if (genomeIdentifierHex == "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"){
return "111111111111111111111111111111"
}
@ -214,7 +214,7 @@ func GetMyRawGenomeMetadata(genomeIdentifier string)(bool, string, int64, int64,
}
lookupMap := map[string]string{
"GenomeIdentifier": genomeIdentifier,
"GenomeIdentifier": genomeIdentifierHex,
}
anyItemFound, foundItemsMapList, err := myGenomesMapListDatastore.GetMapListItems(lookupMap)
@ -225,7 +225,7 @@ func GetMyRawGenomeMetadata(genomeIdentifier string)(bool, string, int64, int64,
return false, "", 0, 0, false, 0, "", 0, "", errors.New("Malformed myGenomesMapList: Contains multiple entries for same GenomeIdentifier")
}
genomeMap := foundItemsMapList[0]
personIdentifier, exists := genomeMap["PersonIdentifier"]
if (exists == false){
return false, "", 0, 0, false, 0, "", 0, "", errors.New("Malformed myGenomesMapList: Item missing PersonIdentifier")
@ -290,11 +290,13 @@ func GetMyRawGenomeMetadata(genomeIdentifier string)(bool, string, int64, int64,
}
// This function is used to refresh the genome metadata when a new import version is available
func RefreshRawGenomeMetadata(genomeIdentifier string)error{
func RefreshRawGenomeMetadata(genomeIdentifier [16]byte)error{
updatingMyGenomesMutex.Lock()
defer updatingMyGenomesMutex.Unlock()
genomeIdentifierHex := encoding.EncodeBytesToHexString(genomeIdentifier[:])
myGenomesMapList, err := myGenomesMapListDatastore.GetMapList()
if (err != nil) { return err }
@ -307,7 +309,7 @@ func RefreshRawGenomeMetadata(genomeIdentifier string)error{
return errors.New("myGenomesMapList item is malformed: item missing GenomeIdentifier.")
}
if (currentGenomeIdentifier != genomeIdentifier){
if (currentGenomeIdentifier != genomeIdentifierHex){
continue
}
if (foundGenome == true){
@ -355,12 +357,14 @@ func RefreshRawGenomeMetadata(genomeIdentifier string)error{
//Outputs:
// -string: Genome raw data string
// -error
func GetGenomeRawDataString(genomeIdentifier string)(string, error){
func GetGenomeRawDataString(genomeIdentifier [16]byte)(string, error){
genomeIdentifierHex := encoding.EncodeBytesToHexString(genomeIdentifier[:])
userDirectory, err := localFilesystem.GetAppUserFolderPath()
if (err != nil) { return "", err }
genomeFileName := genomeIdentifier + ".txt"
genomeFileName := genomeIdentifierHex + ".txt"
genomeFilePath := filepath.Join(userDirectory, "MyGenomes", genomeFileName)
@ -392,20 +396,25 @@ func GetAllPersonGenomesMapList(personIdentifier string)([]map[string]string, er
}
// This will not include any calculated genome identifiers, which only exist within analyses
func GetAllPersonRawGenomeIdentifiersList(personIdentifier string)([]string, error){
func GetAllPersonRawGenomeIdentifiersList(personIdentifier string)([][16]byte, error){
allPersonGenomesMapList, err := GetAllPersonGenomesMapList(personIdentifier)
if (err != nil) { return nil, err }
personGenomeIdentifiersList := make([]string, 0, len(allPersonGenomesMapList))
personGenomeIdentifiersList := make([][16]byte, 0, len(allPersonGenomesMapList))
for _, genomeMap := range allPersonGenomesMapList{
genomeIdentifier, exists := genomeMap["GenomeIdentifier"]
genomeIdentifierHex, exists := genomeMap["GenomeIdentifier"]
if (exists == false){
return nil, errors.New("Malformed myGenomesMapList: Item missing GenomeIdentifier")
}
genomeIdentifier, err := encoding.DecodeHexStringTo16ByteArray(genomeIdentifierHex)
if (err != nil){
return nil, errors.New("Malformed myGenomesMapList: Item contains invalid GenomeIdentifier: " + genomeIdentifierHex)
}
personGenomeIdentifiersList = append(personGenomeIdentifiersList, genomeIdentifier)
}

View file

@ -186,9 +186,9 @@ func GetPersonInfo(personIdentifier string)(bool, string, int64, string, error){
getPersonName := func()string{
if (personIdentifier == "111111111111111111111111111111"){
return "Person A"
return "Person 1"
}
return "Person B"
return "Person 2"
}
personName := getPersonName()

View file

@ -18,7 +18,7 @@ import "strings"
type RawGenomeWithMetadata struct{
GenomeIdentifier string
GenomeIdentifier [16]byte
GenomeIsPhased bool
@ -31,8 +31,7 @@ type GenomeWithMetadata struct{
// "Single"/"OnlyExcludeConflicts"/"OnlyIncludeShared"
GenomeType string
// A 16 byte hex-encoded identifier
GenomeIdentifier string
GenomeIdentifier [16]byte
// Map Structure: RSID -> Locus base pair value object
GenomeMap map[int64]locusValue.LocusValue
@ -43,12 +42,7 @@ type GenomeWithMetadata struct{
// -bool: Raw genome string is valid
// -RawGenomeWithMetadata
// -error (returns non-nil if called with invalid genomeIdentifier)
func CreateRawGenomeWithMetadataObject(genomeIdentifier string, rawGenomeString string)(bool, RawGenomeWithMetadata, error){
isValid := helpers.VerifyHexString(16, genomeIdentifier)
if (isValid == false){
return false, RawGenomeWithMetadata{}, errors.New("CreateRawGenomeWithMetadataObject called with invalid genomeIdentifier: " + genomeIdentifier)
}
func CreateRawGenomeWithMetadataObject(genomeIdentifier [16]byte, rawGenomeString string)(bool, RawGenomeWithMetadata, error){
rawDataReader := strings.NewReader(rawGenomeString)
@ -75,32 +69,32 @@ func CreateRawGenomeWithMetadataObject(genomeIdentifier string, rawGenomeString
// -func(int)error: Update Percentage Complete Function
//Outputs:
// -[]GenomeWithMetadata: Genomes with metadata list
// -[]string: All raw genome identifiers list (not including combined genomes)
// -[][16]byte: All raw genome identifiers list (not including combined genomes)
// -bool: Combined genomes exist
// -string: Only exclude conflicts genome identifier
// -string: Only include shared genome identifier
// -[16]byte: Only exclude conflicts genome identifier
// -[16]byte: Only include shared genome identifier
// -error
func GetGenomesWithMetadataListFromRawGenomesList(inputGenomesList []RawGenomeWithMetadata, updatePercentageCompleteFunction func(int)error)([]GenomeWithMetadata, []string, bool, string, string, error){
func GetGenomesWithMetadataListFromRawGenomesList(inputGenomesList []RawGenomeWithMetadata, updatePercentageCompleteFunction func(int)error)([]GenomeWithMetadata, [][16]byte, bool, [16]byte, [16]byte, error){
// The reading of genomes will take up the first 20% of the percentage range
// The creation of multiple genomes will take up the last 80% of the percentage range
// Structure: A list of genomes.
// Each map stores a genome from a company or a combined genome.
// Each map stores a genome from a company or a combined genome.
genomesWithMetadataList := make([]GenomeWithMetadata, 0)
numberOfGenomesRead := 0
totalNumberOfGenomesToRead := len(inputGenomesList)
allRawGenomeIdentifiersList := make([]string, 0)
allRawGenomeIdentifiersList := make([][16]byte, 0)
for _, rawGenomeWithMetadataObject := range inputGenomesList{
newPercentageCompletion, err := helpers.ScaleNumberProportionally(true, numberOfGenomesRead, 0, totalNumberOfGenomesToRead, 0, 20)
if (err != nil) { return nil, nil, false, "", "", err }
if (err != nil) { return nil, nil, false, [16]byte{}, [16]byte{}, err }
err = updatePercentageCompleteFunction(newPercentageCompletion)
if (err != nil) { return nil, nil, false, "", "", err }
if (err != nil) { return nil, nil, false, [16]byte{}, [16]byte{}, err }
genomeIdentifier := rawGenomeWithMetadataObject.GenomeIdentifier
genomeIsPhased := rawGenomeWithMetadataObject.GenomeIsPhased
@ -150,7 +144,7 @@ func GetGenomesWithMetadataListFromRawGenomesList(inputGenomesList []RawGenomeWi
}
aliasExists, rsidAliasesList, err := locusMetadata.GetRSIDAliases(rsID)
if (err != nil){ return nil, nil, false, "", "", err }
if (err != nil){ return nil, nil, false, [16]byte{}, [16]byte{}, err }
if (aliasExists == false){
continue
}
@ -209,11 +203,11 @@ func GetGenomesWithMetadataListFromRawGenomesList(inputGenomesList []RawGenomeWi
containsDuplicates, _ := helpers.CheckIfListContainsDuplicates(allRawGenomeIdentifiersList)
if (containsDuplicates == true){
return nil, nil, false, "", "", errors.New("GetGenomesWithMetadataListFromRawGenomesList called with inputGenomesList containing duplicate genomeIdentifiers.")
return nil, nil, false, [16]byte{}, [16]byte{}, errors.New("GetGenomesWithMetadataListFromRawGenomesList called with inputGenomesList containing duplicate genomeIdentifiers.")
}
err := updatePercentageCompleteFunction(20)
if (err != nil){ return nil, nil, false, "", "", err }
if (err != nil){ return nil, nil, false, [16]byte{}, [16]byte{}, err }
if (len(genomesWithMetadataList) == 1){
@ -221,9 +215,9 @@ func GetGenomesWithMetadataListFromRawGenomesList(inputGenomesList []RawGenomeWi
// No genome combining is needed.
err = updatePercentageCompleteFunction(100)
if (err != nil){ return nil, nil, false, "", "", err }
if (err != nil){ return nil, nil, false, [16]byte{}, [16]byte{}, err }
return genomesWithMetadataList, allRawGenomeIdentifiersList, false, "", "", nil
return genomesWithMetadataList, allRawGenomeIdentifiersList, false, [16]byte{}, [16]byte{}, nil
}
// Now we create the shared genomes
@ -241,10 +235,10 @@ func GetGenomesWithMetadataListFromRawGenomesList(inputGenomesList []RawGenomeWi
for index, genomeWithMetadataObject := range genomesWithMetadataList{
newPercentageCompletion, err := helpers.ScaleNumberProportionally(true, index, 0, finalIndex, 20, 50)
if (err != nil){ return nil, nil, false, "", "", err }
if (err != nil){ return nil, nil, false, [16]byte{}, [16]byte{}, err }
err = updatePercentageCompleteFunction(newPercentageCompletion)
if (err != nil){ return nil, nil, false, "", "", err }
if (err != nil){ return nil, nil, false, [16]byte{}, [16]byte{}, err }
genomeMap := genomeWithMetadataObject.GenomeMap
@ -266,10 +260,10 @@ func GetGenomesWithMetadataListFromRawGenomesList(inputGenomesList []RawGenomeWi
for rsID, _ := range allRSIDsMap{
newPercentageCompletion, err := helpers.ScaleNumberProportionally(true, index, 0, finalIndex, 50, 100)
if (err != nil){ return nil, nil, false, "", "", err }
if (err != nil){ return nil, nil, false, [16]byte{}, [16]byte{}, err }
err = updatePercentageCompleteFunction(newPercentageCompletion)
if (err != nil){ return nil, nil, false, "", "", err }
if (err != nil){ return nil, nil, false, [16]byte{}, [16]byte{}, err }
index += 1
@ -280,7 +274,7 @@ func GetGenomesWithMetadataListFromRawGenomesList(inputGenomesList []RawGenomeWi
}
anyAliasesExist, rsidAliasesList, err := locusMetadata.GetRSIDAliases(rsID)
if (err != nil){ return nil, nil, false, "", "", err }
if (err != nil){ return nil, nil, false, [16]byte{}, [16]byte{}, err }
if (anyAliasesExist == true){
for _, rsidAlias := range rsidAliasesList{
@ -466,7 +460,7 @@ func GetGenomesWithMetadataListFromRawGenomesList(inputGenomesList []RawGenomeWi
}
locusBase1, locusBase2, phaseIsKnown_OnlyExcludeConflicts, phaseIsKnown_OnlyIncludeShared, err := getLocusBasePair()
if (err != nil){ return nil, nil, false, "", "", err }
if (err != nil){ return nil, nil, false, [16]byte{}, [16]byte{}, err }
// Now we add to the combined genome maps
// The OnlyExcludeConflicts will only omit when there is a tie
@ -493,21 +487,19 @@ func GetGenomesWithMetadataListFromRawGenomesList(inputGenomesList []RawGenomeWi
}
}
onlyExcludeConflictsGenomeIdentifier, err := helpers.GetNewRandomHexString(16)
if (err != nil) { return nil, nil, false, "", "", err }
onlyExcludeConflictsGenomeIdentifier, err := helpers.GetNewRandom16ByteArray()
if (err != nil) { return nil, nil, false, [16]byte{}, [16]byte{}, err }
onlyExcludeConflictsGenomeWithMetadataObject := GenomeWithMetadata{
GenomeType: "OnlyExcludeConflicts",
GenomeIdentifier: onlyExcludeConflictsGenomeIdentifier,
GenomeMap: onlyExcludeConflictsGenomeMap,
}
onlyIncludeSharedGenomeIdentifier, err := helpers.GetNewRandomHexString(16)
if (err != nil) { return nil, nil, false, "", "", err }
onlyIncludeSharedGenomeIdentifier, err := helpers.GetNewRandom16ByteArray()
if (err != nil) { return nil, nil, false, [16]byte{}, [16]byte{}, err }
onlyIncludeSharedGenomeWithMetadataObject := GenomeWithMetadata{
GenomeType: "OnlyIncludeShared",
GenomeIdentifier: onlyIncludeSharedGenomeIdentifier,
GenomeMap: onlyIncludeSharedGenomeMap,
@ -516,7 +508,7 @@ func GetGenomesWithMetadataListFromRawGenomesList(inputGenomesList []RawGenomeWi
genomesWithMetadataList = append(genomesWithMetadataList, onlyExcludeConflictsGenomeWithMetadataObject, onlyIncludeSharedGenomeWithMetadataObject)
err = updatePercentageCompleteFunction(100)
if (err != nil){ return nil, nil, false, "", "", err }
if (err != nil){ return nil, nil, false, [16]byte{}, [16]byte{}, err }
return genomesWithMetadataList, allRawGenomeIdentifiersList, true, onlyExcludeConflictsGenomeIdentifier, onlyIncludeSharedGenomeIdentifier, nil
}

File diff suppressed because it is too large Load diff

View file

@ -1,712 +0,0 @@
[
{
"AnalysisType": "Couple",
"AnalysisVersion": "1",
"ItemType": "Metadata",
"Pair1PersonAGenomeIdentifier": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
"Pair1PersonBGenomeIdentifier": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
"PersonAHasMultipleGenomes": "No",
"PersonBHasMultipleGenomes": "No",
"SecondPairExists": "No"
},
{
"DiseaseName": "Cystic Fibrosis",
"ItemType": "MonogenicDisease",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOffspringHasDisease": "25",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOffspringHasVariant": "75",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_NumberOfVariantsTested": "26",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_NumberOfVariantsTested": "26"
},
{
"DiseaseName": "Cystic Fibrosis",
"ItemType": "MonogenicDiseaseVariant",
"VariantIdentifier": "36965d",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf0MutationsLowerBound": "50",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf0MutationsUpperBound": "50",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf1MutationLowerBound": "50",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf1MutationUpperBound": "50",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf2MutationsLowerBound": "0",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf2MutationsUpperBound": "0"
},
{
"DiseaseName": "Cystic Fibrosis",
"ItemType": "MonogenicDiseaseVariant",
"VariantIdentifier": "5706b0",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf0MutationsLowerBound": "100",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf0MutationsUpperBound": "100",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf1MutationLowerBound": "0",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf1MutationUpperBound": "0",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf2MutationsLowerBound": "0",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf2MutationsUpperBound": "0"
},
{
"DiseaseName": "Cystic Fibrosis",
"ItemType": "MonogenicDiseaseVariant",
"VariantIdentifier": "01a2a0",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf0MutationsLowerBound": "100",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf0MutationsUpperBound": "100",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf1MutationLowerBound": "0",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf1MutationUpperBound": "0",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf2MutationsLowerBound": "0",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf2MutationsUpperBound": "0"
},
{
"DiseaseName": "Cystic Fibrosis",
"ItemType": "MonogenicDiseaseVariant",
"VariantIdentifier": "bd4106",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf0MutationsLowerBound": "100",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf0MutationsUpperBound": "100",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf1MutationLowerBound": "0",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf1MutationUpperBound": "0",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf2MutationsLowerBound": "0",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf2MutationsUpperBound": "0"
},
{
"DiseaseName": "Cystic Fibrosis",
"ItemType": "MonogenicDiseaseVariant",
"VariantIdentifier": "4d6f38",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf0MutationsLowerBound": "100",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf0MutationsUpperBound": "100",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf1MutationLowerBound": "0",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf1MutationUpperBound": "0",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf2MutationsLowerBound": "0",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf2MutationsUpperBound": "0"
},
{
"DiseaseName": "Cystic Fibrosis",
"ItemType": "MonogenicDiseaseVariant",
"VariantIdentifier": "c6135a",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf0MutationsLowerBound": "50",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf0MutationsUpperBound": "50",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf1MutationLowerBound": "50",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf1MutationUpperBound": "50",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf2MutationsLowerBound": "0",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf2MutationsUpperBound": "0"
},
{
"DiseaseName": "Cystic Fibrosis",
"ItemType": "MonogenicDiseaseVariant",
"VariantIdentifier": "88a7f4",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf0MutationsLowerBound": "100",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf0MutationsUpperBound": "100",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf1MutationLowerBound": "0",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf1MutationUpperBound": "0",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf2MutationsLowerBound": "0",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf2MutationsUpperBound": "0"
},
{
"DiseaseName": "Cystic Fibrosis",
"ItemType": "MonogenicDiseaseVariant",
"VariantIdentifier": "058a4d",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf0MutationsLowerBound": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf0MutationsUpperBound": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf1MutationLowerBound": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf1MutationUpperBound": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf2MutationsLowerBound": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf2MutationsUpperBound": "Unknown"
},
{
"DiseaseName": "Cystic Fibrosis",
"ItemType": "MonogenicDiseaseVariant",
"VariantIdentifier": "2a4ddf",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf0MutationsLowerBound": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf0MutationsUpperBound": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf1MutationLowerBound": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf1MutationUpperBound": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf2MutationsLowerBound": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf2MutationsUpperBound": "Unknown"
},
{
"DiseaseName": "Cystic Fibrosis",
"ItemType": "MonogenicDiseaseVariant",
"VariantIdentifier": "e1bcfb",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf0MutationsLowerBound": "100",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf0MutationsUpperBound": "100",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf1MutationLowerBound": "0",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf1MutationUpperBound": "0",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf2MutationsLowerBound": "0",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf2MutationsUpperBound": "0"
},
{
"DiseaseName": "Cystic Fibrosis",
"ItemType": "MonogenicDiseaseVariant",
"VariantIdentifier": "c28795",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf0MutationsLowerBound": "100",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf0MutationsUpperBound": "100",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf1MutationLowerBound": "0",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf1MutationUpperBound": "0",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf2MutationsLowerBound": "0",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf2MutationsUpperBound": "0"
},
{
"DiseaseName": "Cystic Fibrosis",
"ItemType": "MonogenicDiseaseVariant",
"VariantIdentifier": "f1965c",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf0MutationsLowerBound": "100",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf0MutationsUpperBound": "100",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf1MutationLowerBound": "0",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf1MutationUpperBound": "0",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf2MutationsLowerBound": "0",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf2MutationsUpperBound": "0"
},
{
"DiseaseName": "Cystic Fibrosis",
"ItemType": "MonogenicDiseaseVariant",
"VariantIdentifier": "3420c1",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf0MutationsLowerBound": "100",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf0MutationsUpperBound": "100",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf1MutationLowerBound": "0",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf1MutationUpperBound": "0",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf2MutationsLowerBound": "0",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf2MutationsUpperBound": "0"
},
{
"DiseaseName": "Cystic Fibrosis",
"ItemType": "MonogenicDiseaseVariant",
"VariantIdentifier": "25d0b4",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf0MutationsLowerBound": "100",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf0MutationsUpperBound": "100",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf1MutationLowerBound": "0",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf1MutationUpperBound": "0",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf2MutationsLowerBound": "0",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf2MutationsUpperBound": "0"
},
{
"DiseaseName": "Cystic Fibrosis",
"ItemType": "MonogenicDiseaseVariant",
"VariantIdentifier": "139ab2",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf0MutationsLowerBound": "100",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf0MutationsUpperBound": "100",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf1MutationLowerBound": "0",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf1MutationUpperBound": "0",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf2MutationsLowerBound": "0",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf2MutationsUpperBound": "0"
},
{
"DiseaseName": "Cystic Fibrosis",
"ItemType": "MonogenicDiseaseVariant",
"VariantIdentifier": "f7a12e",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf0MutationsLowerBound": "100",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf0MutationsUpperBound": "100",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf1MutationLowerBound": "0",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf1MutationUpperBound": "0",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf2MutationsLowerBound": "0",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf2MutationsUpperBound": "0"
},
{
"DiseaseName": "Cystic Fibrosis",
"ItemType": "MonogenicDiseaseVariant",
"VariantIdentifier": "deb2e2",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf0MutationsLowerBound": "100",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf0MutationsUpperBound": "100",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf1MutationLowerBound": "0",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf1MutationUpperBound": "0",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf2MutationsLowerBound": "0",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf2MutationsUpperBound": "0"
},
{
"DiseaseName": "Cystic Fibrosis",
"ItemType": "MonogenicDiseaseVariant",
"VariantIdentifier": "884cf0",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf0MutationsLowerBound": "100",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf0MutationsUpperBound": "100",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf1MutationLowerBound": "0",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf1MutationUpperBound": "0",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf2MutationsLowerBound": "0",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf2MutationsUpperBound": "0"
},
{
"DiseaseName": "Cystic Fibrosis",
"ItemType": "MonogenicDiseaseVariant",
"VariantIdentifier": "b9fad1",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf0MutationsLowerBound": "100",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf0MutationsUpperBound": "100",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf1MutationLowerBound": "0",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf1MutationUpperBound": "0",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf2MutationsLowerBound": "0",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf2MutationsUpperBound": "0"
},
{
"DiseaseName": "Cystic Fibrosis",
"ItemType": "MonogenicDiseaseVariant",
"VariantIdentifier": "f2448d",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf0MutationsLowerBound": "100",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf0MutationsUpperBound": "100",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf1MutationLowerBound": "0",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf1MutationUpperBound": "0",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf2MutationsLowerBound": "0",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf2MutationsUpperBound": "0"
},
{
"DiseaseName": "Cystic Fibrosis",
"ItemType": "MonogenicDiseaseVariant",
"VariantIdentifier": "09b96f",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf0MutationsLowerBound": "100",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf0MutationsUpperBound": "100",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf1MutationLowerBound": "0",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf1MutationUpperBound": "0",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf2MutationsLowerBound": "0",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf2MutationsUpperBound": "0"
},
{
"DiseaseName": "Cystic Fibrosis",
"ItemType": "MonogenicDiseaseVariant",
"VariantIdentifier": "2f8651",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf0MutationsLowerBound": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf0MutationsUpperBound": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf1MutationLowerBound": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf1MutationUpperBound": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf2MutationsLowerBound": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf2MutationsUpperBound": "Unknown"
},
{
"DiseaseName": "Cystic Fibrosis",
"ItemType": "MonogenicDiseaseVariant",
"VariantIdentifier": "46efe1",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf0MutationsLowerBound": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf0MutationsUpperBound": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf1MutationLowerBound": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf1MutationUpperBound": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf2MutationsLowerBound": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf2MutationsUpperBound": "Unknown"
},
{
"DiseaseName": "Cystic Fibrosis",
"ItemType": "MonogenicDiseaseVariant",
"VariantIdentifier": "528406",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf0MutationsLowerBound": "100",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf0MutationsUpperBound": "100",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf1MutationLowerBound": "0",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf1MutationUpperBound": "0",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf2MutationsLowerBound": "0",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf2MutationsUpperBound": "0"
},
{
"DiseaseName": "Cystic Fibrosis",
"ItemType": "MonogenicDiseaseVariant",
"VariantIdentifier": "e8e8fc",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf0MutationsLowerBound": "100",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf0MutationsUpperBound": "100",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf1MutationLowerBound": "0",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf1MutationUpperBound": "0",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf2MutationsLowerBound": "0",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf2MutationsUpperBound": "0"
},
{
"DiseaseName": "Cystic Fibrosis",
"ItemType": "MonogenicDiseaseVariant",
"VariantIdentifier": "e60633",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf0MutationsLowerBound": "100",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf0MutationsUpperBound": "100",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf1MutationLowerBound": "0",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf1MutationUpperBound": "0",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf2MutationsLowerBound": "0",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf2MutationsUpperBound": "0"
},
{
"DiseaseName": "Cystic Fibrosis",
"ItemType": "MonogenicDiseaseVariant",
"VariantIdentifier": "d72d30",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf0MutationsLowerBound": "100",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf0MutationsUpperBound": "100",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf1MutationLowerBound": "0",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf1MutationUpperBound": "0",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf2MutationsLowerBound": "0",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf2MutationsUpperBound": "0"
},
{
"DiseaseName": "Cystic Fibrosis",
"ItemType": "MonogenicDiseaseVariant",
"VariantIdentifier": "a3b068",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf0MutationsLowerBound": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf0MutationsUpperBound": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf1MutationLowerBound": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf1MutationUpperBound": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf2MutationsLowerBound": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf2MutationsUpperBound": "Unknown"
},
{
"DiseaseName": "Cystic Fibrosis",
"ItemType": "MonogenicDiseaseVariant",
"VariantIdentifier": "770086",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf0MutationsLowerBound": "100",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf0MutationsUpperBound": "100",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf1MutationLowerBound": "0",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf1MutationUpperBound": "0",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf2MutationsLowerBound": "0",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf2MutationsUpperBound": "0"
},
{
"DiseaseName": "Cystic Fibrosis",
"ItemType": "MonogenicDiseaseVariant",
"VariantIdentifier": "a00f11",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf0MutationsLowerBound": "100",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf0MutationsUpperBound": "100",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf1MutationLowerBound": "0",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf1MutationUpperBound": "0",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf2MutationsLowerBound": "0",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf2MutationsUpperBound": "0"
},
{
"DiseaseName": "Cystic Fibrosis",
"ItemType": "MonogenicDiseaseVariant",
"VariantIdentifier": "79d73b",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf0MutationsLowerBound": "100",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf0MutationsUpperBound": "100",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf1MutationLowerBound": "0",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf1MutationUpperBound": "0",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf2MutationsLowerBound": "0",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf2MutationsUpperBound": "0"
},
{
"DiseaseName": "Sickle Cell Anemia",
"ItemType": "MonogenicDisease",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOffspringHasDisease": "0",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOffspringHasVariant": "0",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_NumberOfVariantsTested": "1",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_NumberOfVariantsTested": "1"
},
{
"DiseaseName": "Sickle Cell Anemia",
"ItemType": "MonogenicDiseaseVariant",
"VariantIdentifier": "50e857",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf0MutationsLowerBound": "100",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf0MutationsUpperBound": "100",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf1MutationLowerBound": "0",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf1MutationUpperBound": "0",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf2MutationsLowerBound": "0",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOf2MutationsUpperBound": "0"
},
{
"DiseaseName": "Breast Cancer",
"ItemType": "PolygenicDisease",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_NumberOfLociTested": "24",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_OffspringRiskScore": "1"
},
{
"DiseaseName": "Breast Cancer",
"ItemType": "PolygenicDiseaseLocus",
"LocusIdentifier": "d7891c",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_OffspringOddsRatio": "1.14000",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_OffspringRiskWeight": "1",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_OffspringUnknownOddsRatiosWeightSum": "0"
},
{
"DiseaseName": "Breast Cancer",
"ItemType": "PolygenicDiseaseLocus",
"LocusIdentifier": "41c164",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_OffspringOddsRatio": "1.00000",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_OffspringRiskWeight": "0",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_OffspringUnknownOddsRatiosWeightSum": "0"
},
{
"DiseaseName": "Breast Cancer",
"ItemType": "PolygenicDiseaseLocus",
"LocusIdentifier": "f3a097",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_OffspringOddsRatio": "0.50000",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_OffspringRiskWeight": "0",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_OffspringUnknownOddsRatiosWeightSum": "0"
},
{
"DiseaseName": "Breast Cancer",
"ItemType": "PolygenicDiseaseLocus",
"LocusIdentifier": "d4626f",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_OffspringOddsRatio": "1.07000",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_OffspringRiskWeight": "0",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_OffspringUnknownOddsRatiosWeightSum": "0"
},
{
"DiseaseName": "Breast Cancer",
"ItemType": "PolygenicDiseaseLocus",
"LocusIdentifier": "84aaa4",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_OffspringOddsRatio": "1.00000",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_OffspringRiskWeight": "0",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_OffspringUnknownOddsRatiosWeightSum": "0"
},
{
"DiseaseName": "Breast Cancer",
"ItemType": "PolygenicDiseaseLocus",
"LocusIdentifier": "c8de7a",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_OffspringOddsRatio": "1.50000",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_OffspringRiskWeight": "1",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_OffspringUnknownOddsRatiosWeightSum": "0"
},
{
"DiseaseName": "Breast Cancer",
"ItemType": "PolygenicDiseaseLocus",
"LocusIdentifier": "d30087",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_OffspringOddsRatio": "1.07000",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_OffspringRiskWeight": "0",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_OffspringUnknownOddsRatiosWeightSum": "0"
},
{
"DiseaseName": "Breast Cancer",
"ItemType": "PolygenicDiseaseLocus",
"LocusIdentifier": "cafa72",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_OffspringOddsRatio": "1.00000",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_OffspringRiskWeight": "0",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_OffspringUnknownOddsRatiosWeightSum": "0"
},
{
"DiseaseName": "Breast Cancer",
"ItemType": "PolygenicDiseaseLocus",
"LocusIdentifier": "8f671c",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_OffspringOddsRatio": "1.14000",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_OffspringRiskWeight": "1",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_OffspringUnknownOddsRatiosWeightSum": "0"
},
{
"DiseaseName": "Breast Cancer",
"ItemType": "PolygenicDiseaseLocus",
"LocusIdentifier": "b3e49a",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_OffspringOddsRatio": "1.00000",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_OffspringRiskWeight": "0",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_OffspringUnknownOddsRatiosWeightSum": "0"
},
{
"DiseaseName": "Breast Cancer",
"ItemType": "PolygenicDiseaseLocus",
"LocusIdentifier": "8b0b02",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_OffspringOddsRatio": "1.00000",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_OffspringRiskWeight": "0",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_OffspringUnknownOddsRatiosWeightSum": "0"
},
{
"DiseaseName": "Breast Cancer",
"ItemType": "PolygenicDiseaseLocus",
"LocusIdentifier": "25cafc",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_OffspringOddsRatio": "1.00000",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_OffspringRiskWeight": "0",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_OffspringUnknownOddsRatiosWeightSum": "0"
},
{
"DiseaseName": "Breast Cancer",
"ItemType": "PolygenicDiseaseLocus",
"LocusIdentifier": "34c7e5",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_OffspringOddsRatio": "1.00000",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_OffspringRiskWeight": "0",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_OffspringUnknownOddsRatiosWeightSum": "0"
},
{
"DiseaseName": "Breast Cancer",
"ItemType": "PolygenicDiseaseLocus",
"LocusIdentifier": "60ce27",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_OffspringOddsRatio": "1.00000",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_OffspringRiskWeight": "0",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_OffspringUnknownOddsRatiosWeightSum": "0"
},
{
"DiseaseName": "Breast Cancer",
"ItemType": "PolygenicDiseaseLocus",
"LocusIdentifier": "328cdf",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_OffspringOddsRatio": "1.00000",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_OffspringRiskWeight": "0",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_OffspringUnknownOddsRatiosWeightSum": "0"
},
{
"DiseaseName": "Breast Cancer",
"ItemType": "PolygenicDiseaseLocus",
"LocusIdentifier": "849bc7",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_OffspringOddsRatio": "1.00000",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_OffspringRiskWeight": "0",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_OffspringUnknownOddsRatiosWeightSum": "0"
},
{
"DiseaseName": "Breast Cancer",
"ItemType": "PolygenicDiseaseLocus",
"LocusIdentifier": "5af5e3",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_OffspringOddsRatio": "1.00000",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_OffspringRiskWeight": "0",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_OffspringUnknownOddsRatiosWeightSum": "0"
},
{
"DiseaseName": "Breast Cancer",
"ItemType": "PolygenicDiseaseLocus",
"LocusIdentifier": "c354fa",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_OffspringOddsRatio": "1.00000",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_OffspringRiskWeight": "0",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_OffspringUnknownOddsRatiosWeightSum": "0"
},
{
"DiseaseName": "Breast Cancer",
"ItemType": "PolygenicDiseaseLocus",
"LocusIdentifier": "eedc23",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_OffspringOddsRatio": "1.02500",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_OffspringRiskWeight": "0",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_OffspringUnknownOddsRatiosWeightSum": "0"
},
{
"DiseaseName": "Breast Cancer",
"ItemType": "PolygenicDiseaseLocus",
"LocusIdentifier": "2ee027",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_OffspringOddsRatio": "1.00000",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_OffspringRiskWeight": "0",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_OffspringUnknownOddsRatiosWeightSum": "0"
},
{
"DiseaseName": "Breast Cancer",
"ItemType": "PolygenicDiseaseLocus",
"LocusIdentifier": "fc4bab",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_OffspringOddsRatio": "1.00000",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_OffspringRiskWeight": "0",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_OffspringUnknownOddsRatiosWeightSum": "0"
},
{
"DiseaseName": "Breast Cancer",
"ItemType": "PolygenicDiseaseLocus",
"LocusIdentifier": "f8b225",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_OffspringOddsRatio": "1.00000",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_OffspringRiskWeight": "0",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_OffspringUnknownOddsRatiosWeightSum": "0"
},
{
"DiseaseName": "Breast Cancer",
"ItemType": "PolygenicDiseaseLocus",
"LocusIdentifier": "4a072c",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_OffspringOddsRatio": "1.00000",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_OffspringRiskWeight": "0",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_OffspringUnknownOddsRatiosWeightSum": "0"
},
{
"DiseaseName": "Breast Cancer",
"ItemType": "PolygenicDiseaseLocus",
"LocusIdentifier": "070f24",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_OffspringOddsRatio": "1.00000",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_OffspringRiskWeight": "0",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_OffspringUnknownOddsRatiosWeightSum": "0"
},
{
"DiseaseName": "Breast Cancer",
"ItemType": "PolygenicDiseaseLocus",
"LocusIdentifier": "d08516",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_OffspringOddsRatio": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_OffspringRiskWeight": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_OffspringUnknownOddsRatiosWeightSum": "Unknown"
},
{
"DiseaseName": "Breast Cancer",
"ItemType": "PolygenicDiseaseLocus",
"LocusIdentifier": "047b84",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_OffspringOddsRatio": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_OffspringRiskWeight": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_OffspringUnknownOddsRatiosWeightSum": "Unknown"
},
{
"ItemType": "Trait",
"TraitName": "Lactose Tolerance",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_NumberOfRulesTested": "5",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_OffspringAverageOutcomeScore_Intolerant": "0",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_OffspringAverageOutcomeScore_Tolerant": "2.50"
},
{
"ItemType": "TraitRule",
"RuleIdentifier": "f4e02c",
"TraitName": "Lactose Tolerance",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_OffspringProbabilityOfPassingRule": "0"
},
{
"ItemType": "TraitRule",
"RuleIdentifier": "cc3df0",
"TraitName": "Lactose Tolerance",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_OffspringProbabilityOfPassingRule": "100"
},
{
"ItemType": "TraitRule",
"RuleIdentifier": "8170ee",
"TraitName": "Lactose Tolerance",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_OffspringProbabilityOfPassingRule": "0"
},
{
"ItemType": "TraitRule",
"RuleIdentifier": "52425f",
"TraitName": "Lactose Tolerance",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_OffspringProbabilityOfPassingRule": "50"
},
{
"ItemType": "TraitRule",
"RuleIdentifier": "4b5c35",
"TraitName": "Lactose Tolerance",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_OffspringProbabilityOfPassingRule": "50"
},
{
"ItemType": "Trait",
"TraitName": "Hair Texture",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_NumberOfRulesTested": "9",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_OffspringAverageOutcomeScore_Curly": "1.50",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_OffspringAverageOutcomeScore_Straight": "3"
},
{
"ItemType": "TraitRule",
"RuleIdentifier": "fde405",
"TraitName": "Hair Texture",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_OffspringProbabilityOfPassingRule": "50"
},
{
"ItemType": "TraitRule",
"RuleIdentifier": "6bd1da",
"TraitName": "Hair Texture",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_OffspringProbabilityOfPassingRule": "50"
},
{
"ItemType": "TraitRule",
"RuleIdentifier": "32e377",
"TraitName": "Hair Texture",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_OffspringProbabilityOfPassingRule": "0"
},
{
"ItemType": "TraitRule",
"RuleIdentifier": "34e6d2",
"TraitName": "Hair Texture",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_OffspringProbabilityOfPassingRule": "50"
},
{
"ItemType": "TraitRule",
"RuleIdentifier": "cf6cb5",
"TraitName": "Hair Texture",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_OffspringProbabilityOfPassingRule": "50"
},
{
"ItemType": "TraitRule",
"RuleIdentifier": "2ba65b",
"TraitName": "Hair Texture",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_OffspringProbabilityOfPassingRule": "0"
},
{
"ItemType": "TraitRule",
"RuleIdentifier": "ae3274",
"TraitName": "Hair Texture",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_OffspringProbabilityOfPassingRule": "50"
},
{
"ItemType": "TraitRule",
"RuleIdentifier": "a546bf",
"TraitName": "Hair Texture",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_OffspringProbabilityOfPassingRule": "50"
},
{
"ItemType": "TraitRule",
"RuleIdentifier": "b8dc0a",
"TraitName": "Hair Texture",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_OffspringProbabilityOfPassingRule": "0"
},
{
"ItemType": "Trait",
"TraitName": "Facial Structure",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_NumberOfRulesTested": "0"
},
{
"ItemType": "Trait",
"TraitName": "Eye Color",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_NumberOfRulesTested": "0"
},
{
"ItemType": "Trait",
"TraitName": "Hair Color",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_NumberOfRulesTested": "0"
},
{
"ItemType": "Trait",
"TraitName": "Skin Color",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_NumberOfRulesTested": "0"
}
]

View file

@ -1,922 +0,0 @@
[
{
"AnalysisType": "Person",
"AnalysisVersion": "1",
"CombinedGenomesExist": "No",
"GenomeIdentifier": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
"ItemType": "Metadata"
},
{
"DiseaseName": "Cystic Fibrosis",
"ItemType": "MonogenicDisease",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_NumberOfVariantsTested": "26",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_ProbabilityOfHavingDisease": "0",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_ProbabilityOfPassingADiseaseVariant": "50"
},
{
"DiseaseName": "Cystic Fibrosis",
"ItemType": "MonogenicDiseaseVariant",
"VariantIdentifier": "36965d",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_HasVariant": "No;Yes",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusIsPhased": "No"
},
{
"DiseaseName": "Cystic Fibrosis",
"ItemType": "MonogenicDiseaseVariant",
"VariantIdentifier": "5706b0",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_HasVariant": "No;No",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusIsPhased": "No"
},
{
"DiseaseName": "Cystic Fibrosis",
"ItemType": "MonogenicDiseaseVariant",
"VariantIdentifier": "01a2a0",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_HasVariant": "No;No",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusIsPhased": "No"
},
{
"DiseaseName": "Cystic Fibrosis",
"ItemType": "MonogenicDiseaseVariant",
"VariantIdentifier": "bd4106",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_HasVariant": "No;No",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusIsPhased": "No"
},
{
"DiseaseName": "Cystic Fibrosis",
"ItemType": "MonogenicDiseaseVariant",
"VariantIdentifier": "4d6f38",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_HasVariant": "No;No",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusIsPhased": "No"
},
{
"DiseaseName": "Cystic Fibrosis",
"ItemType": "MonogenicDiseaseVariant",
"VariantIdentifier": "c6135a",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_HasVariant": "No;No",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusIsPhased": "No"
},
{
"DiseaseName": "Cystic Fibrosis",
"ItemType": "MonogenicDiseaseVariant",
"VariantIdentifier": "88a7f4",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_HasVariant": "No;No",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusIsPhased": "No"
},
{
"DiseaseName": "Cystic Fibrosis",
"ItemType": "MonogenicDiseaseVariant",
"VariantIdentifier": "058a4d",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_HasVariant": "Unknown"
},
{
"DiseaseName": "Cystic Fibrosis",
"ItemType": "MonogenicDiseaseVariant",
"VariantIdentifier": "2a4ddf",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_HasVariant": "Unknown"
},
{
"DiseaseName": "Cystic Fibrosis",
"ItemType": "MonogenicDiseaseVariant",
"VariantIdentifier": "e1bcfb",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_HasVariant": "No;No",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusIsPhased": "No"
},
{
"DiseaseName": "Cystic Fibrosis",
"ItemType": "MonogenicDiseaseVariant",
"VariantIdentifier": "c28795",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_HasVariant": "No;No",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusIsPhased": "No"
},
{
"DiseaseName": "Cystic Fibrosis",
"ItemType": "MonogenicDiseaseVariant",
"VariantIdentifier": "f1965c",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_HasVariant": "No;No",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusIsPhased": "No"
},
{
"DiseaseName": "Cystic Fibrosis",
"ItemType": "MonogenicDiseaseVariant",
"VariantIdentifier": "3420c1",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_HasVariant": "No;No",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusIsPhased": "No"
},
{
"DiseaseName": "Cystic Fibrosis",
"ItemType": "MonogenicDiseaseVariant",
"VariantIdentifier": "25d0b4",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_HasVariant": "No;No",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusIsPhased": "No"
},
{
"DiseaseName": "Cystic Fibrosis",
"ItemType": "MonogenicDiseaseVariant",
"VariantIdentifier": "139ab2",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_HasVariant": "No;No",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusIsPhased": "No"
},
{
"DiseaseName": "Cystic Fibrosis",
"ItemType": "MonogenicDiseaseVariant",
"VariantIdentifier": "f7a12e",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_HasVariant": "No;No",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusIsPhased": "No"
},
{
"DiseaseName": "Cystic Fibrosis",
"ItemType": "MonogenicDiseaseVariant",
"VariantIdentifier": "deb2e2",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_HasVariant": "No;No",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusIsPhased": "No"
},
{
"DiseaseName": "Cystic Fibrosis",
"ItemType": "MonogenicDiseaseVariant",
"VariantIdentifier": "884cf0",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_HasVariant": "No;No",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusIsPhased": "No"
},
{
"DiseaseName": "Cystic Fibrosis",
"ItemType": "MonogenicDiseaseVariant",
"VariantIdentifier": "b9fad1",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_HasVariant": "No;No",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusIsPhased": "No"
},
{
"DiseaseName": "Cystic Fibrosis",
"ItemType": "MonogenicDiseaseVariant",
"VariantIdentifier": "f2448d",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_HasVariant": "No;No",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusIsPhased": "No"
},
{
"DiseaseName": "Cystic Fibrosis",
"ItemType": "MonogenicDiseaseVariant",
"VariantIdentifier": "09b96f",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_HasVariant": "No;No",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusIsPhased": "No"
},
{
"DiseaseName": "Cystic Fibrosis",
"ItemType": "MonogenicDiseaseVariant",
"VariantIdentifier": "2f8651",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_HasVariant": "Unknown"
},
{
"DiseaseName": "Cystic Fibrosis",
"ItemType": "MonogenicDiseaseVariant",
"VariantIdentifier": "46efe1",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_HasVariant": "Unknown"
},
{
"DiseaseName": "Cystic Fibrosis",
"ItemType": "MonogenicDiseaseVariant",
"VariantIdentifier": "528406",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_HasVariant": "No;No",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusIsPhased": "No"
},
{
"DiseaseName": "Cystic Fibrosis",
"ItemType": "MonogenicDiseaseVariant",
"VariantIdentifier": "e8e8fc",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_HasVariant": "No;No",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusIsPhased": "No"
},
{
"DiseaseName": "Cystic Fibrosis",
"ItemType": "MonogenicDiseaseVariant",
"VariantIdentifier": "e60633",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_HasVariant": "No;No",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusIsPhased": "No"
},
{
"DiseaseName": "Cystic Fibrosis",
"ItemType": "MonogenicDiseaseVariant",
"VariantIdentifier": "d72d30",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_HasVariant": "No;No",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusIsPhased": "No"
},
{
"DiseaseName": "Cystic Fibrosis",
"ItemType": "MonogenicDiseaseVariant",
"VariantIdentifier": "a3b068",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_HasVariant": "Unknown"
},
{
"DiseaseName": "Cystic Fibrosis",
"ItemType": "MonogenicDiseaseVariant",
"VariantIdentifier": "770086",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_HasVariant": "No;No",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusIsPhased": "No"
},
{
"DiseaseName": "Cystic Fibrosis",
"ItemType": "MonogenicDiseaseVariant",
"VariantIdentifier": "a00f11",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_HasVariant": "No;No",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusIsPhased": "No"
},
{
"DiseaseName": "Cystic Fibrosis",
"ItemType": "MonogenicDiseaseVariant",
"VariantIdentifier": "79d73b",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_HasVariant": "No;No",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusIsPhased": "No"
},
{
"DiseaseName": "Sickle Cell Anemia",
"ItemType": "MonogenicDisease",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_NumberOfVariantsTested": "1",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_ProbabilityOfHavingDisease": "0",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_ProbabilityOfPassingADiseaseVariant": "0"
},
{
"DiseaseName": "Sickle Cell Anemia",
"ItemType": "MonogenicDiseaseVariant",
"VariantIdentifier": "50e857",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_HasVariant": "No;No",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusIsPhased": "No"
},
{
"DiseaseName": "Breast Cancer",
"ItemType": "PolygenicDisease",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_NumberOfLociTested": "24",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_RiskScore": "1"
},
{
"DiseaseName": "Breast Cancer",
"ItemType": "PolygenicDiseaseLocus",
"LocusIdentifier": "d7891c",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusBasePair": "T;T",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_OddsRatio": "1.00000",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_RiskWeight": "0"
},
{
"DiseaseName": "Breast Cancer",
"ItemType": "PolygenicDiseaseLocus",
"LocusIdentifier": "41c164",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusBasePair": "G;G",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_OddsRatio": "1.00000",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_RiskWeight": "0"
},
{
"DiseaseName": "Breast Cancer",
"ItemType": "PolygenicDiseaseLocus",
"LocusIdentifier": "f3a097",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusBasePair": "T;C",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_OddsRatio": "1.00000",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_RiskWeight": "0"
},
{
"DiseaseName": "Breast Cancer",
"ItemType": "PolygenicDiseaseLocus",
"LocusIdentifier": "d4626f",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusBasePair": "A;C",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_OddsRatio": "1.14000",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_RiskWeight": "1"
},
{
"DiseaseName": "Breast Cancer",
"ItemType": "PolygenicDiseaseLocus",
"LocusIdentifier": "84aaa4",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusBasePair": "A;A",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_OddsRatio": "1.00000",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_RiskWeight": "0"
},
{
"DiseaseName": "Breast Cancer",
"ItemType": "PolygenicDiseaseLocus",
"LocusIdentifier": "c8de7a",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusBasePair": "C;C",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_OddsRatio": "1.72000",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_RiskWeight": "2"
},
{
"DiseaseName": "Breast Cancer",
"ItemType": "PolygenicDiseaseLocus",
"LocusIdentifier": "d30087",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusBasePair": "C;C",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_OddsRatio": "1.00000",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_RiskWeight": "0"
},
{
"DiseaseName": "Breast Cancer",
"ItemType": "PolygenicDiseaseLocus",
"LocusIdentifier": "cafa72",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusBasePair": "T;T",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_OddsRatio": "1.00000",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_RiskWeight": "0"
},
{
"DiseaseName": "Breast Cancer",
"ItemType": "PolygenicDiseaseLocus",
"LocusIdentifier": "8f671c",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusBasePair": "T;T",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_OddsRatio": "1.00000",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_RiskWeight": "0"
},
{
"DiseaseName": "Breast Cancer",
"ItemType": "PolygenicDiseaseLocus",
"LocusIdentifier": "b3e49a",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusBasePair": "C;C",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_OddsRatio": "1.00000",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_RiskWeight": "0"
},
{
"DiseaseName": "Breast Cancer",
"ItemType": "PolygenicDiseaseLocus",
"LocusIdentifier": "8b0b02",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusBasePair": "C;C",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_OddsRatio": "1.00000",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_RiskWeight": "0"
},
{
"DiseaseName": "Breast Cancer",
"ItemType": "PolygenicDiseaseLocus",
"LocusIdentifier": "25cafc",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusBasePair": "T;T",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_OddsRatio": "1.00000",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_RiskWeight": "0"
},
{
"DiseaseName": "Breast Cancer",
"ItemType": "PolygenicDiseaseLocus",
"LocusIdentifier": "34c7e5",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusBasePair": "A;A",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_OddsRatio": "1.00000",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_RiskWeight": "0"
},
{
"DiseaseName": "Breast Cancer",
"ItemType": "PolygenicDiseaseLocus",
"LocusIdentifier": "60ce27",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusBasePair": "A;A",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_OddsRatio": "1.00000",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_RiskWeight": "0"
},
{
"DiseaseName": "Breast Cancer",
"ItemType": "PolygenicDiseaseLocus",
"LocusIdentifier": "328cdf",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusBasePair": "A;A",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_OddsRatio": "1.00000",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_RiskWeight": "0"
},
{
"DiseaseName": "Breast Cancer",
"ItemType": "PolygenicDiseaseLocus",
"LocusIdentifier": "849bc7",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusBasePair": "A;A",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_OddsRatio": "1.00000",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_RiskWeight": "0"
},
{
"DiseaseName": "Breast Cancer",
"ItemType": "PolygenicDiseaseLocus",
"LocusIdentifier": "5af5e3",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusBasePair": "G;G",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_OddsRatio": "1.00000",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_RiskWeight": "0"
},
{
"DiseaseName": "Breast Cancer",
"ItemType": "PolygenicDiseaseLocus",
"LocusIdentifier": "c354fa",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusBasePair": "C;C",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_OddsRatio": "1.00000",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_RiskWeight": "0"
},
{
"DiseaseName": "Breast Cancer",
"ItemType": "PolygenicDiseaseLocus",
"LocusIdentifier": "eedc23",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusBasePair": "T;T",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_OddsRatio": "1.00000",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_RiskWeight": "0"
},
{
"DiseaseName": "Breast Cancer",
"ItemType": "PolygenicDiseaseLocus",
"LocusIdentifier": "2ee027",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusBasePair": "C;C",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_OddsRatio": "1.00000",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_RiskWeight": "0"
},
{
"DiseaseName": "Breast Cancer",
"ItemType": "PolygenicDiseaseLocus",
"LocusIdentifier": "fc4bab",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusBasePair": "T;T",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_OddsRatio": "1.00000",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_RiskWeight": "0"
},
{
"DiseaseName": "Breast Cancer",
"ItemType": "PolygenicDiseaseLocus",
"LocusIdentifier": "f8b225",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusBasePair": "C;C",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_OddsRatio": "1.00000",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_RiskWeight": "0"
},
{
"DiseaseName": "Breast Cancer",
"ItemType": "PolygenicDiseaseLocus",
"LocusIdentifier": "4a072c",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusBasePair": "C;C",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_OddsRatio": "1.00000",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_RiskWeight": "0"
},
{
"DiseaseName": "Breast Cancer",
"ItemType": "PolygenicDiseaseLocus",
"LocusIdentifier": "070f24",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusBasePair": "C;C",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_OddsRatio": "1.00000",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_RiskWeight": "0"
},
{
"DiseaseName": "Breast Cancer",
"ItemType": "PolygenicDiseaseLocus",
"LocusIdentifier": "d08516",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusBasePair": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_OddsRatio": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_RiskWeight": "Unknown"
},
{
"DiseaseName": "Breast Cancer",
"ItemType": "PolygenicDiseaseLocus",
"LocusIdentifier": "047b84",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusBasePair": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_OddsRatio": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_RiskWeight": "Unknown"
},
{
"ItemType": "Trait",
"TraitName": "Lactose Tolerance",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusIsPhased_rs182549": "No",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusIsPhased_rs4988235": "No",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs182549": "T;C",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs4988235": "A;G",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_NumberOfRulesTested": "5",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_OutcomeScore_Intolerant": "0",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_OutcomeScore_Tolerant": "2"
},
{
"ItemType": "TraitRule",
"RuleIdentifier": "f4e02c",
"TraitName": "Lactose Tolerance",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_PassesRule": "No",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_RuleLocusBasePair_43bf19": "T;C"
},
{
"ItemType": "TraitRule",
"RuleIdentifier": "cc3df0",
"TraitName": "Lactose Tolerance",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_PassesRule": "Yes",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_RuleLocusBasePair_a7feff": "T;C"
},
{
"ItemType": "TraitRule",
"RuleIdentifier": "8170ee",
"TraitName": "Lactose Tolerance",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_PassesRule": "No",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_RuleLocusBasePair_da6b04": "A;G"
},
{
"ItemType": "TraitRule",
"RuleIdentifier": "52425f",
"TraitName": "Lactose Tolerance",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_PassesRule": "Yes",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_RuleLocusBasePair_176dde": "A;G"
},
{
"ItemType": "TraitRule",
"RuleIdentifier": "4b5c35",
"TraitName": "Lactose Tolerance",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_PassesRule": "No",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_RuleLocusBasePair_164acb": "A;G"
},
{
"ItemType": "Trait",
"TraitName": "Hair Texture",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusIsPhased_rs11803731": "No",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusIsPhased_rs17646946": "No",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusIsPhased_rs7349332": "No",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs11803731": "A;T",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs17646946": "A;G",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs7349332": "T;C",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_NumberOfRulesTested": "9",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_OutcomeScore_Curly": "3",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_OutcomeScore_Straight": "0"
},
{
"ItemType": "TraitRule",
"RuleIdentifier": "fde405",
"TraitName": "Hair Texture",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_PassesRule": "No",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_RuleLocusBasePair_0e06e2": "T;C"
},
{
"ItemType": "TraitRule",
"RuleIdentifier": "6bd1da",
"TraitName": "Hair Texture",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_PassesRule": "Yes",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_RuleLocusBasePair_2da1b7": "T;C"
},
{
"ItemType": "TraitRule",
"RuleIdentifier": "32e377",
"TraitName": "Hair Texture",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_PassesRule": "No",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_RuleLocusBasePair_c6760e": "T;C"
},
{
"ItemType": "TraitRule",
"RuleIdentifier": "34e6d2",
"TraitName": "Hair Texture",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_PassesRule": "No",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_RuleLocusBasePair_9079c9": "A;T"
},
{
"ItemType": "TraitRule",
"RuleIdentifier": "cf6cb5",
"TraitName": "Hair Texture",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_PassesRule": "Yes",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_RuleLocusBasePair_d0aad3": "A;T"
},
{
"ItemType": "TraitRule",
"RuleIdentifier": "2ba65b",
"TraitName": "Hair Texture",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_PassesRule": "No",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_RuleLocusBasePair_f554b5": "A;T"
},
{
"ItemType": "TraitRule",
"RuleIdentifier": "ae3274",
"TraitName": "Hair Texture",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_PassesRule": "No",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_RuleLocusBasePair_f500c2": "A;G"
},
{
"ItemType": "TraitRule",
"RuleIdentifier": "a546bf",
"TraitName": "Hair Texture",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_PassesRule": "Yes",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_RuleLocusBasePair_f1144a": "A;G"
},
{
"ItemType": "TraitRule",
"RuleIdentifier": "b8dc0a",
"TraitName": "Hair Texture",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_PassesRule": "No",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_RuleLocusBasePair_468bb3": "A;G"
},
{
"ItemType": "Trait",
"TraitName": "Facial Structure",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusIsPhased_rs1005999": "No",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusIsPhased_rs10237838": "No",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusIsPhased_rs11237982": "No",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusIsPhased_rs12694574": "No",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusIsPhased_rs13097965": "No",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusIsPhased_rs17447439": "No",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusIsPhased_rs1747677": "No",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusIsPhased_rs1978859": "No",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusIsPhased_rs2034127": "No",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusIsPhased_rs2327089": "No",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusIsPhased_rs2832438": "No",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusIsPhased_rs2894450": "No",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusIsPhased_rs4552364": "No",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusIsPhased_rs6020940": "No",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusIsPhased_rs6478394": "No",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusIsPhased_rs7516150": "No",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusIsPhased_rs7552331": "No",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusIsPhased_rs7965082": "No",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusIsPhased_rs805722": "No",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusIsPhased_rs9858909": "No",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs1005999": "T;T",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs1008591": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs1015092": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs1019212": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs10234405": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs10237319": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs10237488": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs10237838": "C;C",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs10265937": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs10266101": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs10278187": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs10485860": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs10843104": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs11191909": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs11237982": "T;C",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs1158810": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs11604811": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs12155314": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs12358982": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs12437560": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs12694574": "T;C",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs13097965": "T;C",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs13098099": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs1562005": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs1562006": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs1572037": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs16863422": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs16977002": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs16977008": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs16977009": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs17252053": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs17447439": "A;A",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs1747677": "C;C",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs1887276": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs1939697": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs1939707": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs1978859": "T;C",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs1999527": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs2034127": "G;G",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs2034128": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs2034129": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs2108166": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs2168809": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs2274107": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs2327089": "T;T",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs2327101": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs2342494": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs2422239": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs2422241": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs2832438": "T;C",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs2894450": "A;G",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs397723": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs4053148": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs4353811": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs4433629": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs4552364": "T;C",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs4633993": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs4648379": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs4648477": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs4648478": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs4793389": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs6020940": "A;A",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs6020957": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs6039266": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs6039272": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs6056066": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs6056119": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs6056126": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs6462544": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs6462562": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs6478394": "A;G",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs6555969": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs6749293": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs6795519": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs6950754": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs717463": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs7214306": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs7516150": "C;C",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs7552331": "G;G",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs7617069": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs7628370": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs7640340": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs7779616": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs7781059": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs7799331": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs7803030": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs7807181": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs7965082": "C;C",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs7966317": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs805693": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs805694": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs805722": "C;C",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs8079498": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs875143": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs894883": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs911015": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs911020": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs9692219": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs974448": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs975633": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs9858909": "G;G",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs9971100": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_NumberOfRulesTested": "0"
},
{
"ItemType": "Trait",
"TraitName": "Eye Color",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusIsPhased_rs1003719": "No",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusIsPhased_rs1105879": "No",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusIsPhased_rs1126809": "No",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusIsPhased_rs1129038": "No",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusIsPhased_rs11957757": "No",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusIsPhased_rs121908120": "No",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusIsPhased_rs12203592": "No",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusIsPhased_rs12452184": "No",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusIsPhased_rs12593929": "No",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusIsPhased_rs12896399": "No",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusIsPhased_rs12906280": "No",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusIsPhased_rs12913823": "No",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusIsPhased_rs12913832": "No",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusIsPhased_rs1325127": "No",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusIsPhased_rs1393350": "No",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusIsPhased_rs1408799": "No",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusIsPhased_rs1426654": "No",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusIsPhased_rs1667394": "No",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusIsPhased_rs16891982": "No",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusIsPhased_rs1800401": "No",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusIsPhased_rs1800407": "No",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusIsPhased_rs1800414": "No",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusIsPhased_rs2070959": "No",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusIsPhased_rs2733832": "No",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusIsPhased_rs2748901": "No",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusIsPhased_rs351385": "No",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusIsPhased_rs3794604": "No",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusIsPhased_rs4778138": "No",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusIsPhased_rs4778218": "No",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusIsPhased_rs4778241": "No",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusIsPhased_rs4911414": "No",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusIsPhased_rs4911442": "No",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusIsPhased_rs6058017": "No",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusIsPhased_rs6828137": "No",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusIsPhased_rs6910861": "No",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusIsPhased_rs7174027": "No",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusIsPhased_rs7183877": "No",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusIsPhased_rs7495174": "No",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusIsPhased_rs8028689": "No",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusIsPhased_rs892839": "No",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusIsPhased_rs916977": "No",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusIsPhased_rs9782955": "No",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusIsPhased_rs9894429": "No",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusIsPhased_rs9971729": "No",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs1003719": "G;G",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs10209564": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs1105879": "A;C",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs1126809": "A;G",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs112747614": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs1129038": "T;C",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs11631797": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs116359091": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs11957757": "G;G",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs121908120": "T;T",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs12203592": "C;C",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs12335410": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs12452184": "C;C",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs12543326": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs12552712": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs12593929": "A;G",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs12614022": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs12896399": "T;T",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs12906280": "G;G",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs12913823": "T;C",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs12913832": "A;G",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs13016869": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs1325127": "T;T",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs13297008": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs138777265": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs1393350": "A;G",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs1408799": "C;C",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs141318671": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs1426654": "A;A",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs147068120": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs1667394": "T;C",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs16891982": "G;G",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs17184180": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs1800401": "G;G",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs1800407": "C;C",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs1800414": "T;T",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs2070959": "A;G",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs2095645": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs2238289": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs2240203": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs2252893": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs2385028": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs2733832": "T;T",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs2748901": "A;G",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs2835621": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs2835630": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs2835660": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs2854746": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs341147": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs348613": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs35051352": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs351385": "A;G",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs3768056": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs3794604": "T;C",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs3809761": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs3912104": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs3935591": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs3940272": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs4521336": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs4778138": "A;G",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs4778218": "G;G",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs4778241": "A;C",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs4790309": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs4911414": "T;G",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs4911442": "A;A",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs6058017": "A;A",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs622330": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs62330021": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs6420484": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs6693258": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs6828137": "G;G",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs6910861": "A;G",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs6944702": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs6997494": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs7170852": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs7174027": "A;G",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs7183877": "C;C",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs7219915": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs72777200": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs7277820": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs728405": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs72928978": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs73488486": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs74409360": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs7495174": "A;G",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs790464": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs8028689": "T;C",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs892839": "G;G",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs916977": "T;C",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs9301973": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs9782955": "C;C",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs9894429": "C;C",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs989869": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs9971729": "A;C",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_NumberOfRulesTested": "0"
},
{
"ItemType": "Trait",
"TraitName": "Hair Color",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusIsPhased_rs11636232": "No",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusIsPhased_rs12203592": "No",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusIsPhased_rs12821256": "No",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusIsPhased_rs12896399": "No",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusIsPhased_rs12913832": "No",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusIsPhased_rs1540771": "No",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusIsPhased_rs1667394": "No",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusIsPhased_rs1805007": "No",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusIsPhased_rs1805008": "No",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusIsPhased_rs35264875": "No",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusIsPhased_rs3829241": "No",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusIsPhased_rs6918152": "No",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusIsPhased_rs7174027": "No",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusIsPhased_rs7183877": "No",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusIsPhased_rs7495174": "No",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusIsPhased_rs8028689": "No",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs11636232": "T;C",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs11855019": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs12203592": "C;C",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs12821256": "T;T",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs12896399": "T;T",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs12913832": "A;G",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs1540771": "C;C",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs1667394": "T;C",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs1805007": "C;C",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs1805008": "C;C",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs28777": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs35264875": "T;A",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs3829241": "G;G",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs4778211": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs6918152": "A;G",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs7174027": "A;G",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs7183877": "C;C",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs7495174": "A;G",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs8028689": "T;C",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs8039195": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_NumberOfRulesTested": "0"
},
{
"ItemType": "Trait",
"TraitName": "Skin Color",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusIsPhased_rs1042602": "No",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusIsPhased_rs1126809": "No",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusIsPhased_rs12203592": "No",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusIsPhased_rs1426654": "No",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusIsPhased_rs16891982": "No",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusIsPhased_rs1834640": "No",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusIsPhased_rs26722": "No",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusIsPhased_rs2762462": "No",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusIsPhased_rs642742": "No",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusIsPhased_rs937171": "No",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs10424065": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs1042602": "C;C",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs1126809": "A;G",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs12203592": "C;C",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs142317543": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs1426654": "A;A",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs16891982": "G;G",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs1800422": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs1834640": "A;A",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs26722": "C;C",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs2762462": "C;C",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs3212368": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs3212369": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs642742": "T;C",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs7176696": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs7182710": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs784416": "Unknown",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_LocusValue_rs937171": "G;G",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_NumberOfRulesTested": "0"
}
]

View file

@ -1,923 +0,0 @@
[
{
"AnalysisType": "Person",
"AnalysisVersion": "1",
"CombinedGenomesExist": "No",
"GenomeIdentifier": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
"ItemType": "Metadata"
},
{
"DiseaseName": "Cystic Fibrosis",
"ItemType": "MonogenicDisease",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_NumberOfVariantsTested": "26",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOfHavingDisease": "0",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOfPassingADiseaseVariant": "50"
},
{
"DiseaseName": "Cystic Fibrosis",
"ItemType": "MonogenicDiseaseVariant",
"VariantIdentifier": "36965d",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_HasVariant": "No;No",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusIsPhased": "No"
},
{
"DiseaseName": "Cystic Fibrosis",
"ItemType": "MonogenicDiseaseVariant",
"VariantIdentifier": "5706b0",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_HasVariant": "No;No",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusIsPhased": "No"
},
{
"DiseaseName": "Cystic Fibrosis",
"ItemType": "MonogenicDiseaseVariant",
"VariantIdentifier": "01a2a0",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_HasVariant": "No;No",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusIsPhased": "No"
},
{
"DiseaseName": "Cystic Fibrosis",
"ItemType": "MonogenicDiseaseVariant",
"VariantIdentifier": "bd4106",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_HasVariant": "No;No",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusIsPhased": "No"
},
{
"DiseaseName": "Cystic Fibrosis",
"ItemType": "MonogenicDiseaseVariant",
"VariantIdentifier": "4d6f38",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_HasVariant": "No;No",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusIsPhased": "No"
},
{
"DiseaseName": "Cystic Fibrosis",
"ItemType": "MonogenicDiseaseVariant",
"VariantIdentifier": "c6135a",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_HasVariant": "Yes;No",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusIsPhased": "No"
},
{
"DiseaseName": "Cystic Fibrosis",
"ItemType": "MonogenicDiseaseVariant",
"VariantIdentifier": "88a7f4",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_HasVariant": "No;No",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusIsPhased": "No"
},
{
"DiseaseName": "Cystic Fibrosis",
"ItemType": "MonogenicDiseaseVariant",
"VariantIdentifier": "058a4d",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_HasVariant": "Unknown"
},
{
"DiseaseName": "Cystic Fibrosis",
"ItemType": "MonogenicDiseaseVariant",
"VariantIdentifier": "2a4ddf",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_HasVariant": "Unknown"
},
{
"DiseaseName": "Cystic Fibrosis",
"ItemType": "MonogenicDiseaseVariant",
"VariantIdentifier": "e1bcfb",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_HasVariant": "No;No",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusIsPhased": "No"
},
{
"DiseaseName": "Cystic Fibrosis",
"ItemType": "MonogenicDiseaseVariant",
"VariantIdentifier": "c28795",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_HasVariant": "No;No",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusIsPhased": "No"
},
{
"DiseaseName": "Cystic Fibrosis",
"ItemType": "MonogenicDiseaseVariant",
"VariantIdentifier": "f1965c",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_HasVariant": "No;No",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusIsPhased": "No"
},
{
"DiseaseName": "Cystic Fibrosis",
"ItemType": "MonogenicDiseaseVariant",
"VariantIdentifier": "3420c1",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_HasVariant": "No;No",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusIsPhased": "No"
},
{
"DiseaseName": "Cystic Fibrosis",
"ItemType": "MonogenicDiseaseVariant",
"VariantIdentifier": "25d0b4",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_HasVariant": "No;No",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusIsPhased": "No"
},
{
"DiseaseName": "Cystic Fibrosis",
"ItemType": "MonogenicDiseaseVariant",
"VariantIdentifier": "139ab2",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_HasVariant": "No;No",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusIsPhased": "No"
},
{
"DiseaseName": "Cystic Fibrosis",
"ItemType": "MonogenicDiseaseVariant",
"VariantIdentifier": "f7a12e",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_HasVariant": "No;No",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusIsPhased": "No"
},
{
"DiseaseName": "Cystic Fibrosis",
"ItemType": "MonogenicDiseaseVariant",
"VariantIdentifier": "deb2e2",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_HasVariant": "No;No",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusIsPhased": "No"
},
{
"DiseaseName": "Cystic Fibrosis",
"ItemType": "MonogenicDiseaseVariant",
"VariantIdentifier": "884cf0",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_HasVariant": "No;No",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusIsPhased": "No"
},
{
"DiseaseName": "Cystic Fibrosis",
"ItemType": "MonogenicDiseaseVariant",
"VariantIdentifier": "b9fad1",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_HasVariant": "No;No",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusIsPhased": "No"
},
{
"DiseaseName": "Cystic Fibrosis",
"ItemType": "MonogenicDiseaseVariant",
"VariantIdentifier": "f2448d",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_HasVariant": "No;No",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusIsPhased": "No"
},
{
"DiseaseName": "Cystic Fibrosis",
"ItemType": "MonogenicDiseaseVariant",
"VariantIdentifier": "09b96f",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_HasVariant": "No;No",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusIsPhased": "No"
},
{
"DiseaseName": "Cystic Fibrosis",
"ItemType": "MonogenicDiseaseVariant",
"VariantIdentifier": "2f8651",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_HasVariant": "Unknown"
},
{
"DiseaseName": "Cystic Fibrosis",
"ItemType": "MonogenicDiseaseVariant",
"VariantIdentifier": "46efe1",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_HasVariant": "Unknown"
},
{
"DiseaseName": "Cystic Fibrosis",
"ItemType": "MonogenicDiseaseVariant",
"VariantIdentifier": "528406",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_HasVariant": "No;No",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusIsPhased": "No"
},
{
"DiseaseName": "Cystic Fibrosis",
"ItemType": "MonogenicDiseaseVariant",
"VariantIdentifier": "e8e8fc",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_HasVariant": "No;No",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusIsPhased": "No"
},
{
"DiseaseName": "Cystic Fibrosis",
"ItemType": "MonogenicDiseaseVariant",
"VariantIdentifier": "e60633",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_HasVariant": "No;No",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusIsPhased": "No"
},
{
"DiseaseName": "Cystic Fibrosis",
"ItemType": "MonogenicDiseaseVariant",
"VariantIdentifier": "d72d30",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_HasVariant": "No;No",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusIsPhased": "No"
},
{
"DiseaseName": "Cystic Fibrosis",
"ItemType": "MonogenicDiseaseVariant",
"VariantIdentifier": "a3b068",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_HasVariant": "Unknown"
},
{
"DiseaseName": "Cystic Fibrosis",
"ItemType": "MonogenicDiseaseVariant",
"VariantIdentifier": "770086",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_HasVariant": "No;No",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusIsPhased": "No"
},
{
"DiseaseName": "Cystic Fibrosis",
"ItemType": "MonogenicDiseaseVariant",
"VariantIdentifier": "a00f11",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_HasVariant": "No;No",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusIsPhased": "No"
},
{
"DiseaseName": "Cystic Fibrosis",
"ItemType": "MonogenicDiseaseVariant",
"VariantIdentifier": "79d73b",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_HasVariant": "No;No",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusIsPhased": "No"
},
{
"DiseaseName": "Sickle Cell Anemia",
"ItemType": "MonogenicDisease",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_NumberOfVariantsTested": "1",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOfHavingDisease": "0",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_ProbabilityOfPassingADiseaseVariant": "0"
},
{
"DiseaseName": "Sickle Cell Anemia",
"ItemType": "MonogenicDiseaseVariant",
"VariantIdentifier": "50e857",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_HasVariant": "No;No",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusIsPhased": "No"
},
{
"DiseaseName": "Breast Cancer",
"ItemType": "PolygenicDisease",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_NumberOfLociTested": "24",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_RiskScore": "1"
},
{
"DiseaseName": "Breast Cancer",
"ItemType": "PolygenicDiseaseLocus",
"LocusIdentifier": "d7891c",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusBasePair": "C;C",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_OddsRatio": "1.28000",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_RiskWeight": "1"
},
{
"DiseaseName": "Breast Cancer",
"ItemType": "PolygenicDiseaseLocus",
"LocusIdentifier": "41c164",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusBasePair": "G;G",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_OddsRatio": "1.00000",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_RiskWeight": "0"
},
{
"DiseaseName": "Breast Cancer",
"ItemType": "PolygenicDiseaseLocus",
"LocusIdentifier": "f3a097",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusBasePair": "C;C",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_OddsRatio": "1.00000",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_RiskWeight": "0"
},
{
"DiseaseName": "Breast Cancer",
"ItemType": "PolygenicDiseaseLocus",
"LocusIdentifier": "d4626f",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusBasePair": "A;A",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_OddsRatio": "1.00000",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_RiskWeight": "0"
},
{
"DiseaseName": "Breast Cancer",
"ItemType": "PolygenicDiseaseLocus",
"LocusIdentifier": "84aaa4",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusBasePair": "A;A",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_OddsRatio": "1.00000",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_RiskWeight": "0"
},
{
"DiseaseName": "Breast Cancer",
"ItemType": "PolygenicDiseaseLocus",
"LocusIdentifier": "c8de7a",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusBasePair": "T;T",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_OddsRatio": "1.00000",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_RiskWeight": "0"
},
{
"DiseaseName": "Breast Cancer",
"ItemType": "PolygenicDiseaseLocus",
"LocusIdentifier": "d30087",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusBasePair": "T;C",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_OddsRatio": "1.14000",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_RiskWeight": "1"
},
{
"DiseaseName": "Breast Cancer",
"ItemType": "PolygenicDiseaseLocus",
"LocusIdentifier": "cafa72",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusBasePair": "T;T",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_OddsRatio": "1.00000",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_RiskWeight": "0"
},
{
"DiseaseName": "Breast Cancer",
"ItemType": "PolygenicDiseaseLocus",
"LocusIdentifier": "8f671c",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusBasePair": "C;C",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_OddsRatio": "1.28000",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_RiskWeight": "2"
},
{
"DiseaseName": "Breast Cancer",
"ItemType": "PolygenicDiseaseLocus",
"LocusIdentifier": "b3e49a",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusBasePair": "C;C",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_OddsRatio": "1.00000",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_RiskWeight": "0"
},
{
"DiseaseName": "Breast Cancer",
"ItemType": "PolygenicDiseaseLocus",
"LocusIdentifier": "8b0b02",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusBasePair": "C;C",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_OddsRatio": "1.00000",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_RiskWeight": "0"
},
{
"DiseaseName": "Breast Cancer",
"ItemType": "PolygenicDiseaseLocus",
"LocusIdentifier": "25cafc",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusBasePair": "T;T",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_OddsRatio": "1.00000",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_RiskWeight": "0"
},
{
"DiseaseName": "Breast Cancer",
"ItemType": "PolygenicDiseaseLocus",
"LocusIdentifier": "34c7e5",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusBasePair": "A;A",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_OddsRatio": "1.00000",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_RiskWeight": "0"
},
{
"DiseaseName": "Breast Cancer",
"ItemType": "PolygenicDiseaseLocus",
"LocusIdentifier": "60ce27",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusBasePair": "A;A",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_OddsRatio": "1.00000",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_RiskWeight": "0"
},
{
"DiseaseName": "Breast Cancer",
"ItemType": "PolygenicDiseaseLocus",
"LocusIdentifier": "328cdf",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusBasePair": "A;A",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_OddsRatio": "1.00000",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_RiskWeight": "0"
},
{
"DiseaseName": "Breast Cancer",
"ItemType": "PolygenicDiseaseLocus",
"LocusIdentifier": "849bc7",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusBasePair": "A;A",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_OddsRatio": "1.00000",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_RiskWeight": "0"
},
{
"DiseaseName": "Breast Cancer",
"ItemType": "PolygenicDiseaseLocus",
"LocusIdentifier": "5af5e3",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusBasePair": "G;G",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_OddsRatio": "1.00000",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_RiskWeight": "0"
},
{
"DiseaseName": "Breast Cancer",
"ItemType": "PolygenicDiseaseLocus",
"LocusIdentifier": "c354fa",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusBasePair": "C;C",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_OddsRatio": "1.00000",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_RiskWeight": "0"
},
{
"DiseaseName": "Breast Cancer",
"ItemType": "PolygenicDiseaseLocus",
"LocusIdentifier": "eedc23",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusBasePair": "T;C",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_OddsRatio": "1.05000",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_RiskWeight": "1"
},
{
"DiseaseName": "Breast Cancer",
"ItemType": "PolygenicDiseaseLocus",
"LocusIdentifier": "2ee027",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusBasePair": "C;C",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_OddsRatio": "1.00000",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_RiskWeight": "0"
},
{
"DiseaseName": "Breast Cancer",
"ItemType": "PolygenicDiseaseLocus",
"LocusIdentifier": "fc4bab",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusBasePair": "T;T",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_OddsRatio": "1.00000",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_RiskWeight": "0"
},
{
"DiseaseName": "Breast Cancer",
"ItemType": "PolygenicDiseaseLocus",
"LocusIdentifier": "f8b225",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusBasePair": "C;C",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_OddsRatio": "1.00000",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_RiskWeight": "0"
},
{
"DiseaseName": "Breast Cancer",
"ItemType": "PolygenicDiseaseLocus",
"LocusIdentifier": "4a072c",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusBasePair": "C;C",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_OddsRatio": "1.00000",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_RiskWeight": "0"
},
{
"DiseaseName": "Breast Cancer",
"ItemType": "PolygenicDiseaseLocus",
"LocusIdentifier": "070f24",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusBasePair": "C;C",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_OddsRatio": "1.00000",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_RiskWeight": "0"
},
{
"DiseaseName": "Breast Cancer",
"ItemType": "PolygenicDiseaseLocus",
"LocusIdentifier": "d08516",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusBasePair": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_OddsRatio": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_RiskWeight": "Unknown"
},
{
"DiseaseName": "Breast Cancer",
"ItemType": "PolygenicDiseaseLocus",
"LocusIdentifier": "047b84",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusBasePair": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_OddsRatio": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_RiskWeight": "Unknown"
},
{
"ItemType": "Trait",
"TraitName": "Lactose Tolerance",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusIsPhased_rs182549": "No",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusIsPhased_rs4988235": "No",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs182549": "T;T",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs4988235": "A;A",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_NumberOfRulesTested": "5",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_OutcomeScore_Intolerant": "0",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_OutcomeScore_Tolerant": "3"
},
{
"ItemType": "TraitRule",
"RuleIdentifier": "f4e02c",
"TraitName": "Lactose Tolerance",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_PassesRule": "No",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_RuleLocusBasePair_43bf19": "T;T"
},
{
"ItemType": "TraitRule",
"RuleIdentifier": "cc3df0",
"TraitName": "Lactose Tolerance",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_PassesRule": "Yes",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_RuleLocusBasePair_a7feff": "T;T"
},
{
"ItemType": "TraitRule",
"RuleIdentifier": "8170ee",
"TraitName": "Lactose Tolerance",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_PassesRule": "No",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_RuleLocusBasePair_da6b04": "A;A"
},
{
"ItemType": "TraitRule",
"RuleIdentifier": "52425f",
"TraitName": "Lactose Tolerance",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_PassesRule": "No",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_RuleLocusBasePair_176dde": "A;A"
},
{
"ItemType": "TraitRule",
"RuleIdentifier": "4b5c35",
"TraitName": "Lactose Tolerance",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_PassesRule": "Yes",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_RuleLocusBasePair_164acb": "A;A"
},
{
"ItemType": "Trait",
"TraitName": "Hair Texture",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusIsPhased_rs11803731": "No",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusIsPhased_rs17646946": "No",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusIsPhased_rs7349332": "No",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs11803731": "A;A",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs17646946": "G;G",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs7349332": "C;C",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_NumberOfRulesTested": "9",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_OutcomeScore_Curly": "0",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_OutcomeScore_Straight": "6"
},
{
"ItemType": "TraitRule",
"RuleIdentifier": "fde405",
"TraitName": "Hair Texture",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_PassesRule": "Yes",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_RuleLocusBasePair_0e06e2": "C;C"
},
{
"ItemType": "TraitRule",
"RuleIdentifier": "6bd1da",
"TraitName": "Hair Texture",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_PassesRule": "No",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_RuleLocusBasePair_2da1b7": "C;C"
},
{
"ItemType": "TraitRule",
"RuleIdentifier": "32e377",
"TraitName": "Hair Texture",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_PassesRule": "No",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_RuleLocusBasePair_c6760e": "C;C"
},
{
"ItemType": "TraitRule",
"RuleIdentifier": "34e6d2",
"TraitName": "Hair Texture",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_PassesRule": "Yes",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_RuleLocusBasePair_9079c9": "A;A"
},
{
"ItemType": "TraitRule",
"RuleIdentifier": "cf6cb5",
"TraitName": "Hair Texture",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_PassesRule": "No",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_RuleLocusBasePair_d0aad3": "A;A"
},
{
"ItemType": "TraitRule",
"RuleIdentifier": "2ba65b",
"TraitName": "Hair Texture",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_PassesRule": "No",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_RuleLocusBasePair_f554b5": "A;A"
},
{
"ItemType": "TraitRule",
"RuleIdentifier": "ae3274",
"TraitName": "Hair Texture",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_PassesRule": "Yes",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_RuleLocusBasePair_f500c2": "G;G"
},
{
"ItemType": "TraitRule",
"RuleIdentifier": "a546bf",
"TraitName": "Hair Texture",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_PassesRule": "No",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_RuleLocusBasePair_f1144a": "G;G"
},
{
"ItemType": "TraitRule",
"RuleIdentifier": "b8dc0a",
"TraitName": "Hair Texture",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_PassesRule": "No",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_RuleLocusBasePair_468bb3": "G;G"
},
{
"ItemType": "Trait",
"TraitName": "Facial Structure",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusIsPhased_rs1005999": "No",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusIsPhased_rs10237838": "No",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusIsPhased_rs10843104": "No",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusIsPhased_rs11237982": "No",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusIsPhased_rs12694574": "No",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusIsPhased_rs13097965": "No",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusIsPhased_rs17447439": "No",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusIsPhased_rs1747677": "No",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusIsPhased_rs1978859": "No",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusIsPhased_rs2034127": "No",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusIsPhased_rs2327089": "No",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusIsPhased_rs2832438": "No",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusIsPhased_rs2894450": "No",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusIsPhased_rs4552364": "No",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusIsPhased_rs6020940": "No",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusIsPhased_rs6478394": "No",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusIsPhased_rs7516150": "No",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusIsPhased_rs7552331": "No",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusIsPhased_rs7965082": "No",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusIsPhased_rs805722": "No",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusIsPhased_rs9858909": "No",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs1005999": "C;C",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs1008591": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs1015092": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs1019212": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs10234405": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs10237319": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs10237488": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs10237838": "T;C",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs10265937": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs10266101": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs10278187": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs10485860": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs10843104": "T;T",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs11191909": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs11237982": "T;C",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs1158810": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs11604811": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs12155314": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs12358982": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs12437560": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs12694574": "T;C",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs13097965": "T;C",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs13098099": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs1562005": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs1562006": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs1572037": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs16863422": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs16977002": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs16977008": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs16977009": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs17252053": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs17447439": "A;A",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs1747677": "C;C",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs1887276": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs1939697": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs1939707": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs1978859": "T;C",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs1999527": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs2034127": "G;G",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs2034128": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs2034129": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs2108166": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs2168809": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs2274107": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs2327089": "T;T",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs2327101": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs2342494": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs2422239": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs2422241": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs2832438": "T;T",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs2894450": "G;G",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs397723": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs4053148": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs4353811": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs4433629": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs4552364": "C;C",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs4633993": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs4648379": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs4648477": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs4648478": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs4793389": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs6020940": "A;A",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs6020957": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs6039266": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs6039272": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs6056066": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs6056119": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs6056126": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs6462544": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs6462562": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs6478394": "A;A",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs6555969": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs6749293": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs6795519": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs6950754": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs717463": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs7214306": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs7516150": "C;C",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs7552331": "G;G",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs7617069": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs7628370": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs7640340": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs7779616": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs7781059": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs7799331": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs7803030": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs7807181": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs7965082": "T;C",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs7966317": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs805693": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs805694": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs805722": "C;C",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs8079498": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs875143": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs894883": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs911015": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs911020": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs9692219": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs974448": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs975633": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs9858909": "G;G",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs9971100": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_NumberOfRulesTested": "0"
},
{
"ItemType": "Trait",
"TraitName": "Eye Color",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusIsPhased_rs1003719": "No",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusIsPhased_rs1105879": "No",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusIsPhased_rs1126809": "No",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusIsPhased_rs1129038": "No",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusIsPhased_rs11957757": "No",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusIsPhased_rs121908120": "No",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusIsPhased_rs12203592": "No",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusIsPhased_rs12452184": "No",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusIsPhased_rs12593929": "No",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusIsPhased_rs12896399": "No",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusIsPhased_rs12906280": "No",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusIsPhased_rs12913823": "No",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusIsPhased_rs12913832": "No",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusIsPhased_rs1325127": "No",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusIsPhased_rs1393350": "No",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusIsPhased_rs1408799": "No",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusIsPhased_rs1426654": "No",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusIsPhased_rs1667394": "No",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusIsPhased_rs16891982": "No",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusIsPhased_rs1800401": "No",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusIsPhased_rs1800407": "No",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusIsPhased_rs1800414": "No",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusIsPhased_rs2070959": "No",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusIsPhased_rs2733832": "No",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusIsPhased_rs2748901": "No",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusIsPhased_rs351385": "No",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusIsPhased_rs3794604": "No",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusIsPhased_rs4778138": "No",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusIsPhased_rs4778218": "No",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusIsPhased_rs4778241": "No",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusIsPhased_rs4911414": "No",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusIsPhased_rs4911442": "No",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusIsPhased_rs6058017": "No",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusIsPhased_rs6828137": "No",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusIsPhased_rs6910861": "No",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusIsPhased_rs7174027": "No",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusIsPhased_rs7183877": "No",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusIsPhased_rs7495174": "No",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusIsPhased_rs8028689": "No",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusIsPhased_rs892839": "No",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusIsPhased_rs916977": "No",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusIsPhased_rs9782955": "No",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusIsPhased_rs9894429": "No",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusIsPhased_rs9971729": "No",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs1003719": "A;A",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs10209564": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs1105879": "A;A",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs1126809": "A;G",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs112747614": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs1129038": "T;C",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs11631797": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs116359091": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs11957757": "A;G",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs121908120": "T;T",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs12203592": "C;C",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs12335410": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs12452184": "C;C",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs12543326": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs12552712": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs12593929": "A;A",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs12614022": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs12896399": "G;G",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs12906280": "A;G",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs12913823": "T;C",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs12913832": "A;G",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs13016869": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs1325127": "T;T",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs13297008": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs138777265": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs1393350": "A;G",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs1408799": "C;C",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs141318671": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs1426654": "A;G",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs147068120": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs1667394": "T;C",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs16891982": "G;G",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs17184180": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs1800401": "G;G",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs1800407": "C;C",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs1800414": "T;T",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs2070959": "A;A",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs2095645": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs2238289": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs2240203": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs2252893": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs2385028": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs2733832": "T;T",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs2748901": "A;G",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs2835621": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs2835630": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs2835660": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs2854746": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs341147": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs348613": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs35051352": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs351385": "G;G",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs3768056": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs3794604": "C;C",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs3809761": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs3912104": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs3935591": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs3940272": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs4521336": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs4778138": "A;G",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs4778218": "G;G",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs4778241": "C;C",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs4790309": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs4911414": "T;G",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs4911442": "A;G",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs6058017": "A;A",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs622330": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs62330021": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs6420484": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs6693258": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs6828137": "T;G",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs6910861": "A;G",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs6944702": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs6997494": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs7170852": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs7174027": "G;G",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs7183877": "C;C",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs7219915": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs72777200": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs7277820": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs728405": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs72928978": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs73488486": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs74409360": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs7495174": "A;A",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs790464": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs8028689": "T;T",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs892839": "G;G",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs916977": "T;C",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs9301973": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs9782955": "C;C",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs9894429": "T;C",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs989869": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs9971729": "A;C",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_NumberOfRulesTested": "0"
},
{
"ItemType": "Trait",
"TraitName": "Hair Color",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusIsPhased_rs11636232": "No",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusIsPhased_rs12203592": "No",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusIsPhased_rs12821256": "No",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusIsPhased_rs12896399": "No",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusIsPhased_rs12913832": "No",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusIsPhased_rs1540771": "No",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusIsPhased_rs1667394": "No",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusIsPhased_rs1805007": "No",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusIsPhased_rs1805008": "No",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusIsPhased_rs35264875": "No",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusIsPhased_rs3829241": "No",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusIsPhased_rs6918152": "No",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusIsPhased_rs7174027": "No",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusIsPhased_rs7183877": "No",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusIsPhased_rs7495174": "No",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusIsPhased_rs8028689": "No",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs11636232": "T;C",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs11855019": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs12203592": "C;C",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs12821256": "T;T",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs12896399": "G;G",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs12913832": "A;G",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs1540771": "T;C",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs1667394": "T;C",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs1805007": "C;C",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs1805008": "C;C",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs28777": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs35264875": "A;A",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs3829241": "A;G",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs4778211": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs6918152": "A;A",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs7174027": "G;G",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs7183877": "C;C",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs7495174": "A;A",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs8028689": "T;T",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs8039195": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_NumberOfRulesTested": "0"
},
{
"ItemType": "Trait",
"TraitName": "Skin Color",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusIsPhased_rs1042602": "No",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusIsPhased_rs1126809": "No",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusIsPhased_rs12203592": "No",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusIsPhased_rs1426654": "No",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusIsPhased_rs16891982": "No",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusIsPhased_rs1834640": "No",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusIsPhased_rs26722": "No",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusIsPhased_rs2762462": "No",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusIsPhased_rs642742": "No",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusIsPhased_rs937171": "No",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs10424065": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs1042602": "C;C",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs1126809": "A;G",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs12203592": "C;C",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs142317543": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs1426654": "A;G",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs16891982": "G;G",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs1800422": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs1834640": "A;G",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs26722": "C;C",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs2762462": "C;C",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs3212368": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs3212369": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs642742": "T;C",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs7176696": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs7182710": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs784416": "Unknown",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_LocusValue_rs937171": "G;G",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_NumberOfRulesTested": "0"
}
]

View file

@ -4,6 +4,7 @@
package sampleAnalyses
import "seekia/internal/genetics/geneticAnalysis"
import "seekia/internal/genetics/readGeneticAnalysis"
import _ "embed"
@ -11,45 +12,45 @@ import _ "embed"
import "errors"
//go:embed SamplePerson1Analysis.json
//go:embed SamplePerson1Analysis.messagepack
var person1Analysis []byte
//go:embed SamplePerson2Analysis.json
//go:embed SamplePerson2Analysis.messagepack
var person2Analysis []byte
//go:embed SampleCoupleAnalysis.json
//go:embed SampleCoupleAnalysis.messagepack
var coupleAnalysis []byte
func GetSamplePerson1Analysis()([]map[string]string, error){
func GetSamplePerson1Analysis()(geneticAnalysis.PersonAnalysis, error){
analysisMapList, err := readGeneticAnalysis.ReadGeneticAnalysisString(string(person1Analysis))
analysisObject, err := readGeneticAnalysis.ReadPersonGeneticAnalysisString(string(person1Analysis))
if (err != nil){
return nil, errors.New("sampleAnalyses contains invalid person1Analysis: " + err.Error())
return geneticAnalysis.PersonAnalysis{}, errors.New("sampleAnalyses contains invalid person1Analysis: " + err.Error())
}
return analysisMapList, nil
return analysisObject, nil
}
func GetSamplePerson2Analysis()([]map[string]string, error){
func GetSamplePerson2Analysis()(geneticAnalysis.PersonAnalysis, error){
analysisMapList, err := readGeneticAnalysis.ReadGeneticAnalysisString(string(person2Analysis))
analysisObject, err := readGeneticAnalysis.ReadPersonGeneticAnalysisString(string(person2Analysis))
if (err != nil){
return nil, errors.New("sampleAnalyses contains invalid person2Analysis: " + err.Error())
return geneticAnalysis.PersonAnalysis{}, errors.New("sampleAnalyses contains invalid person2Analysis: " + err.Error())
}
return analysisMapList, nil
return analysisObject, nil
}
func GetSampleCoupleAnalysis()([]map[string]string, error){
func GetSampleCoupleAnalysis()(geneticAnalysis.CoupleAnalysis, error){
analysisMapList, err := readGeneticAnalysis.ReadGeneticAnalysisString(string(coupleAnalysis))
analysisObject, err := readGeneticAnalysis.ReadCoupleGeneticAnalysisString(string(coupleAnalysis))
if (err != nil){
return nil, errors.New("sampleAnalyses contains invalid coupleAnalysis: " + err.Error())
return geneticAnalysis.CoupleAnalysis{}, errors.New("sampleAnalyses contains invalid coupleAnalysis: " + err.Error())
}
return analysisMapList, nil
return analysisObject, nil
}

View file

@ -18,22 +18,22 @@ func TestPersonSampleAnalyses(t *testing.T){
polygenicDiseases.InitializePolygenicDiseaseVariables()
traits.InitializeTraitVariables()
person1AnalysisMapList, err := sampleAnalyses.GetSamplePerson1Analysis()
person1AnalysisObject, err := sampleAnalyses.GetSamplePerson1Analysis()
if (err != nil) {
t.Fatalf("GetSamplePerson1Analysis failed: " + err.Error())
}
person2AnalysisMapList, err := sampleAnalyses.GetSamplePerson2Analysis()
person2AnalysisObject, err := sampleAnalyses.GetSamplePerson2Analysis()
if (err != nil){
t.Fatalf("GetSamplePerson2Analysis failed: " + err.Error())
}
err = readGeneticAnalysis.ReadPersonGeneticAnalysisForTests(person1AnalysisMapList)
err = readGeneticAnalysis.VerifyPersonGeneticAnalysis(person1AnalysisObject)
if (err != nil) {
t.Fatalf("SamplePerson1 genetic analysis is malformed: " + err.Error())
}
err = readGeneticAnalysis.ReadPersonGeneticAnalysisForTests(person2AnalysisMapList)
err = readGeneticAnalysis.VerifyPersonGeneticAnalysis(person2AnalysisObject)
if (err != nil) {
t.Fatalf("SamplePerson2 genetic analysis is malformed: " + err.Error())
}
@ -46,12 +46,12 @@ func TestCoupleSampleAnalyses(t *testing.T){
polygenicDiseases.InitializePolygenicDiseaseVariables()
traits.InitializeTraitVariables()
coupleAnalysisMapList, err := sampleAnalyses.GetSampleCoupleAnalysis()
coupleAnalysisObject, err := sampleAnalyses.GetSampleCoupleAnalysis()
if (err != nil){
t.Fatalf("GetSampleCoupleAnalysis failed: " + err.Error())
}
err = readGeneticAnalysis.ReadCoupleGeneticAnalysisForTests(coupleAnalysisMapList)
err = readGeneticAnalysis.VerifyCoupleGeneticAnalysis(coupleAnalysisObject)
if (err != nil) {
t.Fatalf("Sample couple genetic analysis is malformed: " + err.Error())
}

View file

@ -981,6 +981,16 @@ func GetNewRandomDeviceIdentifier()([11]byte, error){
return newArray, nil
}
func GetNewRandom16ByteArray()([16]byte, error){
var newArray [16]byte
_, err := cryptoRand.Read(newArray[:])
if (err != nil) { return [16]byte{}, err }
return newArray, nil
}
func GetNewRandom32ByteArray()([32]byte, error){
var newArray [32]byte
@ -2004,5 +2014,19 @@ func CheckIfStringContainsTabsOrNewlines(inputString string)bool{
return false
}
func JoinTwo16ByteArrays(inputArray1 [16]byte, inputArray2 [16]byte)[32]byte{
arraysJoinedSlice := slices.Concat(inputArray1[:], inputArray2[:])
arraysJoined := [32]byte(arraysJoinedSlice)
return arraysJoined
}
func Split32ByteArrayInHalf(inputArray [32]byte)([16]byte, [16]byte){
piece1 := [16]byte(inputArray[:16])
piece2 := [16]byte(inputArray[16:])
return piece1, piece2
}

View file

@ -437,4 +437,3 @@ func TestSplitListIntoSublists(t *testing.T){
t.Fatalf("Failed to split string list into sublists: invalid sublist elements length.")
}
}

View file

@ -374,7 +374,7 @@ func GetMyMateDownloadsCriteria()(bool, []byte, error){
continue
}
myPersonChosen, myGenomesExist, myAnalysisIsReady, myAnalysisMapList, myGenomeIdentifier, iHaveMultipleGenomes, err := myChosenAnalysis.GetMyChosenMateGeneticAnalysis()
myPersonChosen, myGenomesExist, myAnalysisIsReady, myAnalysisObject, myGenomeIdentifier, _, err := myChosenAnalysis.GetMyChosenMateGeneticAnalysis()
if (err != nil) { return false, nil, err }
if (myPersonChosen == false || myGenomesExist == false || myAnalysisIsReady == false){
// We have not linked our genome to our profile
@ -389,7 +389,7 @@ func GetMyMateDownloadsCriteria()(bool, []byte, error){
diseaseName := diseaseObject.DiseaseName
diseaseIsDominantOrRecessive := diseaseObject.DominantOrRecessive
myProbabilityIsKnown, _, _, myProbabilityOfPassingAMonogenicDiseaseVariant, _, _, _, err := readGeneticAnalysis.GetPersonMonogenicDiseaseInfoFromGeneticAnalysis(myAnalysisMapList, diseaseName, myGenomeIdentifier, iHaveMultipleGenomes)
myProbabilityIsKnown, _, myProbabilityOfPassingAMonogenicDiseaseVariant, _, _, _, _, _, err := readGeneticAnalysis.GetPersonMonogenicDiseaseInfoFromGeneticAnalysis(myAnalysisObject, diseaseName, myGenomeIdentifier)
if (err != nil) { return false, nil, err }
if (myProbabilityIsKnown == false){
continue

View file

@ -477,7 +477,7 @@ func GetAnyProfileAttributeIncludingCalculated(attributeName string, getProfileA
// TODO Users should eventually be able to filter users based on how many variants the offspring has been tested for
// For example, If a user has had their entire genome sequenced, they will be able to only show other users who have done the same
myPersonChosen, myGenomesExist, myAnalysisIsReady, myGeneticAnalysisMapList, myGenomeIdentifier, iHaveMultipleGenomes, err := myChosenAnalysis.GetMyChosenMateGeneticAnalysis()
myPersonChosen, myGenomesExist, myAnalysisIsReady, myGeneticAnalysisObject, myGenomeIdentifier, _, err := myChosenAnalysis.GetMyChosenMateGeneticAnalysis()
if (err != nil) { return false, 0, "", err }
if (myPersonChosen == false || myGenomesExist == false || myAnalysisIsReady == false){
@ -511,6 +511,8 @@ func GetAnyProfileAttributeIncludingCalculated(attributeName string, getProfileA
//TODO: Require both probabilities to exist for the same disease at least once?
anyUserProbabilityIsKnown := false
// This stores the probability of the offspring having each tested disease
// Each float in this list is a value between 0-1
allDiseaseProbabilitiesList := make([]float64, 0)
for _, diseaseObject := range monogenicDiseaseObjectsList{
@ -529,88 +531,67 @@ func GetAnyProfileAttributeIncludingCalculated(attributeName string, getProfileA
anyUserProbabilityIsKnown = true
}
myProbabilityIsKnown, _, _, myProbabilityOfPassingADiseaseVariant, _, _, _, err := readGeneticAnalysis.GetPersonMonogenicDiseaseInfoFromGeneticAnalysis(myGeneticAnalysisMapList, monogenicDiseaseName, myGenomeIdentifier, iHaveMultipleGenomes)
myProbabilityIsKnown, _, myProbabilityOfPassingADiseaseVariant, _, _, _, _, _, err := readGeneticAnalysis.GetPersonMonogenicDiseaseInfoFromGeneticAnalysis(myGeneticAnalysisObject, monogenicDiseaseName, myGenomeIdentifier)
if (err != nil) { return false, 0, "", err }
if (userProbabilityIsKnown == false && myProbabilityIsKnown == false){
continue
}
// Outputs:
// -bool: Probability is known
// -float64: Probability offspring will have the disease (0-1)
// -error
getOffspringProbabilityOfDisease := func()(bool, float64, error){
getUserProbabilityOfPassingADiseaseVariantInt := func()(int, error){
if (userProbabilityIsKnown == true && myProbabilityIsKnown == false){
if (diseaseIsDominantOrRecessive == "Dominant"){
if (userProbabilityOfPassingADiseaseVariant == "100"){
// Offspring will always have disease (double dominant)
return true, 1, nil
}
if (userProbabilityOfPassingADiseaseVariant != "0"){
nonZeroUnknownDiseaseRiskExists = true
}
return false, 0, nil
}
// diseaseIsDominantOrRecessive == "Recessive"
if (userProbabilityOfPassingADiseaseVariant == "0"){
// There is a 0% probability of offspring having this disease
return true, 0, nil
}
// User has a non-zero probability of passing variant
nonZeroUnknownDiseaseRiskExists = true
return false, 0, nil
}
if (userProbabilityIsKnown == false && myProbabilityIsKnown == true){
if (diseaseIsDominantOrRecessive == "Dominant"){
if (myProbabilityOfPassingADiseaseVariant == 100){
// Offspring will have disease (we are double dominant, all of our offspring will have this disease)
return true, 1, nil
}
if (myProbabilityOfPassingADiseaseVariant != 0){
nonZeroUnknownDiseaseRiskExists = true
}
return false, 0, nil
}
// diseaseIsDominantOrRecessive == "Recessive"
if (myProbabilityOfPassingADiseaseVariant == 0){
// There is a 0% probability of offspring having this disease
return true, 0, nil
}
// We have a non-zero probability of passing a variant
nonZeroUnknownDiseaseRiskExists = true
return false, 0, nil
if (userProbabilityIsKnown == false){
return 0, nil
}
userProbabilityOfPassingADiseaseVariantInt, err := helpers.ConvertStringToInt(userProbabilityOfPassingADiseaseVariant)
if (err != nil){
return false, 0, errors.New("GetAnyProfileAttributeIncludingCalculated called with profile containing invalid " + probabilityOfPassingAVariantAttributeName + ": " + userProbabilityOfPassingADiseaseVariant)
return 0, errors.New("GetAnyProfileAttributeIncludingCalculated called with profile containing invalid " + probabilityOfPassingAVariantAttributeName + ": " + userProbabilityOfPassingADiseaseVariant)
}
offspringPercentageProbabilityOfDisease, _, err := createGeneticAnalysis.GetOffspringMonogenicDiseaseProbabilities(diseaseIsDominantOrRecessive, myProbabilityOfPassingADiseaseVariant, userProbabilityOfPassingADiseaseVariantInt)
if (err != nil) { return false, 0, err }
offspringProbabilityOfDisease := float64(offspringPercentageProbabilityOfDisease)/100
return true, offspringProbabilityOfDisease, nil
return userProbabilityOfPassingADiseaseVariantInt, nil
}
offspringProbabilityIsKnown, offspringProbabilityOfDisease, err := getOffspringProbabilityOfDisease()
userProbabilityOfPassingADiseaseVariantInt, err := getUserProbabilityOfPassingADiseaseVariantInt()
if (err != nil) { return false, 0, "", err }
if (offspringProbabilityIsKnown == false){
probabilityOffspringHasDiseaseIsKnown, offspringPercentageProbabilityOfDisease, _, _, err := createGeneticAnalysis.GetOffspringMonogenicDiseaseProbabilities(diseaseIsDominantOrRecessive, myProbabilityIsKnown, myProbabilityOfPassingADiseaseVariant, userProbabilityIsKnown, userProbabilityOfPassingADiseaseVariantInt)
if (err != nil) { return false, 0, "", err }
if (probabilityOffspringHasDiseaseIsKnown == false){
// We do not know the probability the offspring will have this disease
// We check to see if either person has a non-zero risk
// If so, the probability of the offspring having the disease is potentially >0
getNonZeroUnknownDiseaseRiskExistsBool := func()bool{
if (diseaseIsDominantOrRecessive == "Recessive"){
// We know there exists a non-zero risk
// We know that at least 1 of the two people has a known pass-the-variant probability
// If either person had a 0% probability of passing a variant, the
// GetOffspringMonogenicDiseaseProbabilities function would have returned a 0% risk of
/// the offspring having the disease.
// Thus, there exists the possibility of the offspring having the disease
// We will warn the user about this, so they can get tested and make sure they are not
// a carrier for the same disease
return true
}
// diseaseIsDominantOrRecessive == "Dominant"
if (userProbabilityIsKnown == true && userProbabilityOfPassingADiseaseVariantInt != 0){
return true
}
if (myProbabilityIsKnown == true && myProbabilityOfPassingADiseaseVariant != 0){
return true
}
return false
}
nonZeroUnknownDiseaseRiskExists = getNonZeroUnknownDiseaseRiskExistsBool()
continue
}
@ -621,12 +602,14 @@ func GetAnyProfileAttributeIncludingCalculated(attributeName string, getProfileA
continue
}
if (offspringProbabilityOfDisease == 100){
if (offspringPercentageProbabilityOfDisease == 100){
// Probability that offspring will have a disease is 100%
return true, profileVersion, "100", nil
}
offspringProbabilityOfDisease := float64(offspringPercentageProbabilityOfDisease)/float64(100)
allDiseaseProbabilitiesList = append(allDiseaseProbabilitiesList, offspringProbabilityOfDisease)
}
@ -654,8 +637,12 @@ func GetAnyProfileAttributeIncludingCalculated(attributeName string, getProfileA
for _, diseaseProbability := range allDiseaseProbabilitiesList{
if (diseaseProbability < 0 || diseaseProbability > 1){
return false, 0, "", errors.New("allDiseaseProbabilitiesList contains invalid disease probability.")
}
// We multiply by the probability of no disease
probabilityOfNoMonogenicDiseases *= 1 - diseaseProbability
probabilityOfNoMonogenicDiseases *= (1 - diseaseProbability)
}
probabilityOfAtLeast1Disease := 1 - probabilityOfNoMonogenicDiseases
@ -773,7 +760,7 @@ func GetAnyProfileAttributeIncludingCalculated(attributeName string, getProfileA
// For example, Breast Cancer is not as bad as Epilepsy
// LifeView.com weights each disease in their polygenic disease risk score calculation
myPersonChosen, myGenomesExist, myAnalysisIsReady, myGeneticAnalysisMapList, myGenomeIdentifier, _, err := myChosenAnalysis.GetMyChosenMateGeneticAnalysis()
myPersonChosen, myGenomesExist, myAnalysisIsReady, myGeneticAnalysisObject, myGenomeIdentifier, _, err := myChosenAnalysis.GetMyChosenMateGeneticAnalysis()
if (err != nil) { return false, 0, "", err }
if (myPersonChosen == false || myGenomesExist == false || myAnalysisIsReady == false){
@ -807,7 +794,11 @@ func GetAnyProfileAttributeIncludingCalculated(attributeName string, getProfileA
for _, locusObject := range diseaseLociList{
locusIdentifier := locusObject.LocusIdentifier
locusIdentifierHex := locusObject.LocusIdentifier
locusIdentifier, err := encoding.DecodeHexStringTo3ByteArray(locusIdentifierHex)
if (err != nil) { return false, 0, "", err }
locusRSID := locusObject.LocusRSID
locusRSIDString := helpers.ConvertInt64ToString(locusRSID)
@ -819,7 +810,7 @@ func GetAnyProfileAttributeIncludingCalculated(attributeName string, getProfileA
locusValueAttributeName := "LocusValue_rs" + locusRSIDString
myLocusInfoIsKnown, _, myLocusBasePair, _, _, _, err := readGeneticAnalysis.GetPersonPolygenicDiseaseLocusInfoFromGeneticAnalysis(myGeneticAnalysisMapList, diseaseName, locusIdentifier, myGenomeIdentifier)
myLocusInfoIsKnown, _, myLocusBase1, myLocusBase2, _, _, _, err := readGeneticAnalysis.GetPersonPolygenicDiseaseLocusInfoFromGeneticAnalysis(myGeneticAnalysisObject, diseaseName, locusIdentifier, myGenomeIdentifier)
if (err != nil) { return false, 0, "", err }
if (myLocusInfoIsKnown == false){
continue
@ -831,7 +822,12 @@ func GetAnyProfileAttributeIncludingCalculated(attributeName string, getProfileA
continue
}
offspringLocusRiskWeight, _, _, _, err := createGeneticAnalysis.GetOffspringPolygenicDiseaseLocusInfo(locusRiskWeightsMap, locusOddsRatiosMap, myLocusBasePair, userLocusBasePair)
userLocusBase1, userLocusBase2, semicolonFound := strings.Cut(userLocusBasePair, ";")
if (semicolonFound == false){
return false, 0, "", errors.New("GetAnyProfileAttributeIncludingCalculated called with profile containing invalid " + locusValueAttributeName + ": " + userLocusBasePair)
}
offspringLocusRiskWeight, _, _, _, err := createGeneticAnalysis.GetOffspringPolygenicDiseaseLocusInfo(locusRiskWeightsMap, locusOddsRatiosMap, myLocusBase1, myLocusBase2, userLocusBase1, userLocusBase2)
if (err != nil) { return false, 0, "", err }
offspringNumberOfLociTested += 1
@ -1385,7 +1381,7 @@ func GetAnyProfileAttributeIncludingCalculated(attributeName string, getProfileA
// We want this similarity comparison to aid users in their search for mates who look like them and with whom
// they are likely to produce offspring who look like them
myPersonChosen, myGenomesExist, myAnalysisIsReady, myGeneticAnalysisMapList, myGenomeIdentifier, iHaveMultipleGenomes, err := myChosenAnalysis.GetMyChosenMateGeneticAnalysis()
myPersonChosen, myGenomesExist, myAnalysisIsReady, myGeneticAnalysisObject, myGenomeIdentifier, _, err := myChosenAnalysis.GetMyChosenMateGeneticAnalysis()
if (err != nil) { return false, 0, "", err }
if (myPersonChosen == false || myGenomesExist == false || myAnalysisIsReady == false){
@ -1424,7 +1420,7 @@ func GetAnyProfileAttributeIncludingCalculated(attributeName string, getProfileA
traitName := getTraitName()
myTraitLociMap, _, _, _, _, err := readGeneticAnalysis.GetPersonTraitInfoFromGeneticAnalysis(myGeneticAnalysisMapList, traitName, myGenomeIdentifier, iHaveMultipleGenomes)
myTraitLociMap, _, _, _, _, err := readGeneticAnalysis.GetPersonTraitInfoFromGeneticAnalysis(myGeneticAnalysisObject, traitName, myGenomeIdentifier)
if (err != nil) { return false, 0, "", err }
traitObject, err := traits.GetTraitObject(traitName)
@ -1461,8 +1457,8 @@ func GetAnyProfileAttributeIncludingCalculated(attributeName string, getProfileA
// This would save space on profiles because we wouldn't have to share an IsPhased bool for each locus (because all loci would be phased)
// People who are more knowledgeable about genetics should share their opinions.
myLocusValueBase1 := myLocusValue.Base1
myLocusValueBase2 := myLocusValue.Base2
myLocusValueBase1 := myLocusValue.Base1Value
myLocusValueBase2 := myLocusValue.Base2Value
userLocusValueBase1, userLocusValueBase2, semicolonExists := strings.Cut(userLocusValue, ";")
if (semicolonExists == false){

View file

@ -135,7 +135,7 @@ func UpdateMyExportedProfile(myProfileType string, networkType byte)error{
return nil
}
myGenomePersonChosen, anyGenomesExist, personAnalysisIsReady, myGeneticAnalysisMapList, genomeIdentifierToShare, multipleGenomesExist, err := myChosenAnalysis.GetMyChosenMateGeneticAnalysis()
myGenomePersonChosen, anyGenomesExist, personAnalysisIsReady, myGeneticAnalysisObject, genomeIdentifierToShare, _, err := myChosenAnalysis.GetMyChosenMateGeneticAnalysis()
if (err != nil) { return err }
if (myGenomePersonChosen == false){
// User has not linked a genome person.
@ -166,7 +166,7 @@ func UpdateMyExportedProfile(myProfileType string, networkType byte)error{
continue
}
probabilitiesKnown, _, _, probabilityOfPassingADiseaseVariant, _, numberOfVariantsTested, _, err := readGeneticAnalysis.GetPersonMonogenicDiseaseInfoFromGeneticAnalysis(myGeneticAnalysisMapList, monogenicDiseaseName, genomeIdentifierToShare, multipleGenomesExist)
probabilitiesKnown, _, probabilityOfPassingADiseaseVariant, _, numberOfVariantsTested, _, _, _, err := readGeneticAnalysis.GetPersonMonogenicDiseaseInfoFromGeneticAnalysis(myGeneticAnalysisObject, monogenicDiseaseName, genomeIdentifierToShare)
if (err != nil) { return err }
if (probabilitiesKnown == false){
continue
@ -209,9 +209,12 @@ func UpdateMyExportedProfile(myProfileType string, networkType byte)error{
for _, locusObject := range diseaseLociList{
locusIdentifier := locusObject.LocusIdentifier
locusIdentifierHex := locusObject.LocusIdentifier
locusValueKnown, _, locusBasePair, _, _, _, err := readGeneticAnalysis.GetPersonPolygenicDiseaseLocusInfoFromGeneticAnalysis(myGeneticAnalysisMapList, diseaseName, locusIdentifier, genomeIdentifierToShare)
locusIdentifier, err := encoding.DecodeHexStringTo3ByteArray(locusIdentifierHex)
if (err != nil) { return err }
locusValueKnown, _, locusBase1, locusBase2, _, _, _, err := readGeneticAnalysis.GetPersonPolygenicDiseaseLocusInfoFromGeneticAnalysis(myGeneticAnalysisObject, diseaseName, locusIdentifier, genomeIdentifierToShare)
if (err != nil) { return err }
if (locusValueKnown == false){
continue
@ -221,7 +224,7 @@ func UpdateMyExportedProfile(myProfileType string, networkType byte)error{
locusRSIDString := helpers.ConvertInt64ToString(locusRSID)
profileMap["LocusValue_rs" + locusRSIDString] = locusBasePair
profileMap["LocusValue_rs" + locusRSIDString] = locusBase1 + ";" + locusBase2
}
}
@ -243,15 +246,15 @@ func UpdateMyExportedProfile(myProfileType string, networkType byte)error{
continue
}
myTraitLocusValuesMap, _, _, _, _, err := readGeneticAnalysis.GetPersonTraitInfoFromGeneticAnalysis(myGeneticAnalysisMapList, traitName, genomeIdentifierToShare, multipleGenomesExist)
myTraitLocusValuesMap, _, _, _, _, err := readGeneticAnalysis.GetPersonTraitInfoFromGeneticAnalysis(myGeneticAnalysisObject, traitName, genomeIdentifierToShare)
if (err != nil) { return err }
for rsID, locusValueObject := range myTraitLocusValuesMap{
rsIDString := helpers.ConvertInt64ToString(rsID)
locusBase1 := locusValueObject.Base1
locusBase2 := locusValueObject.Base2
locusBase1 := locusValueObject.Base1Value
locusBase2 := locusValueObject.Base2Value
basePairValue := locusBase1 + ";" + locusBase2

View file

@ -27,15 +27,11 @@ func TestGeneticReferences(t *testing.T){
verifyIdentifier := func(inputIdentifier string)bool{
decodedBytes, err := encoding.DecodeHexStringToBytes(inputIdentifier)
_, err := encoding.DecodeHexStringTo3ByteArray(inputIdentifier)
if (err != nil) {
return false
}
if (len(decodedBytes) != 3){
return false
}
return true
}

View file

@ -947,7 +947,7 @@ func getBreastCancerDiseaseObject()PolygenicDisease{
DiseaseName: "Breast Cancer",
EffectedSex: "Both",
DiseaseDescription: "Cancer growth in the tissue of a person's breast.",
DiseaseDescription: "Cancer growth in the tissue of a person's chest breast.",
LociList: breastCancerLociList,
GetAverageRiskProbabilitiesFunction: getAverageRiskProbabilitiesFunction,
References: referencesMap,

View file

@ -707,11 +707,10 @@ func setStartAndMonitorCreateTrainingDataPage(window fyne.Window, previousPage f
continue
}
newGenomeIdentifier, err := helpers.GetNewRandomHexString(16)
newGenomeIdentifier, err := helpers.GetNewRandom16ByteArray()
if (err != nil) { return false, false, err }
rawGenomeWithMetadata := prepareRawGenomes.RawGenomeWithMetadata{
GenomeIdentifier: newGenomeIdentifier,
GenomeIsPhased: rawGenomeIsPhased,
RawGenomeMap: rawGenomeMap,

View file

@ -1,5 +1,5 @@
Person1RawGenome.txt
Person2RawGenome.txt
SamplePerson1Analysis.json
SamplePerson2Analysis.json
SampleCoupleAnalysis.json
SamplePerson1Analysis.messagepack
SamplePerson2Analysis.messagepack
SampleCoupleAnalysis.messagepack

View file

@ -12,6 +12,7 @@ import "seekia/resources/geneticReferences/monogenicDiseases"
import "seekia/resources/geneticReferences/polygenicDiseases"
import "seekia/resources/geneticReferences/traits"
import "seekia/internal/encoding"
import "seekia/internal/localFilesystem"
import "seekia/internal/genetics/createGeneticAnalysis"
import "seekia/internal/genetics/prepareRawGenomes"
@ -37,7 +38,7 @@ func main(){
// -[]prepareRawGenomes.RawGenomeWithMetadata: Person genomes list
// -string: Analysis string
// -error
getPersonRawGenomeListAndAnalysis := func(personRawGenomeFilepath string, genomeIdentifier string)(bool, []prepareRawGenomes.RawGenomeWithMetadata, string, error){
getPersonRawGenomeListAndAnalysis := func(personRawGenomeFilepath string, genomeIdentifierHex string)(bool, []prepareRawGenomes.RawGenomeWithMetadata, string, error){
fileExists, personRawGenomeFileBytes, err := localFilesystem.GetFileContents(personRawGenomeFilepath)
if (err != nil){ return false, nil, "", err }
@ -47,6 +48,9 @@ func main(){
personRawGenomeFileString := string(personRawGenomeFileBytes)
genomeIdentifier, err := encoding.DecodeHexStringTo16ByteArray(genomeIdentifierHex)
if (err != nil) { return false, nil, "", err }
genomeIsValid, rawGenomeWithMetadata, err := prepareRawGenomes.CreateRawGenomeWithMetadataObject(genomeIdentifier, personRawGenomeFileString)
if (err != nil){ return false, nil, "", err }
if (genomeIsValid == false){
@ -114,18 +118,18 @@ func main(){
return
}
err = localFilesystem.CreateOrOverwriteFile([]byte(person1GeneticAnalysis), "./", "SamplePerson1Analysis.json")
err = localFilesystem.CreateOrOverwriteFile([]byte(person1GeneticAnalysis), "./", "SamplePerson1Analysis.messagepack")
if (err != nil){
log.Println(err.Error())
return
}
err = localFilesystem.CreateOrOverwriteFile([]byte(person2GeneticAnalysis), "./", "SamplePerson2Analysis.json")
err = localFilesystem.CreateOrOverwriteFile([]byte(person2GeneticAnalysis), "./", "SamplePerson2Analysis.messagepack")
if (err != nil){
log.Println(err.Error())
return
}
err = localFilesystem.CreateOrOverwriteFile([]byte(coupleGeneticAnalysis), "./", "SampleCoupleAnalysis.json")
err = localFilesystem.CreateOrOverwriteFile([]byte(coupleGeneticAnalysis), "./", "SampleCoupleAnalysis.messagepack")
if (err != nil){
log.Println(err.Error())
return