###############################################################################
# Name: min li
# Group:Clough Lab
# Date: 5/13/2005
# usage: this program is to convert gpr file from genepix to input (for R maanova analysis)
#         it extract F635 median and F532 median from each gpr file, also flag information
#         output file is a .txt file, the program will take the gpr files and change to Raw data--->calculate the median of X13988-->change Flags to CY3=cy5=x13988 median.
#          this program remove the blank and empty spots.
#	  flag_data.txt doesn't contain blank and empty spots flag information.
#        I add a line to remove the directory name.(100405)
#        I added a demo file format for choice 6(100505).
#        had an error about removeing the directory name.  because I remove the directory name and also change the array of gprfiles. now I use a var onlygprfile to do temp work.(101205)
# Executable format: Perl merge_imputeblank1.pl
###############################################################################

# check the file number make sure no other files in the command line.
if($ARGV[0])
{
  instruction();
  die("\n!!!!!WARNING: you shouldn't have any parameter after the program name!!!!!\n");
}

@gprfiles; #define the gpr file array for latter process.
@allfilecutoff;
#############
###########################";
while(1)
{
    print "Please type the file directory full path: \n\n";
    $filedirectory=<STDIN>;
    chomp $filedirectory;
    $filedirectory=~s/\s*$//;
    $filedirectory=~s/^\s*//;
    print "the file directory is $filedirectory\n\n";
    if($filedirectory=~m/\//)
    {
	print "\n\nThe file directory shouldn't have any slash, use backslash(\\)\n";

    }
    else
    {
	last;
    }
}
opendir(FILEDIRHANDLE, $filedirectory)|| die("Can't open $filedirectory\n");
print "Reminder: Please add index number in the beginning for each file name from 001 to 999\n, based on the array order\n";

while(1)
{
    print "Have you sorted your files yet? Type(Y/N): ";
    $answer=<STDIN>;
    chomp $answer;
    $answer=~s/\s*$//;
    $answer=~s/^\s*//;
    $answer=lc($answer);
    ###############print "the answer is $answer\n";
    if($answer eq "n")
    {
	die("add index number in the beginning for each files\n");
    }
    if($answer eq "y")
    {
	last;
    }
}

foreach $singlefile (sort readdir(FILEDIRHANDLE))
{
    if($singlefile=~m/\.gpr$/)
    {
	    push @gprfiles, $singlefile;
    }
print "found: file: $singlefile\n";
}
@gprfiles=sort(@gprfiles);


print join("\n", @gprfiles );

###########################
#############

##########################################
############
while(1)
{
    print "\n\nPlease Enter the File Name which you are going to use for \n";
    print "R_MAANOVA input File(Extension is .txt)\n\n";
    $outfile=<STDIN>;
#check the output file formatf
    if($outfile=~m/.+\.txt$/)
    {
             last;
    }
}
##########################################
###############

##########################################
###############
 @filehandlers;
  ###open every gpr file for reading and ###check the consistance of the gpr version
  @genepixversionarray;
 ForEach: foreach $file (@gprfiles)
 {
         $file=~m/(.+)\.gpr/;
	 $file=$filedirectory."\\".$file;
         $filehandler=$1;
         push (@filehandlers, $filehandler);
         open $filehandler, $file or die "can't open $file for read\n";

         while($line=<$filehandler>)
         {
                 if($line=~m/Creator/)
                {
                        ($creator, $genepixversion)=split(/=/, $line);
                        $genepixversion=~s/\s*$//;
						$genepixversion=~s/^\s*//;
						$genepixversion=~m/(\d)/;
						push @rawversion, $1;
                        push @genepixversionarray, $genepixversion;
                        next ForEach;
                }
         }
}
print "\n*****************************\n";
print "the format you are using is: \n";
$fileindex=0;
foreach $genepixversion (@genepixversionarray)
{
    $fileindex++;
    print "File $fileindex: $genepixversion\n";
}
#print join("\n", @genepixversionarray), "\n";
print "****************************\n\n";

################
#################################################
$standard=$rawversion[0];
foreach $version (@rawversion)
{
        if($version ne $standard)
        {
                print "\n********************************************************\n";
                print "The GPR files Format is not consistant, please check\n";
                print "********************************************************\n\n";
                die;
        }
}
####menu for Slide Type number
while(1)
{
	print "\n***********************************************************\n\n";
	print "    Which Soybean cDNA Slide did you used:               \n\n";
	print "           1. Soybean_18KA   2. Soybean_18KB             \n\n";
	print "           3. Soybean_1088   4. Soybean_1070             \n\n";
	print "           5. Soybean_1021/1083   6. Soybean_18kA_Demo   \n\n";
	print "           7. Exit                                       \n\n";
	print "***********************************************************\n\n";
	print "Please type the slide type number: ";
	$slidetype=<stdin>;
	#print "slidetype is $slidetype\n";
	chomp $slidetype; #this will chomp the newline key.
	if(length($slidetype)==1 and $slidetype=~m/[1-6]/)
	{
		last;
	}
}
######open the format file based on the user input.
if($slidetype==1)
{
	open FILEHANDLE, "18ka_format.txt" or die "can't open 18ka_format.txt for read\n";
}
elsif($slidetype==2)
{
	open FILEHANDLE, "18kb_format.txt" or die "can't open 18kb_format.txt for read\n";
}
elsif($slidetype==3)
{
	open FILEHANDLE, "1088_format.txt" or die "can't open 1088_format.txt for read\n";
}
elsif($slidetype==4)
{
	open FILEHANDLE, "1070_format.txt" or die "can't open 1070_format.txt for read\n";
}
elsif($slidetype==5)
{
	open FILEHANDLE, "1021_1083_format.txt" or die "can't open 1021_1083_format.txt for read\n";
}#end of format file openning.
elsif($slidetype==6)
{
	open FILEHANDLE, "18ka_format_demo.txt" or die "can't open 18ka_format_demo.txt for read\n";
}
else
{
    die("\nYou selected the EXIT\n");
}
####menu for Cy3/Cy5 order
while(1)
{
	print "\n***********************************************************\n\n";
	print "            Type Order Numbers of Cy3 and Cy5:           \n\n";
	print "                  1. Cy3 Cy5          \n\n";
	print "                  2. Cy5 Cy3          \n\n";
	print "                  3. EXIT             \n\n";
	print "***********************************************************\n\n";
	print "Please type the order number: ";
	$order=<stdin>;
	chomp $order; #this will chomp the newline key.
	if(length($order)==1 and $order=~m/[1-3]/)
	{
		last;
	}
}#end of menu for Cy3/cy5 order.
if($order==3)
{
    die("\nYou selected the EXIT\n");
}
####################################################menu for control spot
$controlgene;
$arbitraryvalue;
while(1)
{
	print "\n***********************************************************\n\n";
	print "                  Cutoff Control Options:           \n\n";
	print "                  1. X13988          \n\n";
	print "                  2. Other GeneID          \n\n";
	print "                  3. Arbitrary Value(ex:300)             \n\n";
	print "***********************************************************\n\n";
	print "Please type a option index: ";
	$cutoffoption=<stdin>;
	chomp $cutoffoption; #this will chomp the newline key.
	$cutoffoption=removebothendspace($cutoffoption);
	if(length($cutoffoption)==1 and $cutoffoption=~m/[1-3]/)
	{
		last;
	}
}
if($cutoffoption==1)
{
	$arbitraryvalue=0;
	$controlgene="X13988";
}
if($cutoffoption==2)
{
	$arbitraryvalue=0;
	while(1)
	{
		print "***********************************************************\n\n";
		print "Please type a GenBankID for your cutoff control gene: \n";
		$controlgene=<stdin>;
		chomp $controlgene; #this will chomp the newline key.
		$controlgene=removebothendspace($controlgene);
		if(length($controlgene)>11)
		{
			print "none of genbankID is that long\n";
		}
		if(!($controlgene=~m/^\D/))
		{
			print "non-digital character shouldn't be typed\n";
		}
		if($controlgene=~m/.+\s+.+$/)
		{
			print "None of genbankID contains space\n";
		}
	}
}
if($cutoffoption==3)
{
	$controlgene="";
	while(1)
	{
		print "***********************************************************\n\n";
		print "Please type an Arbitrary Value(ex:300): \n";
		$arbitraryvalue=<stdin>;
		chomp $arbitraryvalue; #this will chomp the newline key.
		$arbitraryvalue=removebothendspace($arbitraryvalue);
		if(length($cutoffoption)==1 and $cutoffoption=~m/[1-3]/)
		{
			last;
		}
		if($arbitraryvalue=~m/\D/)
		{
			print "non-digital character shouldn't be typed\n";
		}
	}
}

###################################################end of menu for control spot
##################################menu for replicate number
$replicates;
while(1)
{
	print "\n***********************************************************\n\n";
	print " Type Experiment Replicate Numbers:           \n\n";
	print "***********************************************************\n\n";
	print "Please type a replicate number: ";
	$replicates=<stdin>;
	chomp $replicates; #this will chomp the newline key.
	if(length($replicates)==1 and $replicates=~m/[1-9]/)
	{
		last;
	}
}
if($replicates=~m/\D/)
{
	print "Please check your input\n";
}
elsif(length($replicates)>=2)
{
    print "Please check your input, Replicate number is assumed to be less than 10\n ";
}
##############################################
 ###open output file for writing.
open OUTFILE, ">rawdata_beforeBackgroundcorrection.txt" or die "Cannot open rawdata_beforeBackgroundcorrection.txt for write\n";

@allusefulcolumn;          #this will hold the all column number of F635, F532 and flags for each file.
@stringforinputfile;

Point_File: for($i = 0; $i < ($#gprfiles+1);  $i++)
{
	$filehandler=$filehandlers[$i];
	while($line=<$filehandler>)
	{
		if($line=~m/Block/)#this is a indicator for the data column name.
		{
			@columns=split (/\t/, $line) ;
			$indexnum=0;
			foreach $item (@columns)
			{
				$item=removebothendspace($item);
				if($item=~m/F635 Median/ and !($item=~m/[Bb]/))
				{
					push @stringforinputfile, $item;
					push @allusefulcolumn, $indexnum;
				}
				if($item=~m/F532 Median/ and !($item=~m/[Bb]/))
				{
					push @stringforinputfile, $item;
					push @allusefulcolumn, $indexnum;
				}
				if($item=~m/lag/)
				{
					push @stringforinputfile, $item;
					push @allusefulcolumn, $indexnum;
				}
				$indexnum++;
			}
				next Point_File;
		}
	}
}

	#print join(",", @allusefulcolumn);

	#base on the cy3cy5 order, do the column name arrangement. note: default is Cy5Cy3, so we only do once for cy3cy5.
	#and in the mean time add file name for every column name so make clear where they are from.
if($order==1) #cy3cy5 and then change the order of F635 and F532. keep flag same order.
{
	for($i=0; $i<$#gprfiles+1; $i++)
	{
		$firstcolumnofeveryfile=$i*3;
		#############if you don't need the directory name, do the following.
		    $gprfiles[$i]=~ m/(.*\\)(.*)$/;
			$onlygprfile=$2;
		 ###########################################
		$stringforinputfile[$firstcolumnofeveryfile]=$stringforinputfile[$firstcolumnofeveryfile]."($onlygprfile)";
		$stringforinputfile[$firstcolumnofeveryfile+1]=$stringforinputfile[$firstcolumnofeveryfile+1]."($onlygprfile)";
		$stringforinputfile[$firstcolumnofeveryfile+2]=$stringforinputfile[$firstcolumnofeveryfile+2]."($onlygprfile)";
		$temp=$stringforinputfile[$firstcolumnofeveryfile];
		$stringforinputfile[$firstcolumnofeveryfile]=$stringforinputfile[$firstcolumnofeveryfile+1];
		$stringforinputfile[$firstcolumnofeveryfile+1]=$temp;
	}
}
else
{
		for($i=0; $i<$#gprfiles+1; $i++)
	{
	    #############if you don't need the directory name, do the following.
		    $gprfiles[$i]=~ m/(.*\\)(.*)$/;
			$onlygprfile=$2;
		 ###########################################
		$firstcolumnofeveryfile=$i*3;
		$stringforinputfile[$firstcolumnofeveryfile]=$stringforinputfile[$firstcolumnofeveryfile]."($onlygprfile)";
		$stringforinputfile[$firstcolumnofeveryfile+1]=$stringforinputfile[$firstcolumnofeveryfile+1]."($onlygprfile)";
		$stringforinputfile[$firstcolumnofeveryfile+2]=$stringforinputfile[$firstcolumnofeveryfile+2]."($onlygprfile)";
	}
}
#before writing to the input file, open the format file and read the first line and combine it with @stringforinputfile
$firstline=<FILEHANDLE>; ####this is from 18ka or 18kb format file reading.
chomp $firstline;
print OUTFILE $firstline, "\t", join("\t", @stringforinputfile), "\n";
#print $firstline, "\t", join("\t", @stringforinputfile), "\n";


#####start reading the real data and writing to the output file

@realdata; #this array will hold every line for input the new file
Line_Loop:while(1)
{
	$linefromformat=<FILEHANDLE>;
	chomp $linefromformat;
	@realdata=(); #before go to the next line, empty the array. $#array=-1 does same thing. also undef @array does same thing.
	Point_File1: for($i = 0; $i < ($#gprfiles+1);  $i++)
	{
		$filehandler=$filehandlers[$i];

		while($line=<$filehandler>)
		{
			@columns=split (/\t/, $line) ;
			$usefuldataindex=3*$i;
			if($order==2)#cy5cy3
			{
				push @realdata, $columns[$allusefulcolumn[$usefuldataindex]];
				push @realdata, $columns[$allusefulcolumn[$usefuldataindex+1]];
				push @realdata, $columns[$allusefulcolumn[$usefuldataindex+2]];
				if($controlgene ne "" and $linefromformat=~m/$controlgene/)   #controlgene is "" means that cutoffoption is 3
				{
				print "in the file $gprfiles[$i]\n";
					push @{$humancontrol[$i]}, $columns[$allusefulcolumn[$usefuldataindex]];
					push @{$humancontrol[$i]}, $columns[$allusefulcolumn[$usefuldataindex+1]];
					print $columns[$allusefulcolumn[$usefuldataindex]], "\n";
					print $columns[$allusefulcolumn[$usefuldataindex+1]], "\n";
				}
			}
			else#cy3cy5
			{
				push @realdata, $columns[$allusefulcolumn[$usefuldataindex+1]];
				push @realdata, $columns[$allusefulcolumn[$usefuldataindex]];
				push @realdata, $columns[$allusefulcolumn[$usefuldataindex+2]];
				if($controlgene ne "" and $linefromformat=~m/$controlgene/)   #controlgene is "" means that cutoffoption is 3
				{
				print "in the file $gprfiles[$i]\n";
					push @{$humancontrol[$i]}, $columns[$allusefulcolumn[$usefuldataindex+1]];
					push @{$humancontrol[$i]}, $columns[$allusefulcolumn[$usefuldataindex]];
					print $columns[$allusefulcolumn[$usefuldataindex]], "\n";
					print $columns[$allusefulcolumn[$usefuldataindex+1]], "\n";
				}
			}

			if($i==$#gprfiles)
			{
				print OUTFILE $linefromformat, "\t", join("\t", @realdata), "\n";
			   # print join("\t", @realdata), "\n";
				next Line_Loop;
			}
			else
			{
				next Point_File1;
			}
		}
			last Line_Loop; #if last without label, it exit the innermost loop.

	}

}
###################
close(OUTFILE);
close(FILEHANDLE);
###################


#############starting remove blank and empty cell################
open tempfilehandler, "rawdata_beforeBackgroundcorrection.txt" or die "can't open rawdata_beforeBackgroundcorrection.txt for read\n";
open tempfilehandler1, ">rawdata_beforeBackgroundcorrection_noblank.txt" or die "can't open rawdata_beforeBackgroundcorrection_noblank.txt for read\n";
while($line=<tempfilehandler>)
{
	chomp $line;
	if($line=~m/[bB][lL][aA][nN][Kk]|[Nn][oO]|[eE][mM][pP][tT][yY]/)
	{
		next;
	}
	$line=removebothendspace($line);
	print tempfilehandler1 $line, "\n";
}
close(tempfilehandler);
close(tempfilehandler1);
#############ending remove blank and empty cells################


#################################determine the cutoff value for each file.
if($controlgene eq "")
{
	for($i = 0; $i < @gprfiles;  $i++)
	{
		$medianoffile=$arbitraryvalue;
		push @allfilecutoff, $medianoffile;
	}
}
else
{
	for($i = 0; $i < @gprfiles;  $i++)
	{
		$medianoffile=median(@{$humancontrol[$i]});
		#$doublemedian=$medianoffile * 2;
		#print "in the file $gprfiles[$i]:\n";
		push @allfilecutoff, $medianoffile;
	}
}
print "\nthe cutoff value of the file is @allfilecutoff\n";
#############cutoff value has been set for each file. they are stored in the @allfilecutoff.

###########from here, we start process the file generated, and read it and write to a new file
###########in the new file, all blank id and empty id's data will be remove(whole line),
###########flagged spot's 2 channel both will be changed to median cutoff value.
open tempfilehandler1, "rawdata_beforeBackgroundcorrection_noblank.txt" or die "can't open rawdata_beforeBackgroundcorrection_noblank.txt for read\n";
open OUTFILE1, ">$outfile" or die "can't open $outfile for writing\n";
open OUTFILE2, ">summary_flags.txt" or die "can't open summary_flags.txt for writing\n";
open FLAGDATA, ">flag_data.txt" or die "can't open flag_data.txt to writing\n";
##################process and write the new title line to the final file
$line=<tempfilehandler1>;
chomp $line;  #remove the enterkey.
$newcolumntitle=writecolumntitle($line);
writetofinalfile($newcolumntitle);
print FLAGDATA $controlgene, "and", $arbitraryvalue, "and", $replicates,"\n";
print FLAGDATA $line,"\n"; #this in second line of the flag_data.txt file, we will pass the titles to the file for SAS, this title not useful for this file.
########################end of writing the title line to the new file.

$inputline="";  #line input for file user typed which will be used for R normalization.
$inputlineforsummary=""; #line input for summary_flags.txt, which reports bad flag information.
$inputlineforflagdata="";

while($line=<tempfilehandler1>)
{
	chomp $line;
	$line=removebothendspace($line);

	$line=~m/^(\d+\t+\d+\t+\d+\t+\d+\t+\S+)(.+)/; # $1 will contains the spot location information. $2 will contain the real data information.
	$formatforeveryline=$1;
	$inputline=$formatforeveryline;
	$inputlineforflagdata=$formatforeveryline;
	@realarray=split/(\t+\S+\t+\S+\t+\S+)/, $2;
	for($i=0; $i<(@realarray/2); $i++)
	{
		$j=$i*2+1;
		#print "the item is $realarray[$j]\n";
		$onelinefromonefile=removebothendspace($realarray[$j]);
		#print "$onelinefromonefile\n";
		($onechannel, $anotherchannel, $flag)=split/\t/, $onelinefromonefile;
		if(!($flag==0))
		{
		#############if you don't need the directory name, do the following.
		    $gprfiles[$i]=~ m/(.*\\)(.*)$/;
			$onlygprfile=$2;
		 ###########################################
			$inputlineforsummary=$formatforeveryline."\t".$onelinefromonefile."\t".$onlygprfile."\t".$allfilecutoff[$i];
			writetosummary($inputlineforsummary);
			#$onechannel=".";
			#$anotherchannel=".";
			$onechannel=$allfilecutoff[$i];
			$anotherchannel=$allfilecutoff[$i];
			$inputline=$inputline."\t".$onechannel."\t".$anotherchannel. "\t".$flag;
        }
		else
		{
			$inputline=$inputline."\t".$onechannel."\t".$anotherchannel. "\t".$flag;
		}
                $inputlineforflagdata=$inputlineforflagdata."\t".$flag;
   	}
	print FLAGDATA $inputlineforflagdata,"\n";
	writetofinalfile($inputline);
}
close(OUTFILE2);


sub removebothendspace
{
	my $item=$_[0];
	$item=~s/^\s+//;
	$item=~s/\s+$//;
	return $item;
}
sub writecolumntitle
{
	$titleline=$_[0];
	#$titleline=~s/\s+"Flags"\S+//g;
	return $titleline;
}
sub writetofinalfile
{
	$realline=$_[0];
	print OUTFILE1 $realline, "\n";
}
sub writetosummary
{
	$summaryline=$_[0];
	print OUTFILE2 $summaryline, "\n";
}
sub instruction
{
print "\n\n*************************************************************\n\n";
print     "   Thank you for choosing this program to prepare your input\n";
print   "   file for microarray R_MAANOVA analysis.\n";
print   "\n   This program's goal is to help the users who use R_MAANOVA\n";
print     "   to do microarray analysis to prepare the input file. Please\n";
print     "   make sure that you have all gpr files in the same directory \n";
print "   USAGE:  Perl gpr_to_inputR2.0.pl \n";
print "\n*************************************************************\n\n";
}
sub mean
{
	(@data)=@_;
	my $sum;
	foreach $item (@data) {
		$sum+=$item;
	}
	return($sum/@data);
}
sub median
{
	my(@data)=sort { $a <=> $b} @_;
	if (scalar(@data)%2) {
			return($data[@data/2]);
	} else {
			my($upper, $lower);
			$lower=$data[@data/2];
			$upper=$data[@data/2 - 1];
			return(mean($lower, $upper));
	}
}
sub writetoreplicate
{
	$newline=$_[0];
	print REPLICATE $newline, "\n";
}