package ClustersForQAManager;


use lib (qw/Classes Core/);
use Algorithm::Cluster;
use GroupsManager;
use Database;
use Logger;
use Exporter;

use LocalConfiguration;

my $NCLUSTERS = $LOCAL_CONFIG->{NUMBER_MODELS_QA_STAGE1}; # = number of models in stage 1

my $NUM_MODELS_STAGE2 = $LOCAL_CONFIG->{NUMBER_MODELS_QA_STAGE2};

my $CUTOFF_MOL_PRB = 4.00; # it's upper cutoff - models with higher molprobity score will be eliminated from clustering

#deprecated parameter since CASP_11
#my $CUTOFF_PROSA = 0.00; # it's upper cutoff - models with higher z-score (prosa) will be eliminated from clustering
			 # TODO this criteria is too weak, the cutoff should be dependent on the length of the sequence being smaller for longer sequences

sub new {
   my ($class, $target_name ) = @_;
   my $self = {
	_target => $target_name,
	_predictions => undef, # $ref_predictions,
	_matrixDist => undef,
	_gdt_pred1_pred2 => undef,
	_map_prediction_index => undef,
	_stage1_predictions => undef,
	_stage2_predictions => undef,
	_similar => undef
   };


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

sub process{
   my ($self) = @_;

   $self->parseDir();
 
   sleep(2);

   $self->set_predictions_stage1();

   sleep(2);

   $self->set_predictions_stage2();

   sleep(2);

   $self->process_clustering();

   sleep(2);

   $self->create_tarballs_stage1();
 
   sleep(2);

   $self->create_tarballs_stage2();

   sleep(2);

   $self->create_prediction_QAconsensus_stage1();

   sleep(2);

   $self->create_prediction_QAconsensus_stage2();

   sleep(2);

   $self->create_prediction_QAconsensus_ALL_stage1();

   sleep(2);

   $self->create_prediction_QAconsensus_ALL_stage2();
   
   sleep(2);

   $self->printStatistics();

   return 1;
}


sub parseDir(){
  my ($self) = @_;
 
  # read dir with predictions
  my $pred_dir = $LOCAL_CONFIG->{DATA_SERV_MODELS_DIR}."/".$self->{_target}."/";
  opendir(DIR, $pred_dir) || return 0; 
  my @files = ();
  my $target = $self->{_target};
  while(defined(my $file = readdir(DIR))){
    if($file =~ m/^$target[TA][SL][0-9]{3}_[1-5]$/){ # T0921TS123_1
	push(@files, $file);
    }
  }
  closedir DIR;
 
  # sort files and create hash: predictions - indexes
  @files = sort @files;
  my $grp_manager = new GroupsManager();
  my @predictions = ();
  my %map_prediction_index = ();
  my $index = 0;
  foreach my $file (@files){
	
	if($file =~ m/^$target([TA][SL])([0-9]{3})_([1-5])$/){
	   my $grp_id = $grp_manager->get_id_by_code($2);
	   my $grp_name = $grp_manager->name($grp_id);
	   my $prediction = {
		_group_name=> $grp_name,
		_group_code => $2,
		_prfrmat => $1,
		_model => $3,
		_avrg_gdt_ts => undef,
		_is_stage1 => 0,
		_is_stage2 => 0,
		_index => $index,
	   };
	   push(@predictions, $prediction);
	   $map_prediction_index{$file} = $index; # hash prediction_name T0921TS123_1 -> index
	   $index++;
	}
  }
  $self->{_predictions} = \@predictions;

  $self->{_map_prediction_index} = \%map_prediction_index;


  # hash of gdt_ts of all pairs of models
  my %gdt_pred1_pred2 = ();
  
  # hash of similar models
  my %hash_similar = ();

  # parse files ;  save gdt_ts_average 
  
  my $res_dir = $LOCAL_CONFIG->{RESULTS_DIR}."/MVSM_SERV/DATA/".$self->{_target}."/";;

  my $res_file_molprob = $LOCAL_CONFIG->{RESULTS_DIR}."/MOLPROBITY/".$self->{_target}.".molprb";
#  my $res_file_prosa = $LOCAL_CONFIG->{RESULTS_DIR}."/PROSA/".$self->{_target}.".prosa";
  
  for(my $i = 0; $i < scalar(@predictions); $i++){
	my $pred = sprintf("%s%s%03d_%1d",$self->{_target},$predictions[$i]->{_prfrmat},$predictions[$i]->{_group_code}, $predictions[$i]->{_model});
	open RES, "cat $res_dir/* | grep AVERAGE -v | grep SIMILAR -v | grep $pred | " ; # die("Couldn't open file $dir/$file");
	while(<RES>){
		if($_ =~ m/^\d+/){
			my ($rmsd, $pred1, $pred2, $gdt_ts) = split(/\s+/, $_);
			$gdt_pred1_pred2{$pred1}{$pred2} = $gdt_ts;
			$gdt_pred1_pred2{$pred2}{$pred1} = $gdt_ts;
		}
	}
        close(RES);
	
	# calculate gdt_ts average
	my $count = 0;
	my $gdt_ts_avg = 0;
	foreach my $key	(keys (%gdt_pred1_pred2)){
		if ($key eq $pred){next;} 
		$gdt_ts_avg = $gdt_ts_avg + $gdt_pred1_pred2{$pred}{$key};
		$count++;
	}
	$predictions[$i]->{_avrg_gdt_ts} = $gdt_ts_avg/$count;
	
	# similar models
	open RES, "cat $res_dir/* | grep SIMILAR | grep $pred | ";
	while(<RES>){
	  if($_ =~ m/SIMILAR_MODELS\s+$pred\s+(\S+)/){
		$hash_similar{$pred} = 1;
	  }
	}
	close RES;
	
	# read results molprobity
	  my $mol_prb =  `grep $pred $res_file_molprob | cut -d: -f32`;
	  chomp $mol_prb;
	  if($mol_prb eq ''){ # for some reasons molprobity failed 
		$predictions[$i]->{_mol_prb} = 99.999; # set to CUTOFF i.e. remove this prediction from clustering
	  }else{
		$predictions[$i]->{_mol_prb} = $mol_prb;
	  }

# deprecated code regarding PROSA since CASP_11
=head
	# read results prosa
	  my $prosa_score = `grep $pred $res_file_prosa`; # read the whole line
	  chomp $prosa_score;
	  ($prosa_score, $prosa_score, $prosa_score) = split(/\s+/,$prosa_score); # extract third field in the line
	  if(!(defined($prosa_score)) || $prosa_score eq '' ){
	    $predictions[$i]->{_prosa_zs} = 99.999;
	  }else{
	    $predictions[$i]->{_prosa_zs} = $prosa_score;
	  }
=cut
	# prepare matrix of Distances for Clustering
  }

  $self->{_gdt_pred1_pred2} = \%gdt_pred1_pred2;
  $self->{_similar} = \%hash_similar;
  return 1;
}


sub printStatistics{
   my ($self) = @_;
   my @predictions = @{$self->{_predictions}};
   @predictions = sort {$b->{_avrg_gdt_ts}<=>$a->{_avrg_gdt_ts}} @predictions;
   my $outFile = sprintf("/data/%s/tmp_QA/%s.stat.txt", $LOCAL_CONFIG->{CASP_VERSION},$self->{_target});
   open OUT, "> $outFile" ;
#   print OUT "Prediction\tMolPrb\tProSA\tQA_consensus\n";
   print OUT "Prediction\tMolPrb\tQA_consensus\n";
   foreach my $prediction (@predictions){
        my $pred = sprintf("%s%s%03d_%d", $self->{_target},$prediction->{_prfrmat},$prediction->{_group_code}, $prediction->{_model});
#        my $toString = sprintf("%s\t%5.3f\t%5.3f\t%5.3f\n", $pred, $prediction->{_mol_prb}, $prediction->{_prosa_zs},$prediction->{_avrg_gdt_ts});
	my $toString = sprintf("%s\t%5.3f\t%5.3f\n", $pred, $prediction->{_mol_prb}, $prediction->{_avrg_gdt_ts});
        print OUT $toString;
   }
   close OUT;
}



# method was used for debuging - it sn't needed any more
sub process_clustering{
  my ($self, $add_clusters) = @_;

  if(! defined($add_clusters)){
	$add_clusters = 5;
  }
  
  if(! defined($self->{_matrixDist})){
	$self->set_predictions_stage1();
  }

  my %param = (
        data => $self->{_matrixDist},
        mask => '',
        weight => '',
        transpose => 0,
        dist => 'e',
        method => 'a',
  );


  my $tree = Algorithm::Cluster::treecluster(%param);
  my $logFile = sprintf("/data/%s/tmp_QA/%s.clusters.log",$LOCAL_CONFIG->{CASP_VERSION},$self->{_target});
  open (LOGFILE , "> $logFile") ;
  for(my $k = 0; $k < $add_clusters; $k++){
  my $clusterid = $tree->cut($NCLUSTERS + $k);
  print LOGFILE "NUMBER OF CLUSTERS: ". ($NCLUSTERS + $k)."\n";
  my $i=0;
  my @clusters = ();
  my @clusters_indexes = ();
 
  my @predictions;
  my %hash_similar = %{$self->{_similar}};
  foreach my $prediction (@{$self->{_predictions}}){
        my $pred = sprintf("%s%s%03d_%1d",$self->{_target},$prediction->{_prfrmat},$prediction->{_group_code}, $prediction->{_model});
        if($prediction->{_mol_prb} < $CUTOFF_MOL_PRB &&
#                $prediction->{_prosa_zs} < $CUTOFF_PROSA &&
                !defined($hash_similar{$pred})
                ){
            push(@predictions, $prediction);
        }
  }

 
  foreach (@$clusterid) {
  #	print "Cluster $_\n";
  #     print "\nDescriptor $ik ($desc_list[$ik]):\tCluster $_";
        push @{$clusters[$_]}, $predictions[$i];
	push @{$clusters_indexes[$_]}, $i;
        $i++;
  }
 
  foreach my $cluster (@clusters){
	foreach my $pred (@{$cluster}){
		print LOGFILE $pred->{_group_code} . "_" . $pred->{_model} ." ";
	#	print $pred->{_avrg_gdt_ts}." ";
	}
	print LOGFILE "\n";
  }

  #  foreach my $cluster_i (@clusters_indexes){
  #      foreach my $i (@{$cluster_i}){
  #              print $i . " ";
  #      }
  #      print "\n";
  #}

  print LOGFILE "\n++++++++++++++++++++++++++++\n\n";
  }
  close(LOGFILE);

}


sub set_predictions_stage1{
  my ($self) = @_;
  # filter predictions eleminating those with molprobity and/or prosa scores higher than cutOffs
  my %hash_similar = %{$self->{_similar}};
  my %gdt_pred1_pred2 = %{$self->{_gdt_pred1_pred2}};
  my @predictions; 
  foreach my $prediction (@{$self->{_predictions}}){
	my $pred = sprintf("%s%s%03d_%1d",$self->{_target},$prediction->{_prfrmat},$prediction->{_group_code}, $prediction->{_model});
	if($prediction->{_mol_prb} < $CUTOFF_MOL_PRB &&
#		$prediction->{_prosa_zs} < $CUTOFF_PROSA && 
		!defined($hash_similar{$pred})
		){
	    push(@predictions, $prediction);	
	}
  }
  # form matrix of distances for filtered predictions
  my @distMatr;
  for(my $i = 0; $i<scalar(@predictions); $i++){
        my @row = ();
        for (my $j=0; $j < $i; $j++){
                my $pred1 = sprintf("%s%s%03d_%1d",$self->{_target},$predictions[$i]->{_prfrmat},$predictions[$i]->{_group_code}, $predictions[$i]->{_model});
                my $pred2 = sprintf("%s%s%03d_%1d",$self->{_target},$predictions[$j]->{_prfrmat},$predictions[$j]->{_group_code}, $predictions[$j]->{_model});
                if(exists $gdt_pred1_pred2{$pred1}{$pred2}){
                  push (@row, 100.00 - $gdt_pred1_pred2{$pred1}{$pred2}); # for bihavior like distance use (100 - gdt_ts)
                } else{
                  push (@row, 100.00);
                }
        }
	push(@distMatr, \@row);
  }
  # clustering
  my %param = (
        data => \@distMatr,
        mask => '',
        weight => '',
        transpose => 0,
        dist => 'e',
        method => 'a',
  );
  my $tree = Algorithm::Cluster::treecluster(%param);
  my $clusterid = $tree->cut($NCLUSTERS);

  my $i=0;
  my @clusters = ();
  my @clusters_indexes = ();


  foreach (@$clusterid) {
  #     print "Cluster $_\n";
  #     print "\nDescriptor $ik ($desc_list[$ik]):\tCluster $_";
        push @{$clusters[$_]}, $predictions[$i];
        push @{$clusters_indexes[$_]}, $i;
        $i++;
  }
  my  @result = ();
  foreach my $cluster (@clusters){
	## select randomly 
	#my $ind = int(rand(scalar(@{$cluster})));
	#push(@result, ${$cluster}[$ind]);
	
	## select element with max avrg_gdt_ts
	push(@result, $self->get_max_from_cluster($cluster));
	#print ${$cluster}[$ind]->{_group_code}."_".${$cluster}[$ind]->{_model}."\n";
  }
  $self->{_stage1_predictions} = \@result;

  # set ditance matrix
  $self->{_matrixDist} = \@distMatr;
  return 1;
}

# select element with maximum avrg_gdt_ts from the cluster
sub get_max_from_cluster{
  my ($self, $cluster) = @_;
  my $result = ${$cluster}[0];
  for(my $i = 1; $i < scalar(@{$cluster}); $i++){
	if($result->{_avrg_gdt_ts} < ${$cluster}[$i]->{_avrg_gdt_ts} ){
		$result = ${$cluster}[$i];
	}
  }
  return $result;
}

sub set_predictions_stage2{
   my ($self) = @_;
   my @result  = ();
   my %hash_similar = %{$self->{_similar}};
   foreach my $prediction (@{$self->{_predictions}}){
	my $pred = sprintf("%s%s%03d_%1d",$self->{_target},$prediction->{_prfrmat},$prediction->{_group_code}, $prediction->{_model});
	if(! defined($hash_similar{$pred})){ # filter the same models from the same group
	  push(@result, $prediction);
	}
   }
   @result = sort { $b->{_avrg_gdt_ts} <=> $a->{_avrg_gdt_ts} } @result;
   $#result = (scalar(@result) > $NUM_MODELS_STAGE2) ? ($NUM_MODELS_STAGE2 - 1) : (scalar(@result) - 1);
   $self->{_stage2_predictions} = \@result;
   return 1;
}


sub create_tarballs_stage1{
    my ($self) = @_;
       
        my @predictions = @{$self->{_stage1_predictions}};
        # sort @predictions alphabetically
        @predictions = sort {$a->{_group_name} cmp $b->{_group_name} } @predictions;

        my $tarball_name = sprintf("%s.stage1.3D.srv.tar.gz", $self->{_target});

        my $download_area = sprintf("/data/".$LOCAL_CONFIG->{CASP_VERSION}."/tmp_QA/%s", $tarball_name);
        if (!(-e $download_area)) {
              my $new_dir = sprintf("%s/%s", $LOCAL_CONFIG->{TARBALLS_PREDICTIONS_DIR}, $self->{_target});
              my $old_dir = sprintf("%s/%s", $LOCAL_CONFIG->{CLEAN_PREDICTIONS_DIR}, $self->{_target});
              if(!(-e $new_dir)) {
                  system(sprintf("mkdir %s", $new_dir));
                  system(sprintf("chgrp casp %s", $new_dir));
                  system(sprintf("chmod 775 %s", $new_dir));
              }
	      # copy files and write file with code servers correspondence
	      my $code_corr = sprintf("/data/%s/tmp_QA/%s.code_server_corr.txt", $LOCAL_CONFIG->{CASP_VERSION}, $self->{_target});
 	      open FILE, "> $code_corr";
              for(my $p_count = 0; $p_count < scalar(@predictions); $p_count++) {
		   print FILE sprintf("%s%s%03d_%s  ->  server%02d_TS1\n", $self->{_target}, $predictions[$p_count]->{_prfrmat}, $predictions[$p_count]->{_group_code},$predictions[$p_count]->{_model}, ($p_count + 1));
                  #my $new_file = sprintf("%s/%s_%s%s%s", $new_dir, $predictions[$p_count]->{_group_name}, $predictions[$p_count]->{_prfrmat}, $predictions[$p_count]->{_model}, (($predictions[$p_count]->{_prfrmat} eq 'AL')?'.pdb':''));
		   my $new_file = sprintf("%s/server%02d_TS1", $new_dir, ($p_count + 1));
                   my $old_file = sprintf("%s/%s%s%s_%s", $old_dir, $self->{_target}, $predictions[$p_count]->{_prfrmat}, $predictions[$p_count]->{_group_code}, $predictions[$p_count]->{_model});

                  system(sprintf("cp %s %s", $old_file, $new_file));
                  system(sprintf("chmod a+r %s", $new_file))
              }
	      close(FILE);

              system(sprintf("cd %s; tar -czf %s %s/* --remove-files", $LOCAL_CONFIG->{TARBALLS_PREDICTIONS_DIR}, $tarball_name, $self->{_target}));
              system(sprintf("chgrp users %s/%s",$LOCAL_CONFIG->{TARBALLS_PREDICTIONS_DIR}, $tarball_name));
              system(sprintf("chmod 664 %s/%s",$LOCAL_CONFIG->{TARBALLS_PREDICTIONS_DIR}, $tarball_name));

              system(sprintf("mv %s/%s %s", $LOCAL_CONFIG->{TARBALLS_PREDICTIONS_DIR}, $tarball_name, $download_area));
              system(sprintf("rm -f -r %s/%s ", $LOCAL_CONFIG->{TARBALLS_PREDICTIONS_DIR}, $self->{_target}));
       }

    return 1;

}



sub create_tarballs_stage2{
    my ($self) = @_;

        my @predictions = @{$self->{_stage2_predictions}};
        # sort @predictions alphabetically
        @predictions = sort {$a->{_group_name} cmp $b->{_group_name} } @predictions;

        my $tarball_name = sprintf("%s.stage2.3D.srv.tar.gz", $self->{_target});

        my $download_area = sprintf("/data/".$LOCAL_CONFIG->{CASP_VERSION}."/tmp_QA/%s", $tarball_name);
        if (!(-e $download_area)) {
              my $new_dir = sprintf("%s/%s", $LOCAL_CONFIG->{TARBALLS_PREDICTIONS_DIR}, $self->{_target});
              my $old_dir = sprintf("%s/%s", $LOCAL_CONFIG->{CLEAN_PREDICTIONS_DIR}, $self->{_target});
              if(!(-e $new_dir)) {
                  system(sprintf("mkdir %s", $new_dir));
                  system(sprintf("chgrp users %s", $new_dir));
                  system(sprintf("chmod 775 %s", $new_dir));
              }

              for(my $p_count = 0; $p_count < scalar(@predictions); $p_count++) {
                  my $new_file = sprintf("%s/%s_%s%s%s", $new_dir, $predictions[$p_count]->{_group_name}, $predictions[$p_count]->{_prfrmat}, $predictions[$p_count]->{_model}, (($predictions[$p_count]->{_prfrmat} eq 'AL')?'.pdb':''));
                   my $old_file = sprintf("%s/%s%s%s_%s", $old_dir, $self->{_target}, $predictions[$p_count]->{_prfrmat}, $predictions[$p_count]->{_group_code}, $predictions[$p_count]->{_model});

                  system(sprintf("cp %s %s", $old_file, $new_file));
                  system(sprintf("chmod a+r %s", $new_file))
              }

              system(sprintf("cd %s; tar -czf %s %s/* --remove-files", $LOCAL_CONFIG->{TARBALLS_PREDICTIONS_DIR}, $tarball_name, $self->{_target}));
              system(sprintf("chgrp users %s/%s",$LOCAL_CONFIG->{TARBALLS_PREDICTIONS_DIR}, $tarball_name));
              system(sprintf("chmod 664 %s/%s",$LOCAL_CONFIG->{TARBALLS_PREDICTIONS_DIR}, $tarball_name));

              system(sprintf("mv %s/%s %s", $LOCAL_CONFIG->{TARBALLS_PREDICTIONS_DIR}, $tarball_name, $download_area));
              system(sprintf("rm -f -r %s/%s ", $LOCAL_CONFIG->{TARBALLS_PREDICTIONS_DIR}, $self->{_target}));
       }

	return 1;
}


sub create_prediction_QAconsensus_ALL_stage1{
    my ($self) = @_;
	my @predictions = @{$self->{_stage1_predictions}};
        # sort @predictions alphabetically
        @predictions = sort {$a->{_group_name} cmp $b->{_group_name} } @predictions;	
	my $pred_file_name = $self->{_target}.".Davis-EMAconsensusAL.stage1"; 
	my $pred_file = sprintf("/data/".$LOCAL_CONFIG->{CASP_VERSION}."/tmp_QA/%s", $pred_file_name);
	open(FILE, "> $pred_file");
	print FILE "PFRMAT QA\n";
	print FILE "TARGET ".$self->{_target}."\n";
	print FILE "AUTHOR Davis-EMAconsensusAL\n"; # pin of group Davis-ConsensusAll in CASP13
	print FILE "METHOD predictions based on consensus of all models\n";
	print FILE "MODEL 1\n";
	print FILE "QMODE 1\n";
	my $p_count = 0;
	foreach my $prediction (@predictions){
	   #my $serv_model = sprintf("%s_%s%s%s",$prediction->{_group_name}, $prediction->{_prfrmat}, $prediction->{_model}, (($prediction->{_prfrmat} eq 'AL')?'.pdb':''));
	   my $serv_model = sprintf("server%02d_TS1", ($p_count + 1));
	   print FILE sprintf("%s %1.5f\n", $serv_model, ($prediction->{_avrg_gdt_ts}/100.0));
	   $p_count++;
	}	
	print FILE "END\n";
	close(FILE);
}

sub create_prediction_QAconsensus_ALL_stage2{
    my ($self) = @_;
        my @predictions = @{$self->{_stage2_predictions}};
        # sort @predictions alphabetically
        @predictions = sort {$a->{_group_name} cmp $b->{_group_name} } @predictions;
        my $pred_file_name = $self->{_target}.".Davis-EMAconsensusAL.stage2";
        my $pred_file = sprintf("/data/".$LOCAL_CONFIG->{CASP_VERSION}."/tmp_QA/%s", $pred_file_name);
        open(FILE, "> $pred_file");
        print FILE "PFRMAT QA\n";
        print FILE "TARGET ".$self->{_target}."\n";
        print FILE "AUTHOR Davis-EMAconsensusAL\n"; # pin of group Davis-ConsensusAll in CASP13
        print FILE "METHOD predictions based on consensus of all models\n";
        print FILE "MODEL 2\n";
        print FILE "QMODE 1\n";

        foreach my $prediction (@predictions){
           my $serv_model = sprintf("%s_%s%s%s",$prediction->{_group_name}, $prediction->{_prfrmat}, $prediction->{_model}, (($prediction->{_prfrmat} eq 'AL')?'.pdb':''));
           print FILE sprintf("%s %1.5f\n",$serv_model, ($prediction->{_avrg_gdt_ts}/100.0));
        }
        print FILE "END\n";
	close(FILE);
}


sub create_prediction_QAconsensus_stage1{
    my ($self) = @_;
        my @predictions = @{$self->{_stage1_predictions}};
        # sort @predictions alphabetically
        @predictions = sort {$a->{_group_name} cmp $b->{_group_name} } @predictions;
        my $pred_file_name = $self->{_target}.".Davis-EMAconsensus.stage1";
        my $pred_file = sprintf("/data/".$LOCAL_CONFIG->{CASP_VERSION}."/tmp_QA/%s", $pred_file_name);
        open(FILE, "> $pred_file");
        print FILE "PFRMAT QA\n";
        print FILE "TARGET ".$self->{_target}."\n";
        print FILE "AUTHOR Davis-EMAconsensus\n"; # pin of group Davis-QAConsensus in CASP13
        print FILE "METHOD predictions based on consensus of selected models\n";
        print FILE "MODEL 1\n";
        print FILE "QMODE 1\n";
	
	my %hash_gdt_ts = %{$self->{_gdt_pred1_pred2}};
	my $p_count = 0;
        foreach my $prediction (@predictions){
	   # calc pred score loop over 
	   my $pred1 = sprintf("%s%s%03d_%1d", $self->{_target}, $prediction->{_prfrmat}, $prediction->{_group_code}, $prediction->{_model});
	   my $score = 0;
	   my $count = 0;
	   foreach my $prediction2 (@predictions){
		my $pred2 = sprintf("%s%s%03d_%1d", $self->{_target}, $prediction2->{_prfrmat}, $prediction2->{_group_code}, $prediction2->{_model});
		if($pred1 ne $pred2){
			$score = $score + $hash_gdt_ts{$pred1}{$pred2};
			$count++;
		}
	   }
           #my $serv_model = sprintf("%s_%s%s%s",$prediction->{_group_name}, $prediction->{_prfrmat}, $prediction->{_model}, (($prediction->{_prfrmat} eq 'AL')?'.pdb':''));
	   my $serv_model = sprintf("server%02d_TS1", ($p_count + 1));
           print FILE sprintf("%s %1.5f\n", $serv_model, ($count > 0 ? ($score/(100.0 * $count)) : 0.0));
	   $p_count++;
        }       
        print FILE "END\n";
	close(FILE);
}

sub create_prediction_QAconsensus_stage2{
    my ($self) = @_;
        my @predictions = @{$self->{_stage2_predictions}};
        # sort @predictions alphabetically
        @predictions = sort {$a->{_group_name} cmp $b->{_group_name} } @predictions;
        my $pred_file_name = $self->{_target}.".Davis-EMAconsensus.stage2";
        my $pred_file = sprintf("/data/".$LOCAL_CONFIG->{CASP_VERSION}."/tmp_QA/%s", $pred_file_name);
        open(FILE, "> $pred_file");
        print FILE "PFRMAT QA\n";
        print FILE "TARGET ".$self->{_target}."\n";
        print FILE "AUTHOR Davis-EMAconsensus\n"; # pin of group Davis-QAConsensus in CASP13
        print FILE "METHOD predictions based on consensus of selected models\n";
        print FILE "MODEL 2\n";
        print FILE "QMODE 1\n";

	my %hash_gdt_ts = %{$self->{_gdt_pred1_pred2}};

        foreach my $prediction (@predictions){
           # calc pred score loop over 
           my $pred1 = sprintf("%s%s%03d_%1d", $self->{_target}, $prediction->{_prfrmat}, $prediction->{_group_code}, $prediction->{_model});
           my $score = 0;
           my $count = 0;
           foreach my $prediction2 (@predictions){
                my $pred2 = sprintf("%s%s%03d_%1d", $self->{_target}, $prediction2->{_prfrmat}, $prediction2->{_group_code}, $prediction2->{_model});
                if($pred1 ne $pred2){
                        $score = $score + $hash_gdt_ts{$pred1}{$pred2};
                        $count++;
                }
           }

           my $serv_model = sprintf("%s_%s%s%s",$prediction->{_group_name}, $prediction->{_prfrmat}, $prediction->{_model}, (($prediction->{_prfrmat} eq 'AL')?'.pdb':''));
           print FILE sprintf("%s %1.5f\n",$serv_model, ($count > 0 ? ($score/(100.0 * $count)) : 0.0));
        }
        print FILE "END\n";
	close(FILE);

}




1; 

