Skip to content

Commit d9d271f

Browse files
authored
Merge pull request #9 from lvclark/VCF_export
Vcf export
2 parents 94e6bce + a1eac6c commit d9d271f

25 files changed

Lines changed: 2026 additions & 726 deletions

DESCRIPTION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
Package: polyRAD
22
Version: 1.2
3-
Date: 2019-11-03
3+
Date: 2020-05-12
44
Title: Genotype Calling with Uncertainty from Sequencing Data in Polyploids and Diploids
55
Authors@R: c(person("Lindsay V.", "Clark", email = "lvclark@illinois.edu",
66
role = c("aut", "cre"),

NAMESPACE

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,9 @@ GetLocDepth, GetLoci, GetProbableGenotypes, GetRecurrentParent,
1616
GetTaxa, GetWeightedMeanGenotypes, HindHe, HindHeMapping,
1717
InbreedingFromHindHe, IterateHWE, IterateHWE_LD,
1818
IteratePopStruct, IteratePopStructLD, LocusInfo, MakeTasselVcfFilter,
19-
MergeRareHaplotypes, MergeTaxaDepth, nTaxa, nAlleles, nLoci,
20-
OneAllelePerMarker,
21-
PipelineMapping2Parents, RADdata, readHMC, readProcessSamMulti,
19+
MergeIdenticalHaplotypes, MergeRareHaplotypes, MergeTaxaDepth, nTaxa, nAlleles,
20+
nLoci, OneAllelePerMarker,
21+
PipelineMapping2Parents, RADdata, RADdata2VCF, readHMC, readProcessSamMulti,
2222
readProcessIsoloci,readStacks, readTagDigger, readTASSELGBSv2,
2323
RemoveHighDepthLoci, RemoveMonomorphicLoci, RemoveUngenotypedLoci,
2424
SetBlankTaxa, SetContamRate, SetDonorParent, SetRecurrentParent,
@@ -28,7 +28,7 @@ TestOverdispersion, VCF2RADdata)
2828
importFrom("stats", "dist", "dmultinom", "pchisq", "lm", "na.omit", "dbinom",
2929
"hclust", "cutree", "as.dist", "cor", "residuals", "lm.fit", "sd",
3030
"median")
31-
importFrom("utils", "read.csv", "write.table", "write.csv")
31+
importFrom("utils", "read.csv", "write.table", "write.csv", "packageVersion")
3232
importFrom("fastmatch", "%fin%")
3333
importFrom("methods", "is")
3434
importFrom("Rcpp", "evalCpp")
@@ -68,6 +68,7 @@ S3method(GetWeightedMeanGenotypes, RADdata)
6868
S3method(HindHe, RADdata)
6969
S3method(HindHeMapping, RADdata)
7070
S3method(LocusInfo, RADdata)
71+
S3method(MergeIdenticalHaplotypes, RADdata)
7172
S3method(MergeRareHaplotypes, RADdata)
7273
S3method(MergeTaxaDepth, RADdata)
7374
S3method(nAlleles, RADdata)

NEWS

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ Duplicated Genomes" (isolocus_sorting.Rmd). The functions readProcessSamMulti
1313
and readProcessIsoloci have been added for import of data from the Python
1414
scripts into polyRAD.
1515

16+
The function RADdata2VCF has been added for export to VCF.
17+
1618
A Python script has been added to help identify full tag sequences for alleles
1719
imported from TASSEL-GBSv2 using VCF2RADdata.
1820

@@ -42,6 +44,8 @@ impact anything frin the user's perspective, but makes the code slightly
4244
less unweildy and allows parental genotype estimations to be used for other
4345
purposes.
4446

47+
The MergeIdenticalHaplotypes function has been added.
48+
4549
Internal functions for simulating gametes and calculating their frequencies have
4650
been corrected so that they still work when only one allele is being simulated.
4751

R/RcppExports.R

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,22 @@ InitHapAssign <- function(NMmat) {
3737
.Call('_polyRAD_InitHapAssign', PACKAGE = 'polyRAD', NMmat)
3838
}
3939

40+
Hap2SNP <- function(haps, refhap, pos) {
41+
.Call('_polyRAD_Hap2SNP', PACKAGE = 'polyRAD', haps, refhap, pos)
42+
}
43+
44+
Hap2Hap <- function(haps, refhap, pos) {
45+
.Call('_polyRAD_Hap2Hap', PACKAGE = 'polyRAD', haps, refhap, pos)
46+
}
47+
48+
MakeGTstrings <- function(genotypes, ploidy) {
49+
.Call('_polyRAD_MakeGTstrings', PACKAGE = 'polyRAD', genotypes, ploidy)
50+
}
51+
52+
PrepVCFexport <- function(genotypes, alleles2loc, alleleDepth, alleleNucleotides, locTable, ploidy, asSNPs) {
53+
.Call('_polyRAD_PrepVCFexport', PACKAGE = 'polyRAD', genotypes, alleles2loc, alleleDepth, alleleNucleotides, locTable, ploidy, asSNPs)
54+
}
55+
4056
ThirdDimProd <- function(probs, ngen, ntaxa) {
4157
.Call('_polyRAD_ThirdDimProd', PACKAGE = 'polyRAD', probs, ngen, ntaxa)
4258
}

R/classes_methods.R

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2274,3 +2274,41 @@ RemoveUngenotypedLoci.RADdata <- function(object, removeNonvariant = TRUE,
22742274

22752275
return(object)
22762276
}
2277+
2278+
# Function to merge alleles with identical nucleotides, generally because
2279+
# one tag was truncated with respect to the variable region.
2280+
MergeIdenticalHaplotypes <- function(object, ...){
2281+
UseMethod("MergeIdenticalHaplotypes", object)
2282+
}
2283+
MergeIdenticalHaplotypes.RADdata <- function(object, ...){
2284+
if(!is.null(object$alleleFreq) || !is.null(object$depthSamplingPermutations)){
2285+
stop("Run MergeIdenticalHaplotypes before running any pipeline functions.")
2286+
}
2287+
2288+
remal <- integer(0) # indices of alleles to remove
2289+
for(L in 1:nLoci(object)){
2290+
thesecol <- which(object$alleles2loc == L)
2291+
dup <- duplicated(object$alleleNucleotides[thesecol])
2292+
for(al in thesecol[dup]){
2293+
# find allele to merge this one into
2294+
alM <- min(thesecol[object$alleleNucleotides[thesecol] ==
2295+
object$alleleNucleotides[al]])
2296+
stopifnot(al != alM)
2297+
# consolidate read depth
2298+
object$alleleDepth[,alM] <- object$alleleDepth[,alM] +
2299+
object$alleleDepth[,al]
2300+
object$antiAlleleDepth[,alM] <- object$antiAlleleDepth[,alM] -
2301+
object$alleleDepth[,al]
2302+
}
2303+
remal <- c(remal, thesecol[dup])
2304+
}
2305+
2306+
# remove duplicated alleles from all slots
2307+
object$alleleDepth <- object$alleleDepth[,-remal]
2308+
object$antiAlleleDepth <- object$antiAlleleDepth[,-remal]
2309+
object$alleles2loc <- object$alleles2loc[-remal]
2310+
object$alleleNucleotides <- object$alleleNucleotides[-remal]
2311+
object$depthRatio <- object$depthRatio[,-remal]
2312+
2313+
return(object)
2314+
}

R/data_export.R

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -315,3 +315,107 @@ Export_GWASpoly <- function(object, file, naIfZeroReads = TRUE){
315315
# export
316316
write.csv(outdata, file = file, row.names = FALSE, quote = FALSE)
317317
}
318+
319+
RADdata2VCF <- function(object, file = NULL, asSNPs = TRUE, hindhe = TRUE,
320+
sampleinfo = data.frame(row.names = GetTaxa(object)),
321+
contigs = data.frame(row.names = unique(object$locTable$Chr))){
322+
# shortcuts to functions to use
323+
DataFrame <- S4Vectors::DataFrame
324+
325+
varok <- attr(object$alleleNucleotides, "Variable_sites_only")
326+
if(is.null(varok) || varok){
327+
stop("Complete haplotype information not provided; unable to determine SNP positions. Use refgenome argument in VCF2RADdata.")
328+
}
329+
if(is.null(object$locTable$Chr) || is.null(object$locTable$Pos)){
330+
stop("Need chromosome and position information (Chr and Pos in locTable).")
331+
}
332+
if(is.null(object$locTable$Ref)){
333+
warning("Reference allele not indicated. Using the major allele for each locus.")
334+
object$locTable$Ref <- object$alleleNucleotides[OneAllelePerMarker(object, commonAllele = TRUE)]
335+
}
336+
if(nrow(sampleinfo) != nTaxa(object) || !all(rownames(sampleinfo) %in% GetTaxa(object))){
337+
"sampleinfo doesn't match taxa in RADdata object."
338+
}
339+
340+
# Determine most probable genotypes, and their ploidies
341+
temp <- GetProbableGenotypes(object, omit1allelePerLocus = FALSE)
342+
geno <- temp$genotypes
343+
pld_index <- temp$ploidy_index
344+
pld_ind_per_loc <-
345+
tapply(pld_index, object$alleles2loc,
346+
function(x){
347+
u <- unique(x)
348+
if(length(u) == 1){
349+
return(u)
350+
} else {
351+
return(as.integer(names(which.max(table(x)))))
352+
}
353+
})
354+
pld_per_loc <- sapply(object$priorProbPloidies, sum)[pld_ind_per_loc]
355+
356+
# Process data with internal RCpp function
357+
temp <- PrepVCFexport(geno, object$alleles2loc, object$alleleDepth,
358+
object$alleleNucleotides, object$locTable, pld_per_loc,
359+
asSNPs)
360+
REF <- Biostrings::DNAStringSet(temp$REF)
361+
ALT <- Biostrings::DNAStringSetList(temp$ALT)
362+
CHROM <- as.character(object$locTable$Chr)[temp$Lookup]
363+
rr <- GenomicRanges::GRanges(CHROM,
364+
IRanges::IRanges(start = temp$POS,
365+
width = BiocGenerics::width(REF)))
366+
fixed <- DataFrame(REF = REF, ALT = ALT)
367+
cd <- DataFrame(row.names = GetTaxa(object))
368+
if(ncol(sampleinfo) > 0){
369+
cd <- cbind(cd, sampleinfo[GetTaxa(object),])
370+
colnames(cd) <- colnames(sampleinfo)
371+
}
372+
DP <- t(object$locDepth[,as.character(temp$Lookup)])
373+
rownames(DP) <- NULL
374+
info <- DataFrame(NS = rowSums(DP > 0), DP = rowSums(DP), LU = temp$Lookup)
375+
infohdr <- DataFrame(row.names = c("NS", "DP", "LU"), Number = c("1", "1", "1"),
376+
Type = c("Integer", "Integer", "Integer"),
377+
Description = c("Number of samples with data", "Combined depth across samples",
378+
"Lookup index of marker in RADdata object"))
379+
metahdr <- DataFrame()
380+
if(ncol(contigs) > 0){
381+
ctg <- DataFrame(row.names = rownames(contigs), contigs)
382+
colnames(ctg) <- colnames(contigs)
383+
} else {
384+
ctg <- DataFrame(row.names = rownames(contigs))
385+
}
386+
387+
# Add Hind/He if desired
388+
if(hindhe){
389+
infohdr <- rbind(infohdr,
390+
DataFrame(row.names = "HH", Number = "1", Type = "Float",
391+
Description = "Hind/He for the locus in the RADdata object"))
392+
metahdr <- DataFrame(row.names = "HH", Number = "1", Type = "Float",
393+
Description = "Hind/He for the sample, averaged across loci in the RADdata object")
394+
hh <- HindHe(object)
395+
info$HH <- colMeans(hh, na.rm = TRUE)[temp$Lookup]
396+
cd$HH <- rowMeans(hh, na.rm = TRUE)
397+
}
398+
399+
# Build VCF object
400+
hdr <- VariantAnnotation::VCFHeader(reference = rownames(ctg),
401+
samples = GetTaxa(object),
402+
IRanges::DataFrameList(fileformat = DataFrame(row.names = "fileformat", Value = "VCFv4.3"),
403+
fileDate = DataFrame(row.names = "fileDate", Value = gsub("-", "", Sys.Date())),
404+
source = DataFrame(row.names = "source", Value = paste0("polyRADv", packageVersion("polyRAD"))),
405+
FORMAT = DataFrame(row.names = c("GT", "AD", "DP"),
406+
Number = c("1", "R", "1"), Type = c("String", "Integer", "Integer"),
407+
Description = c("Genotype", "Read depth for each allele", "Read depth")),
408+
INFO = infohdr, META = metahdr, contig = ctg))
409+
if(ncol(cd) > 0){
410+
VariantAnnotation::meta(hdr)$SAMPLE <- cd
411+
}
412+
vcf <- VariantAnnotation::VCF(rowRanges = rr, fixed = fixed, info = info, colData = cd,
413+
geno = S4Vectors::SimpleList(GT = temp$GT, AD = temp$AD, DP = DP),
414+
exptData = list(header = hdr), collapsed = TRUE)
415+
416+
# output
417+
if(!is.null(file)){
418+
VariantAnnotation::writeVcf(vcf, file)
419+
}
420+
return(vcf)
421+
}

0 commit comments

Comments
 (0)