#!/usr/bin/perl

use strict;
use warnings;

use lib qw(Classes);
use lib qw(Core);

use ZscoresManager;


my $DEBUG = 0;
my $manager = new ZscoresManager();

my  %weights =  ("w_gdt_ts_4" =>  0.0,
                 "w_gdt_ha_4" => 0.5,
                 "w_gdc_all" => 0.0,
                 "w_lga_4_tr" => 0.0,
                 "w_ace_rms_ca" => 0.0,
                 "w_lga_s_5" => 0.0,
                 "w_al0" => 0.0,
                 "w_dali_raw" => 0.0,
                 "w_z_score_m" => 0.0,
                 "w_mp_score" => 0.0,
                 "w_lddt" => 0.0,
                 "w_cad_aa" => 0.0,
                 "w_cad_ss" => 0.0,
                 "w_rpf" => 0.0, 
                 "w_codm" => 0.0, 
                 "w_dfm" => 0.0, 
                 "w_handedness" => 0.0, 
                 "w_sov" => 0.0, 
                 "w_qcs" => 0.0, 
                 "w_conts" => 0.0, 
                 "w_tm_score" => 0.0, 
                 "w_sg_lvr_6_2" => 0.0, 
                 "w_tens" => 0.0,
		 "w_qse" => 0.5, # ASE
		 "w_rf" => 0.0,
		 "w_ace_rms_all" => 0.0
                 );

my $flag ;
my $tbm = 'on';
my $tbm_hard = 'on';
my $tbmfm = 'off';
my $fm = 'off';
my $class_other = 'off';
my $target_flag ;
my $perdomain_flag = 'false';  # the parameter is valid for contact-assisted targets
			  # switch between two regimes: analysis per domain or per whole targets, default - per whole targets

# for GDT_TS only: 4 combinations of domains classes
#$flag = 'GDT_TS';
$flag = '05GDT_HA_05ASE';
$target_flag = 'TBM' ; 
#$target_flag = 'TBM_TBMFM' ;
#$target_flag = 'FM' ;
#$target_flag = 'FM_TBMFM' ;


# A - F : FM domains
#$flag = 'A';  # w_gdt_ts_4=1,  w_qcs=1, w_conts=1, w_tens=1
#$flag = 'B';  # w_gdt_ts_4=1, w_mp_score=1, w_qcs=1, w_conts=1, w_tens=1
#$flag = 'C';  # w_gdt_ts_4=1, w_mp_score=4, w_qcs=1, w_conts=1, w_tens=1
#$flag = 'D';  # w_gdt_ts_4=1
#$flag = 'E';  # w_gdt_ts_4=1, w_qcs=1, w_conts=1, w_tens=1, w_lddt=1
#$flag = 'F';  # w_gdt_ts_4=1, w_qcs=1, w_conts=1, w_tens=1, w_lddt=1, w_mp_score=1
#$target_flag = 'FM';

# for TBM : Roland's formula
#$flag = 'G';  # TBM  domains:  w_gdt_ha_4=1.0, w_gdc_all=1.0, w_lddt=1.0, w_mp_score=0.2, w_sg_lvr_6_2=1.0
#$target_flag = 'TBM';

# for contact-assisted targets
#$perdomain_flag = 'false';
#$target_flag = 'Tc'; 
#$flag = 'H'; # Tc targets (the same as TBM):  w_gdt_ha_4=1.0, w_gdc_all=1.0, w_lddt=1.0, w_mp_score=0.2, w_sg_lvr_6_2=1.0
#$flag = 'J'; # Tc targets (the same as FM): w_gdt_ts_4=1, w_qcs=1, w_conts=1, w_tens=1, w_lddt=1, w_mp_score=1
#$flag = 'K'; # Tc targets (gdt_ts) : w_gdt_ts_4=1

#$target_flag = 'Ts';
#$flag = 'S'; # Ts targets (the same as TBM):  w_gdt_ha_4=1.0, w_gdc_all=1.0, w_lddt=1.0, w_mp_score=0.2, w_sg_lvr_6_2=1.0
#$flag = 'T'; # Ts targets (the same as FM): w_gdt_ts_4=1, w_qcs=1, w_conts=1, w_tens=1, w_lddt=1, w_mp_score=1
#$flag = 'U'; # Ts targets (gdt_ts) : w_gdt_ts_4=1

#$target_flag = 'Tp';
#$flag = 'P'; # Tp targets (the same as FM): w_gdt_ts_4=1, w_qcs=1, w_conts=1, w_tens=1, w_lddt=1, w_mp_score=1 
#$flag = 'Q'; # Tp targets (gdt_ts) : w_gdt_ts_4=1

#$target_flag = 'Tx';
#$flag = 'X'; # Tx targets (the same as FM): w_gdt_ts_4=1, w_qcs=1, w_conts=1, w_tens=1, w_lddt=1, w_mp_score=1
#$flag = 'Y'; # Tx targets (gdt_ts) : w_gdt_ts_4=1


# for refinement targets
#$target_flag = "TR";
#$flag = 'GDT_HA'; # TR targets (gdt_ha) : w_gdt_ha_4=1


#
my $sum = 0;
foreach my $key (sort keys %weights){
	$sum += $weights{$key};
}

foreach my $key (sort keys %weights){
        $weights{$key} = sprintf("%7.6f", $weights{$key}/$sum);
#	print "$key\t".$weights{$key}."\n";
}

if ( $DEBUG ) {
	my $param = {
		tbm => 'off', #$tbm,
	        tbm_hard => 'off', #$tbm_hard,
        	tbmfm => 'off', #$tbmfm,
	        fm => 'off', # $fm,
        	class_other => 'off', # $class_other,
		target_flag => 'TR',
		perdomain_flag => 'false',
	        weights => \%weights,
	        gr_type => 'all',
	        model_type => 'best',
	};
	my ($ref1, $ref2) = $manager->get_data_for_two_groups($param, 204, 61);	
	my $no = scalar(@$ref1);
	print "No comon: $no\n";
	for (my $i = 0; $i < scalar(@$ref1); $i++) {
		printf "%s\t%s\t%s\n", $$ref1[$i]->{GR_CODE}, $$ref1[$i]->{DOM_ID}, $$ref1[$i]->{SCORE};
	}
	print "\n";
	for (my $i = 0; $i < scalar(@$ref1); $i++) {
                printf "%s\t%s\t%s\n",  $$ref2[$i]->{GR_CODE}, $$ref2[$i]->{DOM_ID}, $$ref2[$i]->{SCORE};
        }
	my ($noComm, $over12, $over21, $no_over12, $no_over21) =  $manager->head2head_test($param, 204, 61);
	printf "Out: %s\t%s\t%s\t%s\t%s\n", $noComm, $over12, $over21, $no_over12, $no_over21;
exit;
}


my @params;

if (defined($target_flag) && $target_flag =~ m/^T[acspx]/){
  $tbm = 'off'; $tbm_hard = 'off'; $tbmfm = 'off';  $fm = 'off';
  push @params, {
        tbm => $tbm,
        tbm_hard => $tbm_hard,
        tbmfm => $tbmfm,
        fm => $fm,
	target_flag => $target_flag,
        class_other => $class_other,
	perdomain_flag => $perdomain_flag,
        weights => \%weights,
        gr_type => 'all',
        model_type => 'best',
  };

  push @params, {
        tbm => $tbm,
        tbm_hard => $tbm_hard,
        tbmfm => $tbmfm,
        fm => $fm,
	target_flag => $target_flag,
	perdomain_flag => $perdomain_flag,
        class_other => $class_other,
        weights => \%weights,
        gr_type => 'all',
        model_type => 'first',
  };

} elsif (defined($target_flag) && $target_flag =~ m/^TR/) {
  $tbm = 'off'; $tbm_hard = 'off'; $tbmfm = 'off';  $fm = 'off';
  push @params, {
        tbm => $tbm,
        tbm_hard => $tbm_hard,
        tbmfm => $tbmfm,
        fm => $fm,
        target_flag => $target_flag,
        class_other => $class_other,
        perdomain_flag => $perdomain_flag,
        weights => \%weights,
        gr_type => 'all',
        model_type => 'best',
  };

  push @params, {
        tbm => $tbm,
        tbm_hard => $tbm_hard,
        tbmfm => $tbmfm,
        fm => $fm,
        target_flag => $target_flag,
        perdomain_flag => $perdomain_flag,
        class_other => $class_other,
        weights => \%weights,
        gr_type => 'all',
        model_type => 'first',
  };
} else {
  push @params, {
	tbm => $tbm,
        tbm_hard => $tbm_hard,
        tbmfm => $tbmfm,
        fm => $fm,
	target_flag => $target_flag,
        class_other => $class_other,
        gr_type => 'server_only',
        model_type => 'first',
	weights => \%weights,
  };

  push @params, {
        tbm => $tbm,
        tbm_hard => $tbm_hard,
        tbmfm => $tbmfm,
        fm => $fm,
	target_flag => $target_flag,
        class_other => $class_other,
        gr_type => 'server_only',
        model_type => 'best',
        weights => \%weights,
  };

  push @params, {
        tbm => $tbm,
        tbm_hard => $tbm_hard,
        tbmfm => $tbmfm,
        fm => $fm,
	target_flag => $target_flag,
        class_other => $class_other,
        weights => \%weights,
        gr_type => 'all',
        model_type => 'best',
  };

  push @params, {
        tbm => $tbm,
        tbm_hard => $tbm_hard,
        tbmfm => $tbmfm,
        fm => $fm,
	target_flag => $target_flag,
        class_other => $class_other,
        weights => \%weights,
        gr_type => 'all',
        model_type => 'first',
  };
}

#loop over parameters
foreach  my $param (@params){
	my @data ;
        if (defined($target_flag) && $target_flag =~ m/^T[acspx]/) {
		@data = $manager->get_Tacspx_rows($param);
	} elsif (defined($target_flag) && $target_flag =~ m/^TR/) { 
		@data = $manager->get_refinement_domain_rows($param);
	}  else {
		@data = $manager->get_rows($param);
	}

	my $fout3 = sprintf "/local/CASP13/tmp_Grishin/_%s%s_%s_head2head_%s_%s.csv", $target_flag, ($target_flag =~ m/T[acspx]/ && $perdomain_flag eq 'true' ? 'D' : ''), $flag, $param->{gr_type}, $param->{model_type};
	my $fout4 = sprintf "/local/CASP13/tmp_Grishin/_%s%s_%s_head2head_numbs_%s_%s.csv", $target_flag, ($target_flag =~ m/T[acspx]/ && $perdomain_flag eq 'true' ? 'D' : ''), $flag, $param->{gr_type}, $param->{model_type};
	open F3, ">$fout3";
	open F4, ">$fout4";
	print F3 ".";
	print F4 ".";
	
	foreach my $el (@data) {
                printf F3 ("\tTS%03d", $el->{GR_CODE});
		printf F4 ("\tTS%03d", $el->{GR_CODE});
	}
	print F3 "\n";
	print F4 "\n";

	for(my $i = 0 ; $i < scalar(@data); $i++){
		my $gr_code1 = $data[$i]->{GR_CODE};
                printf F3 "TS%03d\t", $gr_code1;
		printf F4 "TS%03d\t", $gr_code1;
		for (my $j = 0; $j < scalar(@data); $j++){
			if ($i == $j){
                                print F3 "-\t";
				print F4 "-\t";
			} else {
				my $gr_code2 = $data[$j]->{GR_CODE};
				my ($no_common, $over12, $over21, $no_over12, $no_over21) = $manager->head2head_test($param, $gr_code1, $gr_code2);
				($over12 eq '-' ? print F3 "    -\t" : printf F3 "%5.4f\t", $over12);
				($no_over12 eq '-' ? print F4 "    -\t" : printf F4 "%5d\t", $no_over12);
			}
		}
		print F3 "\n";
		print F4 "\n";
	}
	close(F3);
	close(F4);
	#next;


	my $fout1 = sprintf "/local/CASP13/tmp_Grishin/_%s%s_%s_ttest_%s_%s.csv", $target_flag, ($target_flag =~ m/T[acspx]/ && $perdomain_flag eq 'true' ? 'D' : ''), $flag, $param->{gr_type}, $param->{model_type};
	my $fout2 = sprintf "/local/CASP13/tmp_Grishin/_%s%s_%s_bootstrap_%s_%s.csv", $target_flag, ($target_flag =~ m/T[acspx]/ && $perdomain_flag eq 'true' ? 'D' : ''), $flag, $param->{gr_type}, $param->{model_type};
	open F1, ">$fout1";
	open F2, ">$fout2";
	# print header
	print F1 "."; print F2 ".";
	foreach my $el (@data) {
		printf F1 ("\tTS%03d", $el->{GR_CODE});
		printf F2 ("\tTS%03d", $el->{GR_CODE});
	}
	print F1 "\n"; print F2 "\n";
	my %hash_common;
	for(my $i = 0 ; $i < scalar(@data); $i++){
		my $gr_code1 = $data[$i]->{GR_CODE};
		printf F1 "TS%03d\t", $gr_code1;
		printf F2 "TS%03d\t", $gr_code1;
		for (my $j = 0; $j < scalar(@data); $j++){
			if ($i == $j){
				print F1 "-\t";
				print F2 "-\t";
			} elsif ( $i < $j ){
				my $gr_code2 = $data[$j]->{GR_CODE};
				my ($no_common, $prob, $count_1_over_2) = $manager->stat_significance_test($param, $gr_code1, $gr_code2);
				$hash_common{$i}{$j} = $no_common; $hash_common{$j}{$i} = $no_common;
				($prob eq '-' ? print F1 "    -\t" : printf F1 "%5.4f\t", $prob);
				($count_1_over_2 eq '-' ? print F2 "    -\t" : printf F2 "%5.4f\t", $count_1_over_2);
			} elsif ( $j < $i ){
				printf F1 "%5d\t", $hash_common{$i}{$j};
				printf F2 "%5d\t", $hash_common{$i}{$j};
			}
		}
		print F1 "\n"; print F2 "\n";
	}

}



sub usage{
    print "\n=========\nUSAGE: $0 (change parameters in the script)\n=========\n\n";
    exit;
}
