/// <summary> /// Read data into the specified SnpCollection from the SnpCollection /// file having the specified filename (which may include a path). /// The specified CancellationToken can be used to abort the read. /// The progress parameter will be updated by this method with a /// value of 0-100 to reflect the percent progress of the read. /// </summary> /// <param name="snps">The SnpCollection to receive the read data.</param> /// <param name="filename">The path and filename of the SnpCollection file.</param> /// <param name="cancel">The CancellationToken that can be used to abort the read.</param> /// <param name="progress">The progress parameter that will be updated to reflect /// the percent progress of the read.</param> public static void Read(SnpCollection snps, string filename, CancellationToken cancel, Progress progress) { if (snps == null) throw new ArgumentNullException("The SnpCollection cannot be null."); if (filename == null) throw new ArgumentNullException("filename cannot be null."); if (String.IsNullOrWhiteSpace(filename)) throw new ArgumentOutOfRangeException("filename cannot be empty."); using (StreamReader reader = new StreamReader(filename)) { long length = 0; if (progress != null) length = reader.BaseStream.Length; string[] columns = new string[6]; string line; while ((line = reader.ReadLine()) != null) { cancel.ThrowIfCancellationRequested(); line.FastSplit(',', columns); byte chr = Convert.ToByte(columns[2]); if (chr == 0) chr = 23; // handles legacy use of 0 for X Snp snp; if ((!String.IsNullOrWhiteSpace(columns[3]) && Char.IsDigit(columns[3][0]))) { // new format snp file snp = new Snp(columns[0], chr, Convert.ToInt32(columns[3]), Convert.ToSingle(columns[4]), columns[1], columns[5]); } else { // old SnpMap format snp file snp = new Snp(columns[0], chr, -1, -1, columns[1], columns[3]); } snps.Add(snp); if (progress != null) progress.Set(reader.BaseStream.Position, length); } } }
/// <summary> /// Create a new SegmentMatch struct with the specified values. /// </summary> /// <param name="startSnp">The Snp that is the start of the segment.</param> /// <param name="endSnp">The Snp that is the end of the segment (inclusive).</param> /// <param name="snpCount">The number of matching Snps within the segment.</param> /// <param name="halvesMatched">The number of halves matched; either 1 for a half /// matching segment, or 2 for a full matching segment.</param> public SegmentMatch(Snp startSnp, Snp endSnp, int snpCount, int phasedSnpCount, int score, PhasedGenome.Phasing.MatchKind matchKind, int halvesMatched) { this.startSnp = startSnp; this.endSnp = endSnp; this.snpCount = snpCount; this.phasedSnpCount = phasedSnpCount; this.score = score; this.matchKind = matchKind; this.halvesMatched = halvesMatched; }
/// <summary> /// Determines whether the specified Snp is equal to this Snp. /// </summary> /// <param name="other">The Snp to compare with this Snp.</param> /// <returns>true if the specified Snp is equal to this Snp; otherwise, false.</returns> public bool Equals(Snp other) { return ((other != null) && (this.Chromosome == other.Chromosome) && (this.Position == other.Position) && (this.Id == other.Id)); }
// FTDNA files are are made available by the Family Tree DNA testing // service to their customers. /// <summary> /// Read data into the specified Genome from an individual's /// FTDNA personal genome file, using the specified filename (which /// may include a path). The specified SnpCollection does not need /// to contain all the SNPs that may be present in the genome file. /// The SnpCollection is used as the source of physical and cM /// positional information. Centimorgan values for SNPs present in /// the genome but not in the SnpCollection are extrapolated. /// The specified CancellationToken can be used to abort the read. /// The progress parameter will be updated by this method with a /// value of 0-100 to reflect the percent progress of the read. /// </summary> /// <param name="genome">The Genome to receive the read data.</param> /// <param name="snps">The SnpCollection containing reference SNP positional data.</param> /// <param name="filename">The path and filename of the FTDNA genome file.</param> /// <param name="cancel">The CancellationToken that can be used to abort the read.</param> /// <param name="progress">The progress parameter that will be updated to reflect /// the percent progress of the read.</param> private void ReadFtdnaGenome(SnpCollection snps, CancellationToken cancel, Progress progress) { using (StreamReader reader = new StreamReader(this.filename)) { long length = 0; if (progress != null) length = reader.BaseStream.Length; string[] columns = new string[4]; string line; bool started = false; while ((line = reader.ReadLine()) != null) { cancel.ThrowIfCancellationRequested(); if ((line.Length > 0) && (line[0] != '#') && (line[0] != '-') && (started || !line.StartsWith("RSID,", StringComparison.Ordinal))) { started = true; line.Replace("\"", "").FastSplit(',', columns); string rsId = columns[0]; Snp snp = snps[rsId]; if (snp == null) { byte chr = Snp.ChromosomeToByte(columns[1]).Value; if (chr > 23) continue; int position = Convert.ToInt32(columns[2]); snp = new Snp(rsId, chr, position, snps.ExtrapolateCentiMorganPosition(chr, position), null, ""); } var alleles = columns[3]; if ((snp.Chromosome == 23) && (alleles.Length == 1)) alleles += alleles; this.genome.Add(snp, Allele.ToAlleles(alleles)); } else if ((line.Length > 0) && (this.genome.Count == 0) && !line.StartsWith("# rsid\t")) { this.comments.Add(line); } if (progress != null) progress.Set(reader.BaseStream.Position, length); } } }
// 23AndMe files are are made available by the 23AndMe DNA testing service to // their customers. /// <summary> /// Read data into the specified Genome from an individual's /// 23AndMe personal genome file, using the specified filename (which /// may include a path). The specified SnpCollection does not need /// to contain all the SNPs that may be present in the genome file. /// The SnpCollection is used as the source of physical and cM /// positional information. Centimorgan values for SNPs present in /// the genome but not in the SnpCollection are extrapolated. /// The specified CancellationToken can be used to abort the read. /// The progress parameter will be updated by this method with a /// value of 0-100 to reflect the percent progress of the read. /// </summary> /// <param name="genome">The Genome to receive the read data.</param> /// <param name="snps">The SnpCollection containing reference SNP positional data.</param> /// <param name="filename">The path and filename of the 23AndMe genome file.</param> /// <param name="cancel">The CancellationToken that can be used to abort the read.</param> /// <param name="progress">The progress parameter that will be updated to reflect /// the percent progress of the read.</param> private void Read23AndMeGenome(SnpCollection snps, CancellationToken cancel, Progress progress) { using (StreamReader reader = new StreamReader(this.filename)) { long length = 0; if (progress != null) length = reader.BaseStream.Length; string line; string[] columns = new string[4]; while ((line = reader.ReadLine()) != null) { cancel.ThrowIfCancellationRequested(); if ((line.Length > 0) && (line[0] != '#') && (line[0] != '-')) { int colCount = line.FastSplit('\t', columns); if (colCount <= 1) throw new ApplicationException("Not 23andMe format."); string rsId = columns[0]; Snp snp = snps[rsId]; if ((snp == null) && (colCount == 4)) { byte chr = Snp.ChromosomeToByte(columns[1]).Value; if (chr <= 23) { int position = Convert.ToInt32(columns[2]); snp = new Snp(rsId, chr, position, snps.ExtrapolateCentiMorganPosition(chr, position), null, ""); } } if (snp != null) { var alleles = columns[colCount - 1]; if ((alleles != null) && (snp.Chromosome == 23) && (alleles.Length == 1)) alleles += alleles; this.genome.Add(snp, Allele.ToAlleles(alleles)); } } else if ((line.Length > 0) && (genome.Count == 0) && !line.StartsWith("# rsid\t")) { this.comments.Add(line); } if (progress != null) progress.Set(reader.BaseStream.Position, length); } } if (this.genome.Count < 700000) { this.genome.GenomeTestType = Genome.GenomeType.MeAnd23v2; } else { this.genome.GenomeTestType = Genome.GenomeType.MeAnd23v3; } }
/// <summary> /// Read data into the specified SnpCollection from the Rutgers SNP /// map file having the specified filename (which may include a path). /// The specified CancellationToken can be used to abort the read. /// The progress parameter will be updated by this method with a /// value of 0-100 to reflect the percent progress of the read. /// </summary> /// </summary> /// <remarks>See http://compgen.rutgers.edu/RutgersMap/AffymetrixIllumina.aspx </remarks> /// <param name="snps">The SnpCollection to receive the read data.</param> /// <param name="filename">The path and filename of the Rutgers SNP map file.</param> /// <param name="cancel">The CancellationToken that can be used to abort the read.</param> /// <param name="progress">The progress parameter that will be updated to reflect /// the percent progress of the read.</param> public static void ReadRutgers(SnpCollection snps, string filename, CancellationToken cancel, Progress progress) { if (snps == null) throw new ArgumentNullException("The SnpCollection cannot be null."); if (filename == null) throw new ArgumentNullException("filename cannot be null."); if (String.IsNullOrWhiteSpace(filename)) throw new ArgumentOutOfRangeException("filename cannot be empty."); using (StreamReader reader = new StreamReader(filename)) { long length = 0; if (progress != null) length = reader.BaseStream.Length; string[] columns = new string[4]; string line; reader.ReadLine(); // skip header while ((line = reader.ReadLine()) != null) { cancel.ThrowIfCancellationRequested(); line.FastSplit(',', columns); byte? chr = Snp.ChromosomeToByte(columns[1]); if (chr.HasValue && (chr.Value >= 1) && (chr.Value <= 23)) { float cM; Snp snp; if (float.TryParse(columns[3], out cM)) { snp = new Snp(columns[0], chr.Value, Convert.ToInt32(columns[2]), cM, null, null); } else { snp = new Snp(columns[0], chr.Value, Convert.ToInt32(columns[2])); } snps.Add(snp); } if (progress != null) progress.Set(reader.BaseStream.Position, length); } } }
/// <summary> /// Determines whether the specified Snp is contained in this Genome. /// </summary> /// <param name="snp">The Snp to find.</param> /// <returns>true if this Genome contains the specified Snp, otherwise false.</returns> public bool ContainsKey(Snp snp) { return this.genotypes.ContainsKey(snp); }
/// <summary> /// Adds the specified byte Alleles value for the specified Snp to this Genome. /// </summary> /// <param name="snp">The Snp being added.</param> /// <param name="alleles">The byte Alleles value to add for the specified Snp.</param> public virtual void Add(Snp snp, byte alleles) { if (snp == null) throw new ArgumentNullException("Snp cannot be null."); this.genotypes.Add(snp, alleles); }
/// <summary> /// Gets the byte Alleles value for the specified Snp. /// </summary> /// <param name="snp">The Snp whose alleles value is desired.</param> /// <returns>The byte Alleles value for the specified Snp.</returns> public byte this[Snp snp] { get { if (snp == null) throw new ArgumentNullException("Snp cannot be null."); return this.genotypes[snp]; } }
/// <summary> /// Create a new SegmentMatch struct with the specified values. /// </summary> /// <param name="startSnp">The Snp that is the start of the segment.</param> /// <param name="endSnp">The Snp that is the end of the segment (inclusive).</param> /// <param name="snpCount">The number of matching Snps within the segment.</param> /// <param name="halvesMatched">The number of halves matched; either 1 for a half /// matching segment, or 2 for a full matching segment.</param> public SegmentMatch(Snp startSnp, Snp endSnp, int snpCount, int hoHoSnpCount, int halvesMatched) { this.startSnp = startSnp; this.endSnp = endSnp; this.snpCount = snpCount; this.hoHoSnpCount = hoHoSnpCount; this.halvesMatched = halvesMatched; }