1634 lines
62 KiB
Go
1634 lines
62 KiB
Go
|
|
||
|
// readGeneticAnalysis provides function to read genetic analyses
|
||
|
|
||
|
package readGeneticAnalysis
|
||
|
|
||
|
import "seekia/resources/geneticReferences/monogenicDiseases"
|
||
|
import "seekia/resources/geneticReferences/polygenicDiseases"
|
||
|
import "seekia/resources/geneticReferences/traits"
|
||
|
|
||
|
|
||
|
import "seekia/internal/helpers"
|
||
|
|
||
|
import "encoding/json"
|
||
|
import "strings"
|
||
|
import "errors"
|
||
|
|
||
|
// This works for person and couple analyses
|
||
|
func ReadGeneticAnalysisString(inputAnalysisString string)([]map[string]string, error){
|
||
|
|
||
|
inputAnalysisBytes := []byte(inputAnalysisString)
|
||
|
|
||
|
var newAnalysisMapList []map[string]string
|
||
|
|
||
|
err := json.Unmarshal(inputAnalysisBytes, &newAnalysisMapList)
|
||
|
if (err != nil) { return nil, err }
|
||
|
|
||
|
return newAnalysisMapList, nil
|
||
|
}
|
||
|
|
||
|
//Outputs:
|
||
|
// -[]string: All raw genome identifiers list (excluding combined genomes)
|
||
|
// -bool: Multiple genomes exist
|
||
|
// -string: OnlyExcludeConflicts GenomeIdentifier
|
||
|
// -string: OnlyIncludeShared GenomeIdentifier
|
||
|
// -error
|
||
|
func GetMetadataFromPersonGeneticAnalysis(inputGeneticAnalysisMapList []map[string]string)([]string, bool, string, string, error){
|
||
|
|
||
|
for _, element := range inputGeneticAnalysisMapList{
|
||
|
|
||
|
itemType, exists := element["ItemType"]
|
||
|
if (exists == false){
|
||
|
return nil, false, "", "", errors.New("Malformed genetic analysis map list: Item missing itemType")
|
||
|
}
|
||
|
if (itemType != "Metadata"){
|
||
|
continue
|
||
|
}
|
||
|
|
||
|
analysisVersion, exists := element["AnalysisVersion"]
|
||
|
if (exists == false){
|
||
|
return nil, false, "", "", errors.New("Cannot read analysis: Metadata missing analysisVersion")
|
||
|
}
|
||
|
|
||
|
if (analysisVersion != "1"){
|
||
|
// This analysis must have been created by a newer version of Seekia
|
||
|
// We cannot read it
|
||
|
return nil, false, "", "", errors.New("Cannot read analysis: Is a newer analysis version.")
|
||
|
}
|
||
|
|
||
|
analysisType, exists := element["AnalysisType"]
|
||
|
if (exists == false || analysisType != "Person"){
|
||
|
return nil, false, "", "", errors.New("Trying to get metadata from non-person analysis.")
|
||
|
}
|
||
|
|
||
|
combinedGenomesExist, exists := element["CombinedGenomesExist"]
|
||
|
if (exists == false){
|
||
|
return nil, false, "", "", errors.New("Malformed analysis map list: Metadata missing CombinedGenomesExist")
|
||
|
}
|
||
|
if (combinedGenomesExist == "No"){
|
||
|
|
||
|
mainGenomeIdentifier, exists := element["GenomeIdentifier"]
|
||
|
if (exists == false){
|
||
|
return nil, false, "", "", errors.New("Malformed analysis map list: Single-genome analysis Metadata missing GenomeIdentifier")
|
||
|
}
|
||
|
|
||
|
allRawGenomeIdentifiersList := []string{mainGenomeIdentifier}
|
||
|
|
||
|
return allRawGenomeIdentifiersList, false, "", "", nil
|
||
|
}
|
||
|
|
||
|
onlyExcludeConflictsGenomeIdentifier, exists := element["OnlyExcludeConflictsGenomeIdentifier"]
|
||
|
if (exists == false){
|
||
|
return nil, false, "", "", errors.New("Malformed analysis map list: Metadata missing OnlyExcludeConflictsGenomeIdentifier")
|
||
|
}
|
||
|
onlyIncludeSharedGenomeIdentifier, exists := element["OnlyIncludeSharedGenomeIdentifier"]
|
||
|
if (exists == false){
|
||
|
return nil, false, "", "", errors.New("Malformed genetic analysis map list: Metadata missing OnlyIncludeSharedGenomeIdentifier")
|
||
|
}
|
||
|
|
||
|
allRawGenomeIdentifiersListString, exists := element["AllRawGenomeIdentifiersList"]
|
||
|
if (exists == false){
|
||
|
return nil, false, "", "", errors.New("Malformed analysis map list: Multi-genome Metadata missing AllRawGenomeIdentifiersList")
|
||
|
}
|
||
|
|
||
|
allRawGenomeIdentifiersList := strings.Split(allRawGenomeIdentifiersListString, "+")
|
||
|
|
||
|
if (len(allRawGenomeIdentifiersList) < 2){
|
||
|
return nil, false, "", "", errors.New("Malformed analysis map list: Multi-genome Metadata contains AllRawGenomeIdentifiersList with less than two identifiers")
|
||
|
}
|
||
|
|
||
|
return allRawGenomeIdentifiersList, true, onlyExcludeConflictsGenomeIdentifier, onlyIncludeSharedGenomeIdentifier, nil
|
||
|
}
|
||
|
|
||
|
return nil, false, "", "", errors.New("GetMetadataFromPersonGeneticAnalysis called with malformed person analysis map list: missing Metadata item.")
|
||
|
}
|
||
|
|
||
|
//Outputs:
|
||
|
// -string: Pair 1 Person A Genome Identifier
|
||
|
// -string: Pair 1 Person B Genome Identifier
|
||
|
// -bool: Second Genome pair exists
|
||
|
// -string: Pair 2 Person A Genome Identifier
|
||
|
// -string: Pair 2 Person B Genome Identifier
|
||
|
// -bool: Person A Has Multiple Genomes
|
||
|
// -string: Person A OnlyExcludeConflicts Genome Identifier
|
||
|
// -string: Person A OnlyIncludeShared Genome Identifier
|
||
|
// -bool: Person B Has Multiple Genomes
|
||
|
// -string: Person B OnlyExcludeConflicts Genome Identifier
|
||
|
// -string: Person B OnlyIncludeShared Genome Identifier
|
||
|
// -error
|
||
|
func GetMetadataFromCoupleGeneticAnalysis(inputGeneticAnalysisMapList []map[string]string)(string, string, bool, string, string, bool, string, string, bool, string, string, error){
|
||
|
|
||
|
for _, element := range inputGeneticAnalysisMapList{
|
||
|
|
||
|
itemType, exists := element["ItemType"]
|
||
|
if (exists == false){
|
||
|
return "", "", false, "", "", false, "", "", false, "", "", errors.New("Malformed genetic analysis map list: Item missing itemType")
|
||
|
}
|
||
|
if (itemType != "Metadata"){
|
||
|
continue
|
||
|
}
|
||
|
|
||
|
analysisVersion, exists := element["AnalysisVersion"]
|
||
|
if (exists == false){
|
||
|
return "", "", false, "", "", false, "", "", false, "", "", errors.New("Cannot read analysis: Metadata missing analysisVersion")
|
||
|
}
|
||
|
|
||
|
if (analysisVersion != "1"){
|
||
|
// This analysis must have been created by a newer version of Seekia
|
||
|
// We cannot read it
|
||
|
return "", "", false, "", "", false, "", "", false, "", "", errors.New("Cannot read analysis: Is a newer analysis version.")
|
||
|
}
|
||
|
|
||
|
analysisType, exists := element["AnalysisType"]
|
||
|
if (exists == false || analysisType != "Couple"){
|
||
|
return "", "", false, "", "", false, "", "", false, "", "", errors.New("Trying to get metadata from non-couple analysis.")
|
||
|
}
|
||
|
|
||
|
pair1PersonAGenomeIdentifier, exists := element["Pair1PersonAGenomeIdentifier"]
|
||
|
if (exists == false){
|
||
|
return "", "", false, "", "", false, "", "", false, "", "", errors.New("Malformed couple analysis: Metadata missing Pair1PersonAGenomeIdentifier")
|
||
|
}
|
||
|
|
||
|
pair1PersonBGenomeIdentifier, exists := element["Pair1PersonBGenomeIdentifier"]
|
||
|
if (exists == false){
|
||
|
return "", "", false, "", "", false, "", "", false, "", "", errors.New("Malformed couple analysis: Metadata missing Pair1PersonBGenomeIdentifier")
|
||
|
}
|
||
|
|
||
|
secondPairExists, exists := element["SecondPairExists"]
|
||
|
if (exists == false){
|
||
|
return "", "", false, "", "", false, "", "", false, "", "", errors.New("Malformed analysis map list: Metadata missing CombinedGenomesExist")
|
||
|
}
|
||
|
if (secondPairExists == "No"){
|
||
|
|
||
|
return pair1PersonAGenomeIdentifier, pair1PersonBGenomeIdentifier, false, "", "", false, "", "", false, "", "", nil
|
||
|
}
|
||
|
|
||
|
pair2PersonAGenomeIdentifier, exists := element["Pair2PersonAGenomeIdentifier"]
|
||
|
if (exists == false){
|
||
|
return "", "", false, "", "", false, "", "", false, "", "", errors.New("Malformed couple analysis map list: Metadata missing Pair2PersonAGenomeIdentifier")
|
||
|
}
|
||
|
|
||
|
pair2PersonBGenomeIdentifier, exists := element["Pair2PersonBGenomeIdentifier"]
|
||
|
if (exists == false){
|
||
|
return "", "", false, "", "", false, "", "", false, "", "", errors.New("Malformed couple analysis map list: Metadata missing Pair2PersonBGenomeIdentifier")
|
||
|
}
|
||
|
|
||
|
getPersonAMultipleGenomesInfo := func()(bool, string, string, error){
|
||
|
|
||
|
personAHasMultipleGenomes, exists := element["PersonAHasMultipleGenomes"]
|
||
|
if (exists == false){
|
||
|
return false, "", "", errors.New("Couple analysis malformed: Missing PersonAHasMultipleGenomes")
|
||
|
}
|
||
|
|
||
|
if (personAHasMultipleGenomes == "No"){
|
||
|
return false, "", "", nil
|
||
|
}
|
||
|
|
||
|
personAOnlyExcludeConflictsGenomeIdentifier, exists := element["PersonAOnlyExcludeConflictsGenomeIdentifier"]
|
||
|
if (exists == false) {
|
||
|
return false, "", "", errors.New("Couple analysis malformed: Missing PersonAOnlyExcludeConflictsGenomeIdentifier")
|
||
|
}
|
||
|
|
||
|
personAOnlyIncludeSharedGenomeIdentifier, exists := element["PersonAOnlyIncludeSharedGenomeIdentifier"]
|
||
|
if (exists == false) {
|
||
|
return false, "", "", errors.New("Couple analysis malformed: Missing PersonAOnlyIncludeSharedGenomeIdentifier")
|
||
|
}
|
||
|
|
||
|
return true, personAOnlyExcludeConflictsGenomeIdentifier, personAOnlyIncludeSharedGenomeIdentifier, nil
|
||
|
}
|
||
|
|
||
|
getPersonBMultipleGenomesInfo := func()(bool, string, string, error){
|
||
|
|
||
|
personBHasMultipleGenomes, exists := element["PersonBHasMultipleGenomes"]
|
||
|
if (exists == false){
|
||
|
return false, "", "", errors.New("Couple analysis malformed: Missing PersonBHasMultipleGenomes")
|
||
|
}
|
||
|
|
||
|
if (personBHasMultipleGenomes == "No"){
|
||
|
return false, "", "", nil
|
||
|
}
|
||
|
|
||
|
personBOnlyExcludeConflictsGenomeIdentifier, exists := element["PersonBOnlyExcludeConflictsGenomeIdentifier"]
|
||
|
if (exists == false) {
|
||
|
return false, "", "", errors.New("Couple analysis malformed: Missing PersonBOnlyExcludeConflictsGenomeIdentifier")
|
||
|
}
|
||
|
|
||
|
personBOnlyIncludeSharedGenomeIdentifier, exists := element["PersonBOnlyIncludeSharedGenomeIdentifier"]
|
||
|
if (exists == false) {
|
||
|
return false, "", "", errors.New("Couple analysis malformed: Missing PersonBOnlyIncludeSharedGenomeIdentifier")
|
||
|
}
|
||
|
|
||
|
return true, personBOnlyExcludeConflictsGenomeIdentifier, personBOnlyIncludeSharedGenomeIdentifier, nil
|
||
|
}
|
||
|
|
||
|
personAHasMultipleGenomes, personAOnlyExcludeConflictsGenomeIdentifier, personAOnlyIncludeSharedGenomeIdentifier, err := getPersonAMultipleGenomesInfo()
|
||
|
if (err != nil) { return "", "", false, "", "", false, "", "", false, "", "", err }
|
||
|
|
||
|
personBHasMultipleGenomes, personBOnlyExcludeConflictsGenomeIdentifier, personBOnlyIncludeSharedGenomeIdentifier, err := getPersonBMultipleGenomesInfo()
|
||
|
if (err != nil) { return "", "", false, "", "", false, "", "", false, "", "", err }
|
||
|
|
||
|
return pair1PersonAGenomeIdentifier, pair1PersonBGenomeIdentifier, true, pair2PersonAGenomeIdentifier, pair2PersonBGenomeIdentifier, personAHasMultipleGenomes, personAOnlyExcludeConflictsGenomeIdentifier, personAOnlyIncludeSharedGenomeIdentifier, personBHasMultipleGenomes, personBOnlyExcludeConflictsGenomeIdentifier, personBOnlyIncludeSharedGenomeIdentifier, nil
|
||
|
}
|
||
|
|
||
|
return "", "", false, "", "", false, "", "", false, "", "", errors.New("GetMetadataFromCoupleGeneticAnalysis called with malformed couple analysis map list: missing Metadata item.")
|
||
|
}
|
||
|
|
||
|
|
||
|
// This function will take a couple and person analysis
|
||
|
// It takes in a genome identifier from the couple analysis
|
||
|
// It returns the equivalent genome identifier from the person analysis
|
||
|
// This is needed for combined genomes, because their identifiers are generated randomly for each analysis
|
||
|
//Inputs:
|
||
|
// -bool: Is person A
|
||
|
// -[]map[string]string: Person A Analysis Map List
|
||
|
// -[]map[string]string: Person B Analysis Map List
|
||
|
// -[]map[string]string: Couple Analysis Map List
|
||
|
// -string: Input Genome Identifier (Should be from Couple identifier)
|
||
|
//Outputs:
|
||
|
// -string: Genome identifier from person analysis
|
||
|
// -bool: Person analysis has multiple genomes
|
||
|
// -bool: Genome is a combined genome
|
||
|
// -string: Genome combined type ("Only Exclude Conflicts"/"Only Include Shared")
|
||
|
// -error
|
||
|
func GetMatchingPersonAnalysisGenomeIdentifierFromCoupleAnalysis(isPersonA bool, personAAnalysisMapList []map[string]string, personBAnalysisMapList []map[string]string, coupleAnalysisMapList []map[string]string, inputGenomeIdentifier string)(string, bool, bool, string, error){
|
||
|
|
||
|
// We need to figure out which genome identifier the current genome identifier corresponds to within the person analysis
|
||
|
// If the genome is not a combined genome, then the genome identifier should be identical between each analysis
|
||
|
// If it is a combined genome, we need to determine which genome it corresponds to
|
||
|
|
||
|
_, _, secondGenomePairExists, _, _, personAHasMultipleGenomes, personAOnlyExcludeConflictsGenomeIdentifier, personAOnlyIncludeSharedGenomeIdentifier, personBHasMultipleGenomes, personBOnlyExcludeConflictsGenomeIdentifier, personBOnlyIncludeSharedGenomeIdentifier, err := GetMetadataFromCoupleGeneticAnalysis(coupleAnalysisMapList)
|
||
|
if (err != nil) { return "", false, false, "", err }
|
||
|
|
||
|
if (isPersonA == true){
|
||
|
|
||
|
if (personAHasMultipleGenomes == false){
|
||
|
// This person does not have multiple genomes. The genome identifier is the same between both analyses
|
||
|
return inputGenomeIdentifier, false, false, "", nil
|
||
|
}
|
||
|
|
||
|
if (secondGenomePairExists == false){
|
||
|
return inputGenomeIdentifier, true, false, "", nil
|
||
|
}
|
||
|
|
||
|
_, multipleGenomesExist, onlyExcludeConflictsGenomeIdentifier, onlyIncludeSharedGenomeIdentifier, err := GetMetadataFromPersonGeneticAnalysis(personAAnalysisMapList)
|
||
|
if (err != nil) { return "", false, false, "", err }
|
||
|
if (multipleGenomesExist == false){
|
||
|
return "", false, false, "", errors.New("Couple analysis says person has multiple genomes, person analysis does not.")
|
||
|
}
|
||
|
|
||
|
if (inputGenomeIdentifier == personAOnlyExcludeConflictsGenomeIdentifier){
|
||
|
return onlyExcludeConflictsGenomeIdentifier, true, true, "Only Exclude Conflicts", nil
|
||
|
}
|
||
|
if (inputGenomeIdentifier == personAOnlyIncludeSharedGenomeIdentifier){
|
||
|
return onlyIncludeSharedGenomeIdentifier, true, true, "Only Include Shared", nil
|
||
|
}
|
||
|
return "", false, false, "", errors.New("Combined genome identifier from couple analysis does not correspond to either combined genome from person analysis.")
|
||
|
}
|
||
|
|
||
|
// isPersonA == false
|
||
|
|
||
|
if (personBHasMultipleGenomes == false){
|
||
|
// This person does not have multiple genomes. The genome identifier is the same between both analyses
|
||
|
return inputGenomeIdentifier, false, false, "", nil
|
||
|
}
|
||
|
|
||
|
if (secondGenomePairExists == false){
|
||
|
return inputGenomeIdentifier, true, false, "", nil
|
||
|
}
|
||
|
|
||
|
_, multipleGenomesExist, onlyExcludeConflictsGenomeIdentifier, onlyIncludeSharedGenomeIdentifier, err := GetMetadataFromPersonGeneticAnalysis(personBAnalysisMapList)
|
||
|
if (err != nil) { return "", false, false, "", err }
|
||
|
if (multipleGenomesExist == false){
|
||
|
return "", false, false, "", errors.New("Couple analysis says person has multiple genomes, person analysis does not.")
|
||
|
}
|
||
|
|
||
|
if (inputGenomeIdentifier == personBOnlyExcludeConflictsGenomeIdentifier){
|
||
|
return onlyExcludeConflictsGenomeIdentifier, true, true, "Only Exclude Conflicts", nil
|
||
|
}
|
||
|
if (inputGenomeIdentifier == personBOnlyIncludeSharedGenomeIdentifier){
|
||
|
return onlyIncludeSharedGenomeIdentifier, true, true, "Only Include Shared", nil
|
||
|
}
|
||
|
|
||
|
return "", false, false, "", errors.New("Combined genome identifier from couple analysis does not correspond to either combined genome from person analysis.")
|
||
|
}
|
||
|
|
||
|
|
||
|
//Outputs:
|
||
|
// -bool: Probabilities known
|
||
|
// -int: Probability of having disease
|
||
|
// -string: Probability of having disease formatted (with % suffix)
|
||
|
// -int: Probability of passing a disease variant
|
||
|
// -string: Probability of passing a disease variant formatted (with % suffix)
|
||
|
// -int: Number of variants tested
|
||
|
// -bool: Conflict exists
|
||
|
// -error
|
||
|
func GetPersonMonogenicDiseaseInfoFromGeneticAnalysis(personAnalysisMapList []map[string]string, diseaseName string, genomeIdentifier string, personHasMultipleGenomes bool)(bool, int, string, int, string, int, bool, error){
|
||
|
|
||
|
for _, element := range personAnalysisMapList{
|
||
|
|
||
|
itemType, exists := element["ItemType"]
|
||
|
if (exists == false) {
|
||
|
return false, 0, "", 0, "", 0, false, errors.New("Malformed analysisMapList: Item missing itemType")
|
||
|
}
|
||
|
|
||
|
if (itemType != "MonogenicDisease"){
|
||
|
continue
|
||
|
}
|
||
|
|
||
|
currentDiseaseName, exists := element["DiseaseName"]
|
||
|
if (exists == false){
|
||
|
return false, 0, "", 0, "", 0, false, errors.New("Malformed analysisMapList: Monogenic Disease item missing DiseaseName")
|
||
|
}
|
||
|
|
||
|
if (currentDiseaseName != diseaseName){
|
||
|
continue
|
||
|
}
|
||
|
|
||
|
numberOfVariantsTested, exists := element[genomeIdentifier + "_NumberOfVariantsTested"]
|
||
|
if (exists == false){
|
||
|
return false, 0, "", 0, "", 0, false, errors.New("Malformed person analysis: Monogenic Disease item missing _NumberOfVariantsTested")
|
||
|
}
|
||
|
|
||
|
numberOfVariantsTestedInt, err := helpers.ConvertStringToInt(numberOfVariantsTested)
|
||
|
if (err != nil){
|
||
|
return false, 0, "", 0, "", 0, false, errors.New("Malformed person analysis: Monogenic Disease item contains invalid _NumberOfVariantsTested: " + numberOfVariantsTested)
|
||
|
}
|
||
|
|
||
|
getConflictExistsBool := func()(bool, error){
|
||
|
|
||
|
if (personHasMultipleGenomes == false){
|
||
|
return false, nil
|
||
|
}
|
||
|
|
||
|
conflictExists, exists := element["ConflictExists"]
|
||
|
if (exists == false) {
|
||
|
return false, errors.New("Malformed analysisMapList: Missing ConflictExists")
|
||
|
}
|
||
|
|
||
|
if (conflictExists == "Yes"){
|
||
|
return true, nil
|
||
|
}
|
||
|
return false, nil
|
||
|
}
|
||
|
|
||
|
conflictExistsBool, err := getConflictExistsBool()
|
||
|
if (err != nil) { return false, 0, "", 0, "", 0, false, err }
|
||
|
|
||
|
probabilityOfHavingDisease, exists := element[genomeIdentifier + "_ProbabilityOfHavingDisease"]
|
||
|
if (exists == false) {
|
||
|
return false, 0, "", 0, "", 0, false, errors.New("Malformed analysisMapList: Monogenic Disease map missing _ProbabilityOfHavingDisease")
|
||
|
}
|
||
|
|
||
|
if (probabilityOfHavingDisease == "Unknown"){
|
||
|
return false, 0, "", 0, "", numberOfVariantsTestedInt, conflictExistsBool, nil
|
||
|
}
|
||
|
|
||
|
probabilityOfHavingDiseaseInt, err := helpers.ConvertStringToInt(probabilityOfHavingDisease)
|
||
|
if (err != nil){
|
||
|
return false, 0, "", 0, "", 0, false, errors.New("Malformed person analysis: Monogenic Disease map contains invalid _ProbabilityOfHavingDisease: " + probabilityOfHavingDisease)
|
||
|
}
|
||
|
|
||
|
probabilityOfHavingDiseaseFormatted := probabilityOfHavingDisease + "%"
|
||
|
|
||
|
probabilityOfPassingAVariant, exists := element[genomeIdentifier + "_ProbabilityOfPassingADiseaseVariant"]
|
||
|
if (exists == false) {
|
||
|
return false, 0, "", 0, "", 0, false, errors.New("Malformed analysisMapList: Monogenic Disease map missing _ProbabilityOfPassingADiseaseVariant")
|
||
|
}
|
||
|
|
||
|
probabilityOfPassingAVariantInt, err := helpers.ConvertStringToInt(probabilityOfPassingAVariant)
|
||
|
if (err != nil){
|
||
|
return false, 0, "", 0, "", 0, false, errors.New("Malformed person analysis: Monogenic Disease map contains invalid _ProbabilityOfPassingADiseaseVariant: " + probabilityOfPassingAVariant)
|
||
|
}
|
||
|
|
||
|
probabilityOfPassingAVariantFormatted := probabilityOfPassingAVariant + "%"
|
||
|
|
||
|
return true, probabilityOfHavingDiseaseInt, probabilityOfHavingDiseaseFormatted, probabilityOfPassingAVariantInt, probabilityOfPassingAVariantFormatted, numberOfVariantsTestedInt, conflictExistsBool, nil
|
||
|
}
|
||
|
|
||
|
return false, 0, "", 0, "", 0, false, errors.New("GetPersonMonogenicDiseaseInfoFromGeneticAnalysis failed: Cannot find monogenicDisease item in person analysis. Disease name: " + diseaseName)
|
||
|
}
|
||
|
|
||
|
//Outputs:
|
||
|
// -bool: Probabilities known
|
||
|
// -int: Percentage Probability of offspring having disease
|
||
|
// -string: Probability of offspring having disease formatted (with % suffix)
|
||
|
// -int: Percentage probability of offspring having a disease variant
|
||
|
// -string: Percentage probability of offspring having a disease variant formatted (with % suffix)
|
||
|
// -bool: Conflict exists between genome pairs
|
||
|
// -error
|
||
|
func GetOffspringMonogenicDiseaseInfoFromGeneticAnalysis(coupleAnalysisMapList []map[string]string, diseaseName string, genomePairIdentifier string, secondGenomePairExists bool)(bool, int, string, int, string, bool, error){
|
||
|
|
||
|
for _, element := range coupleAnalysisMapList{
|
||
|
|
||
|
itemType, exists := element["ItemType"]
|
||
|
if (exists == false) {
|
||
|
return false, 0, "", 0, "", false, errors.New("Malformed couple analysis: Item missing itemType")
|
||
|
}
|
||
|
|
||
|
if (itemType != "MonogenicDisease"){
|
||
|
continue
|
||
|
}
|
||
|
|
||
|
currentDiseaseName, exists := element["DiseaseName"]
|
||
|
if (exists == false){
|
||
|
return false, 0, "", 0, "", false, errors.New("Malformed couple analysis: Monogenic Disease item missing DiseaseName")
|
||
|
}
|
||
|
|
||
|
if (diseaseName != currentDiseaseName){
|
||
|
continue
|
||
|
}
|
||
|
|
||
|
getConflictExistsBool := func()(bool, error){
|
||
|
|
||
|
if (secondGenomePairExists == false){
|
||
|
return false, nil
|
||
|
}
|
||
|
|
||
|
conflictExists, exists := element["ConflictExists"]
|
||
|
if (exists == false) {
|
||
|
return false, errors.New("Malformed couple analysis: Monogenic disease map missing ConflictExists")
|
||
|
}
|
||
|
|
||
|
if (conflictExists == "Yes"){
|
||
|
return true, nil
|
||
|
}
|
||
|
|
||
|
return false, nil
|
||
|
}
|
||
|
|
||
|
conflictExistsBool, err := getConflictExistsBool()
|
||
|
if (err != nil) { return false, 0, "", 0, "", false, err }
|
||
|
|
||
|
probabilityOfOffspringHavingDisease, exists := element[genomePairIdentifier + "_ProbabilityOffspringHasDisease"]
|
||
|
if (exists == false) {
|
||
|
return false, 0, "", 0, "", false, errors.New("Malformed couple analysis: Monogenic Disease map missing _ProbabilityOffspringHasDisease")
|
||
|
}
|
||
|
|
||
|
if (probabilityOfOffspringHavingDisease == "Unknown"){
|
||
|
return false, 0, "", 0, "", conflictExistsBool, nil
|
||
|
}
|
||
|
|
||
|
probabilityOfOffspringHavingDiseaseInt, err := helpers.ConvertStringToInt(probabilityOfOffspringHavingDisease)
|
||
|
if (err != nil){
|
||
|
return false, 0, "", 0, "", false, errors.New("Malformed couple analysis: Monogenic Disease map contains invalid _ProbabilityOffspringHasDisease: " + probabilityOfOffspringHavingDisease)
|
||
|
}
|
||
|
|
||
|
probabilityOfOffspringHavingDiseaseFormatted := probabilityOfOffspringHavingDisease + "%"
|
||
|
|
||
|
probabilityOfOffspringHavingVariant, exists := element[genomePairIdentifier + "_ProbabilityOffspringHasVariant"]
|
||
|
if (exists == false) {
|
||
|
return false, 0, "", 0, "", false, errors.New("Malformed analysisMapList: Monogenic Disease map missing _ProbabilityOffspringHasVariant")
|
||
|
}
|
||
|
|
||
|
probabilityOfOffspringHavingVariantInt, err := helpers.ConvertStringToInt(probabilityOfOffspringHavingVariant)
|
||
|
if (err != nil){
|
||
|
return false, 0, "", 0, "", false, errors.New("Malformed analysisMapList: Monogenic Disease map missing _ProbabilityOffspringHasVariant")
|
||
|
}
|
||
|
|
||
|
probabilityOfOffspringHavingVariantFormatted := probabilityOfOffspringHavingVariant + "%"
|
||
|
|
||
|
return true, probabilityOfOffspringHavingDiseaseInt, probabilityOfOffspringHavingDiseaseFormatted, probabilityOfOffspringHavingVariantInt, probabilityOfOffspringHavingVariantFormatted, conflictExistsBool, nil
|
||
|
}
|
||
|
|
||
|
return false, 0, "", 0, "", false, errors.New("GetOffspringMonogenicDiseaseInfoFromGeneticAnalysis called with invalid analysis: Cannot find disease info in couple analysis: " + diseaseName)
|
||
|
}
|
||
|
|
||
|
//Outputs:
|
||
|
// -bool: Number of mutations known
|
||
|
// -int: Number of mutations
|
||
|
// -error
|
||
|
func GetPersonMonogenicDiseaseVariantInfoFromGeneticAnalysis(personAnalysisMapList []map[string]string, diseaseName string, variantIdentifier string, genomeIdentifier string)(bool, int, error){
|
||
|
|
||
|
for _, element := range personAnalysisMapList{
|
||
|
|
||
|
itemType, exists := element["ItemType"]
|
||
|
if (exists == false) {
|
||
|
return false, 0, errors.New("Malformed person analysis: Item missing itemType")
|
||
|
}
|
||
|
|
||
|
if (itemType != "MonogenicDiseaseVariant"){
|
||
|
continue
|
||
|
}
|
||
|
|
||
|
currentDiseaseName, exists := element["DiseaseName"]
|
||
|
if (exists == false){
|
||
|
return false, 0, errors.New("Malformed person analysis: Monogenic Disease item missing DiseaseName")
|
||
|
}
|
||
|
|
||
|
if (currentDiseaseName != diseaseName){
|
||
|
continue
|
||
|
}
|
||
|
|
||
|
currentVariantIdentifier, exists := element["VariantIdentifier"]
|
||
|
if (exists == false) {
|
||
|
return false, 0, errors.New("Malformed person analysis: MonogenicDiseaseVariant item missing VariantIdentifier")
|
||
|
}
|
||
|
|
||
|
if (currentVariantIdentifier != variantIdentifier){
|
||
|
continue
|
||
|
}
|
||
|
|
||
|
genomeHasVariantValue, exists := element[genomeIdentifier + "_HasVariant"]
|
||
|
if (exists == false){
|
||
|
return false, 0, errors.New("Malformed person analysis: MonogenicDiseaseVariant item missing _HasVariant key for genome")
|
||
|
}
|
||
|
|
||
|
if (genomeHasVariantValue == "Unknown"){
|
||
|
return false, 0, nil
|
||
|
}
|
||
|
if (genomeHasVariantValue == "No;No"){
|
||
|
return true, 0, nil
|
||
|
}
|
||
|
if (genomeHasVariantValue == "Yes;No" || genomeHasVariantValue == "No;Yes"){
|
||
|
return true, 1, nil
|
||
|
}
|
||
|
if (genomeHasVariantValue == "Yes;Yes"){
|
||
|
return true, 2, nil
|
||
|
}
|
||
|
|
||
|
return false, 0, errors.New("Malformed person analysis: Invalid genomeHasVariantValue: " + genomeHasVariantValue)
|
||
|
}
|
||
|
|
||
|
return false, 0, errors.New("GetPersonMonogenicDiseaseVariantInfoFromGeneticAnalysis failed: Info not found.")
|
||
|
}
|
||
|
|
||
|
|
||
|
//Outputs:
|
||
|
// -bool: Offspring Probabilities Known
|
||
|
// -int: Lower Bound Percentage Probability of 0 mutations
|
||
|
// -int: Upper Bound Percentage Probability of 0 mutations
|
||
|
// -string: Percentage probability of 0 mutations formatted (has % suffix and - between non-identical bounds)
|
||
|
// -int: Lower Bound Percentage probability of only 1 mutation
|
||
|
// -int: Upper Bound Percentage probability of only 1 mutation
|
||
|
// -string: Percentage probability of 1 mutation formatted (has % suffix and - between non-identical bounds)
|
||
|
// -int: Lower Bound Percentage probability of 2 mutations
|
||
|
// -int: Upper Bound Percentage probability of 2 mutations
|
||
|
// -string: Percentage probability of 2 mutations formatted (has % suffix and - between non-identical bounds)
|
||
|
// -error
|
||
|
func GetOffspringMonogenicDiseaseVariantInfoFromGeneticAnalysis(coupleAnalysisMapList []map[string]string, diseaseName string, variantIdentifier string, genomePairIdentifier string)(bool, int, int, string, int, int, string, int, int, string, error){
|
||
|
|
||
|
for _, element := range coupleAnalysisMapList{
|
||
|
|
||
|
itemType, exists := element["ItemType"]
|
||
|
if (exists == false) {
|
||
|
return false, 0, 0, "", 0, 0, "", 0, 0, "", errors.New("Malformed coupleAnalysisMapList: Item missing itemType")
|
||
|
}
|
||
|
|
||
|
if (itemType != "MonogenicDiseaseVariant"){
|
||
|
continue
|
||
|
}
|
||
|
currentDiseaseName, exists := element["DiseaseName"]
|
||
|
if (exists == false) {
|
||
|
return false, 0, 0, "", 0, 0, "", 0, 0, "", errors.New("Malformed couple Analysis: MonogenicDiseaseVariant item missing DiseaseName")
|
||
|
}
|
||
|
|
||
|
if (currentDiseaseName != diseaseName){
|
||
|
continue
|
||
|
}
|
||
|
|
||
|
currentVariantIdentifier, exists := element["VariantIdentifier"]
|
||
|
if (exists == false) {
|
||
|
return false, 0, 0, "", 0, 0, "", 0, 0, "", errors.New("Malformed couple analysis: MonogenicDiseaseVariant item missing VariantIdentifier")
|
||
|
}
|
||
|
|
||
|
if (currentVariantIdentifier != variantIdentifier){
|
||
|
continue
|
||
|
}
|
||
|
|
||
|
probabilityOf0MutationsLowerBound, exists := element[genomePairIdentifier + "_ProbabilityOf0MutationsLowerBound"]
|
||
|
if (exists == false){
|
||
|
return false, 0, 0, "", 0, 0, "", 0, 0, "", errors.New("Malformed analysisMapList: MonogenicDiseaseVariant item missing _ProbabilityOf0MutationsLowerBound key")
|
||
|
}
|
||
|
if (probabilityOf0MutationsLowerBound == "Unknown"){
|
||
|
return false, 0, 0, "", 0, 0, "", 0, 0, "", nil
|
||
|
}
|
||
|
|
||
|
probabilityOf0MutationsUpperBound, exists := element[genomePairIdentifier + "_ProbabilityOf0MutationsUpperBound"]
|
||
|
if (exists == false){
|
||
|
return false, 0, 0, "", 0, 0, "", 0, 0, "", errors.New("Malformed analysisMapList: MonogenicDiseaseVariant item missing _ProbabilityOf0MutationsUpperBound")
|
||
|
}
|
||
|
|
||
|
probabilityOf1MutationLowerBound, exists := element[genomePairIdentifier + "_ProbabilityOf1MutationLowerBound"]
|
||
|
if (exists == false){
|
||
|
return false, 0, 0, "", 0, 0, "", 0, 0, "", errors.New("Malformed analysisMapList: MonogenicDiseaseVariant item missing _ProbabilityOf1MutationLowerBound key")
|
||
|
}
|
||
|
|
||
|
probabilityOf1MutationUpperBound, exists := element[genomePairIdentifier + "_ProbabilityOf1MutationUpperBound"]
|
||
|
if (exists == false){
|
||
|
return false, 0, 0, "", 0, 0, "", 0, 0, "", errors.New("Malformed analysisMapList: MonogenicDiseaseVariant item missing _ProbabilityOf1MutationUpperBound")
|
||
|
}
|
||
|
|
||
|
probabilityOf2MutationsLowerBound, exists := element[genomePairIdentifier + "_ProbabilityOf2MutationsLowerBound"]
|
||
|
if (exists == false){
|
||
|
return false, 0, 0, "", 0, 0, "", 0, 0, "", errors.New("Malformed analysisMapList: MonogenicDiseaseVariant item missing _ProbabilityOf2MutationsLowerBound key")
|
||
|
}
|
||
|
|
||
|
probabilityOf2MutationsUpperBound, exists := element[genomePairIdentifier + "_ProbabilityOf2MutationsUpperBound"]
|
||
|
if (exists == false){
|
||
|
return false, 0, 0, "", 0, 0, "", 0, 0, "", errors.New("Malformed analysisMapList: MonogenicDiseaseVariant item missing _ProbabilityOf2MutationsUpperBound")
|
||
|
}
|
||
|
|
||
|
probabilityOf0MutationsLowerBoundInt, err := helpers.ConvertStringToInt(probabilityOf0MutationsLowerBound)
|
||
|
if (err != nil){
|
||
|
return false, 0, 0, "", 0, 0, "", 0, 0, "", errors.New("Malformed couple analysis: MonogenicDiseaseVariant contains invalid _ProbabilityOf0MutationsLowerBound: " + probabilityOf0MutationsLowerBound)
|
||
|
}
|
||
|
|
||
|
probabilityOf0MutationsUpperBoundInt, err := helpers.ConvertStringToInt(probabilityOf0MutationsUpperBound)
|
||
|
if (err != nil){
|
||
|
return false, 0, 0, "", 0, 0, "", 0, 0, "", errors.New("Malformed couple analysis: MonogenicDiseaseVariant contains invalid _ProbabilityOf0MutationsUpperBound: " + probabilityOf0MutationsUpperBound)
|
||
|
}
|
||
|
|
||
|
probabilityOf1MutationLowerBoundInt, err := helpers.ConvertStringToInt(probabilityOf1MutationLowerBound)
|
||
|
if (err != nil){
|
||
|
return false, 0, 0, "", 0, 0, "", 0, 0, "", errors.New("Malformed couple analysis: MonogenicDiseaseVariant contains invalid _ProbabilityOf1MutationLowerBound: " + probabilityOf1MutationLowerBound)
|
||
|
}
|
||
|
|
||
|
probabilityOf1MutationUpperBoundInt, err := helpers.ConvertStringToInt(probabilityOf1MutationUpperBound)
|
||
|
if (err != nil){
|
||
|
return false, 0, 0, "", 0, 0, "", 0, 0, "", errors.New("Malformed couple analysis: MonogenicDiseaseVariant contains invalid _ProbabilityOf1MutationUpperBound: " + probabilityOf1MutationUpperBound)
|
||
|
}
|
||
|
|
||
|
probabilityOf2MutationsLowerBoundInt, err := helpers.ConvertStringToInt(probabilityOf2MutationsLowerBound)
|
||
|
if (err != nil){
|
||
|
return false, 0, 0, "", 0, 0, "", 0, 0, "", errors.New("Malformed couple analysis: MonogenicDiseaseVariant contains invalid _ProbabilityOf2MutationsLowerBound: " + probabilityOf2MutationsLowerBound)
|
||
|
}
|
||
|
|
||
|
probabilityOf2MutationsUpperBoundInt, err := helpers.ConvertStringToInt(probabilityOf2MutationsUpperBound)
|
||
|
if (err != nil){
|
||
|
return false, 0, 0, "", 0, 0, "", 0, 0, "", errors.New("Malformed couple analysis: MonogenicDiseaseVariant contains invalid _ProbabilityOf2MutationsUpperBound: " + probabilityOf2MutationsUpperBound)
|
||
|
}
|
||
|
|
||
|
getOffspringProbabilityOf0MutationsFormatted := func()string{
|
||
|
|
||
|
probabilityOf0MutationsLowerBoundFormatted := probabilityOf0MutationsLowerBound + "%"
|
||
|
|
||
|
if (probabilityOf0MutationsLowerBoundInt == probabilityOf0MutationsUpperBoundInt){
|
||
|
return probabilityOf0MutationsLowerBoundFormatted
|
||
|
}
|
||
|
|
||
|
probabilityOf0MutationsUpperBoundFormatted := probabilityOf0MutationsUpperBound + "%"
|
||
|
|
||
|
formattedResult := probabilityOf0MutationsLowerBoundFormatted + " - " + probabilityOf0MutationsUpperBoundFormatted
|
||
|
|
||
|
return formattedResult
|
||
|
}
|
||
|
|
||
|
probabilityOf0MutationsFormatted := getOffspringProbabilityOf0MutationsFormatted()
|
||
|
|
||
|
getOffspringProbabilityOf1MutationFormatted := func()string{
|
||
|
|
||
|
probabilityOf1MutationLowerBoundFormatted := probabilityOf1MutationLowerBound + "%"
|
||
|
|
||
|
if (probabilityOf1MutationLowerBoundInt == probabilityOf1MutationUpperBoundInt){
|
||
|
return probabilityOf1MutationLowerBoundFormatted
|
||
|
}
|
||
|
|
||
|
probabilityOf1MutationUpperBoundFormatted := probabilityOf1MutationUpperBound + "%"
|
||
|
|
||
|
formattedResult := probabilityOf1MutationLowerBoundFormatted + " - " + probabilityOf1MutationUpperBoundFormatted
|
||
|
|
||
|
return formattedResult
|
||
|
}
|
||
|
|
||
|
probabilityOf1MutationFormatted := getOffspringProbabilityOf1MutationFormatted()
|
||
|
|
||
|
getOffspringProbabilityOf2MutationsFormatted := func()string{
|
||
|
|
||
|
probabilityOf2MutationsLowerBoundFormatted := probabilityOf2MutationsLowerBound + "%"
|
||
|
|
||
|
if (probabilityOf2MutationsLowerBoundInt == probabilityOf2MutationsUpperBoundInt){
|
||
|
return probabilityOf2MutationsLowerBoundFormatted
|
||
|
}
|
||
|
|
||
|
probabilityOf2MutationsUpperBoundFormatted := probabilityOf2MutationsUpperBound + "%"
|
||
|
|
||
|
formattedResult := probabilityOf2MutationsLowerBoundFormatted + " - " + probabilityOf2MutationsUpperBoundFormatted
|
||
|
|
||
|
return formattedResult
|
||
|
}
|
||
|
|
||
|
probabilityOf2MutationsFormatted := getOffspringProbabilityOf2MutationsFormatted()
|
||
|
|
||
|
return true, probabilityOf0MutationsLowerBoundInt, probabilityOf0MutationsUpperBoundInt, probabilityOf0MutationsFormatted, probabilityOf1MutationLowerBoundInt, probabilityOf1MutationUpperBoundInt, probabilityOf1MutationFormatted, probabilityOf2MutationsLowerBoundInt, probabilityOf2MutationsUpperBoundInt, probabilityOf2MutationsFormatted, nil
|
||
|
}
|
||
|
|
||
|
return false, 0, 0, "", 0, 0, "", 0, 0, "", errors.New("GetOffspringMonogenicDiseaseVariantInfoFromGeneticAnalysis failed: Info not found.")
|
||
|
}
|
||
|
|
||
|
|
||
|
//Outputs:
|
||
|
// -bool: Polygenic Disease Risk Score known
|
||
|
// -int: Disease risk score
|
||
|
// -string: Disease risk score formatted (contains "/10" suffix)
|
||
|
// -int: Number of loci tested
|
||
|
// -bool: Conflict exists
|
||
|
// -error
|
||
|
func GetPersonPolygenicDiseaseInfoFromGeneticAnalysis(personAnalysisMapList []map[string]string, diseaseName string, genomeIdentifier string, personHasMultipleGenomes bool)(bool, int, string, int, bool, error){
|
||
|
|
||
|
for _, element := range personAnalysisMapList{
|
||
|
|
||
|
analysisItemType, exists := element["ItemType"]
|
||
|
if (exists == false) {
|
||
|
return false, 0, "", 0, false, errors.New("Malformed person analysis: Item missing ItemType")
|
||
|
}
|
||
|
|
||
|
if (analysisItemType != "PolygenicDisease"){
|
||
|
continue
|
||
|
}
|
||
|
|
||
|
itemDiseaseName, exists := element["DiseaseName"]
|
||
|
if (exists == false) {
|
||
|
return false, 0, "", 0, false, errors.New("Malformed person analysis: PolygenicDisease item missing DiseaseName")
|
||
|
}
|
||
|
|
||
|
if (itemDiseaseName != diseaseName){
|
||
|
continue
|
||
|
}
|
||
|
|
||
|
numberOfLociTested, exists := element[genomeIdentifier + "_NumberOfLociTested"]
|
||
|
if (exists == false){
|
||
|
return false, 0, "", 0, false, errors.New("Malformed person analysis: PolygenicDisease item missing _NumberOfLociTested")
|
||
|
}
|
||
|
|
||
|
numberOfLociTestedInt, err := helpers.ConvertStringToInt(numberOfLociTested)
|
||
|
if (err != nil){
|
||
|
return false, 0, "", 0, false, errors.New("Malformed person analysis: PolygenicDisease item contains invalid _NumberOfLociTested: " + numberOfLociTested)
|
||
|
}
|
||
|
|
||
|
getConflictExistsBool := func()(bool, error){
|
||
|
|
||
|
if (personHasMultipleGenomes == false){
|
||
|
return false, nil
|
||
|
}
|
||
|
|
||
|
conflictExists, exists := element["ConflictExists"]
|
||
|
if (exists == false) {
|
||
|
return false, errors.New("Malformed analysisMapList: PolygenicDisease analysis missing ConflictExists")
|
||
|
}
|
||
|
|
||
|
if (conflictExists == "Yes"){
|
||
|
return true, nil
|
||
|
}
|
||
|
|
||
|
return false, nil
|
||
|
}
|
||
|
|
||
|
conflictExistsBool, err := getConflictExistsBool()
|
||
|
if (err != nil) { return false, 0, "", 0, false, err }
|
||
|
|
||
|
if (numberOfLociTestedInt == 0){
|
||
|
return false, 0, "", numberOfLociTestedInt, conflictExistsBool, nil
|
||
|
}
|
||
|
|
||
|
personRiskScore, exists := element[genomeIdentifier + "_RiskScore"]
|
||
|
if (exists == false){
|
||
|
return false, 0, "", 0, false, errors.New("Person analysis missing _RiskScore key.")
|
||
|
}
|
||
|
|
||
|
personRiskScoreInt, err := helpers.ConvertStringToInt(personRiskScore)
|
||
|
if (err != nil) {
|
||
|
return false, 0, "", 0, false, errors.New("Person analysis contains invalid _RiskScore: " + personRiskScore)
|
||
|
}
|
||
|
|
||
|
personRiskScoreFormatted := personRiskScore + "/10"
|
||
|
|
||
|
return true, personRiskScoreInt, personRiskScoreFormatted, numberOfLociTestedInt, conflictExistsBool, nil
|
||
|
}
|
||
|
|
||
|
return false, 0, "", 0, false, errors.New("GetPersonPolygenicDiseaseInfoFromGeneticAnalysis failed: Disease info not found.")
|
||
|
}
|
||
|
|
||
|
|
||
|
//Outputs:
|
||
|
// -bool: Disease Risk Score known
|
||
|
// -int: Disease risk score
|
||
|
// -string: Disease risk score formatted (contains "/10" suffix)
|
||
|
// -int: Number of loci tested
|
||
|
// -bool: Conflict exists
|
||
|
// -error
|
||
|
func GetOffspringPolygenicDiseaseInfoFromGeneticAnalysis(coupleAnalysisMapList []map[string]string, diseaseName string, genomePairIdentifier string, secondGenomePairExists bool)(bool, int, string, int, bool, error){
|
||
|
|
||
|
for _, element := range coupleAnalysisMapList{
|
||
|
|
||
|
analysisItemType, exists := element["ItemType"]
|
||
|
if (exists == false) {
|
||
|
return false, 0, "", 0, false, errors.New("Malformed couple analysis: Item missing ItemType")
|
||
|
}
|
||
|
|
||
|
if (analysisItemType != "PolygenicDisease"){
|
||
|
continue
|
||
|
}
|
||
|
|
||
|
itemDiseaseName, exists := element["DiseaseName"]
|
||
|
if (exists == false) {
|
||
|
return false, 0, "", 0, false, errors.New("Malformed couple analysis: PolygenicDisease item missing DiseaseName")
|
||
|
}
|
||
|
|
||
|
if (itemDiseaseName != diseaseName){
|
||
|
continue
|
||
|
}
|
||
|
|
||
|
numberOfLociTested, exists := element[genomePairIdentifier + "_NumberOfLociTested"]
|
||
|
if (exists == false){
|
||
|
return false, 0, "", 0, false, errors.New("Malformed couple analysis: PolygenicDisease item missing _NumberOfLociTested")
|
||
|
}
|
||
|
|
||
|
numberOfLociTestedInt, err := helpers.ConvertStringToInt(numberOfLociTested)
|
||
|
if (err != nil){
|
||
|
return false, 0, "", 0, false, errors.New("Malformed couple analysis: PolygenicDisease item contains invalid _NumberOfLociTested: " + numberOfLociTested)
|
||
|
}
|
||
|
|
||
|
getConflictExistsBool := func()(bool, error){
|
||
|
|
||
|
if (secondGenomePairExists == false){
|
||
|
return false, nil
|
||
|
}
|
||
|
|
||
|
conflictExists, exists := element["ConflictExists"]
|
||
|
if (exists == false) {
|
||
|
return false, errors.New("Malformed analysisMapList: PolygenicDisease analysis missing ConflictExists")
|
||
|
}
|
||
|
|
||
|
if (conflictExists == "Yes"){
|
||
|
return true, nil
|
||
|
}
|
||
|
|
||
|
return false, nil
|
||
|
}
|
||
|
|
||
|
conflictExistsBool, err := getConflictExistsBool()
|
||
|
if (err != nil) { return false, 0, "", 0, false, err }
|
||
|
|
||
|
offspringRiskScore, exists := element[genomePairIdentifier + "_OffspringRiskScore"]
|
||
|
if (exists == false){
|
||
|
return false, 0, "", 0, false, errors.New("Couple analysis missing _RiskScore key.")
|
||
|
}
|
||
|
|
||
|
if (offspringRiskScore == "Unknown"){
|
||
|
return false, 0, "", numberOfLociTestedInt, conflictExistsBool, nil
|
||
|
}
|
||
|
|
||
|
offspringRiskScoreInt, err := helpers.ConvertStringToInt(offspringRiskScore)
|
||
|
if (err != nil) {
|
||
|
return false, 0, "", 0, false, errors.New("Couple analysis contains invalid _RiskScore: " + offspringRiskScore)
|
||
|
}
|
||
|
|
||
|
offspringRiskScoreFormatted := offspringRiskScore + "/10"
|
||
|
|
||
|
return true, offspringRiskScoreInt, offspringRiskScoreFormatted, numberOfLociTestedInt, conflictExistsBool, nil
|
||
|
}
|
||
|
|
||
|
return false, 0, "", 0, false, errors.New("GetOffspringPolygenicDiseaseInfoFromGeneticAnalysis failed: Cannot find disease info for disease: " + diseaseName)
|
||
|
}
|
||
|
|
||
|
//Outputs:
|
||
|
// -bool: Risk Weight and base pair known
|
||
|
// -int: Locus risk weight
|
||
|
// -string: Locus base pair
|
||
|
// -bool: Locus odds ratio known
|
||
|
// -float64: Locus odds ratio
|
||
|
// -string: Locus odds ratio formatted (with x suffix)
|
||
|
// -error
|
||
|
func GetPersonPolygenicDiseaseLocusInfoFromGeneticAnalysis(personAnalyisMapList []map[string]string, diseaseName string, locusIdentifier string, genomeIdentifier string)(bool, int, string, bool, float64, string, error){
|
||
|
|
||
|
for _, element := range personAnalyisMapList{
|
||
|
|
||
|
itemType, exists := element["ItemType"]
|
||
|
if (exists == false) {
|
||
|
return false, 0, "", false, 0, "", errors.New("Malformed person analysis: Item missing itemType")
|
||
|
}
|
||
|
|
||
|
if (itemType != "PolygenicDiseaseLocus"){
|
||
|
continue
|
||
|
}
|
||
|
|
||
|
currentDiseaseName, exists := element["DiseaseName"]
|
||
|
if (exists == false){
|
||
|
return false, 0, "", false, 0, "", errors.New("Malformed person analysis: PolygenicDiseaseLocus item missing DiseaseName")
|
||
|
}
|
||
|
|
||
|
if (currentDiseaseName != diseaseName){
|
||
|
continue
|
||
|
}
|
||
|
|
||
|
currentLocusIdentifier, exists := element["LocusIdentifier"]
|
||
|
if (exists == false) {
|
||
|
return false, 0, "", false, 0, "", errors.New("Malformed person analysis: PolygenicDiseaseLocus item missing LocusIdentifier")
|
||
|
}
|
||
|
|
||
|
if (currentLocusIdentifier != locusIdentifier){
|
||
|
continue
|
||
|
}
|
||
|
|
||
|
genomeLocusRiskWeight, exists := element[genomeIdentifier + "_RiskWeight"]
|
||
|
if (exists == false){
|
||
|
return false, 0, "", false, 0, "", errors.New("Malformed person analysis: PolygenicDiseaseLocus item missing _RiskWeight")
|
||
|
}
|
||
|
|
||
|
if (genomeLocusRiskWeight == "Unknown"){
|
||
|
return false, 0, "", false, 0, "", nil
|
||
|
}
|
||
|
|
||
|
locusBasePair, exists := element[genomeIdentifier + "_LocusBasePair"]
|
||
|
if (exists == false){
|
||
|
return false, 0, "", false, 0, "", errors.New("Malformed person analysis: PolygenicDiseaseLocus item missing LocusBasePair")
|
||
|
}
|
||
|
|
||
|
genomeLocusRiskWeightInt, err := helpers.ConvertStringToInt(genomeLocusRiskWeight)
|
||
|
if (err != nil){
|
||
|
return false, 0, "", false, 0, "", errors.New("Malformed person analysis: PolygenicDiseaseLocus item contains invalid _RiskWeight: " + genomeLocusRiskWeight)
|
||
|
}
|
||
|
|
||
|
genomeLocusOddsRatio, exists := element[genomeIdentifier + "_OddsRatio"]
|
||
|
if (exists == false){
|
||
|
return false, 0, "", false, 0, "", errors.New("Malformed person analysis: PolygenicDiseaseLocus item missing _OddsRatio")
|
||
|
}
|
||
|
|
||
|
if (genomeLocusOddsRatio == "Unknown"){
|
||
|
return true, genomeLocusRiskWeightInt, locusBasePair, false, 0, "", nil
|
||
|
}
|
||
|
|
||
|
locusOddsRatioFloat64, err := helpers.ConvertStringToFloat64(genomeLocusOddsRatio)
|
||
|
if (err != nil){
|
||
|
return false, 0, "", false, 0, "", errors.New("Malformed person analysis: PolygenicDiseaseLocus item contains invalid _OddsRatio: " + genomeLocusOddsRatio)
|
||
|
}
|
||
|
|
||
|
genomeLocusOddsRatioString := helpers.ConvertFloat64ToStringRounded(locusOddsRatioFloat64, 2)
|
||
|
|
||
|
locusOddsRatioFormatted := genomeLocusOddsRatioString + "x"
|
||
|
|
||
|
return true, genomeLocusRiskWeightInt, locusBasePair, true, locusOddsRatioFloat64, locusOddsRatioFormatted, nil
|
||
|
}
|
||
|
|
||
|
return false, 0, "", false, 0, "", errors.New("GetPersonPolygenicDiseaseLocusInfoFromGeneticAnalysis failed: Locus info not found.")
|
||
|
}
|
||
|
|
||
|
//Outputs:
|
||
|
// -bool: Offspring risk weight known
|
||
|
// -int: Offspring risk weight
|
||
|
// -bool: Offspring odds ratio known
|
||
|
// -float64: Offspring odds ratio
|
||
|
// -string: Offspring odds ratio formatted (with + and < from unknownFactors weight sum and x suffix)
|
||
|
// -error
|
||
|
func GetOffspringPolygenicDiseaseLocusInfoFromGeneticAnalysis(coupleAnalysisMapList []map[string]string, diseaseName string, locusIdentifier string, genomePairIdentifier string)(bool, int, bool, float64, string, error){
|
||
|
|
||
|
for _, element := range coupleAnalysisMapList{
|
||
|
|
||
|
itemType, exists := element["ItemType"]
|
||
|
if (exists == false) {
|
||
|
return false, 0, false, 0, "", errors.New("Malformed couple analysis: Item missing itemType")
|
||
|
}
|
||
|
|
||
|
if (itemType != "PolygenicDiseaseLocus"){
|
||
|
continue
|
||
|
}
|
||
|
currentDiseaseName, exists := element["DiseaseName"]
|
||
|
if (exists == false) {
|
||
|
return false, 0, false, 0, "", errors.New("Malformed couple analysis: PolygenicDiseaseLocus item missing DiseaseName")
|
||
|
}
|
||
|
|
||
|
if (currentDiseaseName != diseaseName){
|
||
|
continue
|
||
|
}
|
||
|
|
||
|
currentLocusIdentifier, exists := element["LocusIdentifier"]
|
||
|
if (exists == false) {
|
||
|
return false, 0, false, 0, "", errors.New("Malformed couple analysis: PolygenicDiseaseLocus item missing LocusIdentifier")
|
||
|
}
|
||
|
|
||
|
if (currentLocusIdentifier != locusIdentifier){
|
||
|
continue
|
||
|
}
|
||
|
|
||
|
offspringRiskWeight, exists := element[genomePairIdentifier + "_OffspringRiskWeight"]
|
||
|
if (exists == false){
|
||
|
return false, 0, false, 0, "", errors.New("Malformed couple analysis: PolygenicDiseaseLocus item missing _OffspringRiskWeight key")
|
||
|
}
|
||
|
|
||
|
if (offspringRiskWeight == "Unknown"){
|
||
|
return false, 0, false, 0, "", nil
|
||
|
}
|
||
|
|
||
|
offspringRiskWeightInt, err := helpers.ConvertStringToInt(offspringRiskWeight)
|
||
|
if (err != nil){
|
||
|
return false, 0, false, 0, "", errors.New("Malformed couple analysis: PolygenicDiseaseLocus item contains invalid _OffspringRiskWeight key: " + offspringRiskWeight)
|
||
|
}
|
||
|
|
||
|
offspringOddsRatio, exists := element[genomePairIdentifier + "_OffspringOddsRatio"]
|
||
|
if (exists == false){
|
||
|
return false, 0, false, 0, "", errors.New("Malformed couple analysis: PolygenicDiseaseLocus item missing _OffspringOddsRatio key")
|
||
|
}
|
||
|
if (offspringOddsRatio == "Unknown"){
|
||
|
return true, offspringRiskWeightInt, false, 0, "", nil
|
||
|
}
|
||
|
|
||
|
offspringOddsRatioFloat64, err := helpers.ConvertStringToFloat64(offspringOddsRatio)
|
||
|
if (err != nil){
|
||
|
return false, 0, false, 0, "", errors.New("Malformed couple analysis: Contains invalid _OffspringOddsRatio: " + offspringOddsRatio)
|
||
|
}
|
||
|
|
||
|
offspringUnknownOddsRatiosWeightSum, exists := element[genomePairIdentifier + "_OffspringUnknownOddsRatiosWeightSum"]
|
||
|
if (exists == false){
|
||
|
return false, 0, false, 0, "", errors.New("Malformed couple analysis: PolygenicDiseaseLocus item missing _OffspringUnknownOddsRatiosWeightSum key")
|
||
|
}
|
||
|
|
||
|
offspringUnknownOddsRatiosWeightSumInt, err := helpers.ConvertStringToInt(offspringUnknownOddsRatiosWeightSum)
|
||
|
if (err != nil){
|
||
|
return false, 0, false, 0, "", errors.New("Malformed couple analysis: PolygenicDiseaseLocus item contains invalid _OffspringUnknownOddsRatiosWeightSum key: " + offspringUnknownOddsRatiosWeightSum)
|
||
|
}
|
||
|
|
||
|
getOddsRatioFormatted := func()string{
|
||
|
|
||
|
if (offspringUnknownOddsRatiosWeightSumInt == 0){
|
||
|
result := offspringOddsRatio + "x"
|
||
|
return result
|
||
|
}
|
||
|
if (offspringUnknownOddsRatiosWeightSumInt < 0){
|
||
|
result := "<" + offspringOddsRatio + "x"
|
||
|
return result
|
||
|
}
|
||
|
// offspringUnknownOddsRatiosWeightSumInt > 0
|
||
|
result := offspringOddsRatio + "x+"
|
||
|
return result
|
||
|
}
|
||
|
|
||
|
oddsRatioFormatted := getOddsRatioFormatted()
|
||
|
|
||
|
return true, offspringRiskWeightInt, true, offspringOddsRatioFloat64, oddsRatioFormatted, nil
|
||
|
}
|
||
|
|
||
|
return false, 0, false, 0, "", errors.New("Malformed couple analysis: Polygenic Disease locus not found.")
|
||
|
}
|
||
|
|
||
|
type LocusValue struct{
|
||
|
|
||
|
Base1 string
|
||
|
Base2 string
|
||
|
|
||
|
// Are the bases ordered or in random order?
|
||
|
LocusIsPhased bool
|
||
|
}
|
||
|
|
||
|
//Outputs:
|
||
|
// -map[int64]LocusValue (rsID -> Base pair) (missing rsIDs represent unknown values)
|
||
|
// -bool: Any Trait Rule known/tested
|
||
|
// -map[string]int: Trait outcomes scores map (outcome -> Number of points)
|
||
|
// -int: Number of rules tested
|
||
|
// -bool: Conflict exists
|
||
|
// -error
|
||
|
func GetPersonTraitInfoFromGeneticAnalysis(personAnalysisMapList []map[string]string, traitName string, genomeIdentifier string, personHasMultipleGenomes bool)(map[int64]LocusValue, bool, map[string]int, int, bool, error){
|
||
|
|
||
|
for _, element := range personAnalysisMapList{
|
||
|
|
||
|
analysisItemType, exists := element["ItemType"]
|
||
|
if (exists == false) {
|
||
|
return nil, false, nil, 0, false, errors.New("Malformed person analysis: Item missing ItemType")
|
||
|
}
|
||
|
|
||
|
if (analysisItemType != "Trait"){
|
||
|
continue
|
||
|
}
|
||
|
|
||
|
itemTraitName, exists := element["TraitName"]
|
||
|
if (exists == false) {
|
||
|
return nil, false, nil, 0, false, errors.New("Malformed person analysis: Trait item missing TraitName")
|
||
|
}
|
||
|
|
||
|
if (itemTraitName != traitName){
|
||
|
continue
|
||
|
}
|
||
|
|
||
|
traitObject, err := traits.GetTraitObject(traitName)
|
||
|
if (err != nil) { return nil, false, nil, 0, false, err }
|
||
|
|
||
|
traitLociList := traitObject.LociList
|
||
|
|
||
|
// Map Structure: rsID -> Locus Value
|
||
|
locusValuesMap := make(map[int64]LocusValue)
|
||
|
|
||
|
for _, rsID := range traitLociList{
|
||
|
|
||
|
rsidString := helpers.ConvertInt64ToString(rsID)
|
||
|
|
||
|
locusValue, exists := element[genomeIdentifier + "_LocusValue_rs" + rsidString]
|
||
|
if (exists == false){
|
||
|
return nil, false, nil, 0, false, errors.New("Malformed person analysis: missing trait locus value for locus: " + rsidString)
|
||
|
}
|
||
|
|
||
|
if (locusValue == "Unknown"){
|
||
|
// No value exists for this locus
|
||
|
continue
|
||
|
}
|
||
|
|
||
|
locusIsPhasedString, exists := element[genomeIdentifier + "_LocusIsPhased_rs" + rsidString]
|
||
|
if (exists == false){
|
||
|
return nil, false, nil, 0, false, errors.New("Malformed person analysis: Contains trait locus value which is missing locusIsPhased information.")
|
||
|
}
|
||
|
|
||
|
locusIsPhased, err := helpers.ConvertYesOrNoStringToBool(locusIsPhasedString)
|
||
|
if (err != nil){
|
||
|
return nil, false, nil, 0, false, errors.New("Malformed person analysis: Contains invalid trait locusIsPhased rsID value: " + locusIsPhasedString)
|
||
|
}
|
||
|
|
||
|
locusBase1, locusBase2, semicolonExists := strings.Cut(locusValue, ";")
|
||
|
if (semicolonExists == false){
|
||
|
return nil, false, nil, 0, false, errors.New("Malformed person analysis: Contains invalid trait locus value: " + locusValue)
|
||
|
}
|
||
|
|
||
|
locusValueObject := LocusValue{
|
||
|
Base1: locusBase1,
|
||
|
Base2: locusBase2,
|
||
|
LocusIsPhased: locusIsPhased,
|
||
|
}
|
||
|
|
||
|
locusValuesMap[rsID] = locusValueObject
|
||
|
}
|
||
|
|
||
|
numberOfRulesTestedString, exists := element[genomeIdentifier + "_NumberOfRulesTested"]
|
||
|
if (exists == false){
|
||
|
return nil, false, nil, 0, false, errors.New("Malformed person analysis: Trait item missing _NumberOfRulesTested")
|
||
|
}
|
||
|
|
||
|
numberOfRulesTested, err := helpers.ConvertStringToInt(numberOfRulesTestedString)
|
||
|
if (err != nil){
|
||
|
return nil, false, nil, 0, false, errors.New("Malformed person analysis: Trait item contains invalid _NumberOfRulesTested: " + numberOfRulesTestedString)
|
||
|
}
|
||
|
|
||
|
getConflictExistsBool := func()(bool, error){
|
||
|
|
||
|
if (personHasMultipleGenomes == false){
|
||
|
return false, nil
|
||
|
}
|
||
|
|
||
|
conflictExists, exists := element["ConflictExists"]
|
||
|
if (exists == false) {
|
||
|
return false, errors.New("Malformed analysisMapList: Trait analysis missing ConflictExists")
|
||
|
}
|
||
|
|
||
|
if (conflictExists == "Yes"){
|
||
|
return true, nil
|
||
|
}
|
||
|
|
||
|
return false, nil
|
||
|
}
|
||
|
|
||
|
conflictExistsBool, err := getConflictExistsBool()
|
||
|
if (err != nil) { return nil, false, nil, 0, false, err }
|
||
|
|
||
|
if (numberOfRulesTested == 0){
|
||
|
return locusValuesMap, false, nil, 0, conflictExistsBool, nil
|
||
|
}
|
||
|
|
||
|
traitOutcomesList := traitObject.OutcomesList
|
||
|
|
||
|
traitOutcomeScoresMap := make(map[string]int)
|
||
|
|
||
|
for _, traitOutcome := range traitOutcomesList{
|
||
|
|
||
|
outcomeScoreString, exists := element[genomeIdentifier + "_OutcomeScore_" + traitOutcome]
|
||
|
if (exists == false){
|
||
|
return nil, false, nil, 0, false, errors.New("Person analysis missing _OutcomePoints_" + traitOutcome + " key.")
|
||
|
}
|
||
|
|
||
|
outcomeScoreInt, err := helpers.ConvertStringToInt(outcomeScoreString)
|
||
|
if (err != nil){
|
||
|
return nil, false, nil, 0, false, errors.New("Person analysis contains invalid _OutcomeScore_ value: " + outcomeScoreString)
|
||
|
}
|
||
|
|
||
|
traitOutcomeScoresMap[traitOutcome] = outcomeScoreInt
|
||
|
}
|
||
|
|
||
|
return locusValuesMap, true, traitOutcomeScoresMap, numberOfRulesTested, conflictExistsBool, nil
|
||
|
}
|
||
|
|
||
|
return nil, false, nil, 0, false, errors.New("GetPersonTraitInfoFromGeneticAnalysis failed: Cannot find trait info for trait: " + traitName)
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
//Outputs:
|
||
|
// -bool: Trait Outcome Scores known
|
||
|
// -map[string]float64: Trait average outcome scores map (OutcomeName -> AverageScore)
|
||
|
// -int: Number of rules tested
|
||
|
// -bool: Conflict exists
|
||
|
// -error
|
||
|
func GetOffspringTraitInfoFromGeneticAnalysis(coupleAnalysisMapList []map[string]string, traitName string, genomePairIdentifier string, secondGenomePairExists bool)(bool, map[string]float64, int, bool, error){
|
||
|
|
||
|
for _, element := range coupleAnalysisMapList{
|
||
|
|
||
|
analysisItemType, exists := element["ItemType"]
|
||
|
if (exists == false) {
|
||
|
return false, nil, 0, false, errors.New("Malformed couple analysis: Item missing ItemType")
|
||
|
}
|
||
|
|
||
|
if (analysisItemType != "Trait"){
|
||
|
continue
|
||
|
}
|
||
|
|
||
|
itemTraitName, exists := element["TraitName"]
|
||
|
if (exists == false) {
|
||
|
return false, nil, 0, false, errors.New("Malformed couple analysis: Trait item missing TraitName")
|
||
|
}
|
||
|
|
||
|
if (itemTraitName != traitName){
|
||
|
continue
|
||
|
}
|
||
|
|
||
|
numberOfRulesTestedString, exists := element[genomePairIdentifier + "_NumberOfRulesTested"]
|
||
|
if (exists == false){
|
||
|
return false, nil, 0, false, errors.New("Malformed couple analysis: Trait item missing _NumberOfRulesTested")
|
||
|
}
|
||
|
|
||
|
numberOfRulesTested, err := helpers.ConvertStringToInt(numberOfRulesTestedString)
|
||
|
if (err != nil){
|
||
|
return false, nil, 0, false, errors.New("Malformed couple analysis: Trait item contains invalid _NumberOfRulesTested: " + numberOfRulesTestedString)
|
||
|
}
|
||
|
|
||
|
getConflictExistsBool := func()(bool, error){
|
||
|
|
||
|
if (secondGenomePairExists == false){
|
||
|
return false, nil
|
||
|
}
|
||
|
|
||
|
conflictExists, exists := element["ConflictExists"]
|
||
|
if (exists == false) {
|
||
|
return false, errors.New("Malformed analysisMapList: Trait analysis missing ConflictExists")
|
||
|
}
|
||
|
|
||
|
if (conflictExists == "Yes"){
|
||
|
return true, nil
|
||
|
}
|
||
|
|
||
|
return false, nil
|
||
|
}
|
||
|
|
||
|
conflictExistsBool, err := getConflictExistsBool()
|
||
|
if (err != nil) { return false, nil, 0, false, err }
|
||
|
|
||
|
if (numberOfRulesTested == 0){
|
||
|
return false, nil, 0, conflictExistsBool, nil
|
||
|
}
|
||
|
|
||
|
traitObject, err := traits.GetTraitObject(traitName)
|
||
|
if (err != nil) { return false, nil, 0, false, err }
|
||
|
|
||
|
traitOutcomesList := traitObject.OutcomesList
|
||
|
|
||
|
traitOutcomeScoresMap := make(map[string]float64)
|
||
|
|
||
|
for _, traitOutcome := range traitOutcomesList{
|
||
|
|
||
|
averageOutcomeScoreString, exists := element[genomePairIdentifier + "_OffspringAverageOutcomeScore_" + traitOutcome]
|
||
|
if (exists == false){
|
||
|
return false, nil, 0, false, errors.New("Couple analysis missing _OutcomePoints_" + traitOutcome + " key.")
|
||
|
}
|
||
|
|
||
|
averageOutcomeScoreFloat64, err := helpers.ConvertStringToFloat64(averageOutcomeScoreString)
|
||
|
if (err != nil){
|
||
|
return false, nil, 0, false, errors.New("Couple analysis contains invalid _OutcomeScore_ value: " + averageOutcomeScoreString)
|
||
|
}
|
||
|
|
||
|
traitOutcomeScoresMap[traitOutcome] = averageOutcomeScoreFloat64
|
||
|
}
|
||
|
|
||
|
return true, traitOutcomeScoresMap, numberOfRulesTested, conflictExistsBool, nil
|
||
|
}
|
||
|
|
||
|
return false, nil, 0, false, errors.New("GetOffspringTraitInfoFromGeneticAnalysis failed: Cannot find trait info for trait: " + traitName)
|
||
|
}
|
||
|
|
||
|
//Outputs:
|
||
|
// -bool: Rule status known (we know if the rule is passed or not)
|
||
|
// -bool: Genome passes rule
|
||
|
// -map[string]string: Rule locus identifier -> genome base pair
|
||
|
// -error
|
||
|
func GetPersonTraitRuleInfoFromGeneticAnalysis(personAnalyisMapList []map[string]string, traitName string, ruleIdentifier string, genomeIdentifier string)(bool, bool, map[string]string, error){
|
||
|
|
||
|
for _, element := range personAnalyisMapList{
|
||
|
|
||
|
itemType, exists := element["ItemType"]
|
||
|
if (exists == false) {
|
||
|
return false, false, nil, errors.New("Malformed person analysis: Item missing itemType")
|
||
|
}
|
||
|
|
||
|
if (itemType != "TraitRule"){
|
||
|
continue
|
||
|
}
|
||
|
|
||
|
currentTraitName, exists := element["TraitName"]
|
||
|
if (exists == false){
|
||
|
return false, false, nil, errors.New("Malformed person analysis: Trait item missing TraitName")
|
||
|
}
|
||
|
|
||
|
if (currentTraitName != traitName){
|
||
|
continue
|
||
|
}
|
||
|
|
||
|
currentRuleIdentifier, exists := element["RuleIdentifier"]
|
||
|
if (exists == false) {
|
||
|
return false, false, nil, errors.New("Malformed person analysis: TraitRule item missing RuleIdentifier")
|
||
|
}
|
||
|
|
||
|
if (currentRuleIdentifier != ruleIdentifier){
|
||
|
continue
|
||
|
}
|
||
|
|
||
|
genomePassesRuleString, exists := element[genomeIdentifier + "_PassesRule"]
|
||
|
if (exists == false){
|
||
|
return false, false, nil, errors.New("Malformed person analysis: TraitRule item missing _PassesRule")
|
||
|
}
|
||
|
|
||
|
// Map Structure: Locus Identifier -> Locus base pair
|
||
|
ruleLocusBasePairsMap := make(map[string]string)
|
||
|
|
||
|
locusKeysPrefix := genomeIdentifier + "_RuleLocusBasePair_"
|
||
|
|
||
|
for key, value := range element{
|
||
|
|
||
|
isLocusValueEntry := strings.HasPrefix(key, locusKeysPrefix)
|
||
|
if (isLocusValueEntry == false){
|
||
|
continue
|
||
|
}
|
||
|
|
||
|
locusIdentifier := strings.TrimPrefix(key, locusKeysPrefix)
|
||
|
|
||
|
if (value == "Unknown"){
|
||
|
continue
|
||
|
}
|
||
|
|
||
|
ruleLocusBasePairsMap[locusIdentifier] = value
|
||
|
}
|
||
|
|
||
|
if (genomePassesRuleString == "Unknown"){
|
||
|
return false, false, ruleLocusBasePairsMap, nil
|
||
|
}
|
||
|
|
||
|
genomePassesRuleBool, err := helpers.ConvertYesOrNoStringToBool(genomePassesRuleString)
|
||
|
if (err != nil){
|
||
|
return false, false, nil, errors.New("Malformed person analysis: TraitRule item contains invalid _PassesRule: " + genomePassesRuleString)
|
||
|
}
|
||
|
|
||
|
return true, genomePassesRuleBool, ruleLocusBasePairsMap, nil
|
||
|
}
|
||
|
|
||
|
return false, false, nil, errors.New("GetPersonTraitRuleInfoFromGeneticAnalysis failed: Trait rule info not found.")
|
||
|
}
|
||
|
|
||
|
|
||
|
//Outputs:
|
||
|
// -bool: Offspring trait rule probability known
|
||
|
// -int: Offspring probability of passing rule (0 - 100)
|
||
|
// -string: Offspring probability of passing rule formatted (with % suffix)
|
||
|
// -error
|
||
|
func GetOffspringTraitRuleInfoFromGeneticAnalysis(coupleAnalysisMapList []map[string]string, traitName string, ruleIdentifier string, genomePairIdentifier string)(bool, int, string, error){
|
||
|
|
||
|
for _, element := range coupleAnalysisMapList{
|
||
|
|
||
|
itemType, exists := element["ItemType"]
|
||
|
if (exists == false) {
|
||
|
return false, 0, "", errors.New("Malformed couple analysis: Item missing itemType")
|
||
|
}
|
||
|
|
||
|
if (itemType != "TraitRule"){
|
||
|
continue
|
||
|
}
|
||
|
currentTraitName, exists := element["TraitName"]
|
||
|
if (exists == false) {
|
||
|
return false, 0, "", errors.New("Malformed couple analysis: TraitRule item missing TraitName")
|
||
|
}
|
||
|
|
||
|
if (currentTraitName != traitName){
|
||
|
continue
|
||
|
}
|
||
|
|
||
|
currentRuleIdentifier, exists := element["RuleIdentifier"]
|
||
|
if (exists == false) {
|
||
|
return false, 0, "", errors.New("Malformed couple analysis: TraitRule item missing RuleIdentifier")
|
||
|
}
|
||
|
|
||
|
if (currentRuleIdentifier != ruleIdentifier){
|
||
|
continue
|
||
|
}
|
||
|
|
||
|
offspringProbabilityOfPassingRule, exists := element[genomePairIdentifier + "_OffspringProbabilityOfPassingRule"]
|
||
|
if (exists == false){
|
||
|
return false, 0, "", errors.New("Malformed couple analysis: TraitRule item missing _OffspringProbabilityOfPassingRule key")
|
||
|
}
|
||
|
|
||
|
if (offspringProbabilityOfPassingRule == "Unknown"){
|
||
|
return false, 0, "", nil
|
||
|
}
|
||
|
|
||
|
offspringProbabilityOfPassingRuleInt, err := helpers.ConvertStringToInt(offspringProbabilityOfPassingRule)
|
||
|
if (err != nil) {
|
||
|
return false, 0, "", errors.New("Malformed couple analysis: TraitRule item contains invalid _OffspringProbabilityOfPassingRule: " + offspringProbabilityOfPassingRule)
|
||
|
}
|
||
|
|
||
|
offspringProbabilityOfPassingRuleFormatted := offspringProbabilityOfPassingRule + "%"
|
||
|
|
||
|
return true, offspringProbabilityOfPassingRuleInt, offspringProbabilityOfPassingRuleFormatted, nil
|
||
|
}
|
||
|
|
||
|
return false, 0, "", errors.New("GetOffspringTraitRuleInfoFromGeneticAnalysis failed: Trait rule info not found.")
|
||
|
}
|
||
|
|
||
|
|
||
|
// We use this function to verify a person genetic analysis is well formed
|
||
|
func ReadPersonGeneticAnalysisForTests(personAnalysisMapList []map[string]string)error{
|
||
|
|
||
|
allRawGenomeIdentifiersList, personHasMultipleGenomes, onlyExcludeConflictsGenomeIdentifier, onlyIncludeSharedGenomeIdentifier, err := GetMetadataFromPersonGeneticAnalysis(personAnalysisMapList)
|
||
|
if (err != nil) { return err }
|
||
|
|
||
|
allGenomeIdentifiersList := allRawGenomeIdentifiersList
|
||
|
if (personHasMultipleGenomes == true){
|
||
|
allGenomeIdentifiersList = append(allGenomeIdentifiersList, onlyExcludeConflictsGenomeIdentifier, onlyIncludeSharedGenomeIdentifier)
|
||
|
}
|
||
|
|
||
|
monogenicDiseaseObjectsList, err := monogenicDiseases.GetMonogenicDiseaseObjectsList()
|
||
|
if (err != nil) { return err }
|
||
|
|
||
|
for _, monogenicDiseaseObject := range monogenicDiseaseObjectsList{
|
||
|
|
||
|
diseaseName := monogenicDiseaseObject.DiseaseName
|
||
|
|
||
|
for _, genomeIdentifier := range allGenomeIdentifiersList{
|
||
|
|
||
|
_, _, _, _, _, _, _, err := GetPersonMonogenicDiseaseInfoFromGeneticAnalysis(personAnalysisMapList, diseaseName, genomeIdentifier, personHasMultipleGenomes)
|
||
|
if (err != nil) { return err }
|
||
|
}
|
||
|
|
||
|
diseaseVariantObjectsList := monogenicDiseaseObject.VariantsList
|
||
|
|
||
|
for _, diseaseVariantObject := range diseaseVariantObjectsList{
|
||
|
|
||
|
variantIdentifier := diseaseVariantObject.VariantIdentifier
|
||
|
|
||
|
for _, genomeIdentifier := range allGenomeIdentifiersList{
|
||
|
|
||
|
_, _, err := GetPersonMonogenicDiseaseVariantInfoFromGeneticAnalysis(personAnalysisMapList, diseaseName, variantIdentifier, genomeIdentifier)
|
||
|
if (err != nil) { return err }
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
polygenicDiseaseObjectsList, err := polygenicDiseases.GetPolygenicDiseaseObjectsList()
|
||
|
if (err != nil) { return err }
|
||
|
|
||
|
for _, diseaseObject := range polygenicDiseaseObjectsList{
|
||
|
|
||
|
diseaseName := diseaseObject.DiseaseName
|
||
|
|
||
|
for _, genomeIdentifier := range allGenomeIdentifiersList{
|
||
|
|
||
|
_, _, _, _, _, err := GetPersonPolygenicDiseaseInfoFromGeneticAnalysis(personAnalysisMapList, diseaseName, genomeIdentifier, personHasMultipleGenomes)
|
||
|
if (err != nil) { return err }
|
||
|
}
|
||
|
|
||
|
diseaseLocusObjectsList := diseaseObject.LociList
|
||
|
|
||
|
for _, diseaseLocusObject := range diseaseLocusObjectsList{
|
||
|
|
||
|
locusIdentifier := diseaseLocusObject.LocusIdentifier
|
||
|
|
||
|
for _, genomeIdentifier := range allGenomeIdentifiersList{
|
||
|
|
||
|
_, _, _, _, _, _, err := GetPersonPolygenicDiseaseLocusInfoFromGeneticAnalysis(personAnalysisMapList, diseaseName, locusIdentifier, genomeIdentifier)
|
||
|
if (err != nil) { return err }
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
traitObjectsList, err := traits.GetTraitObjectsList()
|
||
|
if (err != nil) { return err }
|
||
|
|
||
|
for _, traitObject := range traitObjectsList{
|
||
|
|
||
|
traitName := traitObject.TraitName
|
||
|
|
||
|
for _, genomeIdentifier := range allGenomeIdentifiersList{
|
||
|
|
||
|
_, _, _, _, _, err := GetPersonTraitInfoFromGeneticAnalysis(personAnalysisMapList, traitName, genomeIdentifier, personHasMultipleGenomes)
|
||
|
if (err != nil) { return err }
|
||
|
}
|
||
|
|
||
|
traitRulesList := traitObject.RulesList
|
||
|
|
||
|
for _, traitRuleObject := range traitRulesList{
|
||
|
|
||
|
ruleIdentifier := traitRuleObject.RuleIdentifier
|
||
|
|
||
|
for _, genomeIdentifier := range allGenomeIdentifiersList{
|
||
|
|
||
|
_, _, _, err := GetPersonTraitRuleInfoFromGeneticAnalysis(personAnalysisMapList, traitName, ruleIdentifier, genomeIdentifier)
|
||
|
if (err != nil) { return err }
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
|
||
|
// We use this function to verify a person genetic analysis is well formed
|
||
|
func ReadCoupleGeneticAnalysisForTests(coupleAnalysisMapList []map[string]string)error{
|
||
|
|
||
|
pair1PersonAGenomeIdentifier, pair1PersonBGenomeIdentifier, secondGenomePairExists, pair2PersonAGenomeIdentifier, pair2PersonBGenomeIdentifier, _, _, _, _, _, _, err := GetMetadataFromCoupleGeneticAnalysis(coupleAnalysisMapList)
|
||
|
if (err != nil) { return err }
|
||
|
|
||
|
pair1GenomeIdentifier := pair1PersonAGenomeIdentifier + "+" + pair1PersonBGenomeIdentifier
|
||
|
|
||
|
allGenomePairIdentifiersList := []string{pair1GenomeIdentifier}
|
||
|
|
||
|
if (secondGenomePairExists == true){
|
||
|
|
||
|
pair2GenomeIdentifier := pair2PersonAGenomeIdentifier + "+" + pair2PersonBGenomeIdentifier
|
||
|
|
||
|
allGenomePairIdentifiersList = append(allGenomePairIdentifiersList, pair2GenomeIdentifier)
|
||
|
}
|
||
|
|
||
|
monogenicDiseaseObjectsList, err := monogenicDiseases.GetMonogenicDiseaseObjectsList()
|
||
|
if (err != nil) { return err }
|
||
|
|
||
|
for _, monogenicDiseaseObject := range monogenicDiseaseObjectsList{
|
||
|
|
||
|
diseaseName := monogenicDiseaseObject.DiseaseName
|
||
|
|
||
|
for _, genomePairIdentifier := range allGenomePairIdentifiersList{
|
||
|
|
||
|
_, _, _, _, _, _, err = GetOffspringMonogenicDiseaseInfoFromGeneticAnalysis(coupleAnalysisMapList, diseaseName, genomePairIdentifier, secondGenomePairExists)
|
||
|
if (err != nil) { return err }
|
||
|
}
|
||
|
|
||
|
diseaseVariantObjectsList := monogenicDiseaseObject.VariantsList
|
||
|
|
||
|
for _, diseaseVariantObject := range diseaseVariantObjectsList{
|
||
|
|
||
|
variantIdentifier := diseaseVariantObject.VariantIdentifier
|
||
|
|
||
|
for _, genomePairIdentifier := range allGenomePairIdentifiersList{
|
||
|
|
||
|
_, _, _, _, _, _, _, _, _, _, err := GetOffspringMonogenicDiseaseVariantInfoFromGeneticAnalysis(coupleAnalysisMapList, diseaseName, variantIdentifier, genomePairIdentifier)
|
||
|
if (err != nil) { return err }
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
polygenicDiseaseObjectsList, err := polygenicDiseases.GetPolygenicDiseaseObjectsList()
|
||
|
if (err != nil) { return err }
|
||
|
|
||
|
for _, diseaseObject := range polygenicDiseaseObjectsList{
|
||
|
|
||
|
diseaseName := diseaseObject.DiseaseName
|
||
|
|
||
|
for _, genomePairIdentifier := range allGenomePairIdentifiersList{
|
||
|
|
||
|
_, _, _, _, _, err := GetOffspringPolygenicDiseaseInfoFromGeneticAnalysis(coupleAnalysisMapList, diseaseName, genomePairIdentifier, secondGenomePairExists)
|
||
|
if (err != nil) { return err }
|
||
|
}
|
||
|
|
||
|
diseaseLocusObjectsList := diseaseObject.LociList
|
||
|
|
||
|
for _, diseaseLocusObject := range diseaseLocusObjectsList{
|
||
|
|
||
|
locusIdentifier := diseaseLocusObject.LocusIdentifier
|
||
|
|
||
|
for _, genomePairIdentifier := range allGenomePairIdentifiersList{
|
||
|
|
||
|
_, _, _, _, _, err := GetOffspringPolygenicDiseaseLocusInfoFromGeneticAnalysis(coupleAnalysisMapList, diseaseName, locusIdentifier, genomePairIdentifier)
|
||
|
if (err != nil) { return err }
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
traitObjectsList, err := traits.GetTraitObjectsList()
|
||
|
if (err != nil) { return err }
|
||
|
|
||
|
for _, traitObject := range traitObjectsList{
|
||
|
|
||
|
traitName := traitObject.TraitName
|
||
|
|
||
|
for _, genomePairIdentifier := range allGenomePairIdentifiersList{
|
||
|
|
||
|
_, _, _, _, err := GetOffspringTraitInfoFromGeneticAnalysis(coupleAnalysisMapList, traitName, genomePairIdentifier, secondGenomePairExists)
|
||
|
if (err != nil) { return err }
|
||
|
}
|
||
|
|
||
|
traitRulesList := traitObject.RulesList
|
||
|
|
||
|
for _, traitRuleObject := range traitRulesList{
|
||
|
|
||
|
ruleIdentifier := traitRuleObject.RuleIdentifier
|
||
|
|
||
|
for _, genomePairIdentifier := range allGenomePairIdentifiersList{
|
||
|
|
||
|
_, _, _, err := GetOffspringTraitRuleInfoFromGeneticAnalysis(coupleAnalysisMapList, traitName, ruleIdentifier, genomePairIdentifier)
|
||
|
if (err != nil) { return err }
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
|