Added new genetic attributes to the calculatedAttributes package. Added the ability to view and sort by these attributes in the GUI.
This commit is contained in:
parent
972252c788
commit
b6f5612bbc
7 changed files with 773 additions and 96 deletions
|
@ -6,6 +6,7 @@ Small and insignificant changes may not be included in this log.
|
|||
|
||||
## Unversioned Changes
|
||||
|
||||
* Added new genetic attributes to the calculatedAttributes package. Added the ability to view and sort by these attributes in the GUI. - *Simon Sarasova*
|
||||
* Upgraded Golang to version 1.23. - *Simon Sarasova*
|
||||
* Added the Obesity disease to genetic analyses. - *Simon Sarasova*
|
||||
* Implemented neural network prediction for polygenic diseases to replace old method. Added autism and homosexualness to genetic analyses. - *Simon Sarasova*
|
||||
|
|
|
@ -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 | 280
|
||||
Simon Sarasova | June 13, 2023 | 281
|
|
@ -1024,23 +1024,44 @@ func setSelectMatchesSortByAttributePage(window fyne.Window, previousPage func()
|
|||
err = addAttributeSelectButton("Physical", "OffspringTotalPolygenicDiseaseRiskScore", "Ascending")
|
||||
if (err != nil) { return nil, err }
|
||||
|
||||
offspringLactoseToleranceProbabilityButton := widget.NewButton("Offspring Lactose Tolerance Probability", func(){
|
||||
//TODO
|
||||
showUnderConstructionDialog(window)
|
||||
})
|
||||
physicalAttributeButtonsGrid.Add(offspringLactoseToleranceProbabilityButton)
|
||||
err = addAttributeSelectButton("Physical", "AutismRiskScore", "Ascending")
|
||||
if (err != nil) { return nil, err }
|
||||
err = addAttributeSelectButton("Physical", "OffspringAutismRiskScore", "Ascending")
|
||||
if (err != nil) { return nil, err }
|
||||
|
||||
offspringCurlyHairProbabilityButton := widget.NewButton("Offspring Curly Hair Probability", func(){
|
||||
//TODO
|
||||
showUnderConstructionDialog(window)
|
||||
})
|
||||
physicalAttributeButtonsGrid.Add(offspringCurlyHairProbabilityButton)
|
||||
err = addAttributeSelectButton("Physical", "ObesityRiskScore", "Ascending")
|
||||
if (err != nil) { return nil, err }
|
||||
err = addAttributeSelectButton("Physical", "OffspringObesityRiskScore", "Ascending")
|
||||
if (err != nil) { return nil, err }
|
||||
|
||||
offspringStraightHairProbabilityButton := widget.NewButton("Offspring Straight Hair Probability", func(){
|
||||
//TODO
|
||||
showUnderConstructionDialog(window)
|
||||
})
|
||||
physicalAttributeButtonsGrid.Add(offspringStraightHairProbabilityButton)
|
||||
err = addAttributeSelectButton("Physical", "OffspringBlueEyesProbability", "Descending")
|
||||
if (err != nil) { return nil, err }
|
||||
err = addAttributeSelectButton("Physical", "OffspringGreenEyesProbability", "Descending")
|
||||
if (err != nil) { return nil, err }
|
||||
err = addAttributeSelectButton("Physical", "OffspringHazelEyesProbability", "Descending")
|
||||
if (err != nil) { return nil, err }
|
||||
err = addAttributeSelectButton("Physical", "OffspringBrownEyesProbability", "Descending")
|
||||
if (err != nil) { return nil, err }
|
||||
|
||||
err = addAttributeSelectButton("Physical", "OffspringLactoseToleranceProbability", "Descending")
|
||||
if (err != nil) { return nil, err }
|
||||
|
||||
err = addAttributeSelectButton("Physical", "OffspringStraightHairProbability", "Descending")
|
||||
if (err != nil) { return nil, err }
|
||||
err = addAttributeSelectButton("Physical", "OffspringCurlyHairProbability", "Descending")
|
||||
if (err != nil) { return nil, err }
|
||||
|
||||
// Numeric Traits:
|
||||
|
||||
err = addAttributeSelectButton("Physical", "HomosexualnessScore", "Ascending")
|
||||
if (err != nil) { return nil, err }
|
||||
err = addAttributeSelectButton("Physical", "OffspringHomosexualnessScore", "Ascending")
|
||||
if (err != nil) { return nil, err }
|
||||
|
||||
err = addAttributeSelectButton("Physical", "PredictedHeight", "Descending")
|
||||
if (err != nil) { return nil, err }
|
||||
err = addAttributeSelectButton("Physical", "OffspringPredictedHeight", "Descending")
|
||||
if (err != nil) { return nil, err }
|
||||
|
||||
err = addAttributeSelectButton("Physical", "23andMe_NeanderthalVariants", "Descending")
|
||||
if (err != nil) { return nil, err }
|
||||
|
@ -1555,7 +1576,6 @@ func setAddAttributeToCustomMatchDisplayPage(window fyne.Window, previousPage fu
|
|||
"23andMe_MaternalHaplogroup",
|
||||
"23andMe_PaternalHaplogroup",
|
||||
"23andMe_NeanderthalVariants",
|
||||
"OffspringProbabilityOfAnyMonogenicDisease",
|
||||
"EyeColorSimilarity",
|
||||
"EyeColorGenesSimilarity",
|
||||
"HairColorSimilarity",
|
||||
|
@ -1568,6 +1588,27 @@ func setAddAttributeToCustomMatchDisplayPage(window fyne.Window, previousPage fu
|
|||
"23andMe_AncestralSimilarity",
|
||||
"23andMe_MaternalHaplogroupSimilarity",
|
||||
"23andMe_PaternalHaplogroupSimilarity",
|
||||
"OffspringProbabilityOfAnyMonogenicDisease",
|
||||
"TotalPolygenicDiseaseRiskScore",
|
||||
"OffspringTotalPolygenicDiseaseRiskScore",
|
||||
"AutismRiskScore",
|
||||
"OffspringAutismRiskScore",
|
||||
"ObesityRiskScore",
|
||||
"OffspringObesityRiskScore",
|
||||
"PredictedEyeColor",
|
||||
"OffspringBlueEyesProbability",
|
||||
"OffspringGreenEyesProbability",
|
||||
"OffspringHazelEyesProbability",
|
||||
"OffspringBrownEyesProbability",
|
||||
"PredictedLactoseTolerance",
|
||||
"OffspringLactoseToleranceProbability",
|
||||
"PredictedHairTexture",
|
||||
"OffspringStraightHairProbability",
|
||||
"OffspringCurlyHairProbability",
|
||||
"HomosexualnessScore",
|
||||
"OffspringHomosexualnessScore",
|
||||
"PredictedHeight",
|
||||
"OffspringPredictedHeight",
|
||||
}
|
||||
|
||||
lifestyleAttributeNamesList := []string{
|
||||
|
|
|
@ -449,7 +449,7 @@ func StartUpdatingMyMatches(networkType byte)error{
|
|||
return nil
|
||||
}
|
||||
|
||||
newScaledPercentageInt, err := helpers.ScaleIntProportionally(true, index, 0, maximumIndex, 50, 80)
|
||||
newScaledPercentageInt, err := helpers.ScaleIntProportionally(true, index, 0, maximumIndex, 50, 95)
|
||||
if (err != nil) { return err }
|
||||
|
||||
newProgressFloat := float64(newScaledPercentageInt)/100
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
package attributeDisplay
|
||||
|
||||
//TODO: Deal with singular/multiple values and how that changes an attribute value's units
|
||||
// For example: 1 variant, 2 variants
|
||||
// For example: 1 variant, 2 variants, 1 centimeter, 2 centimeters
|
||||
|
||||
import "seekia/resources/worldLocations"
|
||||
import "seekia/resources/worldLanguages"
|
||||
|
@ -43,6 +43,7 @@ func GetProfileAttributeDisplayInfo(attributeName string)(string, bool, func(str
|
|||
}
|
||||
|
||||
formatPercentageFunction := func(input string)(string, error){
|
||||
|
||||
valueFloat64, err := helpers.ConvertStringToFloat64(input)
|
||||
if (err != nil){
|
||||
return "", errors.New("formatPercentageFunction called with non-numeric " + attributeName + " value: " + input)
|
||||
|
@ -52,7 +53,8 @@ func GetProfileAttributeDisplayInfo(attributeName string)(string, bool, func(str
|
|||
return "", errors.New("formatPercentageFunction called with invalid " + attributeName + " percentage value: " + input)
|
||||
}
|
||||
|
||||
result := input + "%"
|
||||
result := helpers.ConvertIntToString(int(valueFloat64))
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
|
@ -197,24 +199,6 @@ func GetProfileAttributeDisplayInfo(attributeName string)(string, bool, func(str
|
|||
|
||||
return titleTranslated, false, passValueFunction, "", noResponseTranslated, nil
|
||||
}
|
||||
case "CatsRating":{
|
||||
|
||||
titleTranslated := translation.TranslateTextFromEnglishToMyLanguage("Cats Rating")
|
||||
|
||||
return titleTranslated, true, passValueFunction, "/10", noResponseTranslated, nil
|
||||
}
|
||||
case "DogsRating":{
|
||||
|
||||
titleTranslated := translation.TranslateTextFromEnglishToMyLanguage("Dogs Rating")
|
||||
|
||||
return titleTranslated, true, passValueFunction, "/10", noResponseTranslated, nil
|
||||
}
|
||||
case "PetsRating":{
|
||||
|
||||
titleTranslated := translation.TranslateTextFromEnglishToMyLanguage("Pets Rating")
|
||||
|
||||
return titleTranslated, true, passValueFunction, "/10", noResponseTranslated, nil
|
||||
}
|
||||
case "GenderIdentity":{
|
||||
|
||||
titleTranslated := translation.TranslateTextFromEnglishToMyLanguage("Gender Identity")
|
||||
|
@ -231,20 +215,23 @@ func GetProfileAttributeDisplayInfo(attributeName string)(string, bool, func(str
|
|||
return titleTranslated, false, translateGenderFunction, "", noResponseTranslated, nil
|
||||
}
|
||||
case "FruitRating",
|
||||
"VegetablesRating",
|
||||
"NutsRating",
|
||||
"GrainsRating",
|
||||
"DairyRating",
|
||||
"SeafoodRating",
|
||||
"BeefRating",
|
||||
"PorkRating",
|
||||
"PoultryRating",
|
||||
"EggsRating",
|
||||
"BeansRating":{
|
||||
"VegetablesRating",
|
||||
"NutsRating",
|
||||
"GrainsRating",
|
||||
"DairyRating",
|
||||
"SeafoodRating",
|
||||
"BeefRating",
|
||||
"PorkRating",
|
||||
"PoultryRating",
|
||||
"EggsRating",
|
||||
"BeansRating",
|
||||
"PetsRating",
|
||||
"DogsRating",
|
||||
"CatsRating":{
|
||||
|
||||
foodName := strings.TrimSuffix(attributeName, "Rating")
|
||||
thingName := strings.TrimSuffix(attributeName, "Rating")
|
||||
|
||||
attributeTitle := foodName + " Rating"
|
||||
attributeTitle := thingName + " Rating"
|
||||
|
||||
titleTranslated := translation.TranslateTextFromEnglishToMyLanguage(attributeTitle)
|
||||
|
||||
|
@ -422,14 +409,92 @@ func GetProfileAttributeDisplayInfo(attributeName string)(string, bool, func(str
|
|||
|
||||
return titleTranslated, true, passValueFunction, "/4", noResponseTranslated, nil
|
||||
}
|
||||
case "Height":{
|
||||
case "Height",
|
||||
"PredictedHeight",
|
||||
"OffspringPredictedHeight":{
|
||||
|
||||
titleTranslated := translation.TranslateTextFromEnglishToMyLanguage("Height")
|
||||
getAttributeTitle := func()string{
|
||||
|
||||
switch attributeName{
|
||||
case "Height":{
|
||||
return "Height"
|
||||
}
|
||||
case "PredictedHeight":{
|
||||
return "Predicted Height"
|
||||
}
|
||||
}
|
||||
|
||||
return "Offspring Predicted Height"
|
||||
}
|
||||
|
||||
attributeTitle := getAttributeTitle()
|
||||
|
||||
titleTranslated := translation.TranslateTextFromEnglishToMyLanguage(attributeTitle)
|
||||
|
||||
getMyMetricOrImperial := func()(string, error){
|
||||
|
||||
exists, metricOrImperial, err := globalSettings.GetSetting("MetricOrImperial")
|
||||
if (err != nil) { return "", err }
|
||||
if (exists == false){
|
||||
return "Metric", nil
|
||||
}
|
||||
if (metricOrImperial != "Metric" && metricOrImperial != "Imperial"){
|
||||
return "", errors.New("Malformed globalSettings: Invalid metricOrImperial: " + metricOrImperial)
|
||||
}
|
||||
|
||||
return metricOrImperial, nil
|
||||
}
|
||||
|
||||
myMetricOrImperial, err := getMyMetricOrImperial()
|
||||
if (err != nil) { return "", false, nil, "", "", err }
|
||||
|
||||
formatHeightFunction := func(input string)(string, error){
|
||||
|
||||
inputCentimeters, err := helpers.ConvertStringToFloat64(input)
|
||||
if (err != nil) { return "", err }
|
||||
|
||||
if (myMetricOrImperial == "Metric"){
|
||||
|
||||
centimetersString := helpers.ConvertFloat64ToStringRounded(inputCentimeters, 2)
|
||||
|
||||
return centimetersString, nil
|
||||
}
|
||||
|
||||
feetInchesString, err := helpers.ConvertCentimetersToFeetInchesTranslatedString(inputCentimeters)
|
||||
if (err != nil) { return "", err }
|
||||
|
||||
return feetInchesString, nil
|
||||
}
|
||||
|
||||
getUnitsTranslated := func()string{
|
||||
|
||||
if (myMetricOrImperial == "Metric"){
|
||||
|
||||
unitsTranslated := translation.TranslateTextFromEnglishToMyLanguage("Centimeters")
|
||||
|
||||
return unitsTranslated
|
||||
}
|
||||
|
||||
// There are no units to add
|
||||
// The value is in the format "5 feet, 10 inches"
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
unitsTranslated := getUnitsTranslated()
|
||||
|
||||
unitsTranslated := translation.TranslateTextFromEnglishToMyLanguage("centimeters")
|
||||
unitsWithPadding := " " + unitsTranslated
|
||||
|
||||
return titleTranslated, true, roundNumberFunction, unitsWithPadding, noResponseTranslated, nil
|
||||
getUnavailableText := func()string{
|
||||
if (attributeName == "Height"){
|
||||
return noResponseTranslated
|
||||
}
|
||||
return unknownTranslated
|
||||
}
|
||||
|
||||
unavailableText := getUnavailableText()
|
||||
|
||||
return titleTranslated, true, formatHeightFunction, unitsWithPadding, unavailableText, nil
|
||||
}
|
||||
case "Sex":{
|
||||
|
||||
|
@ -452,24 +517,6 @@ func GetProfileAttributeDisplayInfo(attributeName string)(string, bool, func(str
|
|||
|
||||
return titleTranslated, false, translateValueFunction, "", unknownTranslated, nil
|
||||
}
|
||||
case "OffspringProbabilityOfAnyMonogenicDisease":{
|
||||
|
||||
titleTranslated := translation.TranslateTextFromEnglishToMyLanguage("Offspring Probability Of Any Monogenic Disease")
|
||||
|
||||
return titleTranslated, true, formatPercentageFunction, "", unknownTranslated, nil
|
||||
}
|
||||
case "TotalPolygenicDiseaseRiskScore":{
|
||||
|
||||
titleTranslated := translation.TranslateTextFromEnglishToMyLanguage("Total Polygenic Disease Risk Score")
|
||||
|
||||
return titleTranslated, true, passValueFunction, "/100", noResponseTranslated, nil
|
||||
}
|
||||
case "OffspringTotalPolygenicDiseaseRiskScore":{
|
||||
|
||||
titleTranslated := translation.TranslateTextFromEnglishToMyLanguage("Offspring Total Polygenic Disease Risk Score")
|
||||
|
||||
return titleTranslated, true, passValueFunction, "/100", unknownTranslated, nil
|
||||
}
|
||||
case "23andMe_AncestryComposition":{
|
||||
// There is no way to display this as text, we use the gui instead
|
||||
|
||||
|
@ -867,6 +914,24 @@ func GetProfileAttributeDisplayInfo(attributeName string)(string, bool, func(str
|
|||
|
||||
return titleTranslated, true, passValueFunction, "%", unknownTranslated, nil
|
||||
}
|
||||
case "OffspringProbabilityOfAnyMonogenicDisease":{
|
||||
|
||||
titleTranslated := translation.TranslateTextFromEnglishToMyLanguage("Offspring Probability Of Any Monogenic Disease")
|
||||
|
||||
return titleTranslated, true, formatPercentageFunction, "%", unknownTranslated, nil
|
||||
}
|
||||
case "TotalPolygenicDiseaseRiskScore":{
|
||||
|
||||
titleTranslated := translation.TranslateTextFromEnglishToMyLanguage("Total Polygenic Disease Risk Score")
|
||||
|
||||
return titleTranslated, true, passValueFunction, "/100", noResponseTranslated, nil
|
||||
}
|
||||
case "OffspringTotalPolygenicDiseaseRiskScore":{
|
||||
|
||||
titleTranslated := translation.TranslateTextFromEnglishToMyLanguage("Offspring Total Polygenic Disease Risk Score")
|
||||
|
||||
return titleTranslated, true, passValueFunction, "/100", unknownTranslated, nil
|
||||
}
|
||||
case "OffspringProbabilityOfAnyMonogenicDisease_NumberOfDiseasesTested":{
|
||||
|
||||
titleTranslated := translation.TranslateTextFromEnglishToMyLanguage("Offspring Probability Of Any Monogenic Disease - Number Of Diseases Tested")
|
||||
|
@ -897,6 +962,107 @@ func GetProfileAttributeDisplayInfo(attributeName string)(string, bool, func(str
|
|||
|
||||
return titleTranslated, true, passValueFunction, unitsWithPadding, "", nil
|
||||
}
|
||||
case "AutismRiskScore",
|
||||
"OffspringAutismRiskScore",
|
||||
"ObesityRiskScore",
|
||||
"OffspringObesityRiskScore",
|
||||
"HomosexualnessScore",
|
||||
"OffspringHomosexualnessScore":{
|
||||
|
||||
getAttributeTitle := func()(string, error){
|
||||
|
||||
switch attributeName{
|
||||
|
||||
case "AutismRiskScore":{
|
||||
return "Autism Risk Score", nil
|
||||
}
|
||||
case "OffspringAutismRiskScore":{
|
||||
return "Offspring Autism Risk Score", nil
|
||||
}
|
||||
case "ObesityRiskScore":{
|
||||
return "Obesity Risk Score", nil
|
||||
}
|
||||
case "OffspringObesityRiskScore":{
|
||||
return "Offspring Obesity Risk Score", nil
|
||||
}
|
||||
case "HomosexualnessScore":{
|
||||
return "Homosexualness Score", nil
|
||||
}
|
||||
case "OffspringHomosexualnessScore":{
|
||||
return "Offspring Homosexualness Score", nil
|
||||
}
|
||||
}
|
||||
|
||||
return "", errors.New("getAttributeTitle reached with unknown attributeName: " + attributeName)
|
||||
}
|
||||
|
||||
attributeTitle, err := getAttributeTitle()
|
||||
if (err != nil) { return "", false, nil, "", "", err }
|
||||
|
||||
titleTranslated := translation.TranslateTextFromEnglishToMyLanguage(attributeTitle)
|
||||
|
||||
return titleTranslated, true, passValueFunction, "/10", unknownTranslated, nil
|
||||
}
|
||||
case "PredictedEyeColor":{
|
||||
|
||||
titleTranslated := translation.TranslateTextFromEnglishToMyLanguage("Predicted Eye Color")
|
||||
|
||||
return titleTranslated, false, translateValueFunction, "", unknownTranslated, nil
|
||||
}
|
||||
case "PredictedHairTexture":{
|
||||
|
||||
titleTranslated := translation.TranslateTextFromEnglishToMyLanguage("Predicted Hair Texture")
|
||||
|
||||
return titleTranslated, false, translateValueFunction, "", unknownTranslated, nil
|
||||
}
|
||||
case "PredictedLactoseTolerance":{
|
||||
|
||||
titleTranslated := translation.TranslateTextFromEnglishToMyLanguage("Predicted Lactose Tolerance")
|
||||
|
||||
return titleTranslated, false, translateValueFunction, "", unknownTranslated, nil
|
||||
}
|
||||
case "OffspringBlueEyesProbability":{
|
||||
|
||||
titleTranslated := translation.TranslateTextFromEnglishToMyLanguage("Offspring Blue Eyes Probability")
|
||||
|
||||
return titleTranslated, false, formatPercentageFunction, "%", unknownTranslated, nil
|
||||
}
|
||||
case "OffspringGreenEyesProbability":{
|
||||
|
||||
titleTranslated := translation.TranslateTextFromEnglishToMyLanguage("Offspring Green Eyes Probability")
|
||||
|
||||
return titleTranslated, false, formatPercentageFunction, "%", unknownTranslated, nil
|
||||
}
|
||||
case "OffspringHazelEyesProbability":{
|
||||
|
||||
titleTranslated := translation.TranslateTextFromEnglishToMyLanguage("Offspring Hazel Eyes Probability")
|
||||
|
||||
return titleTranslated, false, formatPercentageFunction, "%", unknownTranslated, nil
|
||||
}
|
||||
case "OffspringBrownEyesProbability":{
|
||||
|
||||
titleTranslated := translation.TranslateTextFromEnglishToMyLanguage("Offspring Brown Eyes Probability")
|
||||
|
||||
return titleTranslated, false, formatPercentageFunction, "%", unknownTranslated, nil
|
||||
}
|
||||
case "OffspringLactoseToleranceProbability":{
|
||||
|
||||
titleTranslated := translation.TranslateTextFromEnglishToMyLanguage("Offspring Lactose Tolerance Probability")
|
||||
|
||||
return titleTranslated, false, formatPercentageFunction, "%", unknownTranslated, nil
|
||||
}
|
||||
case "OffspringStraightHairProbability":{
|
||||
|
||||
titleTranslated := translation.TranslateTextFromEnglishToMyLanguage("Offspring Straight Hair Probability")
|
||||
|
||||
return titleTranslated, false, formatPercentageFunction, "%", unknownTranslated, nil
|
||||
}
|
||||
case "OffspringCurlyHairProbability":{
|
||||
|
||||
titleTranslated := translation.TranslateTextFromEnglishToMyLanguage("Offspring Curly Hair Probability")
|
||||
|
||||
return titleTranslated, false, formatPercentageFunction, "%", unknownTranslated, nil
|
||||
}
|
||||
}
|
||||
|
||||
attributeHasMonogenicDiseasePrefix := strings.HasPrefix(attributeName, "MonogenicDisease_")
|
||||
|
|
|
@ -46,10 +46,6 @@ import "slices"
|
|||
|
||||
//TODO:
|
||||
// -LastActive
|
||||
// -OffspringLactoseToleranceProbability
|
||||
// Used to sort users based on probability of lactose tolerance
|
||||
// This allows the user to sort matches based on whose offspring is most likely to be lactose tolerant
|
||||
// -Offspring Probability for all traits
|
||||
// -DietSimilarity
|
||||
|
||||
|
||||
|
@ -62,12 +58,6 @@ var calculatedAttributesList = []string{
|
|||
"Distance",
|
||||
"IsSameSex",
|
||||
"23andMe_OffspringNeanderthalVariants",
|
||||
"OffspringProbabilityOfAnyMonogenicDisease",
|
||||
"OffspringProbabilityOfAnyMonogenicDisease_NumberOfDiseasesTested",
|
||||
"TotalPolygenicDiseaseRiskScore",
|
||||
"TotalPolygenicDiseaseRiskScore_NumberOfDiseasesTested",
|
||||
"OffspringTotalPolygenicDiseaseRiskScore",
|
||||
"OffspringTotalPolygenicDiseaseRiskScore_NumberOfDiseasesTested",
|
||||
"SearchTermsCount",
|
||||
"HasMessagedMe",
|
||||
"IHaveMessaged",
|
||||
|
@ -95,6 +85,46 @@ var calculatedAttributesList = []string{
|
|||
"23andMe_MaternalHaplogroupSimilarity",
|
||||
"23andMe_PaternalHaplogroupSimilarity",
|
||||
"NumberOfReviews",
|
||||
|
||||
"OffspringProbabilityOfAnyMonogenicDisease",
|
||||
"OffspringProbabilityOfAnyMonogenicDisease_NumberOfDiseasesTested",
|
||||
|
||||
// Polygenic Diseases:
|
||||
|
||||
"TotalPolygenicDiseaseRiskScore",
|
||||
"TotalPolygenicDiseaseRiskScore_NumberOfDiseasesTested",
|
||||
|
||||
"OffspringTotalPolygenicDiseaseRiskScore",
|
||||
"OffspringTotalPolygenicDiseaseRiskScore_NumberOfDiseasesTested",
|
||||
|
||||
"AutismRiskScore",
|
||||
"OffspringAutismRiskScore",
|
||||
|
||||
"ObesityRiskScore",
|
||||
"OffspringObesityRiskScore",
|
||||
|
||||
// Discrete Traits:
|
||||
|
||||
"PredictedEyeColor",
|
||||
"OffspringBlueEyesProbability",
|
||||
"OffspringGreenEyesProbability",
|
||||
"OffspringHazelEyesProbability",
|
||||
"OffspringBrownEyesProbability",
|
||||
|
||||
"PredictedLactoseTolerance",
|
||||
"OffspringLactoseToleranceProbability",
|
||||
|
||||
"PredictedHairTexture",
|
||||
"OffspringStraightHairProbability",
|
||||
"OffspringCurlyHairProbability",
|
||||
|
||||
// Numeric Traits:
|
||||
|
||||
"HomosexualnessScore",
|
||||
"OffspringHomosexualnessScore",
|
||||
|
||||
"PredictedHeight",
|
||||
"OffspringPredictedHeight",
|
||||
}
|
||||
|
||||
// We use a map for faster lookups
|
||||
|
@ -677,15 +707,22 @@ func GetAnyProfileAttributeIncludingCalculated(attributeName string, getProfileA
|
|||
// Each risk score is a number between 0 and 1
|
||||
allDiseasesAverageRiskScoreNumerator := float64(0)
|
||||
|
||||
for _, diseaseObject := range polygenicDiseaseObjectsList{
|
||||
// Map Structure: Locus rsID -> Locus Value
|
||||
userDiseaseLocusValuesMap := make(map[int64]locusValue.LocusValue)
|
||||
|
||||
// Map Structure: Locus rsID -> Locus Value
|
||||
userDiseaseLocusValuesMap := make(map[int64]locusValue.LocusValue)
|
||||
for _, diseaseObject := range polygenicDiseaseObjectsList{
|
||||
|
||||
diseaseLociList := diseaseObject.LociList
|
||||
|
||||
for _, locusRSID := range diseaseLociList{
|
||||
|
||||
_, exists := userDiseaseLocusValuesMap[locusRSID]
|
||||
if (exists == true){
|
||||
// We already added this locus
|
||||
// This can happen if two diseases share the same locus
|
||||
continue
|
||||
}
|
||||
|
||||
locusRSIDString := helpers.ConvertInt64ToString(locusRSID)
|
||||
|
||||
locusValueAttributeName := "LocusValue_rs" + locusRSIDString
|
||||
|
@ -769,11 +806,8 @@ func GetAnyProfileAttributeIncludingCalculated(attributeName string, getProfileA
|
|||
if (myPersonChosen == false || myGenomesExist == false || myAnalysisIsReady == false){
|
||||
|
||||
// We have not linked a genome person and performed a genetic analysis
|
||||
// The total monogenic disease risk is unknown
|
||||
// We can still predict disease risk for individual recessive disorders when one person has no variants, but
|
||||
// not the total probability for all monogenic diseases
|
||||
// This is because everyone is a carrier for at least some recessive monogenic disorders
|
||||
//
|
||||
// The total polygenic disease risk is unknown
|
||||
|
||||
return false, profileVersion, "", nil
|
||||
}
|
||||
|
||||
|
@ -794,15 +828,22 @@ func GetAnyProfileAttributeIncludingCalculated(attributeName string, getProfileA
|
|||
// Each risk score is a number between 0 and 1
|
||||
allDiseasesAverageRiskScoreNumerator := float64(0)
|
||||
|
||||
// Map Structure: rsID -> Locus Value
|
||||
userDiseaseLocusValuesMap := make(map[int64]locusValue.LocusValue)
|
||||
|
||||
for _, diseaseObject := range polygenicDiseaseObjectsList{
|
||||
|
||||
diseaseLociList := diseaseObject.LociList
|
||||
|
||||
// Map Structure: rsID -> Locus Value
|
||||
userDiseaseLocusValuesMap := make(map[int64]locusValue.LocusValue)
|
||||
|
||||
for _, locusRSID := range diseaseLociList{
|
||||
|
||||
_, exists := userDiseaseLocusValuesMap[locusRSID]
|
||||
if (exists == true){
|
||||
// We already added this locus
|
||||
// This can happen if two diseases share the same locus
|
||||
continue
|
||||
}
|
||||
|
||||
locusRSIDString := helpers.ConvertInt64ToString(locusRSID)
|
||||
|
||||
locusValueAttributeName := "LocusValue_rs" + locusRSIDString
|
||||
|
@ -834,7 +875,7 @@ func GetAnyProfileAttributeIncludingCalculated(attributeName string, getProfileA
|
|||
Base2Value: userLocusBase2,
|
||||
LocusIsPhased: userLocusIsPhased,
|
||||
}
|
||||
|
||||
|
||||
userDiseaseLocusValuesMap[locusRSID] = newLocusValueObject
|
||||
}
|
||||
|
||||
|
@ -867,6 +908,386 @@ func GetAnyProfileAttributeIncludingCalculated(attributeName string, getProfileA
|
|||
|
||||
return true, profileVersion, allDiseasesAverageRiskScoreString, nil
|
||||
}
|
||||
case "AutismRiskScore",
|
||||
"ObesityRiskScore":{
|
||||
|
||||
// These are polygenic diseases
|
||||
// We get the risk score for the user
|
||||
|
||||
diseaseName := strings.TrimSuffix(attributeName, "RiskScore")
|
||||
|
||||
diseaseObject, err := polygenicDiseases.GetPolygenicDiseaseObject(diseaseName)
|
||||
if (err != nil){ return false, 0, "", err }
|
||||
|
||||
diseaseLociList := diseaseObject.LociList
|
||||
|
||||
userDiseaseLocusValuesMap, err := getUserGenomeLocusValuesMap(diseaseLociList, getProfileAttributesFunction)
|
||||
if (err != nil) { return false, 0, "", err }
|
||||
|
||||
neuralNetworkExists, anyLocusTested, userDiseaseRiskScore, _, _, _, err := createPersonGeneticAnalysis.GetPersonGenomePolygenicDiseaseAnalysis(diseaseObject, userDiseaseLocusValuesMap, true)
|
||||
if (err != nil) { return false, 0, "", err }
|
||||
if (neuralNetworkExists == false){
|
||||
return false, 0, "", errors.New("Neural network missing for disease: " + diseaseName)
|
||||
}
|
||||
if (anyLocusTested == false){
|
||||
// Disease risk is unknown
|
||||
return false, profileVersion, "", nil
|
||||
}
|
||||
|
||||
riskScoreString := helpers.ConvertIntToString(userDiseaseRiskScore)
|
||||
|
||||
return true, profileVersion, riskScoreString, nil
|
||||
}
|
||||
case "OffspringAutismRiskScore",
|
||||
"OffspringObesityRiskScore":{
|
||||
|
||||
// These are polygenic diseases
|
||||
// We get the risk score for the offspring
|
||||
|
||||
myPersonChosen, myGenomesExist, myAnalysisIsReady, myGeneticAnalysisObject, myGenomeIdentifier, _, err := myChosenAnalysis.GetMyChosenMateGeneticAnalysis()
|
||||
if (err != nil) { return false, 0, "", err }
|
||||
if (myPersonChosen == false || myGenomesExist == false || myAnalysisIsReady == false){
|
||||
|
||||
// We have not linked a genome person and performed a genetic analysis
|
||||
// All offspring polygenic disease risks are unknown
|
||||
|
||||
return false, profileVersion, "", nil
|
||||
}
|
||||
|
||||
_, _, _, _, myGenomesMap, err := readGeneticAnalysis.GetMetadataFromPersonGeneticAnalysis(myGeneticAnalysisObject)
|
||||
if (err != nil) { return false, 0, "", err }
|
||||
|
||||
myGenomeLocusValuesMap, exists := myGenomesMap[myGenomeIdentifier]
|
||||
if (exists == false){
|
||||
return false, 0, "", errors.New("GetMyChosenMateGeneticAnalysis returning genetic analysis which has GenomesMap which is missing my genome identifier.")
|
||||
}
|
||||
|
||||
|
||||
diseaseNameWithOffspring := strings.TrimSuffix(attributeName, "RiskScore")
|
||||
|
||||
diseaseName := strings.TrimPrefix(diseaseNameWithOffspring, "Offspring")
|
||||
|
||||
diseaseObject, err := polygenicDiseases.GetPolygenicDiseaseObject(diseaseName)
|
||||
if (err != nil){ return false, 0, "", err }
|
||||
|
||||
diseaseLociList := diseaseObject.LociList
|
||||
|
||||
userDiseaseLocusValuesMap, err := getUserGenomeLocusValuesMap(diseaseLociList, getProfileAttributesFunction)
|
||||
if (err != nil) { return false, 0, "", err }
|
||||
|
||||
neuralNetworkExists, anyLocusValuesTested, offspringAverageRiskScore, _, _, _, _, err := createCoupleGeneticAnalysis.GetOffspringPolygenicDiseaseAnalysis(diseaseObject, myGenomeLocusValuesMap, userDiseaseLocusValuesMap)
|
||||
if (err != nil) { return false, 0, "", err }
|
||||
if (neuralNetworkExists == false){
|
||||
return false, 0, "", errors.New("No neural network exists for disease: " + diseaseName)
|
||||
}
|
||||
if (anyLocusValuesTested == false){
|
||||
// No disease loci are known
|
||||
return false, profileVersion, "", nil
|
||||
}
|
||||
|
||||
offspringAverageRiskScoreString := helpers.ConvertIntToString(offspringAverageRiskScore)
|
||||
|
||||
return true, profileVersion, offspringAverageRiskScoreString, nil
|
||||
}
|
||||
case "PredictedEyeColor",
|
||||
"PredictedLactoseTolerance",
|
||||
"PredictedHairTexture":{
|
||||
|
||||
//Outputs:
|
||||
// -string: Trait name
|
||||
getTraitName := func()(string, error){
|
||||
|
||||
switch attributeName{
|
||||
|
||||
case "PredictedEyeColor":{
|
||||
return "Eye Color", nil
|
||||
}
|
||||
case "PredictedLactoseTolerance":{
|
||||
return "Lactose Tolerance", nil
|
||||
}
|
||||
case "PredictedHairTexture":{
|
||||
return "Hair Texture", nil
|
||||
}
|
||||
}
|
||||
|
||||
return "", errors.New("Discrete trait calculated attribute reached with unknown attributeName: " + attributeName)
|
||||
}
|
||||
|
||||
traitName, err := getTraitName()
|
||||
if (err != nil) { return false, 0, "", err }
|
||||
|
||||
traitObject, err := traits.GetTraitObject(traitName)
|
||||
if (err != nil) { return false, 0, "", err }
|
||||
|
||||
traitLociList := traitObject.LociList
|
||||
|
||||
userTraitLocusValuesMap, err := getUserGenomeLocusValuesMap(traitLociList, getProfileAttributesFunction)
|
||||
if (err != nil) { return false, 0, "", err }
|
||||
|
||||
neuralNetworkExists, neuralNetworkOutcomeIsKnown, predictedOutcome, _, _, _, err := createPersonGeneticAnalysis.GetGenomeDiscreteTraitAnalysis_NeuralNetwork(traitObject, userTraitLocusValuesMap, true)
|
||||
if (err != nil) { return false, 0, "", err }
|
||||
if (neuralNetworkExists == true){
|
||||
if (neuralNetworkOutcomeIsKnown == false){
|
||||
return false, 0, "", nil
|
||||
}
|
||||
|
||||
return true, profileVersion, predictedOutcome, nil
|
||||
}
|
||||
|
||||
anyRulesExist, _, _, _, predictedOutcomeExists, predictedOutcome, err := createPersonGeneticAnalysis.GetGenomeDiscreteTraitAnalysis_Rules(traitObject, userTraitLocusValuesMap, true)
|
||||
if (err != nil) { return false, 0, "", err }
|
||||
if (anyRulesExist == false){
|
||||
return false, 0, "", errors.New("Discrete trait calculated attribute exists for trait without a neural network or rules: " + traitName)
|
||||
}
|
||||
if (predictedOutcomeExists == false){
|
||||
return false, 0, "", nil
|
||||
}
|
||||
|
||||
return true, profileVersion, predictedOutcome, nil
|
||||
}
|
||||
case "OffspringBlueEyesProbability",
|
||||
"OffspringGreenEyesProbability",
|
||||
"OffspringHazelEyesProbability",
|
||||
"OffspringBrownEyesProbability",
|
||||
"OffspringLactoseToleranceProbability",
|
||||
"OffspringStraightHairProbability",
|
||||
"OffspringCurlyHairProbability":{
|
||||
|
||||
//TODO: Add ability to retrieve confidence/quantity of loci known and sort/filter by those attributes
|
||||
|
||||
myPersonChosen, myGenomesExist, myAnalysisIsReady, myGeneticAnalysisObject, myGenomeIdentifier, _, err := myChosenAnalysis.GetMyChosenMateGeneticAnalysis()
|
||||
if (err != nil) { return false, 0, "", err }
|
||||
if (myPersonChosen == false || myGenomesExist == false || myAnalysisIsReady == false){
|
||||
|
||||
// We have not linked a genome person and performed a genetic analysis
|
||||
// All offspring trait predictions are unknown
|
||||
|
||||
return false, profileVersion, "", nil
|
||||
}
|
||||
|
||||
_, _, _, _, myGenomesMap, err := readGeneticAnalysis.GetMetadataFromPersonGeneticAnalysis(myGeneticAnalysisObject)
|
||||
if (err != nil) { return false, 0, "", err }
|
||||
|
||||
myGenomeLocusValuesMap, exists := myGenomesMap[myGenomeIdentifier]
|
||||
if (exists == false){
|
||||
return false, 0, "", errors.New("GetMyChosenMateGeneticAnalysis returning genetic analysis which has GenomesMap which is missing my genome identifier.")
|
||||
}
|
||||
|
||||
// These are discrete traits
|
||||
// We get the outcome probability for the offspring
|
||||
|
||||
//Outputs:
|
||||
// -string: Trait name
|
||||
// -string: Outcome name
|
||||
getTraitAndOutcomeName := func()(string, string, error){
|
||||
|
||||
switch attributeName{
|
||||
|
||||
case "OffspringBlueEyesProbability":{
|
||||
return "Eye Color", "Blue", nil
|
||||
}
|
||||
case "OffspringGreenEyesProbability":{
|
||||
return "Eye Color", "Green", nil
|
||||
}
|
||||
case "OffspringHazelEyesProbability":{
|
||||
return "Eye Color", "Hazel", nil
|
||||
}
|
||||
case "OffspringBrownEyesProbability":{
|
||||
return "Eye Color", "Brown", nil
|
||||
}
|
||||
case "OffspringLactoseToleranceProbability":{
|
||||
return "Lactose Tolerance", "Tolerant", nil
|
||||
}
|
||||
case "OffspringStraightHairProbability":{
|
||||
return "Hair Texture", "Straight", nil
|
||||
}
|
||||
case "OffspringCurlyHairProbability":{
|
||||
return "Hair Texture", "Curly", nil
|
||||
}
|
||||
}
|
||||
|
||||
return "", "", errors.New("Offspring discrete trait calculated attribute reached with unknown attributeName: " + attributeName)
|
||||
}
|
||||
|
||||
traitName, outcomeName, err := getTraitAndOutcomeName()
|
||||
if (err != nil) { return false, 0, "", err }
|
||||
|
||||
traitObject, err := traits.GetTraitObject(traitName)
|
||||
if (err != nil) { return false, 0, "", err }
|
||||
|
||||
traitLociList := traitObject.LociList
|
||||
|
||||
userTraitLocusValuesMap, err := getUserGenomeLocusValuesMap(traitLociList, getProfileAttributesFunction)
|
||||
if (err != nil) { return false, 0, "", err }
|
||||
|
||||
neuralNetworkExists, anyLociKnown, outcomeProbabilitiesMap, _, _, _, err := createCoupleGeneticAnalysis.GetOffspringDiscreteTraitAnalysis_NeuralNetwork(traitObject, myGenomeLocusValuesMap, userTraitLocusValuesMap)
|
||||
if (err != nil) { return false, 0, "", err }
|
||||
if (neuralNetworkExists == true){
|
||||
if (anyLociKnown == false){
|
||||
|
||||
// Trait prediction is not possible
|
||||
return false, 0, "", nil
|
||||
}
|
||||
|
||||
outcomeProbability, exists := outcomeProbabilitiesMap[outcomeName]
|
||||
if (exists == false){
|
||||
return true, profileVersion, "0", nil
|
||||
}
|
||||
|
||||
outcomeProbabilityString := helpers.ConvertIntToString(outcomeProbability)
|
||||
|
||||
return true, profileVersion, outcomeProbabilityString, nil
|
||||
}
|
||||
|
||||
anyRulesExist, rulesAnalysisExists, _, _, _, outcomeProbabilitiesMap, err := createCoupleGeneticAnalysis.GetOffspringDiscreteTraitAnalysis_Rules(traitObject, myGenomeLocusValuesMap, userTraitLocusValuesMap)
|
||||
if (err != nil) { return false, 0, "", err }
|
||||
if (anyRulesExist == false){
|
||||
return false, 0, "", errors.New("Calculation of offspring attribute for discrete trait called with trait missing neural network or rules: " + traitName)
|
||||
}
|
||||
if (rulesAnalysisExists == false){
|
||||
// Analysis is impossible for this trait
|
||||
return false, 0, "", nil
|
||||
}
|
||||
|
||||
outcomeProbability, exists := outcomeProbabilitiesMap[outcomeName]
|
||||
if (exists == false){
|
||||
return true, profileVersion, "0", nil
|
||||
}
|
||||
|
||||
outcomeProbabilityString := helpers.ConvertIntToString(outcomeProbability)
|
||||
|
||||
return true, profileVersion, outcomeProbabilityString, nil
|
||||
}
|
||||
case "HomosexualnessScore",
|
||||
"PredictedHeight":{
|
||||
|
||||
// These are numeric traits
|
||||
// We calculate the value for the user
|
||||
|
||||
//Outputs:
|
||||
// -string: Trait name
|
||||
// -bool: Is a score between 0-10
|
||||
// -error
|
||||
getTraitNameAndIsAScoreBool := func()(string, bool, error){
|
||||
|
||||
switch attributeName{
|
||||
case "HomosexualnessScore":{
|
||||
return "Homosexualness", true, nil
|
||||
}
|
||||
case "PredictedHeight":{
|
||||
return "Height", false, nil
|
||||
}
|
||||
}
|
||||
|
||||
return "", false, errors.New("User numeric trait value calculation called with unknown attributeName: " + attributeName)
|
||||
}
|
||||
|
||||
traitName, traitIsAScore, err := getTraitNameAndIsAScoreBool()
|
||||
if (err != nil) { return false, 0, "", err }
|
||||
|
||||
traitObject, err := traits.GetTraitObject(traitName)
|
||||
if (err != nil) { return false, 0, "", err }
|
||||
|
||||
traitLociList := traitObject.LociList
|
||||
|
||||
userTraitLocusValuesMap, err := getUserGenomeLocusValuesMap(traitLociList, getProfileAttributesFunction)
|
||||
if (err != nil) { return false, 0, "", err }
|
||||
|
||||
traitNeuralNetworkExists, anyLocusValuesAreKnown, predictedOutcome, _, _, _, err := createPersonGeneticAnalysis.GetGenomeNumericTraitAnalysis(traitObject, userTraitLocusValuesMap, true)
|
||||
if (err != nil) { return false, 0, "", err }
|
||||
if (traitNeuralNetworkExists == false){
|
||||
return false, 0, "", errors.New("Numeric trait attribute calculation reached for trait with no neural network: " + traitName)
|
||||
}
|
||||
if (anyLocusValuesAreKnown == false){
|
||||
// Trait prediction is impossible
|
||||
return false, 0, "", nil
|
||||
}
|
||||
|
||||
if (traitIsAScore == true){
|
||||
|
||||
predictedScoreString := helpers.ConvertIntToString(int(predictedOutcome))
|
||||
|
||||
return true, profileVersion, predictedScoreString, nil
|
||||
}
|
||||
|
||||
predictedOutcomeString := helpers.ConvertFloat64ToString(predictedOutcome)
|
||||
|
||||
return true, profileVersion, predictedOutcomeString, nil
|
||||
}
|
||||
case "OffspringHomosexualnessScore",
|
||||
"OffspringPredictedHeight":{
|
||||
|
||||
// These are numeric traits
|
||||
// We calculate the value for the offspring
|
||||
|
||||
myPersonChosen, myGenomesExist, myAnalysisIsReady, myGeneticAnalysisObject, myGenomeIdentifier, _, err := myChosenAnalysis.GetMyChosenMateGeneticAnalysis()
|
||||
if (err != nil) { return false, 0, "", err }
|
||||
if (myPersonChosen == false || myGenomesExist == false || myAnalysisIsReady == false){
|
||||
|
||||
// We have not linked a genome person and performed a genetic analysis
|
||||
// All offspring trait predictions are unknown
|
||||
|
||||
return false, profileVersion, "", nil
|
||||
}
|
||||
|
||||
_, _, _, _, myGenomesMap, err := readGeneticAnalysis.GetMetadataFromPersonGeneticAnalysis(myGeneticAnalysisObject)
|
||||
if (err != nil) { return false, 0, "", err }
|
||||
|
||||
myGenomeLocusValuesMap, exists := myGenomesMap[myGenomeIdentifier]
|
||||
if (exists == false){
|
||||
return false, 0, "", errors.New("GetMyChosenMateGeneticAnalysis returning genetic analysis which has GenomesMap which is missing my genome identifier.")
|
||||
}
|
||||
|
||||
//Outputs:
|
||||
// -string: Trait name
|
||||
// -bool: Is a score between 0-10
|
||||
// -error
|
||||
getTraitNameAndIsAScoreBool := func()(string, bool, error){
|
||||
|
||||
switch attributeName{
|
||||
case "OffspringHomosexualnessScore":{
|
||||
return "Homosexualness", true, nil
|
||||
}
|
||||
case "OffspringPredictedHeight":{
|
||||
return "Height", false, nil
|
||||
}
|
||||
}
|
||||
|
||||
return "", false, errors.New("Offspring numeric trait value calculation called with unknown attributeName: " + attributeName)
|
||||
}
|
||||
|
||||
traitName, traitIsAScore, err := getTraitNameAndIsAScoreBool()
|
||||
if (err != nil) { return false, 0, "", err }
|
||||
|
||||
traitObject, err := traits.GetTraitObject(traitName)
|
||||
if (err != nil) { return false, 0, "", err }
|
||||
|
||||
traitLociList := traitObject.LociList
|
||||
|
||||
userTraitLocusValuesMap, err := getUserGenomeLocusValuesMap(traitLociList, getProfileAttributesFunction)
|
||||
if (err != nil) { return false, 0, "", err }
|
||||
|
||||
neuralNetworkExists, anyLociKnown, predictedOutcome, _, _, _, _, err := createCoupleGeneticAnalysis.GetOffspringNumericTraitAnalysis(traitObject, userTraitLocusValuesMap, myGenomeLocusValuesMap)
|
||||
if (err != nil) { return false, 0, "", err }
|
||||
if (neuralNetworkExists == false){
|
||||
return false, 0, "", errors.New("Offspring Numeric trait attribute calculation reached for trait with no neural network: " + traitName)
|
||||
}
|
||||
if (anyLociKnown == false){
|
||||
// Prediction is impossible
|
||||
return false, profileVersion, "", nil
|
||||
}
|
||||
|
||||
if (traitIsAScore == true){
|
||||
|
||||
predictedScoreString := helpers.ConvertIntToString(int(predictedOutcome))
|
||||
|
||||
return true, profileVersion, predictedScoreString, nil
|
||||
}
|
||||
|
||||
predictedOutcomeString := helpers.ConvertFloat64ToString(predictedOutcome)
|
||||
|
||||
return true, profileVersion, predictedOutcomeString, nil
|
||||
}
|
||||
case "SearchTermsCount":{
|
||||
|
||||
myDesireExists, myDesiredChoicesListString, err := myLocalDesires.GetDesire("SearchTerms")
|
||||
|
@ -1645,7 +2066,55 @@ func GetAnyProfileAttributeIncludingCalculated(attributeName string, getProfileA
|
|||
return false, 0, "", errors.New("GetAnyProfileAttributeIncludingCalculated called with unknown attribute: " + attributeName)
|
||||
}
|
||||
|
||||
|
||||
// This function constructs a traitLocusValuesMap from a user's profile and a set of loci
|
||||
//Outputs:
|
||||
// -map[int64]locusValue.LocusValue: Genome map for provided loci
|
||||
// -error
|
||||
func getUserGenomeLocusValuesMap(lociList []int64, getProfileAttributesFunction func(string)(bool, int, string, error))(map[int64]locusValue.LocusValue, error){
|
||||
|
||||
// We construct the user's locus values map
|
||||
// Map Structure: Locus rsID -> locusValue.LocusValue
|
||||
userTraitLocusValuesMap := make(map[int64]locusValue.LocusValue)
|
||||
|
||||
for _, rsID := range lociList{
|
||||
|
||||
rsIDString := helpers.ConvertInt64ToString(rsID)
|
||||
|
||||
userLocusValueAttributeName := "LocusValue_rs" + rsIDString
|
||||
|
||||
userLocusValueIsKnown, _, userLocusValue, err := getProfileAttributesFunction(userLocusValueAttributeName)
|
||||
if (err != nil) { return nil, err }
|
||||
if (userLocusValueIsKnown == false){
|
||||
continue
|
||||
}
|
||||
|
||||
userLocusBase1, userLocusBase2, semicolonFound := strings.Cut(userLocusValue, ";")
|
||||
if (semicolonFound == false){
|
||||
return nil, errors.New("Database corrupt: Contains profile with invalid " + userLocusValueAttributeName + " value: " + userLocusValue)
|
||||
}
|
||||
|
||||
userLocusIsPhasedAttributeName := "LocusIsPhased_rs" + rsIDString
|
||||
|
||||
userLocusIsPhasedExists, _, userLocusIsPhasedString, err := getProfileAttributesFunction(userLocusIsPhasedAttributeName)
|
||||
if (err != nil) { return nil, err }
|
||||
if (userLocusIsPhasedExists == false){
|
||||
return nil, errors.New("Database corrupt: Contains profile with locusValue but not locusIsPhased status for locus: " + rsIDString)
|
||||
}
|
||||
|
||||
userLocusIsPhased, err := helpers.ConvertYesOrNoStringToBool(userLocusIsPhasedString)
|
||||
if (err != nil) { return nil, err }
|
||||
|
||||
userLocusValueObject := locusValue.LocusValue{
|
||||
Base1Value: userLocusBase1,
|
||||
Base2Value: userLocusBase2,
|
||||
LocusIsPhased: userLocusIsPhased,
|
||||
}
|
||||
|
||||
userTraitLocusValuesMap[rsID] = userLocusValueObject
|
||||
}
|
||||
|
||||
return userTraitLocusValuesMap, nil
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -26,7 +26,7 @@ func TestCalculatedAttributes(t *testing.T){
|
|||
|
||||
calculatedAttributesList := calculatedAttributes.GetCalculatedAttributesList()
|
||||
|
||||
for i:=0; i<100; i++{
|
||||
for i:=0; i<10; i++{
|
||||
|
||||
identityPublicKey, identityPrivateKey, err := identity.GetNewRandomPublicPrivateIdentityKeys()
|
||||
if (err != nil){
|
||||
|
|
Loading…
Reference in a new issue