Beispiel #1
0
        /// <summary>
        /// Returns an aray of trait possibilites and their spawn percentages.
        /// Bad data/data that does not obey the algorithm will cause hilarious (read: annoying)
        /// bugs. Make sure the user is forced to follow the rules rigidly.
        /// </summary>
        /// <param name="p_fatherTraits">Father's traits</param>
        /// <param name="p_motherTraits">Mother's traits</param>
        /// <returns></returns>
        private CrossList ThreePointCross(ReducedTraitModel[] p_fatherTraits, ReducedTraitModel[] p_motherTraits)
        {
            //FIX ORDER
            p_fatherTraits = p_fatherTraits.OrderBy(t => t.Distance).ToArray();
            p_motherTraits = p_motherTraits.OrderBy(t => t.Distance).ToArray();

            List<CrossTrait> returnArr = new List<CrossTrait>();
            #region Trait_Prep
            //generate wild, het, hom for each trait & gender
            Trait[] wild = new Trait[3];
            Trait[] hets = new Trait[3];
            Trait[] homs = new Trait[3];

            Trait[] father_raw = new Trait[3];
            Trait[] mother_raw = new Trait[3];

            for (int i = 0; i < 3; i++)
            {
                Trait dbTrt1 = db.Trait.Find(p_fatherTraits[i].Id);
                Trait dbTrt2 = db.Trait.Find(p_motherTraits[i].Id);

                wild[i] = db.Trait.FirstOrDefault(t => t.CategoryId == dbTrt1.CategoryId && t.Name.ToLower() == Constants.Wild.ToLower());
                hets[i] = GetTrait((dbTrt1.Name != Constants.Wild) ? dbTrt1 : dbTrt2, true);
                homs[i] = GetTrait((dbTrt1.Name != Constants.Wild) ? dbTrt1 : dbTrt2, false);
            }
            #endregion
            #region Distance_Linked
            //check father trait, then mother trait to determine case
            List<Trait> building = new List<Trait>();
            if ((!p_fatherTraits[0].IsHeterozygous && !p_fatherTraits[1].IsHeterozygous && !p_fatherTraits[2].IsHeterozygous) &&
                (!p_motherTraits[0].IsHeterozygous && !p_motherTraits[1].IsHeterozygous && !p_motherTraits[2].IsHeterozygous))
            {
                //father hom-hom, mother hom-hom
                //one output: het-het
                building.Add(hets[0]);
                building.Add(hets[1]);
                building.Add(hets[2]);
                returnArr.Add(new CrossTrait(building, 1));
                return FinishCross(returnArr, 1);
            }
            else
            {
                //2 traits must be heterozygous by necessity of the algorithm
                //calculate recombinance rates
                double dist1 = (p_fatherTraits[0].Name != Constants.Wild) ? p_fatherTraits[0].Distance : p_motherTraits[0].Distance;
                double dist2 = (p_fatherTraits[1].Name != Constants.Wild) ? p_fatherTraits[1].Distance : p_motherTraits[1].Distance;
                double dist3 = (p_fatherTraits[2].Name != Constants.Wild) ? p_fatherTraits[2].Distance : p_motherTraits[2].Distance;

                //TODO CHANGE!!
                double recombined_rate_1_2 = Math.Abs(dist1 - dist2) / 100;
                double unrecombined_rate_1_2 = 1 - recombined_rate_1_2;

                double recombined_rate_2_3 = Math.Abs(dist2 - dist3) / 100;
                double unrecombined_rate_2_3 = 1 - recombined_rate_2_3;

                #region no_recombine
                building = new List<Trait>();
                building.Add(homs[0]);
                building.Add(homs[1]);
                building.Add(homs[2]);
                returnArr.Add(new CrossTrait(building, (unrecombined_rate_1_2 * unrecombined_rate_2_3)));
                building = new List<Trait>();
                building.Add(hets[0]);
                building.Add(hets[1]);
                building.Add(hets[2]);
                returnArr.Add(new CrossTrait(building, (unrecombined_rate_1_2 * unrecombined_rate_2_3)));
                #endregion
                #region single_recombine
                building = new List<Trait>();
                building.Add(homs[0]);
                building.Add(hets[1]);
                building.Add(hets[2]);
                returnArr.Add(new CrossTrait(building, (recombined_rate_1_2 * unrecombined_rate_2_3)));
                building = new List<Trait>();
                building.Add(hets[0]);
                building.Add(hets[1]);
                building.Add(homs[2]);
                returnArr.Add(new CrossTrait(building, (unrecombined_rate_1_2 * recombined_rate_2_3)));
                building = new List<Trait>();
                building.Add(homs[0]);
                building.Add(homs[1]);
                building.Add(hets[2]);
                returnArr.Add(new CrossTrait(building, (unrecombined_rate_1_2 * recombined_rate_2_3)));
                building = new List<Trait>();
                building.Add(hets[0]);
                building.Add(homs[1]);
                building.Add(homs[2]);
                returnArr.Add(new CrossTrait(building, (recombined_rate_1_2 * unrecombined_rate_2_3)));
                #endregion
                #region double_recombine
                building = new List<Trait>();
                building.Add(hets[0]);
                building.Add(homs[1]);
                building.Add(hets[2]);
                returnArr.Add(new CrossTrait(building, (recombined_rate_1_2 * recombined_rate_2_3)));
                building = new List<Trait>();
                building.Add(homs[0]);
                building.Add(hets[1]);
                building.Add(homs[2]);
                returnArr.Add(new CrossTrait(building, (recombined_rate_1_2 * recombined_rate_2_3)));
                #endregion

                return FinishCross(returnArr, 8);
            }
            #endregion

            /*
             THERE ARE 4 POSSIBLE CASES
             * 1: NO RECOMBINE
             * 2: T1T2 RECOMBINE
             * 3: T1T2T3 RECOMBINE
             * 4: T2T3 RECOMBINE
             */

            //return new CrossList();
        }
Beispiel #2
0
        /// <summary>
        /// Compares two traits and determines whether they are a soft match (heterozygous recessive & wild || het dominant & hom dominant)
        /// </summary>
        /// <param name="p_trt1">A traitmod to compare</param>
        /// <param name="p_trt2">Another traitmod to compare</param>
        /// <returns>True if soft match, false otherwise</returns>
        private bool SoftMatchHelper(ReducedTraitModel p_trt1, ReducedTraitModel p_trt2)
        {
            Boolean t1Het = p_trt1.IsHeterozygous;
            Boolean t2Het = p_trt2.IsHeterozygous;
            Boolean t1Dom = p_trt1.IsDominant;
            Boolean t2Dom = p_trt2.IsDominant;

            return (((p_trt1.Name == p_trt2.Name) && (t1Het == t2Het)) ||
                    ((t1Het && t1Dom) && (!t2Het && t2Dom)) ||
                    ((!t1Het && t1Dom) && (t2Het && t2Dom)) ||
                    ((t1Het && !t1Dom) && (p_trt2.Name.ToLower() == Constants.Wild.ToLower())) ||
                    ((p_trt1.Name.ToLower() == Constants.Wild.ToLower()) && (t2Het && !t2Dom)));
        }
Beispiel #3
0
        /// <summary>
        /// Returns an array of trait possibilities and their spawn percentages
        /// based on the provided trait pair
        /// </summary>
        /// <param name="p_fatherTrait">Father's trait</param>
        /// <param name="p_motherTrait">Mother's Trait</param>
        /// <returns>The processed list of child possibilities</returns>
        private CrossList BasicCross(ReducedTraitModel p_fatherTrait, ReducedTraitModel p_motherTrait)
        {
            Trait dbTrt1 = db.Trait.Find(p_fatherTrait.Id);
            Trait dbTrt2 = db.Trait.Find(p_motherTrait.Id);
            Trait trait1 = new Trait();
            Trait trait2 = new Trait();

            List<CrossTrait> returnArr = new List<CrossTrait>();
            int count = 0;

            #region Sex_Linked
            if (dbTrt1.ChromosomeNumber == 1 || dbTrt2.ChromosomeNumber == 1)
            {
                #region Sex_Trait_Prep
                //take in traits after detecting that they are sex linked (on chromosome 1)
                //make special sex trait and perform cross
                //parse it in children method
                //??????
                //profit

                //make trait1 heterozygous (Male XY) and trait2 homozygous (Female XX)
                trait1 = new Trait()
                {
                    Id = dbTrt1.Id,
                    Name = Constants.SexLinked,
                    Father = GetTrait(dbTrt1, p_fatherTrait.IsHeterozygous),
                    Mother = GetTrait(dbTrt2, p_motherTrait.IsHeterozygous),
                    IsHeterozygous = true,
                    ChromosomeNumber = 1,
                    CategoryId = dbTrt1.CategoryId
                };
                trait2 = new Trait()
                {
                    Id = dbTrt2.Id,
                    Name = Constants.SexLinked,
                    Father = GetTrait(dbTrt1, p_fatherTrait.IsHeterozygous),
                    Mother = GetTrait(dbTrt2, p_motherTrait.IsHeterozygous),
                    IsHeterozygous = false,
                    ChromosomeNumber = 1,
                    CategoryId = dbTrt2.CategoryId
                };

                //do some fancy processing and abuse CrossTrait's new Male and Female bools
                //we know the list contains a sex-linked trait, so find it

                Trait sexLinkedTrait = dbTrt1.ChromosomeNumber == 1 ? trait1 : trait2;

                Trait hetFatherTrait = GetTrait(sexLinkedTrait.Father, true);
                Trait homFatherTrait = GetTrait(sexLinkedTrait.Father, false);
                Trait hetMotherTrait = GetTrait(sexLinkedTrait.Mother, true);
                Trait homMotherTrait = GetTrait(sexLinkedTrait.Mother, false);

                #endregion

                if (sexLinkedTrait.Mother.ChromosomeNumber == 1 && sexLinkedTrait.Father.ChromosomeNumber == 1)
                {
                    //we know they will be the same trait, so there are only 2 cross cases here...
                    if (sexLinkedTrait.Mother.IsHeterozygous ?? false)
                    {
                        //het - hemi cross
                        Trait wildTrait = db.Trait.First(t => t.CategoryId == sexLinkedTrait.Father.ChromosomeNumber && t.Name.ToLower() == Constants.Wild.ToLower());

                        returnArr.Add(new CrossTrait(homMotherTrait, .5, false, true)); //aff female
                        returnArr.Add(new CrossTrait(hetMotherTrait, .5, false, true)); //carrier female
                        returnArr.Add(new CrossTrait(homMotherTrait, .5, true, false)); //aff male
                        returnArr.Add(new CrossTrait(wildTrait     , .5, true, false)); //unaff male
                        count = 4;
                        return FinishCross(returnArr, count);
                    }
                    else
                    {
                        //hom - hemi cross
                        returnArr.Add(new CrossTrait(homMotherTrait, 1, true, false)); //aff male
                        returnArr.Add(new CrossTrait(homMotherTrait, 1, false, true)); //aff female
                        count = 2;
                        return FinishCross(returnArr, count);
                    }
                }
                if (sexLinkedTrait.Father.ChromosomeNumber == 1)
                {
                    //affected father
                    if (!(sexLinkedTrait.Mother.IsHeterozygous ?? false))
                    {
                        returnArr.Add(new CrossTrait(hetFatherTrait, 1, false, true)); //carrier females
                        returnArr.Add(new CrossTrait(homMotherTrait, 1, true, false)); //unaff males
                        count = 2;
                        return FinishCross(returnArr, count);
                    }
                }
                else
                {
                    //affected mother
                    if (sexLinkedTrait.Mother.IsHeterozygous ?? false)
                    {
                        //hetrec sex linked
                        //1 son wild, 1 son aff, 1 daughter wild, 1 daughter het
                        returnArr.Add(new CrossTrait(hetMotherTrait, .5, false, true)); //carrier female
                        returnArr.Add(new CrossTrait(homFatherTrait, .5, false, true)); //unaff female
                        returnArr.Add(new CrossTrait(homMotherTrait, .5, true, false)); //aff male
                        returnArr.Add(new CrossTrait(homFatherTrait, .5, true, false)); //unaff male
                        count = 4;
                        return FinishCross(returnArr, count);
                    }
                    else
                    {
                        returnArr.Add(new CrossTrait(hetMotherTrait, 1, false, true)); //carrier females
                        returnArr.Add(new CrossTrait(homMotherTrait, 1, true, false)); //aff males
                        count = 2;
                        return FinishCross(returnArr, count);
                    }
                }
            }
            #endregion
            #region Non_Sex_Linked
            else
            {
                #region Trait_Prep
                trait1 = GetTrait(dbTrt1, p_fatherTrait.IsHeterozygous);
                trait2 = GetTrait(dbTrt2, p_motherTrait.IsHeterozygous);
                #endregion
            }

            //het-het
            if ((trait1.IsHeterozygous ?? false) && (trait2.IsHeterozygous ?? false))
            {
                //we know theyre same trait so we return accordingly
                Trait wildTrait = db.Trait.First(t => t.Name.ToLower() == Constants.Wild.ToLower() && t.CategoryId == trait1.CategoryId);

                Trait homTrait = GetTrait(trait1, false);
                Trait hetTrait = GetTrait(trait1, true);

                returnArr.Add(new CrossTrait(homTrait, .25));
                returnArr.Add(new CrossTrait(hetTrait, .5));
                returnArr.Add(new CrossTrait(wildTrait, .25));
                count = 3;
                return FinishCross(returnArr, count);
            }
            //hom-hom
            if (!(trait1.IsHeterozygous ?? false) && !(trait2.IsHeterozygous ?? false))
            {
                if (trait1.Name.ToLower() == Constants.Wild.ToLower() && trait2.Name.ToLower() == Constants.Wild.ToLower())
                {
                    returnArr.Add(new CrossTrait(trait1, 1));
                    count = 1;
                    return FinishCross(returnArr, count);
                }
                //rec-wild
                else if (!trait1.IsDominant && trait2.Name.ToLower() == Constants.Wild.ToLower())
                {
                    Trait expressed = trait1;
                    expressed.IsHeterozygous = true;

                    returnArr.Add(new CrossTrait(expressed, 1));
                    count = 1;
                    return FinishCross(returnArr, count);
                }
                //wild-rec
                else if (!trait2.IsDominant && trait1.Name.ToLower() == Constants.Wild.ToLower())
                {
                    Trait expressed = trait2;
                    expressed.IsHeterozygous = true;

                    returnArr.Add(new CrossTrait(expressed, 1));
                    count = 1;
                    return FinishCross(returnArr, count);
                }
                //dom-rec*
                else if (trait1.IsDominant)
                {
                    Trait expressed = trait1;
                    expressed.IsHeterozygous = true;

                    returnArr.Add(new CrossTrait(expressed, 1));
                    count = 1;
                    return FinishCross(returnArr, count);
                }
                else if (trait2.IsDominant)
                {
                    Trait expressed = trait2;
                    expressed.IsHeterozygous = true;

                    returnArr.Add(new CrossTrait(expressed, 1));
                    count = 1;
                    return FinishCross(returnArr, count);
                }
            }
            //hom-het
            if ((!(trait1.IsHeterozygous ?? false) && (trait2.IsHeterozygous ?? false)) ||
                (!(trait2.IsHeterozygous ?? false) && (trait1.IsHeterozygous ?? false)))
            {
                Trait homTrait = (trait1.IsHeterozygous ?? false) ? trait2 : trait1;
                Trait hetTrait = (trait1.IsHeterozygous ?? false) ? trait1 : trait2;

                returnArr.Add(new CrossTrait(hetTrait, .5));
                returnArr.Add(new CrossTrait(homTrait, .5));
                count = 2;
                return FinishCross(returnArr, count);
            }
            #endregion

            return new CrossList();
        }
Beispiel #4
0
        /// <summary>
        /// helper method to create a fly from the trait strings javascript sends over
        /// </summary>
        /// <param name="p_module">Module parameter for the new fly</param>
        /// <param name="p_gender">Gender parameter for the new fly</param>
        /// <param name="p_traits">Array of TraitIDs for the new fly</param>
        /// <returns>A new Fly, null if it fails</returns>
        private Fly LogFly(int p_module, UseInstance p_instance, string p_gender, ReducedTraitModel[] p_traits)
        {
            Fly toAdd = new Fly() { Id = 0 };
            try
            {
                toAdd.Gender = db.Gender.First(t => t.GenderName == p_gender);
                toAdd.Module = db.Module.First(t => t.Call_id == p_module);
                toAdd.UseInstance = p_instance;
            }
            catch (Exception e)
            {
                Exception ex = new InvalidOperationException("Something in the configuration of gender or module is wrong. This should be easily fixable through the Admin Dashboard.", e);
                Elmah.ErrorSignal.FromCurrentContext().Raise(ex);
                return null;
            }

            //foreach (ReducedTraitModel cur in p_traits)
            //{
            //    Trait newTrait = GetTrait( db.Trait.Find(cur.Id), cur.IsHeterozygous );
            //    toAdd.Traits.Add(newTrait);
            //    db.Entry(newTrait).State = EntityState.Detached;
            //}

            db.Fly.Add(toAdd);
            try
            {
                db.SaveChanges();
            }
            catch (Exception e)
            {
                Exception ex = new InvalidOperationException("There was an issue storing a fly (Lab/NewFly).", e);
                Elmah.ErrorSignal.FromCurrentContext().Raise(ex);

                return null;
            }

            return toAdd;
        }
Beispiel #5
0
        /// <summary>
        /// Returns an aray of trait possibilites and their spawn percentages.
        /// Bad data/data that does not obey the algorithm will cause hilarious (read: annoying)
        /// bugs. Make sure the user is forced to follow the rules rigidly.
        /// </summary>
        /// <param name="p_fatherTraits">Father's traits</param>
        /// <param name="p_motherTraits">Mother's traits</param>
        /// <returns></returns>
        private CrossList TwoPointCross(ReducedTraitModel[] p_fatherTraits, ReducedTraitModel[] p_motherTraits)
        {
            List<CrossTrait> returnArr = new List<CrossTrait>();
            #region Trait_Prep
            //generate wild, het, hom for each trait & gender
            Trait[] wild = new Trait[2];

            Trait[] father_hets = new Trait[2];
            Trait[] father_homs = new Trait[2];

            Trait[] mother_hets = new Trait[2];
            Trait[] mother_homs = new Trait[2];

            Trait[] father_raw = new Trait[2];
            Trait[] mother_raw = new Trait[2];

            for (int i = 0; i < 2; i++)
            {
                Trait dbTrt1 = db.Trait.Find(p_fatherTraits[i].Id);
                Trait dbTrt2 = db.Trait.Find(p_motherTraits[i].Id);

                wild[i] = db.Trait.FirstOrDefault(t => t.CategoryId == dbTrt1.CategoryId && t.Name.ToLower() == Constants.Wild.ToLower());

                //father modified
                father_hets[i] = GetTrait(dbTrt1, true);
                father_homs[i] = GetTrait(dbTrt1, false);

                //mother modified
                mother_hets[i] = GetTrait(dbTrt2, true);
                mother_homs[i] = GetTrait(dbTrt2, false);

                //raw arrays
                father_raw[i] = GetTrait(dbTrt1, p_fatherTraits[i].IsHeterozygous);
                mother_raw[i] = GetTrait(dbTrt2, p_motherTraits[i].IsHeterozygous);
            }
            #endregion
            #region Distance_Linked
            //check father trait, then mother trait to determine case
            List<Trait> building = new List<Trait>();
            if ((!p_fatherTraits[0].IsHeterozygous && !p_fatherTraits[1].IsHeterozygous) &&
                (!p_motherTraits[0].IsHeterozygous && !p_motherTraits[1].IsHeterozygous))
            {
                //father hom-hom, mother hom-hom
                //one output: het-het
                building.Add((father_hets[0].Name != Constants.Wild) ? father_hets[0] : mother_hets[0]);
                building.Add((father_hets[1].Name != Constants.Wild) ? father_hets[1] : mother_hets[1]);
                returnArr.Add(new CrossTrait(building, 1));
                return FinishCross(returnArr, 1);
            }
            else
            {
                //2 traits must be heterozygous by necessity of the algorithm
                //calculate recombinance rates
                double dist1 = (p_fatherTraits[0].Name != Constants.Wild) ? father_raw[0].Distance : mother_raw[0].Distance;
                double dist2 = (p_fatherTraits[1].Name != Constants.Wild) ? father_raw[1].Distance : mother_raw[1].Distance;
                double recombined_rate   = Math.Abs(dist1 - dist2) / 100;
                double unrecombined_rate = 1 - recombined_rate;
                //build all four possibilities
                building.Add(father_raw[0]);
                building.Add(father_raw[1]); //unrecombined
                returnArr.Add(new CrossTrait(building, unrecombined_rate / 2));
                building = new List<Trait>();
                building.Add(mother_raw[0]);
                building.Add(mother_raw[1]); //unrecombined
                returnArr.Add(new CrossTrait(building, unrecombined_rate / 2));
                building = new List<Trait>();
                building.Add(mother_raw[0]);
                building.Add(father_raw[1]); //recombined
                returnArr.Add(new CrossTrait(building, recombined_rate / 2));
                building = new List<Trait>();
                building.Add(father_raw[0]);
                building.Add(mother_raw[1]); //recombined
                returnArr.Add(new CrossTrait(building, recombined_rate / 2));

                return FinishCross(returnArr, 4);
            }
            #endregion

            //return new CrossList();
        }