package ZscoresDeltaRefinementManager;

use strict;
use warnings;

use DBI;

use lib qw(Core);

use Database;


use Configuration;
use LocalConfiguration;
use ResultsRefinementManager;
use ResultsTargetRefinementManager;

my $zscores_manager = undef;
my $OUTLIER_CUTOFF = -2.0;
my @SCORES = qw/delta_gdt_ts_4  delta_ace_rms_ca  delta_ace_rms_all   delta_gdt_ha_4  delta_lga_4_tr  delta_z_score_m  delta_dali_z_score  delta_lddt  delta_cad_aa  delta_sg_py  delta_mp_score  delta_codm  delta_dfm  delta_handedness  delta_rpf  delta_sov  delta_ce  delta_tm_score  delta_qcs  delta_flexe/;

sub new {
    my ($class) = @_;
    return $zscores_manager if(defined($zscores_manager));

    my $self = {
        _database => Database->new($CONFIG->{HOSTNAME}, $CONFIG->{PORT}, $CONFIG->{DATABASE}, $CONFIG->{USERNAME}, $CONFIG->{PASSWORD}),
    };

    $zscores_manager = bless $self, $class;
    return $zscores_manager;
}

#######################################
#
# Methods to upload data to database
#
########################################

sub get_new_record{
    my ($self) = @_;
    my %record = (
	id => '',
	target => '',
	domain => '', 
	gr_code => '',
	model => '',
	delta_gdt_ts_4 => '', 
	delta_ace_rms_ca => '',
	delta_ace_rms_all => '',
	delta_gdt_ha_4 => '', 
	delta_lga_4_tr => '', 
	delta_z_score_m => '', 
	delta_dali_z_score => '', 
	delta_lddt => '', 
	delta_cad_aa => '', 
	delta_sg_py => '', 
	delta_mp_score => '', 
	delta_codm => '', 
	delta_dfm => '', 
	delta_handedness => '', 
	delta_rpf => '', 
	delta_sov => '', 
	delta_ce => '', 
	delta_tm_score => '', 
	delta_qcs => '', 
	delta_flexe => ''
    );
    return %record;
}

sub is_valid_columname {
    my ($self, $colname) = @_;
    if ('id' eq $colname ||
        'gr_code' eq $colname ||
	'target' eq $colname ||
        'domain' eq $colname ||
        'gr_code' eq $colname ||
        'model' eq $colname ||
        'delta_gdt_ts_4' eq $colname ||
        'delta_ace_rms_ca' eq $colname ||
        'delta_ace_rms_all' eq $colname ||
        'delta_gdt_ha_4' eq $colname ||
        'delta_lga_4_tr' eq $colname ||
        'delta_z_score_m' eq $colname ||
        'delta_dali_z_score' eq $colname ||
        'delta_lddt' eq $colname ||
        'delta_cad_aa' eq $colname ||
        'delta_sg_py' eq $colname ||
        'delta_mp_score' eq $colname ||
        'delta_codm' eq $colname ||
        'delta_dfm' eq $colname ||
        'delta_handedness' eq $colname ||
        'delta_rpf' eq $colname ||
        'delta_sov' eq $colname ||
        'delta_ce' eq $colname ||
        'delta_tm_score' eq $colname ||
        'delta_qcs' eq $colname ||
        'delta_flexe' eq $colname
    ){
	return 1;
    } else {
	return 0;
    }
}

sub getRawScores{
   my ($self, $param ) = @_;
   my $rr_manager = new ResultsRefinementManager();
   my @data = $rr_manager->get_delta_refinement($param);
   my $rt_manager = new ResultsTargetRefinementManager();
   my @data2 = $rt_manager->get_rows($param);
   # starting model
   my $start_model = {
        target => $data2[0]->{TARGET},
        domain => $data2[0]->{DOMAIN},
        gr_code => -1, # for starting model
        model => -1, # for starting model
        gdt_ts_4 => $data2[0]->{gdt_ts},
        ace_rms_ca => $data2[0]->{ace_rms_ca},
        ace_rms_all => $data2[0]->{ace_rms_all},
        gdt_ha_4 => $data2[0]->{gdt_ha},
        lga_4_tr => $data2[0]->{lga_4_tr},
        z_score_m => $data2[0]->{z_score_m},
        dali_z_score => $data2[0]->{dali_z_score},
        lddt => $data2[0]->{lddt},
        cad_aa => $data2[0]->{cad_aa},
        sg_py => $data2[0]->{sg_py},
        mp_score => $data2[0]->{mp_score},
        codm => $data2[0]->{codm},
        dfm => $data2[0]->{dfm},
        handedness => $data2[0]->{handedness},
        rpf => $data2[0]->{rpf},
        sov => $data2[0]->{sov},
        ce => $data2[0]->{ce},
        tm_score => $data2[0]->{tm_score},
        qcs => $data2[0]->{qcs},
        flexe => $data2[0]->{flexe}

   };
   return (\@data, $start_model);
   
}

sub calcZScore{
  my ($self, $refData, $start_model) = @_;
  foreach my $score (@SCORES){
    my @arr ; # array to store raw scores
    my $score2 = $score; $score2 =~ s/delta_//;
    if ($score =~ m/ace_rms_ca/ ||
                     $score =~ m/ace_rms_all/ || $score =~ m/dfm/ || $score =~ m/mp_score/ || 
                     $score =~ m/flexe/) {
    	push @arr, -($start_model->{$score2});
    } else {
	push @arr, $start_model->{$score2};
    }
    foreach my $el (@{$refData}) {
        if (defined($el->{$score}) && $el->{$score} ne '-') {
		if ($score =~ m/ace_rms_ca/ || 
		     $score =~ m/ace_rms_all/ || $score =~ m/dfm/ || $score =~ m/mp_score/ ||
	 	     $score =~ m/flexe/) {
			push @arr, -($el->{$score} + $start_model->{$score2});
		} else {
			push @arr, ($el->{$score} + $start_model->{$score2});
		}
        }
    }
    # calculate mean and standard deviation
    my ($m, $std) = $self->calcMeanStdWithoutOutliers(\@arr);
    my $zscore_start;
    if (defined($std)){
       if ($std != 0){
	   
	   if ($score =~ m/ace_rms_ca/ ||
                   $score =~ m/ace_rms_al/ || $score =~ m/dfm/ || $score =~ m/mp_score/ ||
                   $score =~ m/flexe/) {
                      $zscore_start = (-$start_model->{$score2} - $m)/$std;
              } else {
                      $zscore_start = ($start_model->{$score2} - $m)/$std;
              }
       } else {
           $zscore_start = 0.0;
       }
    }
    if (defined($zscore_start) && $zscore_start < $OUTLIER_CUTOFF){
        $zscore_start = $OUTLIER_CUTOFF;
    }
    $start_model->{$score} = $zscore_start;
    # calculate z-score
    foreach my $el (@{$refData}) {
	my $zscore = undef;
	if (defined($el->{$score}) && $el->{$score} ne '-') {
		if (defined($std)) {
                       if ($std != 0) {
				if ($score =~ m/ace_rms_ca/ ||
		                     $score =~ m/ace_rms_al/ || $score =~ m/dfm/ || $score =~ m/mp_score/ ||
		                     $score =~ m/flexe/){
                                	$zscore = (-$el->{$score} - $start_model->{$score2} - $m)/$std;
				} else {
					$zscore = ($el->{$score} + $start_model->{$score2} - $m)/$std;
				}
#				printf "++%s:%s:%s++\n", $el->{$score} + $start_model->{$score2}, $m, $std;
                       } else {
                                $zscore = 0.0;
                       }
                }
	}
	if (defined($zscore) && $zscore < $OUTLIER_CUTOFF) {
		$zscore = $OUTLIER_CUTOFF;
	}
	if (defined($zscore)) {
		$el->{$score} = $zscore - $zscore_start;
	} else {
		$el->{$score} = $OUTLIER_CUTOFF - $zscore_start;
	}
	#printf "%s:%s\n", $score, $el->{$score};
    }
    
  }
  push @{$refData}, $start_model;
  return $refData;
}


sub upload_all{
    my ($self, $param, $refData) = @_;
    my @data = @$refData;
    my $table;
    if ($param->{model_type} eq 'first'){
            $table = 'delta_refinement_zscore_1m';
    } else {
            $table = 'delta_refinement_zscore_am';
    }
    foreach my $record (@data) {
	$self->upload($record, $table);
    }
}

sub upload{
    my ($self, $record, $table) = @_;
    my $id = $self->get_id_record($record, $table);
    if ($id) {
	$record->{id} = $id;
	$self->update($record, $table);
    } else {
	$self->add($record, $table);
    }
}

# check if the record exists in the table 
# if it exists return id else 0
sub get_id_record{
    my ($self, $record, $table) = @_;
    my $query = sprintf("SELECT id FROM casp13.%s WHERE gr_code=%d AND target=\'%s\' AND model=%d  AND domain=%d ", $table, $record->{gr_code}, $record->{target}, $record->{model}, $record->{domain});
    my $sth = $self->{_database}->query($query);
    if (defined($sth) && ($sth->rows() > 0)){
        while(my ($id) = $sth->fetchrow_array()) {
		if ($id eq '' || $id == 0){
			return 0;
		} else {
			return $id;
		}
	}
    }
}

# add one record to table
sub add{
    my ($self, $record, $table) = @_;
    my %hash = %$record;
    my $result = 0;
    my $column_names = '';
    my $column_values = '';
    #my $values_count = 0;
    while(my ($key, $value) = each(%hash)){
	if ($key eq 'id'){
		next;
	}
        if ($self->is_valid_columname($key)){
                $column_names .= sprintf(" %s,", $key);
                $column_values .= sprintf(" \'%s\',", $value);
        }
    }
    $column_names =~ s/,$//;
    $column_values =~ s/,$//;
    my $query = sprintf("INSERT INTO casp13.$table ( %s ) VALUES ( %s ) RETURNING id", $column_names, $column_values);
   # print $query."\n";
   # return $result;

    my $sth = $self->{_database}->query($query);
    if(defined($sth)) {
        #my $query = sprintf("SELECT MAX(id) FROM casp13.$table");
        #my $sth = $self->{_database}->query($query);
        # add logger
        ($result) = $sth->fetchrow_array();
    }
    return $result;
}

# update one record to table
sub update{
    my ($self, $record, $table) = @_;
    my %hash = %$record;
    my $result = 0;
    my $set_query = '';
    while ( my ($key, $value) = each(%hash) ) {
	if ($key eq 'id'){
		next;
	}
	if ($self->is_valid_columname($key)){
		$set_query .= sprintf(" %s = \'%s\',", $key, $value);
	}
    }
    $set_query =~ s/,$//; 

    my $query = sprintf("UPDATE casp13.$table SET %s WHERE id=%d ", $set_query, $hash{id});

   # print $query."\n";
   # return $result;

    my $sth = $self->{_database}->query($query);
    if(defined($sth)) {
        $result = 1;
    }

    return $result;
}

sub mean{
    my ($self, $refArr) = @_;
    my $res = 0.0;
    my @arr = @{$refArr};
    if (scalar(@arr) == 0){
	return undef;
    }
    foreach my $el (@arr){
	$res += $el;
    }
    return $res/scalar(@arr);
}

sub std{
    my ($self, $refArr) = @_;
    my $res = 0.0;
    my @arr = @{$refArr};
    if (scalar(@arr) == 0 ){
	return undef;
    }
    if (scalar(@arr) == 1){
        return $res;
    }
    my $m = $self->mean($refArr);
    foreach my $el (@arr) {
	$res += ($el-$m)*($el-$m);
    }
    $res = sqrt($res/(scalar(@arr) - 1));
    return $res;
}  

sub calcMeanStdWithoutOutliers{
    my ($self, $refArr) = @_;
    my @arr = @{$refArr};
    my @nArr ;
    my $m = $self->mean($refArr);
    my $std = $self->std($refArr);
    foreach my $el (@arr){
	if ($el - $m >= $OUTLIER_CUTOFF * $std){
		push @nArr, $el;
	}
    }
    $m = $self->mean(\@nArr);
    $std = $self->std(\@nArr);
    return ($m, $std);

}

##################################################
#
# methods for retrieving data from database
#
###################################################

sub get_rows{
    my ($self, $params) = @_;
    my @results;
    my $table;
    if (defined($params->{model_type}) && ($params->{model_type} eq 'first' || $params->{model_type} eq '1' ||
		$params->{models} eq 'first' || $params->{models} eq '1' 
	)){
        $table = 'delta_refinement_zscore_1m';
    } else {
        $table = 'delta_refinement_zscore_am';
    }
    my $where = ' WHERE 1=1 ';
    my $query;
    if (defined($params->{target}) && ($params->{target} eq 'all')) {
	$query = "SELECT gr_code, count(*) as count_m, 
                avg(delta_gdt_ts_4) as delta_gdt_ts_4, avg(delta_ace_rms_ca) as delta_ace_rms_ca, 
                avg(delta_ace_rms_all) as delta_ace_rms_all, avg(delta_gdt_ha_4) as delta_gdt_ha_4, 
                avg(delta_lga_4_tr) as delta_lga_4_tr, avg(delta_z_score_m) as delta_z_score_m, 
                avg(delta_dali_z_score) as delta_dali_z_score, avg(delta_lddt) as delta_lddt, 
                avg(delta_cad_aa) as delta_cad_aa, avg(delta_sg_py) as delta_sg_py, 
                avg(delta_mp_score) as delta_mp_score, avg(delta_codm) as delta_codm, 
                avg(delta_dfm) as delta_dfm, avg(delta_handedness) as delta_handedness, 
                avg(delta_rpf) as delta_rpf,
                avg(delta_sov) as delta_sov, avg(delta_ce) as delta_ce, 
                avg(delta_tm_score) as delta_tm_score, avg(delta_qcs) as delta_qcs, avg(delta_flexe) as delta_flexe
                FROM casp13.$table dr
                JOIN casp13.targets t ON t.name::text=dr.target::text
                JOIN casp13.results_targets rt ON rt.targets_id=t.id AND dr.domain=rt.domains_index
                $where  AND rt.access_type=1 AND model<>-1 AND gr_code<>-1
                GROUP BY gr_code
                ORDER BY delta_gdt_ts_4 DESC, gr_code ";
	my $sth = $self->{_database}->query($query);
        if(defined($sth) && ($sth->rows() > 0)) {
          my $index = 1;
          while(my($gr_code, $count_m,
                $delta_gdt_ts_4, $delta_ace_rms_ca,
                $delta_ace_rms_all, $delta_gdt_ha_4, $delta_lga_4_tr,
                $delta_z_score_m, $delta_dali_z_score, $delta_lddt, $delta_cad_aa, $delta_sg_py,
                $delta_mp_score, $delta_codm, $delta_dfm, $delta_handedness, $delta_rpf, $delta_sov, $delta_ce,
                $delta_tm_score, $delta_qcs, $delta_flexe) = $sth->fetchrow_array()) {
            push(@results, {
                INDEX => $index,
                MODEL_NAME => sprintf("G%03d", $gr_code),
                COUNT_M => $count_m,
                delta_gdt_ts_4 => (defined($delta_gdt_ts_4) ? sprintf("%.3f",$delta_gdt_ts_4) : '-'),
                delta_ace_rms_ca => (defined($delta_ace_rms_ca) ? sprintf("%.3f",$delta_ace_rms_ca) : '-'),
                delta_ace_rms_all => (defined($delta_ace_rms_all) ? sprintf("%.3f", $delta_ace_rms_all) : '-'),
                delta_gdt_ha_4 => (defined($delta_gdt_ha_4) ? sprintf("%.3f", $delta_gdt_ha_4) : '-'),
                delta_gdt_sc => (defined($delta_lga_4_tr) ? sprintf("%.3f", $delta_lga_4_tr) : '-'),
                delta_z_score_m => (defined($delta_z_score_m) ? sprintf("%.3f", $delta_z_score_m) : '-'),
                delta_dali_z_score => (defined($delta_dali_z_score) ? sprintf("%.3f", $delta_dali_z_score) : '-'),
                delta_lddt => (defined($delta_lddt) ? sprintf("%.3f", $delta_lddt) : '-'),
                delta_cad_aa => (defined($delta_cad_aa) ? sprintf("%.3f", $delta_cad_aa): '-'),
                delta_sg_py => (defined($delta_sg_py) ? sprintf("%.3f", $delta_sg_py) : '-'),
                delta_mp_score => (defined($delta_mp_score) ? sprintf("%.3f", $delta_mp_score) : '-'),
                delta_codm => (defined($delta_codm) ? sprintf("%.3f", $delta_codm) : '-'),
                delta_dfm => (defined($delta_dfm) ? sprintf("%.3f", $delta_dfm) : '-'),
                delta_handedness => (defined($delta_handedness) ? sprintf("%.3f", $delta_handedness) : '-'),
                delta_rpf => (defined($delta_rpf) ? sprintf("%.3f", $delta_rpf) : '-'),
                delta_sov => (defined($delta_sov) ? sprintf("%.3f", $delta_sov) : '-'),
                delta_ce => (defined($delta_ce) ? sprintf("%.3f", $delta_ce) : ''),
                delta_tm_score => (defined($delta_tm_score) ? sprintf("%.3f", $delta_tm_score) : '-'),
                delta_qcs => (defined($delta_qcs) ? sprintf("%.3f", $delta_qcs) : '-'),
                delta_flexe => (defined($delta_flexe) ? sprintf("%.3f", $delta_flexe) : '-')
                });
            $index++;
          }
      }
    } elsif (defined($params->{target}) && ($params->{target} ne '')) {
        if ($params->{target} =~ /^R/ && $params->{target} !~ m/^R0957s2/) {
            $where .= sprintf(" AND target=\'%s\' AND domain=0 ", $params->{target});
        } elsif ($params->{target} =~ m/^(\S+)-D(\S+)/) {
            $where .= sprintf(" AND target=\'%s\' AND domain=%d ", $1, $2);
        } else {
            $where .= sprintf(" AND target=\'%s\' AND domain=0 ", $params->{target});
        }
        $query = "SELECT gr_code, domain, model, 
                delta_gdt_ts_4, delta_ace_rms_ca, 
                delta_ace_rms_all, delta_gdt_ha_4, 
                delta_lga_4_tr, delta_z_score_m, 
                delta_dali_z_score, delta_lddt, 
                delta_cad_aa, delta_sg_py, 
                delta_mp_score, delta_codm, 
                delta_dfm, delta_handedness, 
                delta_rpf,
                delta_sov, delta_ce, 
                delta_tm_score, delta_qcs, delta_flexe
                FROM casp13.$table 
                $where  AND model<>-1 AND gr_code<>-1
                ORDER BY delta_gdt_ts_4 DESC, gr_code , model 
                ";
        my $sth = $self->{_database}->query($query);
        if(defined($sth) && ($sth->rows() > 0)) {
          my $index = 1;
          while(my($gr_code, $domain, $model,
                $delta_gdt_ts_4, $delta_ace_rms_ca,
                $delta_ace_rms_all, $delta_gdt_ha_4, $delta_lga_4_tr,
                $delta_z_score_m, $delta_dali_z_score, $delta_lddt, $delta_cad_aa, $delta_sg_py,
                $delta_mp_score, $delta_codm, $delta_dfm, $delta_handedness, $delta_rpf, $delta_sov, $delta_ce,
                $delta_tm_score, $delta_qcs, $delta_flexe) = $sth->fetchrow_array()) {
            push(@results, {
                MODEL_NAME => sprintf("%sTS%03d_%d%s", $params->{target}, $gr_code, $model, ($domain == 0 ? '' : '-D'.$domain)),
                INDEX => $index,
                target => $params->{target},
                gr_code => $gr_code,
                model => $model,
                domain => $domain,
                delta_gdt_ts_4 => (defined($delta_gdt_ts_4) ? sprintf("%.3f",$delta_gdt_ts_4) : '-'),
                delta_ace_rms_ca => (defined($delta_ace_rms_ca) ? sprintf("%.3f",$delta_ace_rms_ca) : '-'),
                delta_ace_rms_all => (defined($delta_ace_rms_all) ? sprintf("%.3f", $delta_ace_rms_all) : '-'),
                delta_gdt_ha_4 => (defined($delta_gdt_ha_4) ? sprintf("%.3f", $delta_gdt_ha_4) : '-'),
                delta_gdt_sc => (defined($delta_lga_4_tr) ? sprintf("%.3f", $delta_lga_4_tr) : '-'),
                delta_lga_4_tr => (defined($delta_lga_4_tr) ? sprintf("%.3f", $delta_lga_4_tr) : '-'),
                delta_z_score_m => (defined($delta_z_score_m) ? sprintf("%.3f", $delta_z_score_m) : '-'),
                delta_dali_z_score => (defined($delta_dali_z_score) ? sprintf("%.3f", $delta_dali_z_score) : '-'),
                delta_lddt => (defined($delta_lddt) ? sprintf("%.3f", $delta_lddt) : '-'),
                delta_cad_aa => (defined($delta_cad_aa) ? sprintf("%.3f", $delta_cad_aa): '-'),
                delta_sg_py => (defined($delta_sg_py) ? sprintf("%.3f", $delta_sg_py) : '-'),
                delta_mp_score => (defined($delta_mp_score) ? sprintf("%.3f", $delta_mp_score) : '-'),
                delta_codm => (defined($delta_codm) ? sprintf("%.3f", $delta_codm) : '-'),
                delta_dfm => (defined($delta_dfm) ? sprintf("%.3f", $delta_dfm) : '-'),
                delta_handedness => (defined($delta_handedness) ? sprintf("%.3f", $delta_handedness) : '-'),
                delta_rpf => (defined($delta_rpf) ? sprintf("%.3f", $delta_rpf) : '-'),
                delta_sov => (defined($delta_sov) ? sprintf("%.3f", $delta_sov) : '-'),
                delta_ce => (defined($delta_ce) ? sprintf("%.3f", $delta_ce) : '-'),
                delta_tm_score => (defined($delta_tm_score) ? sprintf("%.3f", $delta_tm_score) : '-'),
                delta_qcs => (defined($delta_qcs) ? sprintf("%.3f", $delta_qcs) : '-'),
                delta_flexe => (defined($delta_flexe) ? sprintf("%.3f", $delta_flexe) : '-')
                });
            $index++;
          }
        }
    }
    return @results;
}


sub get_start_model{
    my ($self, $params) = @_;
    my @results;
    my $table;
    if (defined($params->{model_type}) && ($params->{model_type} eq 'first' || $params->{model_type} eq '1' ||
                $params->{models} eq 'first' || $params->{models} eq '1'
        )){
        $table = 'delta_refinement_zscore_1m';
    } else {
        $table = 'delta_refinement_zscore_am';
    }
    my $where = ' WHERE 1=1 ';
    my $query;
    if (defined($params->{target}) && ($params->{target} eq 'all')) {
        $query = "SELECT gr_code, count(*) as count_m, 
                avg(delta_gdt_ts_4) as delta_gdt_ts_4, avg(delta_ace_rms_ca) as delta_ace_rms_ca, 
                avg(delta_ace_rms_all) as delta_ace_rms_all, avg(delta_gdt_ha_4) as delta_gdt_ha_4, 
                avg(delta_lga_4_tr) as delta_lga_4_tr, avg(delta_z_score_m) as delta_z_score_m, 
                avg(delta_dali_z_score) as delta_dali_z_score, avg(delta_lddt) as delta_lddt, 
                avg(delta_cad_aa) as delta_cad_aa, avg(delta_sg_py) as delta_sg_py, 
                avg(delta_mp_score) as delta_mp_score, avg(delta_codm) as delta_codm, 
                avg(delta_dfm) as delta_dfm, avg(delta_handedness) as delta_handedness, 
                avg(delta_rpf) as delta_rpf,
                avg(delta_sov) as delta_sov, avg(delta_ce) as delta_ce,
                avg(delta_tm_score) as delta_tm_score, avg(delta_qcs) as delta_qcs, avg(delta_flexe) as delta_flexe
                FROM casp13.$table dr
                JOIN casp13.targets t ON t.name::text=dr.target::text
                JOIN casp13.results_targets rt ON rt.targets_id=t.id AND dr.domain=rt.domains_index
                $where  AND rt.access_type=1 AND model=-1 AND gr_code=-1
                GROUP BY gr_code
                ORDER BY delta_gdt_ts_4 DESC, gr_code ";
        my $sth = $self->{_database}->query($query);
        if(defined($sth) && ($sth->rows() > 0)) {
          my $index = 1;
          while(my($gr_code, $count_m,
                $delta_gdt_ts_4, $delta_ace_rms_ca,
                $delta_ace_rms_all, $delta_gdt_ha_4, $delta_lga_4_tr,
                $delta_z_score_m, $delta_dali_z_score, $delta_lddt, $delta_cad_aa, $delta_sg_py,
                $delta_mp_score, $delta_codm, $delta_dfm, $delta_handedness, $delta_rpf, $delta_sov, $delta_ce,
                $delta_tm_score, $delta_qcs, $delta_flexe) = $sth->fetchrow_array()) {
            push(@results, {
                INDEX => $index,
                MODEL_NAME => "starting", 
                COUNT_M => $count_m,
                refinement_gdt_ts_4 => (defined($delta_gdt_ts_4) ? sprintf("%.3f",$delta_gdt_ts_4) : '-'),
                refinement_ace_rms_ca => (defined($delta_ace_rms_ca) ? sprintf("%.3f",$delta_ace_rms_ca) : '-'),
                refinement_ace_rms_all => (defined($delta_ace_rms_all) ? sprintf("%.3f", $delta_ace_rms_all) : '-'),
                refinement_gdt_ha_4 => (defined($delta_gdt_ha_4) ? sprintf("%.3f", $delta_gdt_ha_4) : '-'),
                refinement_lga_4_tr => (defined($delta_lga_4_tr) ? sprintf("%.3f", $delta_lga_4_tr) : '-'),
                refinement_z_score_m => (defined($delta_z_score_m) ? sprintf("%.3f", $delta_z_score_m) : '-'),
                refinement_dali_z_score => (defined($delta_dali_z_score) ? sprintf("%.3f", $delta_dali_z_score) : '-'),
                refinement_lddt => (defined($delta_lddt) ? sprintf("%.3f", $delta_lddt) : '-'),
                refinement_cad_aa => (defined($delta_cad_aa) ? sprintf("%.3f", $delta_cad_aa): '-'),
                refinement_sg_py => (defined($delta_sg_py) ? sprintf("%.3f", $delta_sg_py) : '-'),
                refinement_mp_score => (defined($delta_mp_score) ? sprintf("%.3f", $delta_mp_score) : '-'),
                refinement_codm => (defined($delta_codm) ? sprintf("%.3f", $delta_codm) : '-'),
                refinement_dfm => (defined($delta_dfm) ? sprintf("%.3f", $delta_dfm) : '-'),
                refinement_handedness => (defined($delta_handedness) ? sprintf("%.3f", $delta_handedness) : '-'),
                refinement_rpf => (defined($delta_rpf) ? sprintf("%.3f", $delta_rpf) : '-'),
                refinement_sov => (defined($delta_sov) ? sprintf("%.3f", $delta_sov) : '-'),
                refinement_ce => (defined($delta_ce) ? sprintf("%.3f", $delta_ce) : ''),
                refinement_tm_score => (defined($delta_tm_score) ? sprintf("%.3f", $delta_tm_score) : '-'),
                refinement_qcs => (defined($delta_qcs) ? sprintf("%.3f", $delta_qcs) : '-'),
                refinement_flexe => (defined($delta_flexe) ? sprintf("%.3f", $delta_flexe) : '-')
                });
            $index++;
          }
      }
    } elsif (defined($params->{target}) && ($params->{target} ne '')) {
        if ($params->{target} =~ /^R/ && $params->{target} !~ m/^R0957s2/) {
            $where .= sprintf(" AND target=\'%s\' AND domain=0 ", $params->{target});
        } elsif ($params->{target} =~ m/^(\S+)-D(\S+)/) {
            $where .= sprintf(" AND target=\'%s\' AND domain=%d ", $1, $2);
        } else {
            $where .= sprintf(" AND target=\'%s\' AND domain=0 ", $params->{target});
        }
        $query = "SELECT gr_code, domain, model, 
                delta_gdt_ts_4, delta_ace_rms_ca, 
                delta_ace_rms_all, delta_gdt_ha_4, 
                delta_lga_4_tr, delta_z_score_m, 
                delta_dali_z_score, delta_lddt, 
                delta_cad_aa, delta_sg_py, 
                delta_mp_score, delta_codm, 
                delta_dfm, delta_handedness, 
                delta_rpf,
                delta_sov, delta_ce, 
                delta_tm_score, delta_qcs, delta_flexe
                FROM casp13.$table 
                $where  AND model=-1 AND gr_code=-1
                ORDER BY delta_gdt_ts_4 DESC, gr_code , model 
                ";
        my $sth = $self->{_database}->query($query);
        if(defined($sth) && ($sth->rows() > 0)) {
          my $index = 1;
          while(my($gr_code, $domain, $model,
                $delta_gdt_ts_4, $delta_ace_rms_ca,
                $delta_ace_rms_all, $delta_gdt_ha_4, $delta_lga_4_tr,
                $delta_z_score_m, $delta_dali_z_score, $delta_lddt, $delta_cad_aa, $delta_sg_py,
                $delta_mp_score, $delta_codm, $delta_dfm, $delta_handedness, $delta_rpf, $delta_sov, $delta_ce,
                $delta_tm_score, $delta_qcs, $delta_flexe) = $sth->fetchrow_array()) {
            push(@results, {
                MODEL_NAME => "starting",
                INDEX => $index,
                target => $params->{target},
                gr_code => $gr_code,
                model => $model,
                domain => $domain,
                refinement_gdt_ts_4 => (defined($delta_gdt_ts_4) ? sprintf("%.3f",$delta_gdt_ts_4) : '-'),
                refinement_ace_rms_ca => (defined($delta_ace_rms_ca) ? sprintf("%.3f",$delta_ace_rms_ca) : '-'),
                refinement_ace_rms_all => (defined($delta_ace_rms_all) ? sprintf("%.3f", $delta_ace_rms_all) : '-'),
                refinement_gdt_ha_4 => (defined($delta_gdt_ha_4) ? sprintf("%.3f", $delta_gdt_ha_4) : '-'),
                refinement_gdt_sc => (defined($delta_lga_4_tr) ? sprintf("%.3f", $delta_lga_4_tr) : '-'),
                refinement_lga_4_tr => (defined($delta_lga_4_tr) ? sprintf("%.3f", $delta_lga_4_tr) : '-'),
                refinement_z_score_m => (defined($delta_z_score_m) ? sprintf("%.3f", $delta_z_score_m) : '-'),
                refinement_dali_z_score => (defined($delta_dali_z_score) ? sprintf("%.3f", $delta_dali_z_score) : '-'),
                refinement_lddt => (defined($delta_lddt) ? sprintf("%.3f", $delta_lddt) : '-'),
                refinement_cad_aa => (defined($delta_cad_aa) ? sprintf("%.3f", $delta_cad_aa): '-'),
                refinement_sg_py => (defined($delta_sg_py) ? sprintf("%.3f", $delta_sg_py) : '-'),
                refinement_mp_score => (defined($delta_mp_score) ? sprintf("%.3f", $delta_mp_score) : '-'),
                refinement_codm => (defined($delta_codm) ? sprintf("%.3f", $delta_codm) : '-'),
                refinement_dfm => (defined($delta_dfm) ? sprintf("%.3f", $delta_dfm) : '-'),
                refinement_handedness => (defined($delta_handedness) ? sprintf("%.3f", $delta_handedness) : '-'),
                refinement_rpf => (defined($delta_rpf) ? sprintf("%.3f", $delta_rpf) : '-'),
                refinement_sov => (defined($delta_sov) ? sprintf("%.3f", $delta_sov) : '-'),
                refinement_ce => (defined($delta_ce) ? sprintf("%.3f", $delta_ce) : '-'),
                refinement_tm_score => (defined($delta_tm_score) ? sprintf("%.3f", $delta_tm_score) : '-'),
                refinement_qcs => (defined($delta_qcs) ? sprintf("%.3f", $delta_qcs) : '-'),
                refinement_flexe => (defined($delta_flexe) ? sprintf("%.3f", $delta_flexe) : '-')
                });
            $index++;
          }
        }
    }
    return @results;
}

1;
