# R script to process Data set 2 with PolyHaplotyper, SATlotyper and Happy-inf 
 
rm(list=ls()) # clear existing data from memory  

# If the PolyHaplotyper package was not yet installed this must be done first.
# This is straightforward as it is available on CRAN:
install.packages("PolyHaplotyper")

# We assume that the working directory contains file Dataset2_sim-9_FS_families.RData
load("Dataset2_sim_9_FS_families.RData")



# PolyHaplotyper ###############################################################
 
library(PolyHaplotyper)

# For this demo we include a list which contains all haplotype
# combinations that match the SNP dosage combinations that occur in Data set 2.
# This list must first be saved to a file:
save(ahclist, file="ahclist_4x.RData")
# (normally we would use a precalculated list with all haplotype combinations 
# matching all possible SNP dosage combinations, but that would make Data set 2 
# much larger) 
# 
# Perform the haplotyping, and time it:
timestr <- format(Sys.time(), format="%Y%m%d-%H%M%S")  
pt <- proc.time()
PHresults <- 
  inferHaplotypes(mrkDosage=snpdos, ploidy=4, 
                  haploblock=hb_list, 
                  parents=parents, FS=FS,
                  printtimes=TRUE) 
print(proc.time() - pt)

# compare the haplotyping results to the true haplotype dosages:
PHcomplist <- compareHapresults(haploblock=hb_list, hapresultsA=haplist, 
                                hapresultsB=PHresults)
PHamw <- sapply(PHcomplist, 
                FUN=function(x) c(all=ncol(x$compIndiv),
                                  missing=sum(is.na(x$compIndiv[5,])),
                                  wrong=sum(x$compIndiv[5,], na.rm=TRUE)))
print(t(PHamw))
print(colSums(t(PHamw)))
# check for conflicts between inferred haplotypes and observed marker dosages
cmpdos <- compareHapMrkDosages(mrkDosage=snpdos, hapresults=PHresults)
print(table(cmpdos[,,"match"], useNA="always")) 
#FALSE=conflict, TRUE=match, NA=no marker or haplotyping data

# Save results:
save(PHresults, PHcomplist, PHamw,
     file=paste0("PHresults_", timestr, ".RData"))



# SATlotyper ###################################################################

# Version used was downloaded on 20 January 2020 from
# http://www.gabipd.org/projects/satlotyper/
# Installation: extract contents of downloaded file SATlotyper_v0.1.5.zip 
# to some directory.
# 
# SATlotyper can be run from R using a function in PolyHaplotyper; 
# for this the path to the SATlotyper.jar file is needed.
# modify SATpath to the directory where SATlotyper.jar resides:
SATpath <- "" 
# e.g. SATpath <- "d:/Data/Haplotyping software/SATlotyper/SATlotyper_v0.1.5" 

# also we assume that PolyHaplotyper is available and 
# Dataset2_sim-9_FS_families.RData has been loaded
# 
# We convert data to SATlotyper format, run SATlotyper, and convert the
# results to PolyHaplotyper format in three separate steps, to allow
# timing of the SATlotyper execution itself.

# Create SATlotyper input files using a function in PolyHaplotyper:
for (hb in names(hb_list)) {
  fname <- paste0("SAT_", hb, ".dat")
  SATdat <- 
    make.SATlotyper.input(mrkDosage=snpdos, 
                          markers=hb_list[[hb]], 
                          ploidy=4, 
                          fname=fname)
}

# Perform the haplotyping (using a function in PolyHaplotyper), and time it:
timestr <- format(Sys.time(), format="%Y%m%d-%H%M%S")  
pt <- proc.time()
SAToutput <- list()
for (hb in names(hb_list)) {
  infile <- paste0("SAT_", hb, ".dat")
  outfile <- paste0("SAT_", hb, "_", timestr, "_result.xml")
  SAToutput[[hb]] <- run.SATlotyper(path_to_SATlotyper=SATpath,
                                    infile=infile, 
                                    outfile=outfile)
}
print(proc.time() - pt)
# note that the elapsed time is much larger than the user time;
# this is because the SATlotyper processing is done outside R

# Convert the SATlotyper results to PolyHaplotyper format:
# (using a function in PolyHaplotyper)
SATresults <- list()
for (hb in names(hb_list)) {
  SATresults[[hb]] <- 
    read.SATlotyper.output(fname=paste0("SAT_", hb, "_", timestr, "_result.xml"), 
                           output=SAToutput[[hb]],
                           allelecodes=c("A", "B"), 
                           sep="\t", haploblockname=hb)
}

# compare the haplotyping results to the true haplotype dosages:
SATcomplist <- compareHapresults(haploblock=hb_list, hapresultsA=haplist, 
                                 hapresultsB=SATresults)
SATamw <- sapply(SATcomplist, 
                 FUN=function(x) c(all=ncol(x$compIndiv),
                                   missing=sum(is.na(x$compIndiv[5,])),
                                   wrong=sum(x$compIndiv[5,], na.rm=TRUE)))
print(t(SATamw))
print(colSums(t(SATamw)))
# check for conflicts between inferred haplotypes and observed marker dosages
cmpdos <- compareHapMrkDosages(mrkDosage=snpdos, hapresults=SATresults)
print(table(cmpdos[,,"match"], useNA="always")) 
#FALSE=conflict, TRUE=match, NA=no marker or haplotyping data

# Save results:
save(SAToutput, SATresults, SATcomplist, SATamw,
     file=paste0("SATresults_", timestr, ".RData"))



# Happy-inf ####################################################################

# We assume that PolyHaplotyper is available and 
# Dataset2_sim-population.RData has been loaded

# Create Happy-inf input files using a function in PolyHaplotyper:
make.Happyinf.input(mrkDosage=snpdos, haploblock=hb_list, ploidy=4,
                    fname="Happyinf.dat")

# Happy-inf Version V1 was downloaded on 14 September 2020 from
# https://git.wageningenur.nl/wille094/Happy-haplotype-inference/-/tree/master/V1
# copy happy-inf.py to some directory
# Installation (under Windows10) according to Readme.md, using python 2.7: 
# - Open an Anaconda Powershell Prompt window and enter the following commands: 
# > conda create -n happy-inf python=2.7.* 
# > conda activate happy-inf
# > pip install scipy numpy 
#
# Run Happy-inf; in the following,
# - replace <wd> by the working directory where you just created Happyinf.dat
# - replace <HAPpath> by the path to the directory where haplotyper.py resides
# - the "double quotes" are needed if the paths contain spaces
# > cd "<wd>"
# > conda activate happy-inf
# > python "<HAPpath>/happy-inf.py" -i Happyinf.dat -ploidy 4 -join -o HappyOut -joining_steps 100
# 
# Happy-inf prints its own timing data

# Rename the Happy-inf files with a unique name,
# so new runs won't overwrite them:
timestr <- format(Sys.time(), format="%Y%m%d-%H%M%S")  
file.rename(from=paste0("HappyOut.", c("blk", "freq", "haplotypes", "stat"), ".dat"),
            to=paste0("HappyOut_", timestr, ".", 
                      c("blk", "freq", "haplotypes", "stat"), ".dat"))

# Convert the Happy-inf results to PolyHaplotyper format:
# (using a function in PolyHaplotyper)
HAPresults <- read.Happyinf.output(file_prefix=paste0("HappyOut_", timestr))

# compare the haplotyping results to the true haplotype dosages:
HAPcomplist <- compareHapresults(haploblock=hb_list, hapresultsA=haplist, 
                                 hapresultsB=HAPresults)
HAPamw <- sapply(HAPcomplist, 
                 FUN=function(x) c(all=ncol(x$compIndiv),
                                   missing=sum(is.na(x$compIndiv[5,])),
                                   wrong=sum(x$compIndiv[5,], na.rm=TRUE)))
print(t(HAPamw))
print(colSums(t(HAPamw)))
# check for conflicts between inferred haplotypes and observed marker dosages
cmpdos <- compareHapMrkDosages(mrkDosage=snpdos, hapresults=HAPresults)
print(table(cmpdos[,,"match"], useNA="always")) 
#FALSE=conflict, TRUE=match, NA=no marker or haplotyping data

# Save results:
save(HAPresults, HAPcomplist, HAPamw, 
     file=paste0("HAPresults_", timestr, ".RData"))
