#!/usr/local/bin/perl

# a program to output the calls of overlapping regions of two GTC CNV segment calls output files including the same individuals

die "Usage: Birdsuite_vs_PennCNV_to_plink.pl <.birdseye_calls file> <.rawcnv file> <overlap size> <output file>\n" 
        unless @ARGV == 4;

$output = "@ARGV[3]";

open OUT , ">$output" or die "Can't open $output: @ARGV[3].txt!\n";

$min_CNV_size = @ARGV[2];

###############################################################################################################################################
########################################## open Birdseye output file and store info in hashes #################################################

open (READ1, "@ARGV[0]") || die "Cannot open @ARGV[0]\n";

# The tab-delimited columns represent: 

# 0 - sample: 	sample number - must be in format: 00001-01.CEL -> family ID (5 nrs) + "-" + person ID (2 nrs)
# 1 - sample_index: 	sample index
# 2 - copy_number: 	copy number
# 3 - chr: 		chromsome
# 4 - start: 		segment start
# 5 - end: 		segment end
# 6 - per_probe_score: per-probe quality score
# 7 - size: 		size
# 8 - num_probes: 	number of loci (CN or SNP probes) in the segment
# 9 - lod_score: 	LOD score of the probability of the segment being the stated copy number versus the copy number of the flanking segments

$nrper_1 = -1;

		while ($line=<READ1>) 
		{
				if ($line =~ "sample")				# skip the header
				{
				next;
				}


		@splitCNline = split (/\s+/  , $line);				# create array 

		@perIDtmp = split (/\./  , @splitCNline[0]);			

		if (@perIDraw_1[$nrper_1] ne @perIDtmp[0])
			{
			$nrper_1++;
			}

		@perIDraw_1[$nrper_1] = @perIDtmp[0];				# store person id
		$chr = @splitCNline[3];						# store chromosome number
		$start = @splitCNline[4];						# store start position
		$end = @splitCNline[5];						# store end position

		$CNV_1{$chr}{$start,"-",$end} = "$chr\t" . "$start\t" . "$end" ;
		$CNVchr_1{$chr}{$start,"-",$end} = $chr;
		$CNVstart_1{$chr}{$start,"-",$end} = $start;
		$CNVend_1{$chr}{$start,"-",$end} = $end;
		$size_1{$chr}{$start,"-",$end} = ($end - $start);
		$numprobes_1{$chr}{$start,"-",$end} = @splitCNline[8];
		$cn_1{@perIDraw_1[$nrper_1]}{$CNV_1{$chr}{$start,"-",$end}} = @splitCNline[2];
		$lod_1{@perIDraw_1[$nrper_1]}{$CNV_1{$chr}{$start,"-",$end}} = @splitCNline[9];
		}

$nrper_1++;
print "$nrper_1\n";

close READ1;

###############################################################################################################################################
########################################## open PennCNV output file and store info in hashes #################################################

open (READ2, "@ARGV[1]") || die "Cannot open @ARGV[1]\n";

# The space-delimited columns represent: 

# 0 - chr & positions: 	"chr1:111111-111122"
# 1 - nr of snps (probes?): "numsnp=17"
# 2 - size: 	   		"length=222,893"
# 3 - cn: 			"state1,cn=0"
# 4 - per_id: 		"00793_01.txt"
# 5 - start snp: 		"startsnp=CN_482242"
# 6 - end snp: 		"endsnp=CN_484324"


$nrper_2 = -1;

		while ($line=<READ2>) 
		{

		@splitCNline = split (/\s+/  , $line);				# create array 

		@chrtmp = split (/\:/  , @splitCNline[0]);
		$chr = substr(@chrtmp[0], 3);					# store chromosome number
		@postmp = split (/\-/  , @chrtmp[1]);
		$start = @postmp[0];							# store start position
		$end = @postmp[1];							# store end position

		@perIDtmp_1 = split (/\./  , @splitCNline[4]);			
		@perIDtmp_2 = split (/\_/  , @perIDtmp_1[0]);			
		$perIDtmp = "@perIDtmp_2[0]" . '-' . "@perIDtmp_2[1]";

		if (@perIDraw_2[$nrper_2] ne $perIDtmp)
			{
			$nrper_2++;
			}

		@perIDraw_2[$nrper_2] = $perIDtmp;							# store full id
		$famID{@perIDraw_2[$nrper_2]} = substr(@perIDraw_2[$nrper_2], 0, 5);		# store family id
		$trappext{@perIDraw_2[$nrper_2]} = substr(@perIDraw_2[$nrper_2], 6, 2);	# store person id	

		$CNV_2{$chr}{$start,"-",$end} = "$chr\t" . "$start\t" . "$end" ;
		$CNVchr_2{$chr}{$start,"-",$end} = $chr;
		$CNVstart_2{$chr}{$start,"-",$end} = $start;
		$CNVend_2{$chr}{$start,"-",$end} = $end;
		$size_2{$chr}{$start,"-",$end} = ($end - $start);
		@numprobes_tmp = split (/\=/  , @splitCNline[1]);
		$numprobes_2{$chr}{$start,"-",$end} = @numprobes_tmp[1];
		@cn_tmp = split (/\=/  , @splitCNline[3]);
		$cn_2{@perIDraw_2[$nrper_2]}{$CNV_2{$chr}{$start,"-",$end}} = @cn_tmp[1];
		}

$nrper_2++;
print "$nrper_2\n";

close READ2;

###################################################
# put all person IDs into 1 hash without duplicates

@perIDraw = (@perIDraw_1,@perIDraw_2);
undef %saw;
@perID = grep(!$saw{$_}++, @perIDraw); 

$nrids=$#perID;
print "$nrids\n";

###################################################

############## get maximum & minimum value subs ##############

sub max {

my (@maxinput) = @_;

	if ($maxinput[0] > $maxinput[1])
	{
	return $maxinput[0];
	}

	if ($maxinput[0] <= $maxinput[1])
	{
	return $maxinput[1];
	}

}

sub min {

my (@mininput) = @_;

	if ($mininput[0] > $mininput[1])
	{
	return $mininput[1];
	}

	if ($mininput[0] <= $mininput[1])
	{
	return $mininput[0];
	}

}

#################################################################

################ identify centromere region sub ################ see: http://www.openbioinformatics.org/penncnv/penncnv_faq.html#centromeric

sub centromere {

my (@centromere) = @_;			# array contains: chr, start, end

$incent = 0;

	if 	(
		(($centromere[0] == 1) && (($centromere[1] >= 121100001) && ($centromere[1] <= 128000000)	)) ||
		(($centromere[0] == 2) && (($centromere[1] >= 91000001) && ($centromere[1] <= 95700000)	)) ||
		(($centromere[0] == 3) && (($centromere[1] >= 89400001) && ($centromere[1] <= 93200000)	)) ||
		(($centromere[0] == 4) && (($centromere[1] >= 48700001) && ($centromere[1] <= 52400000)	)) ||
		(($centromere[0] == 5) && (($centromere[1] >= 45800001) && ($centromere[1] <= 50500000)	)) ||
		(($centromere[0] == 6) && (($centromere[1] >= 58400001) && ($centromere[1] <= 63400000)	)) ||
		(($centromere[0] == 7) && (($centromere[1] >= 57400001) && ($centromere[1] <= 61100000)	)) ||
		(($centromere[0] == 8) && (($centromere[1] >= 43200001) && ($centromere[1] <= 48100000)	)) ||
		(($centromere[0] == 9) && (($centromere[1] >= 46700001) && ($centromere[1] <= 60300000)	)) ||
		(($centromere[0] == 10) && (($centromere[1] >= 38800001) && ($centromere[1] <= 42100000)	)) ||
		(($centromere[0] == 11) && (($centromere[1] >= 51400001) && ($centromere[1] <= 56400000)	)) ||
		(($centromere[0] == 12) && (($centromere[1] >= 33200001) && ($centromere[1] <= 36500000)	)) ||
		(($centromere[0] == 13) && (($centromere[1] >= 13500001) && ($centromere[1] <= 18400000)	)) ||
		(($centromere[0] == 14) && (($centromere[1] >= 13600001) && ($centromere[1] <= 19100000)	)) ||
		(($centromere[0] == 15) && (($centromere[1] >= 14100001) && ($centromere[1] <= 18400000)	)) ||
		(($centromere[0] == 16) && (($centromere[1] >= 34400001) && ($centromere[1] <= 40700000)	)) ||
		(($centromere[0] == 17) && (($centromere[1] >= 22100001) && ($centromere[1] <= 23200000)	)) ||
		(($centromere[0] == 18) && (($centromere[1] >= 15400001) && ($centromere[1] <= 17300000)	)) ||
		(($centromere[0] == 19) && (($centromere[1] >= 26700001) && ($centromere[1] <= 30200000)	)) ||
		(($centromere[0] == 20) && (($centromere[1] >= 25700001) && ($centromere[1] <= 28400000)	)) ||
		(($centromere[0] == 21) && (($centromere[1] >= 10000001) && ($centromere[1] <= 13200000)	)) ||
		(($centromere[0] == 22) && (($centromere[1] >= 9600001) && ($centromere[1] <= 16300000)	)) ||
		(($centromere[0] == 23) && (($centromere[1] >= 56600001) && ($centromere[1] <= 65000000)	)) ||
		(($centromere[0] == 24) && (($centromere[1] >= 11200001) && ($centromere[1] <= 12500000)	)) ||
		(($centromere[0] == 1) && (($centromere[2] >= 121100001) && ($centromere[2] <= 128000000)	)) ||
		(($centromere[0] == 2) && (($centromere[2] >= 91000001) && ($centromere[2] <= 95700000)	)) ||
		(($centromere[0] == 3) && (($centromere[2] >= 89400001) && ($centromere[2] <= 93200000)	)) ||
		(($centromere[0] == 4) && (($centromere[2] >= 48700001) && ($centromere[2] <= 52400000)	)) ||
		(($centromere[0] == 5) && (($centromere[2] >= 45800001) && ($centromere[2] <= 50500000)	)) ||
		(($centromere[0] == 6) && (($centromere[2] >= 58400001) && ($centromere[2] <= 63400000)	)) ||
		(($centromere[0] == 7) && (($centromere[2] >= 57400001) && ($centromere[2] <= 61100000)	)) ||
		(($centromere[0] == 8) && (($centromere[2] >= 43200001) && ($centromere[2] <= 48100000)	)) ||
		(($centromere[0] == 9) && (($centromere[2] >= 46700001) && ($centromere[2] <= 60300000)	)) ||
		(($centromere[0] == 10) && (($centromere[2] >= 38800001) && ($centromere[2] <= 42100000)	)) ||
		(($centromere[0] == 11) && (($centromere[2] >= 51400001) && ($centromere[2] <= 56400000)	)) ||
		(($centromere[0] == 12) && (($centromere[2] >= 33200001) && ($centromere[2] <= 36500000)	)) ||
		(($centromere[0] == 13) && (($centromere[2] >= 13500001) && ($centromere[2] <= 18400000)	)) ||
		(($centromere[0] == 14) && (($centromere[2] >= 13600001) && ($centromere[2] <= 19100000)	)) ||
		(($centromere[0] == 15) && (($centromere[2] >= 14100001) && ($centromere[2] <= 18400000)	)) ||
		(($centromere[0] == 16) && (($centromere[2] >= 34400001) && ($centromere[2] <= 40700000)	)) ||
		(($centromere[0] == 17) && (($centromere[2] >= 22100001) && ($centromere[2] <= 23200000)	)) ||
		(($centromere[0] == 18) && (($centromere[2] >= 15400001) && ($centromere[2] <= 17300000)	)) ||
		(($centromere[0] == 19) && (($centromere[2] >= 26700001) && ($centromere[2] <= 30200000)	)) ||
		(($centromere[0] == 20) && (($centromere[2] >= 25700001) && ($centromere[2] <= 28400000)	)) ||
		(($centromere[0] == 21) && (($centromere[2] >= 10000001) && ($centromere[2] <= 13200000)	)) ||
		(($centromere[0] == 22) && (($centromere[2] >= 9600001) && ($centromere[2] <= 16300000)	)) ||
		(($centromere[0] == 23) && (($centromere[2] >= 56600001) && ($centromere[2] <= 65000000)	)) ||
		(($centromere[0] == 24) && (($centromere[2] >= 11200001) && ($centromere[2] <= 12500000)	)) 
		)
	{
	$incent = 1;
	}

	return $incent;
}

#################################################################


################ print header of the output file ################

	print OUT "FID\t";
	print OUT "IID\t";
	print OUT "CHR\t";
	print OUT "BP1\t";
	print OUT "BP2\t";
	print OUT "TYPE\t";
	print OUT "SCORE\t";
	print OUT "SITES\n";

##################################################################

###############################################################################################################################################
############################################## compare calls and write both calls to output ###################################################

for($c=1;$c<=24;++$c)
	{

$j = $c;
$k = $c;

if ($c == 23) 
{
$k = "X";
}
if ($c == 24) 
{
$k = "Y";
}

		foreach $key1 (sort keys %{$CNV_1{$j}})
		{
			foreach $key2 (sort keys %{$CNV_2{$k}})
			{

				if (($CNVstart_2{$k}{$key2} < $CNVstart_1{$j}{$key1}) && ($CNVend_2{$k}{$key2} < $CNVstart_1{$j}{$key1}))
				{
				next;
				}


				if (($CNVstart_2{$k}{$key2} > $CNVend_1{$j}{$key1}) && ($CNVend_2{$k}{$key2} > $CNVend_1{$j}{$key1}))
				{
				next;
				}

				$max = max($CNVstart_1{$j}{$key1},$CNVstart_2{$k}{$key2});
				$min = min($CNVend_1{$j}{$key1},$CNVend_2{$k}{$key2});

				if (centromere($c, $max, $min) == 1)
				{
				next;
				}

				for($i=0;$i<@perID;++$i)
				{

				if 	(						
						($lod_1{@perID[$i]}{$CNV_1{$j}{$key1}} > 10) &&
						(
						(($CNVstart_1{$j}{$key1} >= $CNVstart_2{$k}{$key2}) && ($CNVstart_1{$j}{$key1} <= $CNVend_2{$k}{$key2})) ||
						(($CNVend_1{$j}{$key1} >= $CNVstart_2{$k}{$key2}) && ($CNVend_1{$j}{$key1} <= $CNVend_2{$k}{$key2})) ||
						(($CNVstart_2{$k}{$key2} >= $CNVstart_1{$j}{$key1}) && ($CNVstart_2{$k}{$key2} <= $CNVend_1{$j}{$key1})) ||
						(($CNVend_2{$k}{$key2} >= $CNVstart_1{$j}{$key1}) && ($CNVend_2{$k}{$key2} <= $CNVend_1{$j}{$key1}))	
						)
					)
					{

					######## set missing copy nrs to -1 ########
	
					if ($cn_1{$perID[$i]}{$CNV_1{$j}{$key1}} eq "")
						{
						$cn_1{$perID[$i]}{$CNV_1{$j}{$key1}} = -1;
						}	

					if ($cn_2{$perID[$i]}{$CNV_2{$k}{$key2}} eq "")
						{
						$cn_2{$perID[$i]}{$CNV_2{$k}{$key2}} = -1;
						}	
					#############################################

					if (($cn_1{$perID[$i]}{$CNV_1{$j}{$key1}} != -1) && ($cn_2{$perID[$i]}{$CNV_2{$k}{$key2}} != -1)) 
						{
						$max = max($CNVstart_1{$j}{$key1},$CNVstart_2{$k}{$key2});
						$min = min($CNVend_1{$j}{$key1},$CNVend_2{$k}{$key2});
						$size = $min - $max;

						if (($size_1{$j}{$key1} + $size_2{$k}{$key2}) == $size)
							{
							$overlap = 1;
							} else {
							$overlap = $size / ($size_1{$j}{$key1} + $size_2{$k}{$key2} - $size);
							}

						if ($cn_1{$perID[$i]}{$CNV_1{$j}{$key1}} == $cn_2{$perID[$i]}{$CNV_2{$k}{$key2}})
						{
						$cn_agreement = 1;
						} else {
						$cn_agreement = 0;
						}
					
						if (($size >= $min_CNV_size) && ($cn_agreement == 1))
							{
							print OUT "$famID{$perID[$i]}\t";
							print OUT "$perID[$i]\t";
							print OUT "$j\t";
							print OUT "$max\t";
							print OUT "$min\t";
							print OUT "$cn_1{$perID[$i]}{$CNV_1{$j}{$key1}}\t";
							print OUT "100\t";
							print OUT "100\n";
							}
						}

					}

				}

			}
		}
	}

for($c=1;$c<=24;++$c)
	{

		foreach $key1 (sort keys %{$CNV_1{$c}})
		{

			for($i=0;$i<@perID;++$i)
				{

				if 	(
					($lod_1{@perID[$i]}{$CNV_1{$c}{$key1}} > 10) &&
					($cn_1{$perID[$i]}{$CNV_1{$c}{$key1}} == 2) &&
					($size_1{$c}{$key1} >= $min_CNV_size)
					)
					{
					print OUT "$famID{$perID[$i]}\t";
					print OUT "$perID[$i]\t";
					print OUT "$c\t";
					print OUT "$CNVstart_1{$c}{$key1}\t";
					print OUT "$CNVend_1{$c}{$key1}\t";
					print OUT "$cn_1{$perID[$i]}{$CNV_1{$c}{$key1}}\t";
					print OUT "100\t";
					print OUT "100\n";
					}

				}
			
		}
	}

print "done\n";