#!/usr/bin/perl
#------------------------#
#  PROGRAM:  overlap.pl  #
#------------------------#

# This program detects overlaps in gene set databases


# Author: Xijin Ge
# South Dakota State University
# Xijin.Ge@sdstate.edu
# http://www.bioinformatics.sdstate.edu
# 9/16/2010

# USAGE: perl overlap.pl inputfile
# Output file name: output_inputfile


# INPUT file shuold look like this:
# each line contain one gene set
# Tab-deliminated text file
# first itwo column  GeneSet_name,and title (a sentence). Then the gene IDs follow. 
# GeneSet_name, GeneSet_title, gene IDs
# This is the .gmt format used by MSigDB http://www.broadinstitute.org/gsea/msigdb/index.jsp
# example:
# CMV_IE86_UP     Upregulated by expression of cytomegalovirus  BARD1   BLM     BTG3    CASP3   CCNE1   CDC2    CDT1    CSPG5   DCK
# COCAINE_BRAIN_4WKS_UP   Up-regulated in the nucleus accumbens  AASS    ACTR1A  AKAP8   ANKHD1  APOH    BLK     C17ORF62        C2      CAMK2A
# COCAINE_BRAIN_5D_UP     Up-regulated in the nucleus accumbens  ACTL6B  ACTR2   ADORA1  AP2A1   ATP1B2  BAIAP2  BTRC    CAMK2A  CD47    CORO2B  CTGF

#----Open the file and read out the entire contents of the file and put into array then close the file
if( $#ARGV < 0 ){
  die("Please provide input file name!\n
       USAGE: perl overlap InputFile\n");
}
open(INP, "<$ARGV[0]")  or die("Cannot open file '$ARGV[0]' for reading\n");
@wholefile=<INP>;
close(INP);


$N_lines = @wholefile;
print "Total number of gene sets:",$N_lines,"\n";

# open output file and write header
open(MYFILE,">output_".$ARGV[0]);  
print MYFILE "Set1 \t Description \t Set2 \t Description, \t N_set1 \t N_set2 \t N_common \t N_Union \t Common Genes\n";


# Double loop compairing all possible pairs i,j in the gene set database.
for ($i =0; $i<$N_lines-1;$i++) {
	print $i+1," of ", $N_lines,"\n";
	for ($j=$i+1;$j<$N_lines;$j++) {
           my @raw_genes1 = split ("\t",$wholefile[$i]); # gene set at line i
           my @raw_genes2 = split ("\t",$wholefile[$j]); # gene set at line j

           #--------------clen up gene list i to remove empty ones etc..
           my @genes1 = ();
           my $nc = 0; # skip the first two columns, as this creates problem
           foreach (@raw_genes1) {
           if(length($_)>1  )  {# length of gene symbol has to be at least 2 characters; otherwise ignore.
                if( $nc > 1 ) {
                   $_=~ s/\s//g; # removes space character in the gene name
                }
                push (@genes1,$_);}
                $nc=$nc+1;
           }

           #--------------clen up gene list j to remove empty ones etc..
           my @genes2 = ();
           $nc = 0;
           foreach (@raw_genes2) {
           if(length($_)>1 )  {# length of gene symbol has to be at least 2 characters; otherwise ignore.
                if( $nc> 1) {
                    $_=~ s/\s//g; # removes space character in the gene name
                }
                push (@genes2,$_);}
                $nc = $nc +1;
           }

           #--------------- calculate intersection between two gene sets using harsh tables
           shift @genes1; shift @genes1; shift @genes2; shift @genes2;  # remove the two columns corresponds to name and description
           my %genes1 = map {$_ => 1} @genes1;  #creates two harsh tables
           my %genes2 = map {$_ => 1} @genes2;

	   my @common = grep ($genes1 {$_}, @genes2);  # common elements 
           my @union = (@genes1,@genes2);  # union 
           
           if ($#common gt  0 ) {  # only print if there's overlap
           	print MYFILE $raw_genes1[0],"\t",$raw_genes1[1],"\t",$raw_genes2[0],"\t",$raw_genes2[1],"\t",$#genes1+1,"\t",$#genes2+1,"\t",$#common+1,"\t",$#union,"\t",join(";",@common),"\n";
           }


        }
}
close(MYFILE);
exit;
