示例#1
0
 public CrossTrait(List<Trait> p_traits, double p_rate, bool m = true, bool f = true)
 {
     this.rate = p_rate;
     this.trait = p_traits.ElementAt(0);
     this.dist_traits = p_traits;
     this.male = m;
     this.female = f;
     this.used = 0;
     this.distance_based = true;
 }
示例#2
0
 public CrossTrait(Trait p_trait, double p_rate, bool m = true, bool f = true)
 {
     this.rate = p_rate;
     this.trait = p_trait;
     this.dist_traits = null;
     this.male = m;
     this.female = f;
     this.used = 0;
     this.distance_based = false;
 }
示例#3
0
 public ReducedTraitModel(Trait t) {
     this.Id = t.Id;
     this.ChromosomeNumber = t.ChromosomeNumber;
     this.CategoryId = t.CategoryId;
     this.Distance = t.Distance;
     this.Name = t.Name;
     this.ImagePath = t.ImagePath;
     this.IsHeterozygous = t.IsHeterozygous ?? false;
     this.IsDominant = t.IsDominant;
     this.IsIncompleteDominant = t.IsIncompleteDominant;
     this.IsLethal = t.IsLethal;
 }
示例#4
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();
        }
示例#5
0
 /// <summary>
 /// Build a new trait object from an existing trait
 /// </summary>
 /// <param name="t">Trait to copy</param>
 /// <param name="isHet">Heterozygosity of new trait</param>
 /// <returns></returns>
 private Trait GetTrait(Trait t, bool isHet)
 {
     return new Trait()
         {
             Id = t.Id,
             Category = t.Category,
             CategoryId = t.CategoryId,
             ChromosomeNumber = t.ChromosomeNumber,
             Distance = t.Distance,
             IsDominant = t.IsDominant,
             IsHeterozygous = isHet,
             IsLethal = t.IsLethal,
             Name = t.Name,
             IsIncompleteDominant = t.IsIncompleteDominant,
             ImagePath = t.ImagePath
         };
 }
示例#6
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();
        }
示例#7
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();
        }
示例#8
0
        public ActionResult CreateCat(Category category)
        {
            if (category.Id == 0)
            {
                if (db.Category.Count(t => t.CatName.ToLower().Equals(category.CatName.ToLower())) != 0)
                {
                    return RedirectToAction("Categories");
                }

                db.Category.Add(category);
                //we also need a wild trait for this category
                Trait wild = new Trait() {
                    Id = 0,
                    Category = category,
                    CategoryId = category.Id,
                    ChromosomeNumber = 0,
                    Distance = 200,
                    IsDominant = false,
                    IsIncompleteDominant = false,
                    IsLethal = false,
                    Name = Constants.Wild,
                    ImagePath = Constants.Wild
                };
                db.Trait.Add(wild);
                try
                {
                    db.SaveChanges();
                    return RedirectToAction("Categories");
                }
                catch (Exception e)
                {
                    Exception ex = new InvalidOperationException("There was an issue adding category " + category.CatName + ".", e);
                    Elmah.ErrorSignal.FromCurrentContext().Raise(ex);
                    return View(category);
                }
            }
            else
            {
                if (ModelState.IsValid)
                {
                    db.Entry(category).State = EntityState.Modified;
                    db.SaveChanges();
                    return RedirectToAction("Categories");
                }
            }

            return View(category);
        }
示例#9
0
 public ActionResult Edit(Trait trait)
 {
     try
     {
         //new trait
         if (trait.Id == 0 && trait.Name.ToLower() != Constants.Wild.ToLower())
         {
             if (!trait.IsDominant)
             {
                 trait.IsIncompleteDominant = false;
             }
             db.Trait.Add(trait);
             try
             {
                 db.SaveChanges();
                 return RedirectToAction("Traits");
             }
             catch (Exception e)
             {
                 Elmah.ErrorSignal.FromCurrentContext().Raise(e);
                 ViewBag.CategoryId = new SelectList(db.Category, "Id", "CatName", trait.CategoryId);
                 return View("Create", trait);
             }
         }
         //old trait
         else if (ModelState.IsValid)
         {
             Trait existing = db.Trait.Find(trait.Id);
             if (existing.Name.ToLower() == Constants.Wild.ToLower())
             {
                 //we cant allow anything but imagepath to be changed
                 existing.ImagePath = trait.ImagePath;
             }
             else
             {
                 existing.Name = trait.Name;
                 existing.Category = trait.Category;
                 existing.CategoryId = trait.CategoryId;
                 existing.ChromosomeNumber = trait.ChromosomeNumber;
                 existing.Distance = trait.Distance;
                 existing.Flies = trait.Flies;
                 existing.ImagePath = trait.ImagePath;
                 existing.IsDominant = trait.IsDominant;
                 existing.IsHeterozygous = trait.IsHeterozygous;
                 existing.IsIncompleteDominant = (trait.IsDominant) ? trait.IsIncompleteDominant : false;
                 existing.IsLethal = trait.IsLethal;
             }
             db.Entry(existing).State = EntityState.Modified;
             try
             {
                 db.SaveChanges();
                 return RedirectToAction("Traits");
             }
             catch (Exception e)
             {
                 Elmah.ErrorSignal.FromCurrentContext().Raise(e);
                 return RedirectToAction("InternalError", "Error");
             }
         }
     }
     catch (Exception e)
     {
         Elmah.ErrorSignal.FromCurrentContext().Raise(e);
     }
     //failed trait
     ViewBag.CategoryId = new SelectList(db.Category, "Id", "CatName", trait.CategoryId);
     return View("Create", trait);
 }