#!/usr/bin/perl -w
############################################################
#
# $Id: matrix-clustering,v 1.5 2013/02/19 05:35:16 jvanheld Exp $
#
############################################################

## use strict;

=pod

=head1 NAME

matrix-clustering

=head1 VERSION

$program_version

=head1 DESCRIPTION

Taking  as input  one  or several  sets  of position-specific  scoring matrices,  this program  applies hierarchical  clustering to  identify clusters  of similar  motifs.  It produces  a set  of  trees (one  per cluster) and builds branch motifs at each node of each tree by merging the matrices of all descendent nodes.

=head1 DEPENDENCIES

Some R packages are required in I<matrix-clustering> in order to convert the 
hierarchical tree into different output formats, to manipulate the
dendrogram which is exported, and to produce heatmaps.

    RJSONIO : http://cran.r-project.org/web/packages/RJSONIO/index.html
    ctc : http://www.bioconductor.org/packages/release/bioc/html/ctc.html
    dendextend : http://cran.r-project.org/web/packages/dendextend/index.html
    Rclusterpp: http://cran.r-project.org/web/packages/Rclusterpp/index.html
    gplots : http://cran.r-project.org/web/packages/gplots/index.html
    
For visualize the logo forest it is required the JavaScript I<D3> (Data Driven Documents) library, 
the user can select an option to connect directly with the server to load the functions of this library 
(see option I<-d3_base>). 

    D3 : http://d3js.org/
    
As many files are produced with I<matrix-clustering> we created a dynamic website showing 
the complete list of results. We use the Javascript library I<JQuery> to create this dynamic website.

    JQuery: https://jquery.com/

=head1 AUTHORS

=head2 Implementation

=over

=item Jacques.van-Helden@univ-amu.fr

=item Jaime Castro <jcastro@lcg.unam.mx>

=back

=head2 Conception

=over

=item Jacques van Helden

The following collaborator contributed to the definition of
requirements for this program.

=item Carl Herrmann

=item Denis Thieffry

=item Morgane Thomas-Chollier

=back

=head1 CATEGORY

util

=head1 USAGE

matrix-clustering [-matrix inputfile] [-o outputfile] [-v ] [...]


=head1 OUTPUT FORMAT

=head1 SEE ALSO

=over

=item I<compare-matrices>

The program I<compare-matrices> is used by I<cluster-matrices> to
measure pairwise similarities and define the best alignment (offset,
strand) between each pair of matrices.

=back

=head1 WISH LIST

=cut

BEGIN {
  if ($0 =~ /([^(\/)]+)$/) {
    push (@INC, "$`lib/");
  }
}
require "RSA.lib";
require "RSA2.cgi.lib";
use RSAT::util;
use RSAT::matrix;
use RSAT::MatrixReader;
use RSAT::SeqUtil;
use List::MoreUtils qw(uniq);

require "RSA.disco.lib";
require "footprint.lib.pl";
use Data::Dumper;
use File::Basename;
use File::Path;

################################################################
## Main package
package main;
{

  ################################################################
  ## Initialise parameters
  local $start_time = &RSAT::util::StartScript();
  $program_version = do { my @r = (q$Revision: 1.5 $ =~ /\d+/g); sprintf "%d."."%02d" x $#r, @r };

  ## Input / output files
  %main::infile = ();
  %main::outfile = ();
  %main::dir = ();
  %main::param = ();
  @dirs = ();

  %main::matrix_file = ();
  %main::matrix_titles = ();

  $main::verbose = 0;
  $main::out = STDOUT;

  local @tab_to_convert = (); ## Tables to convert to html

  ## MDIFIED BY JvH (2017-06-30) Input formats: only accept formats supporting multiple matrices
  # local @supported_matrix_formats = qw(transfac tf tab cluster-buster cb infogibbs meme stamp uniprobe);
  # local %supported_matrix_format = ();
  # foreach my $format (@supported_matrix_formats) {
  #   $supported_matrix_format{$format} = 1;
  # }

  ## Supported input formats for the matrices
  local %supported_matrix_format = &RSAT::MatrixReader::ListInputMatrixFormats();
  local @supported_matrix_formats = sort keys %supported_matrix_format;
  local $supported_matrix_formats = join ",", @supported_matrix_formats;
#  local $matrix_format = "transfac"; ## Default matrix format

  ## Flag to export the Newick tree
  local $export_newick = 0;
  
  ## Flag to export the Newick tree
  local $radial_tree_flag = 0;

  ## Detect the input matrices command line is correct
  local $count_input_matrix_parameters = 0;

  ## Flag to add links to motif tree
  local $ID_link_flag = 0;
  local %ID_nb_hash = ();
  local %OLD_ID_link_hash = ();
  local %ID_link_hash = ();
  local %cluster_id_hash = ();

  ## operator
  $operator = "mean";
  local %supported_operator = ("mean"=>1, "sum"=>1);
  local $supported_operators = join ",", sort keys %supported_operator;

  ################################################################
  ## Ensure the access to the java libraries, which are required to
  ## display the results (logo trees, dynamic tables).
  ##
  ## If $include_js_lib is set to 1, the javascript libraries are
  ## included in the output directory, in order to avoid problems with
  ## the links. This solution enables to move the result
  ## (e.g. download a self-contained archive), but costs 500kb of disk
  ## space for each result, we should evaluate alternative solutions.
  ## 
  ## the alternative is to point to the libraries on the RSAT server,
  ## but we faced problems on some servers, due to the the path
  ## public_html/lib, which inludes a soft link (lib ->
  ## ../perl-scripts/lib).
  local $include_js_lib = 1; 


  ## Base on which we will buld the the URLs to the javascripts (D3 +
  ## JQuery libraries, required to display logo trees and tables).
  local $js_base;
  local $d3_base;
  local $d3_venn_base;
  local $jquery_base;
  local $datatable_base;
  local $datatable_css_base;

  ## Motif Collection names counter
  local %motif_collection_count = ();

  ## Parsed JSON files content
  local %json_files_content = ();

  ## Concatenate all the files which a logo will be produced
  ## This is done to call the system once
  local $concat_motif_files = "";

  ## Supported label motif fields
  local @supported_label_motif_fields = qw (id name collection ic);
  local %supported_label_motif_fields = ();
  foreach my $field (@supported_label_motif_fields) {
    $supported_label_motif_fields{$field} = 1;
  }
  local $supported_label_motif_fields = join ",", @supported_label_motif_fields;
  local %label_motif_fields_to_return = ();
  ## Default name::collection
  local @label_motif_fields_to_return = qw (name collection ic);


  ## Supported label fields
  local @supported_label_fields = qw (id name consensus ic);
  local %supported_label_fields = ();
  foreach my $field (@supported_label_fields) {
    $supported_label_fields{$field} = 1;
  }
  local $supported_label_fields = join ",", @supported_label_fields;
  local %label_fields_to_return = ();
  local @label_fields_to_return = ();

  ## Supported hclust methods
  local @supported_hclust_methods = qw (average centroid complete median single);
  local %supported_hclust_methods = ();
  foreach my $method (@supported_hclust_methods) {
    $supported_hclust_methods{$method} = 1;
  }
  local $supported_hclust_methods = join ",", @supported_hclust_methods;
  local $hclust_method = "average";

  ## Threshold parameters
  local %lth = ();		# lower threshold values
  local %uth = ();		# upper threshold values
  local @supported_thresholds = qw(
				     cor
                                     Ncor
                                     NcorS
                                     w
                                     dEucl
                                     NdEucl
                                     logocor
                                     logoDP
                                     Nlogocor
                                     Icor
                                     NIcor
                                     SSD
				   );
  local $supported_thresholds = join ",", @supported_thresholds;
  local %supported_threshold = ();
  foreach my $thr (@supported_thresholds) {
    $supported_threshold{lc($thr)} = 1;
  }

  ## Metric parameters
  local @supported_metrics = qw(
			         cor
                                 Ncor
                                 NcorS
                                 dEucl
                                 NdEucl
                                 logocor
                                 logoDP
                                 Nlogocor
                                 Icor
                                 NIcor
                                 SSD
                                 rank_mean
                                 mean_zscore
			     );
  local $supported_metrics = join ",", @supported_metrics;
  local %supported_metrics = ();
  foreach my $met (@supported_metrics) {
    $supported_metrics{lc($met)} = 1;
  }

  ## Matrices
  local @all_matrices = ();
  local $draw_heatmap = 0;
  local $align_consensus = 0;


  ## Unrecognized arguments are passed to compare-matrices
  local @args_to_pass = ();
  local $args_to_pass = "";
  
  ## Hash with the final alignment information
  local %alignment_info = ();
  local %cluster_info_width = ();

  ## Hash with the cluster information
  ## required to the HTML tree
  local %clusters_info = ();
  local %cluster_nodes = (); 
  local %clusters_to_HTML = (); 

  ## Lower and upper threshold on matrix comparison scores
  local %lth = ();
  local %uth = ();

  ## Merged consensuses logos
  local %merged_consensuses_files = ();

  ## Supported taks
  local @supported_tasks = qw(
			all
		        cluster
                        report
                     );
  local @task = qw (all);
  local $supported_tasks = join ",", @supported_tasks;
  local %supported_tasks = ();
  foreach my $task (@supported_tasks) {
    $supported_tasks{$task} = 1;
  }
  %selected_tasks = ();
  $selected_tasks{all} = 1;

  ## Use compare-matrices-quick
  local $quick_flag = 0;

  ## Heatmap color palette and classes
  local $heatmap_color_palette = "YlOrRd";
  local $heatmap_color_classes = 9;

  ## Permute input matrices
  local $random_flag = 0;

  ## Flag to dectect the user specified at least one input matrix file
  local $input_matrix = 0;

  ## display collection label in trees and alignment table
  local $display_collection_name_flag = 0;

  ## This option return only the root motifs saving time and memory. 
  ## The trees and heatmaps are not computed.
  local $root_matrices_flag = 0;

  ## Saves the features of the root motifs
  local %root_motifs_features = ();

  ## Limit the number of input motifs
  local $max_matrices = 0;
  local $top_matrices = 0;
  local $skip_matrices = 0;
  
  ## To export in the results the input file
  local $clone_input_flag = 1;

  ## Hashes used in the pre-process of the motifs
  local %motif_set_attributes = ();
  local %motifs_ID_unique = ();
  local $longest_title = 0;
  local $single_input_flag = 0;

  ## Saves the width of the largest alignment
  local $motif_width_by_cluster_width = 0;

  ## Supported positions to display the
  ## hclust trees in heatmap.
  ## This argument is passed to R
  local @supported_tree_positions = qw (row column both none);
  local %supported_tree_positions = ();
  foreach my $pos (@supported_tree_positions) {
    $supported_tree_positions{$pos} = 1;
  }
  local $supported_tree_positions = join ",", @supported_tree_positions;
  local $heatmap_tree_pos = "column";

  ## A hash to save the name of the clusters and their corresponding
  ## hexa code
  local %hexa_code = ();
  local $blue_color = '#D6EEFA';
  local $orange_color = '#F6E6CA'; 
  local $font_color = '#CC6600';
  local $blue_font_color = '#0D73A7';

  ## Lower threshold on column-wise information content: left-most and
  ## right-most columns having a lower IC are trimmed.
  $trim_threshold = 0;

  ## Supported fields to return
  local %return_fields = ();
  local @supported_return_fields = qw (align_consensus heatmap json newick root_matrices nb_clusters);
  local %supported_return_fields = ();
  foreach my $field (@supported_return_fields) {
    $supported_return_fields{$field} = 1;
  }
  local $supported_return_fields = join ",", @supported_return_fields;

  ## Supported heatmap colors (taken from http://colorbrewer2.org/)
  local %supported_heatmap_color_palette = ();
  local @supported_heatmap_color_palette = qw (YlOrRd YlOrBr YlGnBu YlGn PuRd PuBuGn PuBu OrRd GnBu BuPu BuGn Reds Purples Oranges Greys Greens Blues);
  local %supported_heatmap_color_palette = ();
  foreach my $palette (@supported_heatmap_color_palette) {
    $supported_heatmap_color_palette{$palette} = 1;
  }
  local $supported_heatmap_color_palette = join ",", @supported_heatmap_color_palette;

  ## Number of input collections
  local $number_of_collections = "";
  
  ## Motif list flag
  local $motif_list_flag = 0;
  local $motif_direct_input_flag = 0;

  ## List of files to delete
  %to_delete = ();
  %to_delete_folder = ();

  ################################################################
  ## Set default options
  local %param = ();
  local @matrix_compa_metrics = qw(cor Ncor Ncor1 Ncor2 NcorS logoDP logocor Nlogocor Icor NIcor cov dEucl NdEucl NsEucl SSD SW NSW match_rank zscores);
  $param{matrix_compa_metrics} = join(",", @matrix_compa_metrics);
  $param{matrix_compa_sort_field} = "Ncor"; ## sorting field
  $main::param{matrix_compa_score} = "Ncor";
  $param{archive_format} = "zip";
  $param{progressive_synthesis} = 1;
  $param{title} = "matrix-clustering results";

  ################################################################
  ## Read argument values
  &ReadArguments();

  ################################################################
  ## Check argument values
  &RSAT::message::TimeWarn("Checking parameter values") if ($main::verbose >= 2);

  ################################################################
  ## Input file is mandatory
  unless ($input_matrix) {
    &RSAT::error::FatalError("At least one matrix file should be specified: see options -matrix or -matrix_file_table)");
  }

  # unless ($matrix_format) {
  #   &RSAT::error::FatalError("Matrix format must be specified (option -matrix_format).");
  # }

  ################################################################
  ## Non-recognized parameters are passed to compare-matrices
  if (scalar(@args_to_pass)) {
    $args_to_pass = join (" ", @args_to_pass);
    &RSAT::message::Info("Unrecognized arguments passed to matrix-clustering", $args_to_pass) if ($main::verbose >= 2);
  }

  ################################################################
  ## Check that the output prefix has been specified
  unless ($outfile{prefix}) {
    &RSAT::error::FatalError("You must define the output prefix (option -o).");
  }

  ################################################################
  ## Labels displayed in the logo tree
  if (scalar(@label_fields_to_return) == 0) {
    @label_fields_to_return = qw(id name);
    for my $field (@label_fields_to_return) {
      $label_fields_to_return{$field} = 1;
    }
  }
  $label_fields_to_return = join ",", @label_fields_to_return;
  &RSAT::message::Info("Labels displayed in logo trees: ", $label_fields_to_return) if ($main::verbose >= 5);

  ################################################################
  ## Check output directories and define file names
  &set_output_file_names();

  ## Initialize HTML summary
  &OpenSynthesis() if ($main::param{progressive_synthesis}); ## Already open the HTML report summary, for the Web site
  if ($root_matrices_flag == 1) {
      $to_delete{'summary'} = $main::outfile{summary};
  }
  
  ################################################################
  ##
  ##
  if($motif_list_flag == 1){     
      &read_motif_table_file();
  }

  ################################################################
  ## Pre-process the input motif file(s):
  ## 1) Restrict the number of motifs
  ## 2) Assign unique IDs to each motif
  &pre_process_motif_files();


  ################################################################
  ## Generate the matrix description table
  &Generate_matrix_description_table();

  ## According to the task selected by the user, execute or skip
  ## some functions
  if ($selected_tasks{all}) {

      if ($quick_flag == 0) {

  	  ################################################################
  	  ## Compare the matrices with compare-matrices
  	  &CompareMatrices();

      } elsif ($quick_flag == 1) {
  	  ################################################################
  	  ## Compare the matrices with compare-matrices-quick
  	  &CompareMatricesQuick();
      }
  }

  if ($selected_tasks{all} || $selected_tasks{cluster}) {

      ################################################################
      ## Cluster the matrices
      &Hclustering();
  }

  if ($selected_tasks{all} || $selected_tasks{cluster} || $selected_tasks{report}) {

      ################################################################
      ## Separate the input motif file into separated files (one file for each cluster)
      ## with the motifs in TRANSFAC format
      &Clustered_PSSMS_TRANSFAC_format();
      
      ################################################################
      ## Read the motif to cluster assignation, which will be required for
      ## several functions below.
      &ReadClusterComposition();
      
      ################################################################
      ## Create the logos with the empty columns, which will be 
      ## displayed in the dynamic tree.
      ## Produce the TRANSFAC files with the aligned motifs in both
      ## orientations. 
      &Add_gaps_to_motifs();

      ################################################################
      ## Create the merged matrices and consensuses
      if($radial_tree_flag == 0){
	  &Merge_matrices();
            
      ################################################################
      ## Export central motif in TF format
	  &Export_central_motif_per_cluster();
      }

      
      if ($root_matrices_flag == 1) {
	  
	  ## Some files and directories that must be deleted
	  $to_delete_folder{'clusters_information'} = $main::outfile{prefix}."_clusters_information";
	  $to_delete_folder{'html'} = $main::outfile{prefix}."_html";
	  $to_delete_folder{'tables'} = $main::outfile{prefix}."_tables";
	  $to_delete_folder{'json_coverage'} = $main::outfile{prefix}."_coverage_json";
	  $to_delete_folder{'aligned_logos'} = $main::outfile{prefix}."_aligned_logos";
	  $to_delete_folder{'data_folder'} = $main::outfile{prefix}."_data";
	  $to_delete{'log'} = $main::outfile{prefix}."_log.txt";
	  $to_delete{'errors'} = $main::outfile{prefix}."_errors.txt";
	  $to_delete{'temp_central'} = $main::outfile{central_motifs_IDs_temp};
	  
      } else {
	  
	  ################################################################
	  ## Produce all the logos 
	  ## Aligned + Branch-wise motifs
	  &Produce_logos();
	  
	  ################################################################
	  ## Read the table with the hexadecimal code 
	  ## for the colors assigned to each cluster
	  %hexa_code = &Read_cluster_colors();
	  
	  ################################################################
	  ## Parse the JSON file
	  &Add_attributes_to_JSON();
	  
	  ################################################################
	  ## Creates the body of html to display
	  ## each cluster separately
	  if($radial_tree_flag == 0){
	      &Create_dynamic_tree();
	  }
	  
	  ################################################################
	  ## Convert tab files to HTML files
	  &ConvertTabToHTML(@tab_to_convert);
      }
  }
	  
  if ($root_matrices_flag == 0) {
	      
      ################################################################
      ## Creates the website
      &Synthesis();
      
      ################################################################
      ## Create an archive with all result files
      &Archive(1);
  }  

  #######################################
  ## Delete temporal files and folders
  &Delete_temporal_files();

  ################################################################
  ## Print verbose
  &Verbose() if ($main::verbose >= 1);
  
  ################################################################
  ## Close output stream
  my $exec_time = &RSAT::util::ReportExecutionTime($start_time); print $main::out $exec_time if ($main::verbose >= 1);
  close $main::out if ($main::outfile{prefix});
  
  exit(0);
}

################################################################
################### SUBROUTINE DEFINITION ######################
################################################################


################################################################
## Display full help message 
sub PrintHelp {
    system "pod2text -c $0";  
    exit()
}

################################################################
## Display short help message
sub PrintOptions {
    &PrintHelp();
}

################################################################
## Read arguments 
sub ReadArguments {
    my $arg;
    my @arguments = @ARGV; ## create a copy to shift, because we need ARGV to report command line in &Verbose()
    while (scalar(@arguments) >= 1) {
	$arg = shift (@arguments);

=pod

=head1 OPTIONS

=over 4

=item B<-v #>

Level of verbosity (detail in the warning messages during execution)

=cut
    if ($arg eq "-v") {
      if (&IsNatural($arguments[0])) {
	$main::verbose = shift(@arguments);
      } else {
	$main::verbose = 1;
      }

=pod

=item B<-h>

Display full help message

=cut
    } elsif ($arg eq "-h") {
      &PrintHelp();


=pod

=item B<-help>

Same as -h

=cut
    } elsif ($arg eq "-help") {
      &PrintOptions();


      
=pod

=item B<-matrix matrix_title input_matrix_file>

The input file contains a set of position-specific scoring
matrices.

Example: -matrix OCt_motifs Oct_motifs_peakmotifs.tf tf

The matrix_title will be concatenated to each motif ID in order to
create unique motif IDs. The collection label is displayed in the results.

This label is useful when two motifs for the same TF come from different
files and the user wants to know to which collection does the motif come from.

B<Supported matrix formats>

Since the program takes several matrices as input, it only accepts
matrices in formats supporting several matrices per file (transfac,
tf, tab, cluster-buster, cb, infogibbs, meme, stamp, uniprobe).

For a description of these formats, see the help of I<convert-matrix>.

=cut
    } elsif ($arg eq "-matrix") {

	$count_input_matrix_parameters = 0;
	my $matrix_title = shift(@arguments);
	
	if ($matrix_title){
	    $count_input_matrix_parameters++;
	}
	
	## Substitue special characters which cannot be used inside a file name
	$matrix_title =~ s|\s|_|g;
	$matrix_title =~ s|/|_|g;
	$matrix_title =~ s|:|_|g;
	
	$main::matrix_file{$matrix_title} = shift(@arguments);
	$main::matrix_format{$matrix_title} = shift(@arguments);

	if ($main::matrix_file{$matrix_title}){
	    $count_input_matrix_parameters++;
	}
	
	push @main::matrix_titles, $matrix_title;
	
	$input_matrix = 1;
    $motif_direct_input_flag = 1;

	if ( ($count_input_matrix_parameters != 2) || ($matrix_title =~ /^-/) || ($main::matrix_file{$matrix_title} =~ /^-/) ){
	    &RSAT::error::FatalError("Input should be specified with matrix file (option -matrix) with 2 parameters: matrix_title matrix_file\n\tExample: -matrix Oct_motifs Oct_motifs_peakmotifs.tf");
	} 
	
	if($motif_list_flag == $motif_direct_input_flag) {
	&RSAT::error::FatalError("The options -matrix and -matrix_file_table are incompatibles");
      }


=pod

=item B<-matrix_file_table matrix_file_table>

This option is recommended when the input number of files is large (> 20), which
would have a large command line and some programs are not capable of read such large arguments.

The input file contains a tab-delimited table with two columns:

1) The motif file - The path to the file with the motif
2) The collection label

Example: 

Sox_pssms.tf	Sox
Oct_pssms.tf	Oct
Nanog_pssms.tf	Nanog

=cut
    } elsif ($arg eq "-matrix_file_table") {
		
		$main::infile{motif_table_file} = shift(@arguments);

		$motif_list_flag = 1;
		$input_matrix = 1;
	  
	  	if($motif_list_flag == $motif_direct_input_flag) {
			&RSAT::error::FatalError("The options -matrix and -matrix_file_table are incompatibles");
		}

=pod

=item B<-matrix_format matrix_format>

Specify the input matrix format.


B<Supported matrix formats>

Since the program takes several matrices as input, it only accepts
matrices in formats supporting several matrices per file (transfac,
tf, tab, clusterbuster, cb, infogibbs, meme, stamp, uniprobe).

For a description of these formats, see the help of I<convert-matrix>.

=cut
    } elsif ($arg eq "-matrix_format") {
      $main::matrix_format = shift(@arguments);
      unless ($supported_matrix_format{$matrix_format}) {
	&RSAT::error::FatalError($matrix_format, "Invalid format for input matrices\tSupported: ".$main::supported_matrix_formats);
      }


=pod

=item B<-ID_link_table matrix_ID_link_table>

This option allows to add a link to a any website specified by the user.
It is useful clustering a full database (e.g. Jaspar), thus each motif in the logo tree
will point to its recpective link in the Jaspar website.

Format: a two-column file
Column 1: Motif ID (the same as the input motif file)
Column 2: Link to any website

=cut
    } elsif ($arg eq "-ID_link_table") {
      $main::infile{ID_link_table} = shift(@arguments);
      $ID_link_flag = 1;


=pod

=item	B<-title title>

Title displayed on top of the report page.

=cut
     } elsif ($arg eq "-title") {
      $main::param{title} = shift(@arguments);
      $main::param{title} =~ s/\s+/_/g;

=pod

=item	B<-radial_tree_only>

Generates a radial motif tree (option recommended for visualization purposes). When this option is indicated, all the input motifs are forced to be aligned in a single alignment displayed in a radial tree (this tree is not interactive). This option skips the generation of branch-motifs and the generation of the dynamic output (e.g., heatmaps). 

=cut
     } elsif ($arg eq "-radial_tree_only") {
      $radial_tree_flag = shift(@arguments);
      $radial_tree_flag = 1;

=pod

=item	B<-o output_prefix>

Prefix for the output files.

Mandatory option: since the program I<cluster-matrices> returns a
list of output files (pairwise matrix comparisons, matrix clusters).

=cut
    } elsif ($arg eq "-o") {
      $main::outfile{prefix} = shift(@arguments);

=pod

=item B<-heatmap_position_tree [row,col,both,none]>

The position in the heatmap where the hierarchical tree will
be displayed.

=cut

    } elsif ($arg eq "-heatmap_position_tree") {
      $heatmap_tree_pos = shift(@arguments);
      unless(exists($supported_tree_positions{$heatmap_tree_pos})) {
	&RSAT::error::FatalError($heatmap_tree_pos, "Invalid position. Supported:", $supported_tree_positions);
      }

=pod

=item B<-task tasks>

Specify one or several tasks to be run. If this option is not
specified, all the tasks are run.

Note that some tasks depend on others. This option should thus be
used with caution, by advanced users only.

Supported tasks: (all, comparison, clustering, report)

=over

=item B<all>

Execute all the parts of the program (default)

=item B<comparison>

Run the motif comparison step. The input set of motifs are compared
against themselves. The output is the pairwise comparison between the input motifs 
and a description table showing the main features of each motif (name, id, consensus, width). 

=item B<clustering>

Skip the matrix comparison step and only executes the clustering step.

Assumes the users already have the description table and comparison table 
exported from the program I<compare-matrices>.

This option is ideal to saving time once all comparison beteen the input motifs had been done. 

=back

=cut

       } elsif ($arg eq "-task") {
	 $arg = shift (@arguments);
	 chomp($arg);
	 my @tasks = split ",", $arg;
         %selected_tasks = ();
	 foreach my $task (@tasks) {
	   $task = lc($task);
	   if ($supported_tasks{$task}) {
	     $selected_tasks{$task} = 1;
	   } else {
	     &RSAT::error::FatalError(join("\t", $task, "Invalid tasks. Supported:", $supported_tasks));
	   }
	 }

=pod

=item	B<-label_in_tree>

Option to select the labels displayed in the logo tree.
    
B<Supported labels>
    
 (name, consensus, id)
 
=cut

    } elsif ($arg eq "-label_in_tree") {
      my $label_fields_to_return = shift(@arguments);
      my @new_label_fields_to_return = split (",", $label_fields_to_return);
      foreach my $field (@new_label_fields_to_return) {
	if ($supported_label_fields{$field}) {
	  $label_fields_to_return{$field} = 1;
	  push @label_fields_to_return, $field;
	} else {
	  &RSAT::error::FatalError(join("\t", $field, "Invalid return field. Supported:", $supported_label_fields));
	}
      }

=pod

=item	B<-label_motif>

Option to select the labels displayed in the cluster summary.

B<Supported labels>
    
 (name, consensus, collection)

Default: name::collection
 
=cut
    } elsif ($arg eq "-label_motif") {
	%label_motif_fields_to_return = ();
	@label_motif_fields_to_return = ();
	my $supported_label_motif_fields = shift(@arguments);
	my @new_label_motif_fields_to_return = split (",", $supported_label_motif_fields);
	foreach my $field (@new_label_motif_fields_to_return) {
	    if ($supported_label_motif_fields{$field}) {
		$label_motif_fields_to_return{$field} = 1;
		push @label_motif_fields_to_return, $field;
	    } else {
		&RSAT::error::FatalError(join("\t", $field, "Invalid motif label field. Supported:", $supported_label_motif_fields));
	    }
	}


=pod

=item	B<-quick>

With this option the motif comparison is done with  the program I<compare-matrices-quick> 
(implemented in C) rather than the program compare-matrices (implemented in Perl).
The quick version runs x100 times faster, but has not all implemented options as in the Perl version.

We suggest use this option for a big set of input motifs > 300 motifs. 

B<NOTE:> By the moment the only a few thresholds can be used with this option. (cor, Ncor, w) 

=cut

    } elsif ($arg eq "-quick") {
    $quick_flag = 1;

=pod

=item	B<-no_clone_input>

Desactive tha option to copy the input file.
If more than one collections of motifs are provided, they are exported in a single file.

NOTE: take into account the input file size

=cut

    } elsif ($arg eq "-no_clone_input") {
    $clone_input_flag = 0;


=pod

=item	B<-rand>

When this option is selected, the columns of the input motifs are randomly permuted (conserving thus the Information Content), the new motifs are used as input for the pairwise-comparison and clustering.

=cut

    } elsif ($arg eq "-rand") {
    $random_flag = 1;


=pod

=item	B<-heatmap_color_palette Color_Palette>

Select the color palette used in the heatmaps (sequential scales)
The color palettes (and their names) are taken from ColorBrewer2 website (http://colorbrewer2.org/)

Supported: YlOrRd,YlOrBr,YlGnBu,YlGn,PuRd,PuBuGn,PuBu,OrRd,GnBu,BuPu,BuGn,Reds,Purples,Oranges,Greys,Greens,Blues

Default: YlOrRd
=cut

    } elsif ($arg eq "-heatmap_color_palette") {
         $heatmap_color_palette = shift(@arguments);
         unless(exists($supported_heatmap_color_palette{$heatmap_color_palette})) {
	   &RSAT::error::FatalError($heatmap_color_palette, "Invalid hclust method. Supported:", $supported_heatmap_color_palette);
         }

=pod

=item	B<-heatmap_color_classes X>

This option specifies in how many color classes the color palette will be divided.

For sequential color palettes: max 9
For diverging color palettes: max 11

If the user specified a color greater than the maximum allowed, the program takes this maximum value.

For more information see ColorBrewer2 website (http://colorbrewer2.org/)

=cut
    } elsif ($arg eq "-heatmap_color_classes") {
      $heatmap_color_classes = shift(@arguments);

      &RSAT::error::FatalError($heatmap_color_classes, "Invalid value for option -top_matrices: must be a natural number") 
         unless (&IsNatural($heatmap_color_classes));

=pod

=item	B<-max_matrices X>

This option specifies how many matrices can be clustered in the same
analysis. If there are more matrices than the specified number, the
program restrics the analyses to the first X matrices, and issues a
warning.

This parameter can be useful to prevent submission of excessive
datasets to the Web server, or for running quick tests before starting
the analysis of a large matrix collection.

=cut
    } elsif ($arg eq "-max_matrices") {
      $max_matrices = shift(@arguments);
    
      
=pod

=item	B<-hclust_method>

Option to select the agglomeration rule for hierarchical clustering.

Supported agglomeration rules:
 
=over

=item I<complete>

Compute inter-cluster distances based on the two most distant nodes.

=item I<average> (default)

Compute inter-cluster distances as the average distance between nodes
belonging to the relative clusters. (UPGMA)

=item I<single>

Compute inter-cluster distances based on the closest nodes.

=back

=cut
    
    } elsif ($arg eq "-hclust_method") {
      $hclust_method = shift(@arguments);
      unless(exists($supported_hclust_methods{$hclust_method})) {
	&RSAT::error::FatalError($hclust_method, "Invalid hclust method. Supported:", $supported_hclust_methods);
      }

=pod

=item B<-top_matrices X>

Only analyze the first X motifs of the input file. This options is
convenient for quick testing before starting the full analysis.

If several motif files are specified, the selection of top motifs is
performed independently for each motif collection (the max number of
motifs will this be X * the number of input files).

=cut
    } elsif ($arg eq "-top_matrices") {
      $top_matrices = shift(@arguments);

      &RSAT::error::FatalError($top_matrices, "Invalid value for option -top_matrices: must be a natural number") 
         unless (&IsNatural($top_matrices));

=pod

=item B<-skip_matrices X>

Skip the first X motifs of the input file. This options is convenient
for testing the program on a subset of the motifs before starting the
full analysis.

If several motif files are specified, the option is applied to each
file independently.

=cut
    } elsif ($arg eq "-skip_matrices") {
      $skip_matrices = shift(@arguments);
      &RSAT::error::FatalError($skip_matrices, "Invalid value for option -skip_matrices: must be a natural number") 
         unless (&IsNatural($skip_matrices));

=pod

=item	B<-metric_build_tree metric>

Select the metric which will be used to cluster the motifs.based in one metric of to measure motif
similarity. This metric can be a similarity or distance, in both cases the values are converted to 
a distance table which is used as input for the hierarchical clustering.

Supported metrics : cor, Ncor, NcorS, dEucl, NdEucl, logocor, logoDP, Nlogocor, Icor, NIcor, SSD, rank_mean, mean_zscore

Default: Ncor 

=cut

    } elsif ($arg eq "-metric_build_tree") {
      my $metric = shift(@arguments);
      unless ($supported_metrics{lc($metric)}) {
	&RSAT::error::FatalError("Invalid metric field $metric. Supported: $supported_metrics");	
      }
      $main::param{matrix_compa_score} = $metric;
      $main::param{matrix_compa_sort_field} = $metric; 
   	
=pod

=item	B<-lth param lower_threshold>

=item	B<-uth param upper_threshold>

Threshold on some parameters (-lth: lower, -uth: upper threshold).

Once the hierarchical tree is built, this tree is traversed in a bottom-up way.
On each branch the descendant motifs are evaluated in the same way the clustering method
selected by the user (average, complete, single).

In this algorithm, the threshold can be set combining values of different metrics.

If the descendant motifs for a particular branch do not satisfy the threshold 
a new cluster is created.

For a complete description of the thresholds and the motif comparison metrics
 see the help of I<compare-matrices>

Suggested thresholds:

    cor >= 0.7

    Ncor >= 0.4

    w >= 5

=cut

    } elsif ($arg eq "-lth") {
      my $thr_field = shift(@arguments);
      my $thr_value =  lc(shift(@arguments));
      unless ($supported_threshold{lc($thr_field)}) {
	&RSAT::error::FatalError("Invalid threshold field $thr_field. Supported: $supported_thresholds");
      }
      &RSAT::error::FatalError($thr_value, "Invalid value for a lower threshold. Should be a real number. ")
	  unless (&RSAT::util::IsReal($thr_value));
      $lth{$thr_field} = $thr_value;
     
      ### Upper threshold
    } elsif ($arg eq "-uth") {
      my $thr_field = shift(@arguments);
      my $thr_value = shift(@arguments);
      unless ($supported_threshold{lc($thr_field)}) {
	&RSAT::error::FatalError("Invalid threshold field $thr_field. Supported: $supported_thresholds");
      }
      &RSAT::error::FatalError($thr_value, "Invalid value for an upper threshold. Should be a real number. ")
	  unless (&RSAT::util::IsReal($thr_value));
      $uth{$thr_field} = $thr_value;

=pod

=item B<-calc merging_stat>

Specify the operator used to merge matrices (argument passed to I<merge-matrices)>. 

Supported: 

=over

=item I<mean> (default)

Each cell of the output matrix contains the mean of the values found
in the corresponding cell of the input matrices.

=item I<sum>

Each cell of the output matrix contains the sum of the values found
in the corresponding cell of the input matrices.

Note: the option I<diff>, supported by I<merge-matrices>, is not accepted
for I<matrix-clustering>.

=back

=cut

    } elsif ($arg eq "-calc") {
      $operator = lc(shift(@arguments));
      unless ($supported_operator{$operator}) {
	&RSAT::error::FatalError($operator, "Invalid operator for option -calc. ", "Supported: ".$supported_operators);
      }


=pod

=item B<-trim_threshold #>

Trimming threshold.

Left- and right-most columns whose information content are smaller
than this threshold will be trimmed, to avoid exporting large matrices
with non-informative flanks. 

B<Beware:> in some cases the trimming can deteriorate the motifs, by
cutting moderately informative positions.

=cut
    } elsif ($arg eq "-trim_threshold") {
      $trim_threshold = shift(@arguments);
      unless (&IsReal($trim_threshold)) {
	&RSAT::error::FatalError($trim_threshold, "Invalid value for option -trim_threshold. Should be a Real number.");
      }


=pod

=item B<-return return_fields>

List of fields to return.

Supported fields:

 heatmap,json,newick,root_matrices

=over

=item B<clone_input:> Copy input file.

When this field is selected, the input motif database is copied 
and exported in the results folder.

NOTE: take into account the input file size.

=item B<heatmap:> Heatmap with similarities.

When this field is selected, exports a heatmap showing the 
similarities, the clusters and the hierarchical tree of the 
input motifs.

The heatmap is exported in JPEG and PDF format. 

We recommend to use this option when the number of motifs is 
lower than 300. 

=item B<json:> Hierarchical tree in JSON format.

File format used for D3 library to visualize the logo forest in HTML.

The hierarchical tree in JSON format is always exported, 
since it is required to display the logo tree with the d3 library.

=item B<newick:> Hierarchical tree in newick format.

When this field is specified, the hierarchical tree is converted 
and exported in Newick format, a widely used text format to represent 
phylogenetic trees.

=item B<root_matrices:> Return only the root motif of each cluster.

When this field is specified, matrix-clustering runs the minimal 
analysis and return a text file with the root motifs of each
cluster.

This option is useful when the user wants to explore the data and
to avoid the cimputation of the visual elements. 

=back

=cut
    } elsif ($arg eq "-return") {
      $arg = shift (@arguments);
      chomp($arg);
      my @fields_to_return = split ",", $arg;
      foreach my $field (@fields_to_return) {
	$field = lc($field);

	if ($supported_return_fields{$field}) {
	  $return_fields{$field} = 1;

	  if ($return_fields{clone_input}){
	      $clone_input_flag = 1;
	  } 

	  if ($return_fields{align_consensus}){
	      $align_consensus = 1;
	  }  

	  if ($return_fields{heatmap}){
	      $draw_heatmap = 1;
	  }  
	  
	  if ($return_fields{newick}){
	      $export_newick = 1;
	  } 

	  if ($return_fields{root_matrices}){
	      $root_matrices_flag = 1;
	      $clone_input_flag = 0;
	  }

	} else {
	  &RSAT::error::FatalError(join("\t", $field, "Invalid return field. Supported:", $supported_return_fields));
	}
      }

    ## Additional arguments are passed to compare-matrices
    } else {
        if ($arg =~ /\s/) {
	    push @args_to_pass, "'".$arg."'";
        } else {
	    push @args_to_pass, $arg;
        }
    }
  }
=pod

=back

=cut

}

################################################################
## Verbose message
sub Verbose {
  print $main::out "; matrix-clustering ";
  &PrintArguments($main::out);
  printf $main::out "; %-22s\t%s\n", "Program version", $program_version;
  if (%main::infile) {
    print $main::out "; Input files\n";
    while (my ($key,$value) = each %main::infile) {
      printf $main::out ";\t%-28s\t%s\n", $key, $value;
    }
  }
  printf $main::out  "; %-28s\t%s\n", "Number of matrices", scalar(@all_matrices);

  if (%main::outfile) {
    print $main::out "; Output files\n";
    while (my ($key,$value) = each %main::outfile) {
      printf $main::out ";\t%-28s\t%s\n", $key, $value;
    }
  }

  if (%main::dir) {
    print $main::out "; Directories\n";
    while (my ($key,$value) = each %main::dir) {
      printf $main::out ";\t%-28s\t%s\n", $key, $value;
    }
  }
}


################################################################
## Set output file names + check output directories
sub set_output_file_names {
  ## Create output dir if required
  my $basename;
  ($dir{output}, $basename) = &RSAT::util::SplitFileName($main::outfile{prefix});
  $dir{output} = "." if ($dir{output} eq "");
  &RSAT::util::CheckOutDir($dir{output});
  push @dirs, "output";

  local @output_folders = ();

  if ($root_matrices_flag == 0) {
      ## Create output directories
      @output_folders = qw( coverage_json tables html figures pairwise_compa_logos aligned_logos);
      foreach my $f (@output_folders) {
	  my $new_f = $main::outfile{prefix}."_".$f;
	  &RSAT::util::CheckOutDir($new_f);
      }
  } elsif ($root_matrices_flag == 1) {
      ## Create output directories
      @output_folders = qw( tables html aligned_logos);
      foreach my $f (@output_folders) {
	  my $new_f = $main::outfile{prefix}."_".$f;
	  &RSAT::util::CheckOutDir($new_f);
      }
  }

  ################################################################
  ## Specify output file names and open output stream

  ## Log file should contain the trace of all commands
  
  $main::outfile{log} = $main::outfile{prefix}."_log.txt"; push @outfiles, "log";
  $main::out = &OpenOutputFile($main::outfile{log});

  ## Error file should contain only errors
  $main::outfile{err_log} = $main::outfile{prefix}."_errors.txt"; push @outfiles, "err_log";
  $main::err = &OpenOutputFile($main::outfile{err_log});

  ## Specific log file for R commands
  $main::outfile{Rlog} = $main::outfile{prefix}."_Rlog.txt"; push @outfiles, "Rlog";

  ## Converted matrices (required for compare-matrices-quick, and to
  ## restrict the number of matrices with option -max_matrices).
  $main::outfile{input_matrices} = $main::outfile{prefix}."_input_motifs.tf"; push @outfiles, "input_matrices"; 

  ## Cluster IDs names
  $main::outfile{cluster_IDs_names} = $main::outfile{prefix}."_cluster_IDs.txt";

  ## Pairwise comparisons between matrices
  $main::outfile{pairwise_compa} = $main::outfile{prefix}."_tables/pairwise_compa.tab"; push @outfiles, "pairwise_compa"; 
  $main::outfile{pairwise_compa_html} = $main::outfile{prefix}."_html/pairwise_compa.html";  push @outfiles, "pairwise_compa_html";

  ## Individual matrix descriptions
  $main::outfile{matrix_descriptions} = $main::outfile{prefix}."_tables/pairwise_compa_matrix_descriptions.tab"; push @outfiles, "matrix_descriptions"; &AddTabToConvert("matrix_descriptions");
  $main::outfile{matrix_descriptions_html} = $main::outfile{prefix}."_html/pairwise_compa_matrix_descriptions.html";  push @outfiles, "matrix_descriptions_html";

  ## Hexadecimal color for the clusters
  $main::outfile{hexa_colors} = $main::outfile{prefix}."_hexa_colors.txt";

  ## Export small d3 forest
  $main::outfile{small_forest_export} = $main::outfile{prefix}."_small_forest.html";

  ## Radial tree template and output file
  $main::outfile{radial_tree} = $main::outfile{prefix}."_radial_tree.html";
  $main::outfile{radial_tree_template} = $ENV{RSAT}."/public_html/templates_html/Radial_tree_template.html";

  ## Table with the number of clusters
  $main::outfile{nb_clusters_table} = $main::outfile{prefix}."_tables/number_of_clusters.tab";

  ## Table with the summary of clusters + percentage
  $main::outfile{cluster_summary_table} = $main::outfile{prefix}."_tables/clusters_summary_table.tab";
  $main::outfile{percent_table} = $main::outfile{prefix}."_tables/clusters_summary_percent_table.tab";
  $main::outfile{coverage_table} = $main::outfile{prefix}."_tables/clusters_summary_coverage_contingency_table.tab";


  ## Table with summary of clusters parsed.
  ## This is the format required for D3 heatmap!
  $main::outfile{heatmap_coverage_d3} = $main::outfile{prefix}."_tables/convergency_heatmap_tab.tsv";
  $main::outfile{heatmap_coverage_attributes} = $main::outfile{prefix}."_tables/convergency_heatmap_attributes.tab";
  $main::outfile{coverage_json_folder} = $main::outfile{prefix}."_coverage_json";

  $main::outfile{heatmap_collections_d3} = $main::outfile{prefix}."_tables/collection_heatmap_tab.tsv";
  $main::outfile{heatmap_collections_attributes} = $main::outfile{prefix}."_tables/collection_heatmap_order.tab";


  $main::outfile{motif_richness_barplot_html} = $main::outfile{prefix}."_motif_richness_barplot.html";
  $main::outfile{motif_richness_tsv} = $main::outfile{prefix}."_motif_richness.tsv";

  ## Table with the Clusters ID + Logo path of root motifs
  $main::outfile{root_motifs_table} = $main::outfile{prefix}."_root_motifs_table.tab";

  ## Output files for the hierarchical clustering trees
  $main::outfile{distance_table} = $main::outfile{prefix}."_tables/distance_table.tab"; push @outfiles, "distance_table"; &AddTabToConvert("distance_table");
  $main::outfile{alignment_table} = $main::outfile{prefix}."_tables/alignment_table.tab"; push @outfiles, "alignment_table"; &AddTabToConvert("alignment_table");
  $main::outfile{clusters_table} = $main::outfile{prefix}."_tables/clusters.tab"; push @outfiles, "clusters"; &AddTabToConvert("clusters_table");
  $main::outfile{clusters_table_motif_names} = $main::outfile{prefix}."_tables/clusters_motif_names.tab"; push @outfiles, "clusters with motif names"; &AddTabToConvert("clusters_table_motif_names");
  $main::outfile{internal_nodes_attributes_table} = $main::outfile{prefix}."_tables/internal_nodes_attributes.tab"; push @outfiles, "internal_nodes_attributes_table";
  $main::outfile{central_motifs_tf} = $main::outfile{prefix}."_central_motifs_transfac.tf";
  $main::outfile{central_motifs} = $main::outfile{prefix}."_central_motifs_IDs.tab";
  $main::outfile{central_motifs_IDs_temp} = $main::outfile{prefix}."_central_motifs_IDs_temporal.tab";

  $main::outfile{consensus_cladogram_json} = $main::outfile{prefix}."_trees/tree.json"; push @outfiles, "consensus_cladogram_json";
  $main::outfile{logo_cladogram_html} = $main::outfile{prefix}."_logo_tree.html"; push @outfiles, "logo_cladogram_html";
  $main::outfile{small_logo_cladogram_html} = $main::outfile{prefix}."_portable_logo_tree.html"; push @outfiles, "small_logo_cladogram_html";
  $main::outfile{dynamic_heatmap_html} = $main::outfile{prefix}."_dynamic_heatmap.html"; push @outfiles, "dynamic_heatmap_html";
  $main::outfile{dynamic_coverage_heatmap_html} = $main::outfile{prefix}."_dynamic_coverage_heatmap.html"; push @outfiles, "coverage_heatmap_html";
  $main::outfile{heatmap_jpg} = $main::outfile{prefix}."_figures/heatmap.jpg";
  $main::outfile{heatmap_pdf} = $main::outfile{prefix}."_figures/heatmap.pdf";

  $main::outfile{all_concatenated_motifs} = $main::outfile{prefix}."_aligned_logos/All_concatenated_motifs.tf";
  &OpenOutputFile($main::outfile{all_concatenated_motifs});
  

  ## Newick-formatted phylogram with motif consensuses
  if ($export_newick == 1) {
    $main::outfile{consensus_phylogram_newick} = $main::outfile{prefix}."_trees/tree.newick"; push @outfiles, "consensus_phylogram_newick";  
  }

  ## Root matrices file
  $main::outfile{root_motifs} = $main::outfile{prefix}."_cluster_root_motifs.tf";

  ## Files required for the summary
  $main::outfile{summary_temp} = $main::outfile{prefix}."_SUMMARY_TEMP.html";
  $main::outfile{summary} = $main::outfile{prefix}."_SUMMARY.html"; push @outfiles, "summary";

  if ($root_matrices_flag == 0) {

      ## Define the base directories for the javascripts, which are
      ## required to display logo trees, animations and dynamic tables

      if ($include_js_lib) {
	  ## Note: we will need to redefine it after having parsed the
	  ## arguments, since it will be relative to output directory.
	  &RSAT::message::Debug("Copying javascript libraries to output directory") if ($main::verbose >= 3);
	  my $js_sync_cmd = "rsync -ruptl";
	  $js_sync_cmd .= " ".$ENV{RSAT}."/perl-scripts/lib/js";
	  $js_sync_cmd .= " ".$dir{output};
	  &doit($js_sync_cmd, 0, 1, $verbose, 0, "", $main::out, $main::err);
	  $js_base = $dir{output}."/js";
	  &RSAT::message::Info("Javascript libraries copied to output directory", $js_base) if ($main::verbose >= 3);
      }  elsif (defined($ENV{RSA_OUTPUT_CONTEXT}) && ($ENV{RSA_OUTPUT_CONTEXT} eq "cgi")) {
	  $js_base = $ENV{rsat_www}."/lib/js";
      } else {
	  ## NOTE from JvH to Jaime: This solution does not allow to see the
	  ## result on another computer than the RSAT server on which
	  ## matrix-clustering ran.
	  $js_base = $ENV{RSAT}."/perl-scripts/lib/js";
      }
      $d3_base= &RSAT::util::RelativePath($main::outfile{summary}, $js_base."/d3.v3.min.js");
      $d3_venn_base= &RSAT::util::RelativePath($main::outfile{summary}, $js_base."/venn.js-master/venn.js");
      $jquery_base = &RSAT::util::RelativePath($main::outfile{summary}, $js_base."/DataTables-1.10.4/media/js/jquery.js");
      $datatable_base = &RSAT::util::RelativePath($main::outfile{summary}, $js_base."/DataTables-1.10.4/media/js/jquery.dataTables.min.js");
      $datatable_css_base = &RSAT::util::RelativePath($main::outfile{summary}, $js_base."/DataTables-1.10.4/media/css/jquery.dataTables.min.css");
      
  }

  ## Some temporary files
  $main::outfile{temp_html} = $main::outfile{prefix}."_temporary.html";
  $main::outfile{temp_html_2} = $main::outfile{prefix}."_temporary_2.html";
  $main::outfile{temp_html_3} = $main::outfile{prefix}."_temporary_3.html";
  $main::outfile{int_align} = $main::outfile{prefix}."_tables/intermediate_alignments.tab";

  ## Archive to facilitate transfer of all the results in a zip file
  $main::outfile{archive} = $main::outfile{prefix}."_archive.zip";

  &RSAT::message::Debug("Archive", $main::outfile{archive}) if ($main::verbose >= 3);

  ## Open the HTML index file and write header
  $main::outfile{html_index} = $main::outfile{prefix}."_html/index.html";
  push @outfiles, "html_index";
}


######################################################
## Read the motif file table file and load the matrices 
## as separated collections
sub read_motif_table_file {
	
	$count_input_matrix_parameters = 0;

    my ($motif_table_file) = &OpenInputFile($main::infile{motif_table_file});
    while (<$motif_table_file>) {
		
		chomp;
		next if (/^#/); ## Skip header line
		next if (/^;/); ## Skip comment lines	
		my $line = $_;
		my @split_line = split(/\t+/, $line);

		## Get the cluster name and motif IDs
		my $motif_file = $split_line[0];
		my $motif_collection = $split_line[1];
#		my $motif_format = $split_line[2];
	
		## Substitue special characters which cannot be used inside a file name
		$motif_collection =~ s|\s|_|gi;
		$motif_collection =~ s|/|_|gi;
		$motif_collection =~ s|:|_|gi;
		$motif_collection =~ s|\.|_|gi;
		
		$main::matrix_file{$motif_collection} = $motif_file;

		if ($main::matrix_file{$motif_collection}){
			$count_input_matrix_parameters++;
		}
		
		push @main::matrix_titles, $motif_collection;

	}
    
	close($motif_table_file)
	
}


######################################################
## Pre-process the input motifs in order to create
## unique IDs and concatenate the input motifs from 
## different collections (file) in a single one. 
sub pre_process_motif_files{
  
  ## Count the number of motif sets
  my $motif_set_counter = 0;
  
  ## This variable (previously optional now mandatory to display the title in the trees)
  $display_collection_name_flag = 1;
  
  ## Create a directory to store the pre-processes motif files
  ## Pre-processing includes 
  ##   - conversion to transfac
  ##   - concatenation of collection name and motif ID if several
  ##     input files are specified
  ##   - selection of top X motifs if required
  ##   - skip the top X motifs if required

  ## Count the number of input files
  $number_of_collections = scalar(keys(%main::matrix_file));
  if ($number_of_collections == 1){
      $single_input_flag = 1;
  } else {
      $single_input_flag = 0;
  }
  

  $main::dir{data} = $main::outfile{prefix}."_data";
  &RSAT::util::CheckOutDir($dir{data});


  ## Assign the title, matrix format and matrix file path to a hash 
  foreach my $k (keys %main::matrix_file){
      
      my $collection_name = $k;

      ## The collection labels must be unique or the program will die
      if (exists($motif_set_attributes{$collection_name}{collection_label})){
	  &RSAT::error::FatalError($motif_set_attributes{$collection_name}{collection_label}, " repeated. The collection label of each file must be unique.");	
      }
      
      $motif_set_attributes{$collection_name}{collection_label} = $collection_name;
      $motif_set_attributes{$collection_name}{matrix_format} = $main::matrix_format{$collection_name};; 
      $motif_set_attributes{$collection_name}{matrix_file_input} = $main::matrix_file{$collection_name};

      &RSAT::message::Info("Matrix file", $matrix_format, $collection_name, $main::matrix_file{$collection_name}) if ($main::verbose >= 2);

      $motif_collection_count{$collection_name} = 0;
      $motif_set_counter++;
  }
  
  &RSAT::message::Info("Read list of",scalar(keys(%motif_set_attributes)),
		       "matrix files") if ($main::verbose >= 2);

  ## Pre-process each motif collection
  foreach my $collection_name (keys(%motif_set_attributes)) {

      $motif_collection_count{$collection_name} = 0;
    
      ## Set the values of the title, file and format in a hash table
      my $matrix_format = $motif_set_attributes{$collection_name}{matrix_format}; 
      my $matrix_file = $motif_set_attributes{$collection_name}{matrix_file_input};
    
      ## Compute the longest collection name for display
      if (length($collection_name) > $longest_title){
	  $longest_title = length($collection_name);
      }
      
      ################################################################
      ## Collect all matrices
      @matrices = &RSAT::MatrixReader::readFromFile($matrix_file, $matrix_format);
      push(@all_matrices, @matrices);
      &RSAT::message::TimeWarn(scalar(@matrices), "Matrices loaded from file", $matrix_file) if ($main::verbose >= 2);
      
      ################################################################
      ## Check matrix number (required for verbose + if max matrices specified).
      if ($max_matrices > 0) {
	  &RSAT::message::TimeWarn("Checking max number of input matrices (".$max_matrices.")") if ($main::verbose >= 2);
	  &RSAT::message::TimeWarn(scalar(@matrices), "Matrices loaded from file", $matrix_file)
	      if ($main::verbose >= 2);
	  &RSAT::message::TimeWarn(scalar(@all_matrices), "Matrices loaded in total")
	      if ($main::verbose >= 2);
	  
	  if (scalar(@all_matrices) > $max_matrices) {
	      &RSAT::message::Warning("Input files contain ".scalar(@all_matrices)." matrices.", 
				      "The analysis will be limited to the ".$max_matrices." first matrices (option -max_matrices).");
	      
	      @all_matrices = @all_matrices[1..$max_matrices];
	  }
      }    
      
      ## Create a single file combining all the matrices from all the current
      ## input file, and append the motif collection name to each matrix ID.
      $motif_set_attributes{$collection_name}{matrix_file_processed_1} = $main::dir{data}."/".$collection_name."_input_motifs_processed_1.tf";
      $motif_set_attributes{$collection_name}{matrix_file_processed} = $main::dir{data}."/".$collection_name."_input_motifs_processed.tf";

      ## If it is required, permute the input motifs
      if ($random_flag == 1){
      
	  ## Temporal file with random motifs
	  my $rand_motif_file = $main::outfile{prefix}."_data/".$collection_name."_random_motifs.tf";
	  my $randomize_motifs_cmd = $SCRIPTS."/convert-matrix";
	  $randomize_motifs_cmd .= " -i ".$matrix_file;
	  $randomize_motifs_cmd .= " -from tf -to tf";
	  $randomize_motifs_cmd .= " -perm 1";
	  $randomize_motifs_cmd .= " -o ".$rand_motif_file;
	  &doit($randomize_motifs_cmd, 0, 1, $verbose, 0, "", $main::out, $main::err);
	  $motif_set_attributes{$collection_name}{matrix_file_input} = $rand_motif_file;
      }
      
      ## Convert input matrices in transfac format + append prefix if required
      &RSAT::message::TimeWarn("Converting input matrices") if ($main::verbose >= 2);
      my $convert_matrix_cmd = $SCRIPTS."/convert-matrix";
      $convert_matrix_cmd .= " -i ".$motif_set_attributes{$collection_name}{matrix_file_input};
      $convert_matrix_cmd .= " -from ".$matrix_format;
      $convert_matrix_cmd .= " -to tf";
      $convert_matrix_cmd .= " -top ".$top_matrices if ($top_matrices > 0);
      $convert_matrix_cmd .= " -skip ".$skip_matrices if ($skip_matrices > 0);
      $convert_matrix_cmd .= " -o ".$motif_set_attributes{$collection_name}{matrix_file_processed_1};
      
      print $convert_matrix_cmd."\n";
      
      &doit($convert_matrix_cmd, 0, 1, $verbose, 0, "", $main::out, $main::err);

      ##############################################
      ## Store the motif link in a hash
      if ($ID_link_flag == 1){

	  my $m_counter = 0;
	  my ($motif_file) = &OpenInputFile($motif_set_attributes{$collection_name}{matrix_file_processed_1});
	  while(<$motif_file>){

	      next if (/^#/); ## Skip header line
	      next if (/^;/); ## Skip comment lines
	      next unless (/\S/); ## Skip empty lines
	      next unless (/^AC\s+/);
	      chomp();
	      my($null, $AC_unique) = split(/\s+/, $_);
	      $m_counter++;
	      $ID_nb_hash{$AC_unique} = $m_counter;
	  }
	  close($motif_file);
      }

      ###############################
      ## Append prefix if required
      &RSAT::message::TimeWarn("Converting input matrices") if ($main::verbose >= 2);
      $convert_matrix_cmd = $SCRIPTS."/convert-matrix";
      $convert_matrix_cmd .= " -i ".$motif_set_attributes{$collection_name}{matrix_file_processed_1};
      $convert_matrix_cmd .= " -from tf";
      $convert_matrix_cmd .= " -to transfac";
      $convert_matrix_cmd .= " -prefix_id ".$collection_name;
      $convert_matrix_cmd .= " -o ".$motif_set_attributes{$collection_name}{matrix_file_processed};
      &doit($convert_matrix_cmd, 0, 1, $verbose, 0, "", $main::out, $main::err);

     #$mat_file_trimmed = &trim_matrix_low_IC_columns_preprocess($motif_set_attributes{$collection_name}{matrix_file_processed}, $motif_set_attributes{$collection_name}{matrix_file_processed_1}, 1);

      #unlink($motif_set_attributes{$collection_name}{matrix_file_processed_1});

      ########################################
      ## Save the unique ID in a hash table
      ## Key = ID unique
      ## Value = title (motif collection)
      my ($processed_matrix_file) = &OpenInputFile($motif_set_attributes{$collection_name}{matrix_file_processed});
      $m_counter = 0;
      while(<$processed_matrix_file>){
	  next if (/^#/); ## Skip header line
	  next if (/^;/); ## Skip comment lines
	  next unless (/\S/); ## Skip empty lines
	  next unless (/^AC\s+/);
	  chomp();
	  my($null, $AC_unique) = split(/\s+/, $_);
	  $motifs_ID_unique{$AC_unique} = $collection_name;
	  $alignment_info{$AC_unique}{file_name} = $main::outfile{prefix}."_data/motif_".$AC_unique.".tf";

	  if ($ID_link_flag == 1){
	      $m_counter++;
	      $new_ID_nb_hash{$m_counter} = $AC_unique;
	  }
      }
      close($processed_matrix_file);

      ##############################################
      ## Store the motif link in a hash
      if ($ID_link_flag == 1){

	  my ($link_table) = &OpenInputFile($main::infile{ID_link_table});
	  while(<$link_table>){

	      next if (/^#/); ## Skip header line
	      next if (/^;/); ## Skip comment lines
	      next unless (/\S/); ## Skip empty lines
	      chomp();
	      my($ID, $link) = split(/\s+/, $_);
	      $OLD_ID_link_hash{$ID} = $link;
	      $ID_link_hash{$new_ID_nb_hash{$ID_nb_hash{$ID}}} = $OLD_ID_link_hash{$ID}; 
	  }
	  close($link_table);
      }
  }

  ################################################################
  ## Concatenate all the processed input files in a single one.
  ## Rename the motif files.
  $main::outfile{motif_file} = $main::outfile{prefix}."_data/input_motifs_processed.tf";
  my $concatenate_processed_files_cmd = "cat ";
  foreach my $t (keys %motif_set_attributes){
      $concatenate_processed_files_cmd .=  $motif_set_attributes{$t}{matrix_file_processed}." ";
  }
  $concatenate_processed_files_cmd .= " > ".$main::outfile{motif_file};
  &doit($concatenate_processed_files_cmd, 0, 1, $verbose, 0, "", $main::out, $main::err); 


  $main::outfile{input_matrices} = $main::outfile{motif_file};

  ################################################################
  ## Split all the processed motifs into single file
  ## each one containing a single motif
  &RSAT::message::TimeWarn("Split the input file in individual files each with a single motif") if ($main::verbose >= 2);
  my $split_matrix_cmd = $SCRIPTS."/convert-matrix";
  $split_matrix_cmd .= " -i ".$main::outfile{motif_file};
  $split_matrix_cmd .= " -split";
  $split_matrix_cmd .= " -from tf -to tf";
  $split_matrix_cmd .= " -o ".$main::outfile{prefix}."_data/motif";
  &doit($split_matrix_cmd, 0, 1, $verbose, 0, "", $main::out, $main::err);
}


################################################################
## Compare each discovered motifs to each other.
sub CompareMatrices {

  ## Pariwise comparisons between discovered matrices.  We don't use
  ## the option "distinct" in order to ensure that all the motifs are
  ## in the output graph even if they are not related to any other
  ## motif.
  $matrix_compa_verbose = &RSAT::stats::max(($main::verbose-1), 1);

  &RSAT::message::TimeWarn("Pairwise matrix comparison.") if ($main::verbose >= 2);
  my $cmd = $SCRIPTS."/compare-matrices -v ".$matrix_compa_verbose; 
  $cmd .= " -mode scores";
  $cmd .= " -format tf";
  $cmd .=  " -file ".$main::outfile{input_matrices};
  $cmd .= " -DR";
  $cmd .= " -sort Ncor";
  $cmd .= " -return matrix_id,matrix_label,strand,offset,".$main::param{matrix_compa_metrics}.",consensus,width";
  $cmd .= " -labels ".$label_fields_to_return;
  $cmd .= " ".$args_to_pass;
  $cmd .= " -o ".$main::outfile{pairwise_compa};
  $cmd .= "; ".$SCRIPTS."/text-to-html -i ".$main::outfile{pairwise_compa};
  $cmd .= " -o ".$main::outfile{pairwise_compa_html};
  &RSAT::util::one_command($cmd, 1,"");


  &RSAT::message::TimeWarn("Matrix comparison table", $main::outfile{pairwise_compa}) if ($main::verbose >= 2);

  ## Parse compare-matrix result file to read score columns
  my ($compa) = &OpenInputFile($main::outfile{pairwise_compa});
  $main::param{score_column} = 0;
  while (<$compa>) {
    if (/;\t(\d+)\t$param{matrix_compa_score}/) {
      $main::param{score_column} = $1;
      &RSAT::message::Info("Score", $param{matrix_compa_score}, 
			   "column", $main::param{score_column}, 
			   "file", $main::outfile{pairwise_compa}) 
	  if ($main::verbose >= 2);
      last;
    }
  }
  close $compa;

  if ($main::param{score_column} == 0) {
    &RSAT::error::FatalError("Cannot identify score column (".$param{matrix_compa_score}.") in matrix comparison file (".$main::outfile{pairwise_compa}.").");
  }

  return();
}


################################################################
## Compare each discovered motifs to each other.
sub CompareMatricesQuick {
  &RSAT::message::TimeWarn("Running compare-matrices-quick") if ($main::verbose >= 2);
  ## Pariwise comparisons between discovered matrices.  We don't
  ## the option "distinct" in order to ensure that all the motifs are
  ## in the output graph even if they are not related to any other
  ## motif.
  ## This is the faster C implemented version of compare-matrices

  $matrix_compa_verbose = 0;
  my $BIN=$ENV{RSAT}."/bin";

  ## Run the pairwise matrix comparison
  &RSAT::message::TimeWarn("Pairwise matrix comparison. Quick version.") if ($main::verbose >= 2);
  my $cmd = $BIN."/compare-matrices-quick -v ".$matrix_compa_verbose; 
  $cmd .=  " -file1 ".$main::outfile{input_matrices};
  $cmd .=  " -file2 ".$main::outfile{input_matrices};
  $cmd .= " -lth_ncor1 -1";
  $cmd .= " -lth_ncor2 -1";
  $cmd .= " -lth_ncor -1";
  $cmd .= " -lth_cor -1";
  $cmd .= " -lth_w 0";
  $cmd .= " -mode matches";
  $cmd .= " -o ".$main::outfile{pairwise_compa};
  $cmd .= "; ".$SCRIPTS."/text-to-html -i ".$main::outfile{pairwise_compa};
  $cmd .= " -o ".$main::outfile{pairwise_compa_html};
  &RSAT::util::one_command($cmd, 1,"");
  &RSAT::message::TimeWarn("Matrix comparison table", $main::outfile{pairwise_compa}) if ($main::verbose >= 2);

  return();
}


###############################################################
## Run the R script "matrix-clustering.R" 
##
## This script takes as input a matrix comparison file
## (generated by compare-matrices), performs hierarchical
## clustering.
##
## It returns the resulting tree in json format
## 
sub Hclustering {
    
    &RSAT::message::TimeWarn("Clustering matrices with R hclust function") if ($main::verbose >= 2);

    ##################################
    ### Identify the path of the R executable
    my $r_path = &RSAT::server::GetProgramPath("R");

    my $cluster_motifs_script  = $ENV{RSAT}."/R-scripts/matrix-clustering.R";
    &RSAT::error::FatalError("Cannot read cluster motifs script", $cluster_motifs_script) unless (-r $cluster_motifs_script);
    $r_verbosity = &RSAT::stats::max(($main::verbose-1), 0);


    ## !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    ## FROM JVH TO JAIME: 
    ##
    ## I think we should better write all parameters in a file, and
    ## call this file with Rscript (or R). This would avoid to create
    ## a very long command line with all parameters, and it would
    ## leave a persistent trace of the complete analysis.
    ## !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    my $pos_drawing_offset = 0;
    
    ## Basic parameters
    my $cluster_motif_cmd = "";
    $cluster_motifs_cmd .= " cat ".$cluster_motifs_script;
    $cluster_motifs_cmd .= " | ".$r_path;
    $cluster_motifs_cmd .= " --slave --no-save --no-restore --no-environ";
    $cluster_motifs_cmd .= " --args \"";
    $cluster_motifs_cmd .= " infile = '".$main::outfile{pairwise_compa}."'";
    $cluster_motifs_cmd .= "; hclust.method = '".$hclust_method."'";
    $cluster_motifs_cmd .= "; description.file = '".$main::outfile{matrix_descriptions}."'";
    $cluster_motifs_cmd .= "; distance.table = '".$main::outfile{distance_table}."'";
    $cluster_motifs_cmd .= "; alignment.file = '".$main::outfile{alignment_table}."'";
    $cluster_motifs_cmd .= "; verbosity = ".$r_verbosity;
    $cluster_motifs_cmd .= "; metric = '".$main::param{matrix_compa_score}."'";
    $cluster_motifs_cmd .= "; heatmap.color.palette = '".$heatmap_color_palette."'";
    $cluster_motifs_cmd .= "; heatmap.color.classes = '".$heatmap_color_classes."'";
    $cluster_motifs_cmd .= "; export.newick = ".$export_newick;

    ## Set the option to compute only the hclust and skip the
    ## tree and heatmap computation
    $draw_heatmap = 0 if $root_matrices_flag == 1;
    $cluster_motifs_cmd .= "; only.hclust = ".$root_matrices_flag if $root_matrices_flag == 1;

    ## Option to compute the heatmap + consensus alignment
    $cluster_motifs_cmd .= "; draw.heatmap = ".$draw_heatmap;
    $cluster_motifs_cmd .= "; draw.consensus = ".$align_consensus;
    $cluster_motifs_cmd .= "; pos.hclust.in.heatmap = '".$heatmap_tree_pos."'";

    ## If the user select the quick option the thresholds are restricted
    ## only to cor and Ncor
    if ($quick_flag == 1) {
	my %lth2 = ();
	my @param = qw (Ncor cor);
	foreach my $p (@param) {
	    my $val = $lth{$p};
	    $lth2{$p} = $val;
	}
	%lth = %lth2;
    }


    ## Pass the lower thresholds
    if (scalar keys %lth > 0){

	my $lthsp = "";

	if($radial_tree_flag == 1){
	    $lthsp .= "cor_-1_Ncor_-1_w_0";
	} else {
	
	    foreach my $par (keys %lth) {
		$lthsp.= $par."_".$lth{$par}."_";
	    }
	}
	$cluster_motifs_cmd .= "; lthsp = '".$lthsp."'";
    }

    
    ## Pass the upper thresholds
    if (scalar keys %uth > 0){
	my $uthsp = "";
	foreach my $par (keys %uth) {
	    $uthsp.= $par."_".$uth{$par}."_";
	}
	$cluster_motifs_cmd .= "; uthsp = '".$uthsp."'";
    }

    ## These parameters force all the motifs to be aligned in one cluster
    ## Only for generate radial trees


    ## Output parameters
    $cluster_motifs_cmd .= "; out.prefix = '".$main::outfile{prefix}."'";
    $cluster_motifs_cmd .= "; \"";
#    $Cluster_motifs_cmd = "(".$cluster_motifs_cmd.")"; # Uncomment this line to check the R output in the terminal
#    $cluster_motifs_cmd = "(".$cluster_motifs_cmd.") 2> ".$main::outfile{Rlog};

    if ($r_path) {
        &doit($cluster_motifs_cmd, 0, 1, $verbose, 0, "", $main::out, $main::err);
    } else {
        &RSAT::message::Warning("Could not run motif clustering because the program R is not available") if ($main::verbose >= 1);
    }
    return();
}


################################################################
## Read the cluster composition, which will be required for several
## methods
##
## Results are stored in global variables of the main memory space.
sub ReadClusterComposition {

  ## Read cluster composition, and store it in a hash table where 
  ##   keys = cluster names
  ##   values = lists of nodes per cluster
  &RSAT::message::TimeWarn("Reading cluster sizes from alignment table", $outfile{alignment_table}) if ($main::verbose >= 2);
  my ($cluster_handle) = &RSAT::util::OpenInputFile($outfile{alignment_table});
  while (<$cluster_handle>) {
    next if (/^#/); ## Skip header line
    next if (/^;/); ## Skip comment lines
    next unless (/\S/); ## Skip empty lines
    chomp();

    my ($node, $name, $cluster, $strand, $offset_l, $offset_r, $width) = split ("\t");
    push(@{$cluster_nodes{$cluster}}, $node);
    ## Store the ID, strand and offset of each aligned motif
    $cluster_info_width{$cluster} = $width;
    $alignment_info{$node}{id} = $node;
    $alignment_info{$node}{collection} = $motifs_ID_unique{$node};
    $alignment_info{$node}{name} = $name;
    $alignment_info{$node}{strand} = $strand;
    $alignment_info{$node}{offset_left} = $offset_l;
    $alignment_info{$node}{offset_right} = $offset_r;
    $alignment_info{$node}{width} = $width;

    &RSAT::message::Debug("\tcluster=".$cluster, "name=".$name, "node=".$node, scalar(@{$cluster_nodes{$cluster}})) if ($main::verbose >= 5);
  }

  @clusters_to_HTML = sort keys %cluster_nodes;

  &RSAT::message::Debug("Cluster names", join ";", @clusters_to_HTML) if ($main::verbose >= 3);
  
  ## Index the number of nodes per cluster
  %clusters_info = (); 

  ## Open the file with the picture's data
  my ($cluster_ID) = &OpenInputFile($main::outfile{cluster_IDs_names});
  while(<$cluster_ID>){
    next if (/^#/); ## Skip header line
    next if (/^;/); ## Skip comment lines
    next unless (/\S/); ## Skip empty lines
    chomp();

    my ($cluster_identifier, $number) = split(" ");
    $clusters_info{$cluster_identifier} = scalar(@{$cluster_nodes{$cluster_identifier}});
    &RSAT::message::Debug("Cluster:", $cluster, 'nb of nodes:', $clusters_info{$cluster}) if ($main::verbose >= 5);

    $cluster_id_hash{$number} = $cluster_identifier;

  }
  close($cluster_ID);
}


################################################################
## Add the empty columns to the logos that will be displayed, in order
## to get multiple alignment on the logo cladogram.
sub Add_gaps_to_motifs {

    &RSAT::message::TimeWarn("Adding gaps to the matrices") if ($main::verbose >= 2);

    ## Call the program 'convert-matrix' to add the empty columns
    ## to the aligned logos and retrieve the logos in RC
    foreach my $id (keys %alignment_info) {

	## Reset the variables
	my $aligned_motif = "";
	my $aligned_motif_rc = "";
	my $offset_left = $alignment_info{$id}{offset_left};
	my $offset_right = $alignment_info{$id}{offset_right};
	my $file_name = $alignment_info{$id}{file_name};
	my $strand = $alignment_info{$id}{strand};
	
	## Run the convert-matrix command to add the empty columns to the logos
	if ($strand eq "D") {

	    $aligned_motif = $main::outfile{prefix}."_aligned_logos/".$id."_aligned.tf";
	    ## Add the empty columns + Produce Transfac File
	    &Add_Empty_Col($file_name, $offset_left, $offset_right, "counts,consensus", $aligned_motif);

	    ## The Logos + RC are not computed when only the root motifs are required
	    if ($root_matrices_flag == 0){ 
		## Compute the logos (both orientations)

		my $c = "cat ".$aligned_motif." >> ".$main::outfile{all_concatenated_motifs};
		&doit($c, 0, $die_on_error, $verbose, 0, "", $main::out, $main::err);		

		## Convert the aligned matrix to reverse complement 
		$aligned_motif_rc = $main::outfile{prefix}."_aligned_logos/".$id."_aligned_rc.tf";
		&Rev_Comp_Motif ($file_name, $aligned_motif_rc);
	    }

	} else {
	    
	    ## First convert the matrix to reverse complement 
	    my $temp_mat = $main::outfile{prefix}."_aligned_logos/temp.tf";
	    &Rev_Comp_Motif ($file_name, $temp_mat);

	    ## Add the empty columns + Produce Transfac File
	    $aligned_motif = $main::outfile{prefix}."_aligned_logos/".$id."_aligned.tf";
	    &Add_Empty_Col($temp_mat, $offset_left, $offset_right, "counts,consensus", $main::outfile{prefix}."_aligned_logos/".$id."_aligned.tf");

	    my $c = "cat ".$aligned_motif." >> ".$main::outfile{all_concatenated_motifs};
	    &doit($c, 0, $die_on_error, $verbose, 0, "", $main::out, $main::err);

	    ## The Logos + RC are not computed when only the root motifs are required
	    if ($root_matrices_flag == 0){ 

		## Compute the logos (both orientations)
		my $c = "cat ".$aligned_motif." >> ".$main::outfile{all_concatenated_motifs};
		&doit($c, 0, $die_on_error, $verbose, 0, "", $main::out, $main::err);
		
		## Convert the aligned matrix to reverse complement 
		$aligned_motif_rc = $main::outfile{prefix}."_aligned_logos/".$id."_aligned_rc.tf";
		&Rev_Comp_Motif ($aligned_motif, $aligned_motif_rc);
	    }
	    unlink($temp_mat);
	}
	unlink($file_name);
	
	## Store the path of the logos
	$alignment_info{$id}{aligned_tf} = $aligned_motif;
	$alignment_info{$id}{aligned_rc_tf} = $aligned_motif_rc;
	$alignment_info{$id}{logo} =  $main::outfile{prefix}."_aligned_logos/".$id."_logo.png";
	$alignment_info{$id}{logo_rc} = $main::outfile{prefix}."_aligned_logos/".$id."_logo_rc.png";
    }  
}

# ################################################################
# ## Identify clusters of similar motifs using MCL ("Markov clustering",
# ## an algorithm partitioning a network into clusters), and build
# ## consensus motifs.
# sub ClusterMotifs {
#   &RSAT::message::TimeWarn("Clustering matrices with MCL") if ($main::verbose >= 2);

#   ## Generate a GML graph with the matrix comparison result (can be opened with CytoScape or Yed)
#   $cmd = $SCRIPTS."/convert-graph -i ".$main::outfile{pairwise_compa};
#   $cmd .= " -ewidth -ecolors fire";
#   $cmd .= " -layout spring_new";
#   $cmd .= " -from tab -to gml -scol 1 -tcol 2 -wcol ".$main::param{score_column};
#   $cmd .= " -o ".$main::outfile{matrix_network_gml};
#   &RSAT::util::one_command($cmd, 1);

#   ## Generate a figure of the motif comparison graph
#   $cmd = $SCRIPTS."/display-graph";
#   $cmd .= " -in_format gml -i ".$main::outfile{matrix_network_gml};
#   $cmd .= " -ewidth";
#   $cmd .= " -layout none";
#   $cmd .= " -out_format png -o ".$main::outfile{compa_png};
#   &RSAT::util::one_command($cmd, 1);

#   ## Use MCL to partition the motif graph into clusters
#   &RSAT::message::TimeWarn("Matrix clustering by running MCL on th matrix-to-matrix network.") if ($main::verbose >= 2);
#   my $mcl = &RSAT::server::GetProgramPath("mcl");  
#   # my $mcl_dir = $ENV{mcl_dir};
#   # unless ($mcl_dir) {
#   #   &RSAT::error::FatalError("Motif comparison requires to install MCL and indicate its path in the file $ENV{RSAT}/RSAT_config.props");
#   # }
#   # my $mcl = $mcl_dir."/mcl";
#   $cmd = "grep -v '^;' ".$main::outfile{pairwise_compa}.">".$main::outfile{pairwise_compa}.".mcl";
#   $cmd .= "; ".$mcl."/mcl ".$main::outfile{pairwise_compa}.".mcl";
#   $cmd .= " -I 1.8 --abc -V all ";
#   $cmd .= " -o ".$main::outfile{clusters_mcl};
#   $cmd .= " >& /dev/null";
#   $cmd .= " ; ".${SCRIPTS}."/convert-classes -i ".$main::outfile{clusters_mcl};
#   $cmd .= " -from mcl -to tab ";
#   $cmd .= " -o ".$main::outfile{clusters_tab};
#   &RSAT::util::one_command($cmd, 1);

#   ## Split the motif graph into clusters as defined by MCL, and
#   ## compute the intra-cluster degree (k) and weighted degree (wk) of
#   ## each node
#   $cmd = $SCRIPTS."/graph-get-clusters -i ".$main::outfile{pairwise_compa};
#   $cmd .= " -in_format tab -scol 1 -tcol 2 -wcol ".$main::param{score_column};
#   $cmd .= " -return clusters ";
#   $cmd .= " -clusters ".$main::outfile{clusters_tab};
#   $cmd .= " -out_format tab -o ".$main::outfile{clusters_subgraph};
#   &RSAT::util::one_command($cmd, 1);


#   ## Identify graph components and count the intra-component degree of
#   ## each node. Most connected nodes will serve as seeds for motif
#   ## clustering.
#   $cmd = $SCRIPTS."/graph-connex-components -v 1";
#   $cmd .= " -i ".$main::outfile{clusters_subgraph};
#   $cmd .= " -wcol ".$main::param{score_column};
#   $cmd .= " -o ".$main::outfile{intra_cluster_degree};
#   &RSAT::util::one_command($cmd, 1);

#   ## Generate a GML graph with the matrix comparison result (can be opened with CytoScape or Yed)
#   $cmd = $SCRIPTS."/convert-graph -i ".$main::outfile{clusters_subgraph};
#   $cmd .= " -ewidth -ecolors fire";
#   $cmd .= " -layout spring_new";
#   $cmd .= " -from tab -to gml -scol 1 -tcol 2 -wcol 3";
#   $cmd .= " -o ".$main::outfile{clusters_subgraph_gml};
#   &RSAT::util::one_command($cmd, 1);

#   ## Generate a figure of the motif comparison graph
#   $cmd = $SCRIPTS."/display-graph";
#   $cmd .= " -in_format gml -i ".$main::outfile{clusters_subgraph_gml};
#   $cmd .= " -ewidth";
#   $cmd .= " -layout none";
#   $cmd .= " -out_format png -o ".$main::outfile{clusters_subgraph_png};
#   &RSAT::util::one_command($cmd, 1);

#   return();
# }


################################################################
## Add attributes to JSON file, like links to pictures and other
## attributes
sub Add_attributes_to_JSON {

  my (%matrix_info) = ();

  #############################################
  ## Create a hash with the attribute data:
  ##	key :  name
  ##	values : attribute (link, etc)

  ## Open the file with the picture's data
  my ($mat_desc) = &OpenInputFile($main::outfile{matrix_descriptions});
  while(<$mat_desc>) {
      next unless (/\S/); ## Skip empty rows
      next if (/^;/); ## Skip comment rows
      next if (/^#/); ## Skip header rows
      chomp();
      @split_line = split(/\s+/, $_);
      my $matrix_label = $split_line[6];
      my $id = $split_line[1];

      $matrix_info{$id}{id} = $id;
      $matrix_info{$id}{name} = $split_line[2];
      $matrix_info{$id}{width} = $alignment_info{$matrix_info{$id}{id}}{width};
      $matrix_info{$id}{consensus} = $split_line[4];
      $matrix_info{$id}{consensus_rc} = $split_line[5];
      $matrix_info{$id}{ic} = $split_line[6];
      $matrix_info{$id}{nb_sites} = $split_line[7];
  }
  close($mat_desc);

      ## Open a file with the attributes of the nodes of each cluster (IC, width, number of motifs, etc)
      my $cluster_nodes_ic_info = &OpenOutputFile($main::outfile{prefix}."_clusters_information/".$cluster."_attributes_table.tab");
      print $cluster_nodes_ic_info join("\t", "#cluster", "node_ID", "child_1", "child_2", "IC", "IC_child_1", "IC_child_2", "Sites", "Sites_child_1", "Sites_child_2"), "\n";


  ############################################################
  ## Read the JSON file and add the link data to each node
  &RSAT::message::TimeWarn("Linking data to nodes in JSON files") if ($main::verbose >= 2);
  foreach my $cluster(@clusters_to_HTML) {
      my $line = "";
      my $children = 0;
      my ($M1, $M2, $Add_this, $Flag);
      my (@Split_line, @Parsed_JSON) = ();
	  my $file = $main::outfile{prefix}."_clusters_information/".$cluster."/levels_JSON_".$cluster."_table.tab";
	  
      my @levels_JSON = ();
      open(LVL_JSON, $file) || &RSAT::error::FatalError($file, "Cannot open the JSON Levels file");
      while(<LVL_JSON>) {
	  chomp;
	  next if /^;/;
	  my @spl = split(/\t+/, $_);
	  push(@levels_JSON, $spl[2]);  
      }
      close(LVL_JSON);

      
      ## Read he file with the linkage order
      ## Save the info in a hash
      my %linkage_order_info = ();

      ## Open the JSON file produced by R
      my $parsed_json;
      my $cluster_width = 0;
      my $JSON = $main::outfile{prefix}."_trees/tree_".$cluster.".json";
      &RSAT::message::TimeWarn("JSON file", $JSON, $cluster ) if ($main::verbose >= 2);
      open(JSON, $JSON) || &RSAT::error::FatalError($JSON, "Cannot open the JSON file");
      while(<JSON>) {
	  chomp;
	  $Flag = 0;
	  $line = $_;

	  ################################################################
	  ## Search the pattern separating the matrices names (tree leaves)
	  if ($line =~ /\s*\"label\":\s*\"(.+)\",/) {
	      $Flag = 1;
	      $Add_this = "";
	      $M1 = $1;
	      
	      ## Define te URL of the logo file, relative to the location of the json file
	      my $aligned_logo_link = &RSAT::util::RelativePath($main::outfile{summary}, $alignment_info{$M1}{logo});
	      $aligned_logo_link =~ s/^\.\.\///g;

	      my $aligned_logo_url = $aligned_logo_link.".png";

	      ## Define te URL of the logo file, relative to the location of the json file
	      my $aligned_rc_logo_link = &RSAT::util::RelativePath($main::outfile{summary}, $alignment_info{$M1}{logo_rc});
	      $aligned_rc_logo_link =~ s/^\.\.\///g;
	      my $aligned_rc_logo_url = $aligned_logo_link.".png";
	      
	      ### Create the line that will be added to JSON file
	      $Add_this .= "\n \"image\" : \"${aligned_logo_link}\"";
	      $Add_this .= ",\n \"image_rc\" : \"${aligned_rc_logo_link}\"";
	      $Add_this .= ",\n \"url\" : \"${aligned_logo_link}\"";
	      
	      foreach my $field (@supported_label_fields) {
		  if ($label_fields_to_return{$field}) {
		      if ($field eq "ic"){
			  $Add_this .= ",\n \"".$field."\" : \"".$matrix_info{$M1}{$field}."\"";
		      } else {
			  $Add_this .= ",\n \"".$field."\" : \"".$matrix_info{$M1}{$field}."\"";
		      }
	 	  }
	      }
	      $Add_this .= ",\n \"ic\" : \"".$matrix_info{$M1}{ic}."\"";
	      $Add_this .= ",\n \"size\" : ".$matrix_info{$M1}{width};
	      $Add_this .= ",\n \"title\" : \"".$motifs_ID_unique{$M1}."\"";
	      $Add_this .= ",\n \"consensus_rc\" : \"".$matrix_info{$M1}{consensus_rc}."\"";

	      if ($ID_link_flag == 1){
		  $Add_this .= ",\n \"link_ext\" : \"".$ID_link_hash{$M1}."\"";
	      }  
	  }
	  
	  if($radial_tree_flag == 0){
	      ################################################################
	      ## Add the consensus to the json file to be displayed in the tree (tree nodes)
	      my $IC_info_line = "";
	      my $folder = "";
	      my @read_motifs = ();
	      my $child_1_ic = 0;
	      my $child_2_ic = 0;
	      if ($line =~ /\"children\":/) {
		  $children++;
		  $Add = "";
		  if ($children > 1) {

		      $folder = $levels_JSON[$children-2];

		      if (exists($merged_consensuses_files{$folder})) {

			  
			  if (scalar(@{$cluster_nodes{$cluster}}) > 1){
			      my ($linkage_order_info_file) = &OpenInputFile($main::outfile{prefix}."_clusters_information/".$cluster."/levels_JSON_".$cluster."_table_linkage_order.tab");

			      while(<$linkage_order_info_file>) {
				  chomp;
				  next if /^;/;
				  my @spl = split(/\t+/, $_);
				  my $merge_ID = $spl[0];
				  my $child_1 = $spl[1];
				  my $child_2 = $spl[2];
				  $linkage_order_info{$merge_ID}{child_1} = $child_1;  
				  $linkage_order_info{$merge_ID}{child_2} = $child_2;  
			      }
			      close $linkage_order_info_file;
			      
			  }

			  ## Calculate IC of branch motif
			  my @branch_motifs = &RSAT::MatrixReader::readFromFile($merged_consensuses_files{$folder}{$cluster}{tf_file}, "tf");
			  my $rounded_ic = 0;
			  my $nb_sites = 0;
			  my $child_1_nb_sites = 0;
			  my $child_2_nb_sites = 0;
			  my $calc_nb_sites = 0;
			  my $calc_child_1_nb_sites = 0;
			  my $calc_child_2_nb_sites = 0;
			  foreach my $matrix (@branch_motifs) {
			      
			      ## Calculates the IC of the matrix
			      $matrix->calcInformation();
			      $matrix->toString(col_width=>(1+4),
						decimals=>1,
						type=>"information",
						format=>"tf");
                          my $ic = $matrix->get_attribute("total.information");
                          $rounded_ic = sprintf("%.2f", $ic);

	                  $calc_nb_sites = $matrix->calcNbSites();
                          $nb_sites = $matrix->getNbSites();
                      }

                      if (scalar(@{$cluster_nodes{$cluster}}) > 1){

                      $linkage_order_info{$folder}{ic} = $rounded_ic;
                      $linkage_order_info{$folder}{sites} = $nb_sites;

                      ## Calculate IC from Children nodes
                      if ($linkage_order_info{$folder}{child_1} =~ /node_\d+/){
                         ## Calculate IC of child 1
		         @read_motifs = &RSAT::MatrixReader::readFromFile($merged_consensuses_files{$linkage_order_info{$folder}{child_1}}{$cluster}{tf_file}, "tf");
                         foreach my $matrix (@read_motifs) {
		    		    
			    ## Calculates the IC of the matrix
			    $matrix->calcInformation();
			    $matrix->toString(col_width=>(1+4),
					    decimals=>1,
					    type=>"information",
					    format=>"tf");
                            my $ic = $matrix->get_attribute("total.information");
                            $child_1_ic = sprintf("%.2f", $ic);

	                    $calc_child_1_nb_sites = $matrix->calcNbSites();
                            $child_1_nb_sites = $matrix->getNbSites();
                         }
                      } else {
                        $child_1_ic = $matrix_info{$linkage_order_info{$folder}{child_1}}{ic};
                        $child_1_nb_sites = $matrix_info{$linkage_order_info{$folder}{child_1}}{nb_sites};

                      }

                      if ($linkage_order_info{$folder}{child_2} =~ /node_\d+/){
                         ## Calculate IC of child 2
		         @read_motifs = &RSAT::MatrixReader::readFromFile($merged_consensuses_files{$linkage_order_info{$folder}{child_2}}{$cluster}{tf_file}, "tf");
                         foreach my $matrix (@read_motifs) {
		    		    
			    ## Calculates the IC of the matrix
			    $matrix->calcInformation();
			    $matrix->toString(col_width=>(1+4),
					    decimals=>1,
					    type=>"information",
					    format=>"tf");
                            my $ic = $matrix->get_attribute("total.information");
                            $child_2_ic = sprintf("%.2f", $ic);
                            $calc_child_2_nb_sites = $matrix->calcNbSites();
                            $child_2_nb_sites = $matrix->getNbSites();
                         }
                      } else {
                        $child_2_ic = $matrix_info{$linkage_order_info{$folder}{child_2}}{ic};
                        $child_2_nb_sites = $matrix_info{$linkage_order_info{$folder}{child_2}}{nb_sites};
                      }

                      $linkage_order_info{$folder}{child_1_ic} = $child_1_ic;
                      $linkage_order_info{$folder}{child_2_ic} = $child_2_ic;

                      $linkage_order_info{$folder}{child_1_nbsites} = $child_1_nb_sites;
                      $linkage_order_info{$folder}{child_2_nbsites} = $child_2_nb_sites;
  }
 
		      my $branch = $folder;
		      $branch =~ s/\D+//g;
		      my $consensus_link = &RSAT::util::RelativePath($main::outfile{summary}, $merged_consensuses_files{$folder}{$cluster}{logo}); 
		      my $id_json = $cluster."_".$folder;
		      $Add .= " \"consensus\" : \"".$merged_consensuses_files{$folder}{$cluster}{consensus}."\",\n";
		      $Add .= " \"branch\" : ".$branch.",\n";
		      $Add .= " \"id\" : \"".$id_json."\",\n";
		      $Add .= " \"ic\" : \"".$rounded_ic."\",\n";
		      $Add .= " \"size\" : ".$cluster_info_width{$cluster}.",\n";
		      $Add .= " \"name\" : \"".$merged_consensuses_files{$folder}{$cluster}{motif_name}."\",\n";
		      $Add .= " \"image\" : \"".&RSAT::util::RelativePath($main::outfile{summary}, $merged_consensuses_files{$folder}{$cluster}{logo})."\",\n";
		      $Add .= " \"image_rc\" : \"".&RSAT::util::RelativePath($main::outfile{summary}, $merged_consensuses_files{$folder}{$cluster}{logo_RC})."\",\n";
		  }
		  push(@Parsed_JSON, $Add."\n");

                  if (scalar(@{$cluster_nodes{$cluster}}) > 1){

                     my $line_to_print = $cluster."\t".$folder."\t".$linkage_order_info{$folder}{child_1}."\t".$linkage_order_info{$folder}{child_2}."\t".$linkage_order_info{$folder}{ic}."\t".$linkage_order_info{$folder}{child_1_ic}."\t".$linkage_order_info{$folder}{child_2_ic}."\t".$linkage_order_info{$folder}{sites}."\t".$linkage_order_info{$folder}{child_1_nbsites}."\t".$linkage_order_info{$folder}{child_2_nbsites}."\n";

                    $line_to_print =~ s/node_//gi;

                     print $cluster_nodes_ic_info $line_to_print;
                  }
	      }
	  }

#print $cluster_nodes_ic_info $IC_info_line;
	  }
	  push(@Parsed_JSON, $line."\n");
	  ### Add the new line
	  if ($Flag) {
	      push(@Parsed_JSON, $Add_this."\n");
	  }
      }
      close(JSON);
  
      ### Create the JSON parsed FILE
      open(PARSED_JSON, ">".$main::outfile{prefix}."_trees/parsed_tree_".$cluster.".json") || &RSAT::error::FatalError("Cannot create the PARSED JSON file", $main::outfile{prefix}."_trees/parsed_tree_".$cluster.".json");
      print PARSED_JSON @Parsed_JSON;
      close(PARSED_JSON);
      $json_files_content{$cluster} = "@Parsed_JSON";
      #unlink($JSON);
  }

  my $cmd = "rm -r ".$main::outfile{prefix}."_pairwise_compa_logos";
  &doit($cmd, 0, $die_on_error, $verbose, 0, "", $main::out, $main::err);

  return();
}


###################################
## Create the html file to 
## display the tree
sub create_html_small_tree_file {

    &RSAT::message::TimeWarn("Generating HTML tree file", $main::outfile{small_logo_cladogram_html}) if ($main::verbose >= 2);

    open(SMALL_TREE, $main::outfile{small_logo_cladogram_html}) || &RSAT::error::FatalError($main::outfile{small_logo_cladogram_html}, "Cannot open HTML file");
    open(TEMP_2, ">".$main::outfile{temp_html_2}) || &RSAT::error::FatalError($main::outfile{temp_html_2}, "Cannot create temporary file");

    ## Values to change in the D3 tree
    my $svg_width = 15;
    my $svg_height = 13;
    my $svg_x1 = 18 * $nb_char;
    my $svg_y1 = -7;
    my $svg_x2 = '2 + '.$svg_x1.' + 7';
    my $add_this = "";
    my $labels_num = 0;
    my $tree_counter = 0;
    my $cluster_nb = 0;
    my $JQuery_dynamic = "";

    my $main_label = 	        
	"\tnodeEnter.append(\"a\")
	\t\t.attr(\"xlink:href\", function(d) { return d.link_ext; })
	\t\t.append(\"text\")
        \t\t.style(\"font-size\", \"20px\")
	\t\t.text(function(d) { return d.children ? \"\" : d.; })
	\t\t.attr(\"dx\", function(d) { return d.children ? 0 : 20; })
	\t\t.attr(\"dy\", function(d) { return d.children ? 0 : 3; })
	\t\t.style(\"fill\", \"blue\")
	\t\t.attr(\"text-anchor\", function(d) { return d.children ? \"end\" : \"start\"; });\n";

    my $new_label = 
	"\tnodeEnter.append(\"text\")
	\t\t.text(function(d) { return d.children ? \"\" : d.ic; })
	\t\t.attr(\"x\", function(d) { return d.children ? 0 : -5; })
	\t\t.attr(\"dy\", function(d) { return d.children ? 0 : -2; })
	\t\t.attr(\"class\", function(d) { return d.children ? \"\" : \"show_con_--cl_id--\"; })
	\t\t.attr(\"display\", function(d) { return d.children ? \"\" : \"none\"; })
        \t\t.attr(\"font-size\", \"20px\")
	\t\t.style(\"fill\", \"blue\")
	\t\t.attr(\"text-anchor\", function(d) { return d.children ? \"end\" : \"end\"; });";
 
    my $display_title_lab .= '
        nodeEnter.append("text")
	.text(function(d) { return d.children ? "" : d.title; })
	.attr("x", function(d) { return d.children ? 0 : 20; })
	.attr("dy", function(d) { return d.children ? 0 : --dis--; })
        .attr("fill", "black")
	.attr("font-size", "20px")
        .attr("font-weight", "bold")
	.attr("text-anchor", function(d) { return d.children ? "end" : "start"; })
        ';

    my $ic_leaves = 
	"\tnodeEnter.append(\"text\")
	\t\t.text(function(d) { return d.children ? \"\" : d.ic; })
	\t\t.attr(\"x\", function(d) { return d.children ? 0 : -20; })
	\t\t.attr(\"dy\", function(d) { return d.children ? 0 : -1; })
        \t\t.attr(\"font-size\", \"20px\")
        \t\t.attr(\"class\", function(d) { return d.children ? \"\" : \"show_con_--cl_id--\"; })
        \t\t.style(\"display\", function(d) { return d.children ? \"\": \"none\"; })
	\t\t.style(\"fill\", \"blue\")
	\t\t.attr(\"text-anchor\", function(d) { return d.children ? \"end\" : \"end\"; });";

    my $hide_show_consensus = '

d3.select("#--cl_id--").append("text")
	.attr("x", 1000)             
	.attr("y", 0)    
	.attr("class", "legend")     
	.attr("id", "cons_button_--cl_id--") 
      .attr("font-size", "20px")
	.text("IC") ; 


// Slide the Heatmap View
$(document).ready(function() {
    $(\'#cons_button_--cl_id--\').click(function() {
        $(\'.show_con_--cl_id--\').toggle();
    }); 
});'."\n\n";


    while(<SMALL_TREE>) {
	chomp;	

	if (/\(function\(\)\s*\{/) { 
		$cluster_nb++;

		## Add the Hide/Show consensus button only to those clusters with 2 or more motifs
		if ($clusters_info{$cluster_id_hash{$cluster_nb}} > 0){
		    my $c = $cluster_id_hash{$cluster_nb};
		    my $new_cons_button = $hide_show_consensus;
		    $new_cons_button =~ s/--cl_id--/$c/g;
		    $JQuery_dynamic .= $new_cons_button;
		}
	}

	if ((defined($ENV{RSA_OUTPUT_CONTEXT})) &&
	    (($ENV{RSA_OUTPUT_CONTEXT}eq "cgi") || ($ENV{RSA_OUTPUT_CONTEXT} eq "RSATWS"))) {
	  $_ =~ s|$ENV{RSAT}/public_html/|$ENV{rsat_www}|g;
	}
	
	### Fix the d3 library path
	if (/--d3--/) {
	    $_ =~ s/--d3--/$d3_base/g;
	}

	### Fix the jquery library path
	if (/--jquery--/) {
	    $_ =~ s/--jquery--/$jquery_base/g;
	}

	## Insert the JQuery code
	if (/--jquerycode--/){
	    $_ =~ s/--jquerycode--/$JQuery_dynamic/g;
	}

	### Set the height 
	if (/--height--/) {
	   my $clust = $cluster_id_hash{$cluster_nb};
	   my $mat_number = $clusters_info{$clust} + 2;
	   $_ =~ s/--height--/50 + 87 * $mat_number/;
	}
	
	### Set the height 
	if (/--widthtree--/) {;
	    $_ =~ s/--widthtree--/2500/;
	}

	### Set the tree size
	if (/--size--/) {;
	    $_ =~ s/--size--/350/;
	}

	### Add the JSON file name
	if (/--json_file--/) {
	    my $clust = $cluster_id_hash{$cluster_nb};
	    $_ =~ s/--json_file--/$json_files_content{$clust}/;
	}

	if (/--cl_id--/) {
	    my $c = $cluster_id_hash{$cluster_nb};
	    $_ =~ s/--cl_id--/$c/g;
	}

	## Add the color of the cluster
	if (/--stroke--/) {
	    my $clust = $cluster_id_hash{$cluster_nb};
	    $_ =~ s/--stroke--/$hexa_code{$clust}/;
	}

	if (/--font--/) {
	    $_ =~ s/--font--/20/g;
	}

	if (/--sep_motifs--/) {
	    my $sep_motifs = 0;
	    $clust = $cluster_id_hash{$cluster_nb};
	    if ($clusters_info{$clust} <= 5){
		$sep_motifs = 150;
	    } elsif ($clusters_info{$clust} <= 9){
		$sep_motifs = 200;
	    } elsif ($clusters_info{$clust} <= 20){
		$sep_motifs = 250;
	    } elsif ($clusters_info{$clust} <= 50 ){
		$sep_motifs = 300;
	    } elsif ($clusters_info{$clust} > 50 ){
		$sep_motifs = 420;
	    }
	    $_ =~ s/--sep_motifs--/$sep_motifs/;
	}

	if (/--insert--/) {
	    $_ =~ s/--insert--//;
	}

	if (/--image_spacer--/) {
	    my $sp = $svg_x1 - 15;
	    $_ =~ s/--image_spacer--/$sp/g;
	}

	if (/--svgwidth--/) {
	    $_ =~ s/--svgwidth--/$svg_width/g;
	}

	if (/--svgheight--/) {
	    $_ =~ s/--svgheight--/$svg_height/g;
	}

	if (/--insert_image--/){
	    $_ =~ s/--insert_image--/d.image/g;
	}

	if (/--x1--/) {
	    $_ =~ s/--x1--/$svg_x1/g;
	}

	if (/--y1--/) {
	    $_ =~ s/--y1--/$svg_y1/g;
	}

	if (/--x2--/) {
	    $_ =~ s/--x2--/$svg_x2/g;
	}


	if ($_ =~ /Insert labels/) {
	    $add_this = "";
	    $labels_num = 0;
	    ################################################################
	    ## Insert in the html script the labels selected by the user
	    foreach my $field (@label_fields_to_return) {
			if ($label_fields_to_return{$field}) {
				$labels_num++;
				
				### Add the first label with the the link to the logo
				if ($labels_num == 1) {
				my $m = $main_label;
				$m =~ s/--cl_id--/$cluster_id_hash{$cluster_nb}/;
				$add_this = $m;
				$up = uc($field);
				$add_this =~ s/d\.;/ d\.$field;/;
				}
				
				### Add the new labels, set the distances among the labels in the tree
				if ($labels_num > 1) {
				my $copy = $new_label;
				$up = uc($field);
				$copy =~ s/d\.;/ d\.$field;/;
				$copy =~ s/--cl_id--/$cluster_id_hash{$cluster_nb}/;
				my $y_displacement = 4 + (($labels_num -1) * 20);
				$copy =~ s/#/$y_displacement/;
				$add_this .= "\n\n".$copy."\n";
				}
			}
	    }

	    	my $copy = $new_label;
			$copy =~ s/--cl_id--/$cluster_id_hash{$cluster_nb}/;
			$add_this .= "\n\n".$copy."\n";
	    

	    ## Add the collection lable to the logo tree
	    if ($display_collection_name_flag == 1 && $single_input_flag == 0) {
	    #if ($display_collection_name_flag == 1) {
		my $displacement = 4 + (scalar(@label_fields_to_return) * 20);
		$display_title_lab =~ s/--dis--/$displacement/;
		$add_this .= "\n".$display_title_lab."\n";	
	    }

	    ## Add the IC to the logo tree

#	    $ic_leaves =~ s/--cl_id--/$cluster_id_hash{$cluster_nb}/g;
#	    $add_this .= "\n".$ic_leaves."\n";
#	    print TEMP_2 $add_this."\n"; 
	    print TEMP_2 $add_this."\n";      
	}
	
	print TEMP_2 $_."\n";
    }
    close(TEMP_2);
    unlink($main::outfile{small_logo_cladogram_html});

    my $cmd = "mv -f ".$main::outfile{temp_html_2}." ".$main::outfile{small_logo_cladogram_html};
    &doit($cmd, 0, $die_on_error, $verbose, 0, "", $main::out, $main::err);
    #return();
}

################################################################
## Index a table to convert to HTML
sub AddTabToConvert {
  my ($key) = @_;
  my $tab = $main::outfile{$key};
  my $html_key = $key."_html";
  my $html = $tab."_html";
  $html =~ s/\.tab.html$/\.html/;
  $html =~ s/\.txt.html$/\.html/;
  $main::outfile{$html_key} = $html; push @outfiles, $html_key; 
  push @tab_to_convert, $key; ## Add the key to the list to be converted
}

################################################################
## Convert tab-delimited files in HTML
sub ConvertTabToHTML {
  my @tab_to_convert = @_;
  &RSAT::message::TimeWarn("Converting tab-delimited to HTML files") if ($main::verbose >= 2);
  for my $key (@tab_to_convert) {
    my $tab = $main::outfile{$key};
    my $html_key = $key."_html";
    my $html = $main::outfile{$html_key};
    my $cmd = $SCRIPTS."/text-to-html ";
    $cmd .= " -i ".$tab;
    $cmd .= " -o ".$html;
    &doit($cmd, 0, $die_on_error, $verbose, 0, "", $main::out, $main::err);
  }
}


#########################################################################
## Merge the matrices at each level of the hclust tree, and produce a
## branch-wise matrix + logo + consensus.
sub Merge_matrices {

    my $root_logo_path = "";
    my @root_motifs_tf = ();

    if ($single_input_flag == 0){
	($root_logo_path) = &OpenOutputFile($main::outfile{root_motifs_table});
	print $root_logo_path ";Cluster_ID\tLogo\tLogo_RC\n";
    }
    
    ## Read the file with the information of the intermediate alignments
    ## This info will be used to create branch motifs
    my %int_align_files = ();
    my ($int_align_file) = &OpenInputFile($main::outfile{int_align});
    while (<$int_align_file>) {
	chomp;
	my $line = $_;
	my @split_line = split("\t", $line);
	my $cluster_number = $cluster_id_hash{$split_line[1]};
	my $level_number = "node_".$split_line[2];
	my $file_path = $split_line[3];
	$int_align_files{$cluster_number}{$level_number} = $file_path;
    }
    close $int_align_file;

    my %width_internal_alignments = ();
    &RSAT::message::TimeWarn("Merging matrices for", scalar(@clusters_to_HTML), "clusters") if ($main::verbose >= 2);
    foreach my $cluster (@clusters_to_HTML) {

        ## Get the cluster sizes
	my @nodes = @{$cluster_nodes{$cluster}};
	&RSAT::message::Debug("Merging matrices for cluster", $cluster, "Nodes", join (";", @nodes)) if ($main::verbose >= 3);
	
	$clusters_info{$cluster} = scalar(@nodes); 
	$clusters_info{$cluster} =~ s/\s+//g;

	## Folders with the aligned matrices
	my @folder_merged_matrices = ();
	my $singleton_cluster = 0;
	if (scalar(@nodes) == 1){
	    $singleton_cluster = 1;	
	} else {
	    for my $n (1..scalar(@nodes)-1){
		push(@folder_merged_matrices, "node_".$n);			
	    }
	}

	my %int_align_info = ();
	if ($singleton_cluster == 0){
	    my $node_counter = 0;
	    foreach my $folder (@folder_merged_matrices) {

		## Skip the merging except for the root node when the
		## root motifs are required
		$node_counter++;
		if ($root_matrices_flag == 1){ 
		    unless(scalar(@folder_merged_matrices) == $node_counter){
			next;
		    }
		}
		
		## Read the table with the number of spaced for each matrix,
		## for each level of each cluster
		my $merge_level = $folder;
		$main::outfile{int_align_offset} = $main::outfile{prefix}."_clusters_information/".$cluster."/levels_JSON_".$cluster."_".$merge_level."_dataframe.tab";
		my @level_motifs = ();
		my ($int_align_dataframe) = &OpenInputFile($main::outfile{int_align_offset});
		while (<$int_align_dataframe>) {
		    chomp;
		    my $line = $_;
		    my @split_line = split("\t+", $line);
		    my $motif_id = $split_line[0];
		    #$motif_id =~ s/\./_/;
		    push(@level_motifs, $motif_id);
		}
		close $int_align_dataframe;
		#unlink($main::outfile{int_align_offset});

		## Count the number of motif of each collection
		%collection_count = %motif_collection_count;

		## Concatenate the motif's file names
		my @file_names = ();
		my @ID_names = ();
		my @ID_motifs = ();

		## Get the names of the files of each level
		foreach my $m (@level_motifs) {

		    push(@ID_motifs, $alignment_info{$m}{name});
		    
		    ## Count the number of motifs belonging to a specific collection
		    $collection_count{$alignment_info{$m}{collection}}++;

		    ## Set the label motifs according to the user selection
		    my @motif_labels = ();
		    foreach my $field (@label_motif_fields_to_return) {
		      my $align_info = "";
		      if (defined($alignment_info{$m}{$field})) {
			$align_info = $alignment_info{$m}{$field};
		      }
		      push(@motif_labels, $align_info);
		    }
		    my $motif_labels_separated = join("::", @motif_labels);
		    push(@ID_names, $motif_labels_separated);
		    push(@file_names, $alignment_info{$m}{aligned_tf});
		}


		## Count the number of motifs belonging to each collection of motifs
		## at each node of each cluster
		$merged_consensuses_files{$folder}{$cluster}{collection_counts} = "";
		foreach my $c (keys %collection_count){

		    ## Store the number of motif for each collection (incluiding 0)
		    $merged_consensuses_files{$cluster}{counter_collection}{$c} = $collection_count{$c};

		    ## Print the HTML string to print the collection counts
		    if ($collection_count{$c} > 0){
			if ($collection_count{$c} == 1){
			    $merged_consensuses_files{$folder}{$cluster}{collection_counts} .= $c."::".$collection_count{$c}."_motif<br>";
			} else {
			    $merged_consensuses_files{$folder}{$cluster}{collection_counts} .= $c."::".$collection_count{$c}."_motifs<br>";
			}
		    }
		}
		my $files = join(" ", @file_names);
		my $ID_cluster = join("<br>", @ID_names);
		
		################################################################
		## Merge the matrices and create a single matrix
		my $cat_file = $main::outfile{prefix}."_clusters_information/".$cluster."/merged_consensuses/".$merge_level."/".$cluster."_".$merge_level."_cat.tf";
		my $merged_mat_file = $main::outfile{prefix}."_clusters_information/".$cluster."/merged_consensuses/".$merge_level."/".$cluster."_".$merge_level."_matrices.tf";

		my $merged_mat_file_trimmed = $main::outfile{prefix}."_clusters_information/".$cluster."/merged_consensuses/".$merge_level."/".$cluster."_".$merge_level."_trimmed_matrices.tf";
		$cmd = "cat ".$files." >".$cat_file;
		$cmd .= "; ".$SCRIPTS."/merge-matrices -i ".$cat_file;
		$cmd .= " -in_format tf -out_format tf";
		$cmd .= " -id ".$cluster." -name ".$cluster;
		$cmd .= " -calc ".$operator;
		$cmd .= " -o ".$merged_mat_file;
		&doit($cmd, 0, $die_on_error, $verbose, 0, "", $main::out, $main::err);
		## Delete files with single matrices
		unlink($cat_file);		

		my $mt_nb = scalar(@file_names)."motifs";
		my $motif_name = $cluster."_".$merge_level."_".$mt_nb;

		if (scalar(@folder_merged_matrices) == $node_counter){
		    $motif_name = $cluster;
		}

		my $lev_motif_ac = join(",", @level_motifs);
		my $lev_motif_id = join(",", @ID_motifs);
		my $matrix_type = "merge";
		my $mer_type = $operator;
		my $mer_number = scalar(@file_names);


		## Addig attributes (ID + AC: cluster + level + motif_nb)
		my $merged_mat_file_2 = $main::outfile{prefix}."_clusters_information/".$cluster."/merged_consensuses/".$merge_level."/".$cluster."_nb_motifs_".scalar(@file_names).".tf";
		$cmd = $SCRIPTS."/convert-matrix -i ".$merged_mat_file;
		$cmd .= " -from tf -to tf -return counts,consensus";
		$cmd .= " -attr name ".$motif_name;
		$cmd .= " -attr accession ".$motif_name;
		$cmd .= " -o ".$merged_mat_file_2; 
		&doit($cmd, 0, $die_on_error, $verbose, 0, "", $main::out, $main::err);		

		## Calculate the IC content and remove low IC columns
		$merged_mat_file_trimmed = &trim_matrix_low_IC_columns($merged_mat_file_2, $merged_mat_file_trimmed, -2, $lev_motif_ac, $lev_motif_id, $matrix_type, $mer_type, $mer_number);

		## Create branch-wise logos
		$concat_motif_files .= $merged_mat_file_trimmed." ";
		my $c = "cat ".$merged_mat_file_trimmed." >> ".$main::outfile{all_concatenated_motifs};
		&doit($c, 0, $die_on_error, $verbose, 0, "", $main::out, $main::err);

		$merged_consensuses_files{$folder}{$cluster}{logo} = $main::outfile{prefix}."_aligned_logos/".$motif_name."_logo.png";
		$merged_consensuses_files{$folder}{$cluster}{logo_RC} = $main::outfile{prefix}."_aligned_logos/".$motif_name."_logo_rc.png";
		$merged_consensuses_files{$folder}{$cluster}{width} = 	$width_internal_alignments{$cluster}{$folder};
		$merged_consensuses_files{$folder}{$cluster}{motif_name} = $motif_name;
		$merged_consensuses_files{$folder}{$cluster}{consensus} = "";
		$merged_consensuses_files{$folder}{$cluster}{tf_file} = $merged_mat_file_trimmed;

		my $mat_file = $merged_mat_file_trimmed;

		my $cons = `more $mat_file | grep '^DE'`;
		chomp($cons);
		$cons =~ s/^DE\s+//;
		$cons =~ s/-//g;
		$merged_consensuses_files{$folder}{$cluster}{consensus} = $cons;

		## Add the most external motif in the tree as a root motif
		## Add the info to the Root Motifs Features hash
		if (scalar(@folder_merged_matrices) == $node_counter){

		    $root_motifs_features{$cluster}{logo} = $merged_consensuses_files{$folder}{$cluster}{logo};
		    $root_motifs_features{$cluster}{logo_RC} = $merged_consensuses_files{$folder}{$cluster}{logo_RC};
		    $root_motifs_features{$cluster}{size} = $node_counter + 1; ## Because we count the number of branches
		    $root_motifs_features{$cluster}{members} = "";
		    $root_motifs_features{$cluster}{file} = $mat_file;
		    $root_motifs_features{$cluster}{members} = $ID_cluster;
		    $root_motifs_features{$cluster}{collection_count} = $merged_consensuses_files{$folder}{$cluster}{collection_counts};
		    push (@root_motifs_tf, $mat_file);
		    #$external_branch_motifs .= $mat_file." ";

		    my $logo_path = &RSAT::util::RelativePath($main::outfile{summary}, $root_motifs_features{$cluster}{logo});
		    my $logo_rc_path = &RSAT::util::RelativePath($main::outfile{summary}, $root_motifs_features{$cluster}{logo_RC});
		    print $root_logo_path $cluster."\t".$logo_path."\t".$logo_rc_path."\n" if ($root_logo_path);
		}
	    }
	} else {

	    ## Store the number of motif for each collection (incluiding 0)
	    foreach my $c (keys %collection_count){
		if ($c eq $alignment_info{"@{$cluster_nodes{$cluster}}"}{collection}){
		    $merged_consensuses_files{node_1}{$cluster}{collection_counts} = $alignment_info{"@{$cluster_nodes{$cluster}}"}{collection}." : 1 motif";
		    $merged_consensuses_files{$cluster}{counter_collection}{$c} = 1;
		} else {
		    $merged_consensuses_files{$cluster}{counter_collection}{$c} = 0;
		}
	    }

	    my $singleton_motif_file = $alignment_info{"@{$cluster_nodes{$cluster}}"}{aligned_tf};

	    my $new_singleton_motif_file_temp = $main::outfile{prefix}."_clusters_information/".$cluster."/".$cluster."_matrices_temp.tf";

	    my $new_singleton_motif_file = $main::outfile{prefix}."_clusters_information/".$cluster."/".$cluster."_matrices.tf";
	    $cmd = "cp ".$singleton_motif_file." ".$new_singleton_motif_file_temp;
	    &doit($cmd, 0, $die_on_error, $verbose, 0, "", $main::out, $main::err);

	    $cmd = $SCRIPTS."/convert-matrix -i ".$new_singleton_motif_file_temp." -from tf -to tf ";
	    $cmd .= " -attr name ".$cluster." -attr accession ".$cluster;
	    $cmd .= " -set_attr merged_AC @{$cluster_nodes{$cluster}} -set_attr merged_ID ".$alignment_info{"@{$cluster_nodes{$cluster}}"}{name};
	    $cmd .= " -set_attr type merge";
	    $cmd .= " -set_attr merge_type ".$operator;
	    $cmd .= " -set_attr merge_nb 1";
	    $cmd .= " -o ".$new_singleton_motif_file;
	    &doit($cmd, 0, $die_on_error, $verbose, 0, "", $main::out, $main::err);
	    unlink($new_singleton_motif_file_temp);

	    $concat_motif_files .= $new_singleton_motif_file." ";
	    my $c = "cat ".$new_singleton_motif_file." >> ".$main::outfile{all_concatenated_motifs};
	    &doit($c, 0, $die_on_error, $verbose, 0, "", $main::out, $main::err);

	    ## Add the info to the Root Motifs Features hash
	    $root_motifs_features{$cluster}{logo} = $alignment_info{"@{$cluster_nodes{$cluster}}"}{logo};
	    $root_motifs_features{$cluster}{logo_RC} = $alignment_info{"@{$cluster_nodes{$cluster}}"}{logo_rc};
	    $root_motifs_features{$cluster}{size} = 1;
	    $root_motifs_features{$cluster}{members} = $alignment_info{"@{$cluster_nodes{$cluster}}"}{name}."::".$alignment_info{"@{$cluster_nodes{$cluster}}"}{collection};

	    $root_motifs_features{$cluster}{file} = $new_singleton_motif_file;
	    $root_motifs_features{$cluster}{collection_count} = $merged_consensuses_files{node_1}{$cluster}{collection_counts};
	    ## Add the singleton cluster to the list of root motifs
	    push (@root_motifs_tf, $new_singleton_motif_file);
#	    $external_branch_motifs .= $new_singleton_motif_file." ";

	    if ($single_input_flag == 0){
		$logo_path = &RSAT::util::RelativePath($main::outfile{summary}, $root_motifs_features{$cluster}{logo});
		$logo_rc_path = &RSAT::util::RelativePath($main::outfile{summary}, $root_motifs_features{$cluster}{logo_RC});
		print $root_logo_path $cluster."\t".$logo_path."\t".$logo_rc_path."\n";
	    }
	}
    }
    
    ## Create the files with the roots motifs
    my ($print_root) = &OpenOutputFile($main::outfile{root_motifs});
    foreach my $root (@root_motifs_tf){
	my ($root_tf_file) = &OpenInputFile($root);
	my $root_tf_text = "";
	while(<$root_tf_file>){
	    $root_tf_text .= $_;
	}
	print $print_root $root_tf_text;
    }
    

    if ($single_input_flag == 0){
	close($root_logo_path);
    }
}


########################################
## Create the radial tree from the html template
sub create_html_radial_tree_file {

    &RSAT::message::TimeWarn("\n; Creating radial tree") if ($main::verbose >= 2);

    my $line = "";
    my $print = "";
    my $temp_radial_tree = "";
    my $json_file = &RSAT::util::RelativePath($main::outfile{summary}, $main::outfile{prefix}."_trees/parsed_tree_cluster_1.json");

    open(RADIAL_TREE, ">".$main::outfile{radial_tree}) || &RSAT::error::FatalError($main::outfile{radial_tree_template}, "Cannot create temporary file for Radial tree");
    open(RADIAL_TREE_TEMPLATE, $main::outfile{radial_tree_template}) || &RSAT::error::FatalError($main::outfile{radial_tree_template}, "Cannot found the HTML Radial tree template file");

    while(<RADIAL_TREE_TEMPLATE>) {
	chomp;
	$line = $_;

	## Insert the JSON file name
	if (/--json_file--/){
	    $line =~ s/--json_file--/$json_file/g;
	}

	$print .= $line."\n";
    }
    close(RADIAL_TREE_TEMPLATE);
    $line = "";

    print RADIAL_TREE $print;
    close(RADIAL_TREE);
    
}


###############################
## Export the cluster header
sub cluster_delim {

  my $cluster_delim = 
      '	
        <!--Div with cluster 1 delimitation and buttons to display results-->
	<div class="cluster_division button_click --Cluster_id_head--">
		<strong>--Cluster_id--</strong>
	</div>
';
  
  return($cluster_delim);
}


###############################
## Export the cluster header
sub Text_end_report {

    my $end_report = '
        <div id="References_Button" class="button_click Section_button selected_header_section"><strong>References</strong></div>
	<div id="end_report" style="margin-bottom:20px;">
	  <ul style="list-style: none;">
	    <li>
	      <strong>References</strong>
              <ol>
                 <li> Castro-Mondragon JA et al. RSAT matrix-clustering: dynamic exploration and redundancy reduction of transcription factor binding motif collections. <a target="_blank" href="https://oup.silverchair-cdn.com/oup/backfile/Content_public/Journal/nar/PAP/10.1093_nar_gkx314/1/gkx314.pdf?Expires=1497370402&Signature=XofQRKX~0-0C8EeL8V5NIwQEFG1UZDiJgo1BxcfsLQtd93E9TpM10q6FRMUUzdpNZrvsu9wmMU9M-VLanWxzZCK~C1KEFKFYaBo1eLIK68WBHWtN4nV1Jsm4XdJ37QoNsCxiacU-VQ2vTuurLR2NnIE2XZgXz6U3vF38JU~MOp-nGqPt2wUDVFA7KGf17JA9twamWygRatTwh1winZg7j0nzolFYJSzPLwxrNkioVTEyAE3Tx8cOCD~E1m5fRvJ5sfx9~g6It17FPb3WJJQqo4bNNfvicMthjluw6USPqQKHbVwvbLxGe~VUpSh2imFfbFbbyi1wbCyo~BwlyZR1yg__&Key-Pair-Id=APKAIUCZBIA4LVPAVW3Q"> doi: 10.1093/nar/gkx314</a>; Nucleic Acids Research (2017)</li>
                 <li><strong>Last RSAT release: </strong><a href="http://nar.oxfordjournals.org/content/early/2015/04/21/nar.gkv362.full" target=\'_blank\'>Medina-Rivera, A. et al. RSAT 2015: Regulatory Sequence Analysis Tools. Nucleic Acids Research (2015).</a></li>
              </ol>
	    </li>
	    <li>
	      <strong>Additional Information</strong>
              <ul>
                 <li type="square"><a href="http://pedagogix-tagc.univ-mrs.fr/courses/SBBCU16L_cisreg/" target=\'_blank\'>Jacques van Helden course</a></li>
              </ul>
	    </li>
	    <li>
	      <strong>Contact</strong>
              <ul>
                 <li type="square"><a href="http://pedagogix-tagc.univ-mrs.fr/rsat/data/published_data/Castro_2016_matrix-clustering/Application_4/Ceevee10/demo_jaime.html" target=\'_blank\'>Jaime Castro-Mondragon</a> - <strong>jcastro@lcg.unam.mx</strong></li>
                 <li type="square"><a href="http://morgane.bardiaux.fr/" target=\'_blank\'>Morgane Thomas-Chollier</a> - <strong>mthomas@biologie.ens.fr</strong></li>
                 <li type="square"><a href="http://jacques.van-helden.perso.luminy.univ-amu.fr/" target=\'_blank\'>Jacques van Helden</a> - <strong>Jacques.van-Helden@univ-amu.fr</strong></li>
              </ul>
              <strong>Software used</strong>
                 <li type="square"><a href="http://d3js.org/" target=\'_blank\'>Data-Driven Documents D3</a></li>
            </li>
          </ul>
	</div>';

    print $syn $end_report."\n";
}


##########################################
## Store in a string the cluster header
sub hide_show_buttons {

  my $HS_buttons = 
      '	
      <div style="clear:both; display:block; margin: 2px 5px 1px 0px;">
        <!--Div with cluster 1 delimitation and buttons to display results-->
	<div class="hide_show_button button_click" id="show_all_button">
		<strong>Show All</strong>
	</div>
	<div class="hide_show_button button_click" id="hide_all_button">
		<strong>Hide All</strong>
	</div>
      </div>
';
  
  return($HS_buttons);
}
 

###########################
## Slide buttons cluster header
sub cluster_head_buttons{
  
  my $size = shift;
  my $jquery_toggle_buttons = "";

  if ($size > 1) {
    $jquery_toggle_buttons = '

  // Slide the buttons to show the results
  $(document).ready(function() {
    $(\'.--Cluster_id_head--\', this).click(function() {
       $(\'#branch_consensus_--nb--\').slideToggle(\'fast\');
       $(\'#--nb--\').slideToggle(\'fast\');
       $(this).toggleClass(\'selected_cluster\');
       $(\'#hide_tree_--nb--\').show();
     }); 
      // $(\'#hide_tree_--nb--\').css(\'display\', \'block\');
    
  });
    ';
  } else {

    $jquery_toggle_buttons = '

  // Slide the buttons to show the results
  $(document).ready(function() {
    $(\'.--Cluster_id_head--\', this).click(function() {
       $(\'#--nb--\').slideToggle(\'fast\');
       $(this).toggleClass(\'selected_cluster\');
       $(\'#hide_tree_--nb--\').show();
     }); 
       // $(\'#hide_tree_--nb--\').css(\'display\', \'block\');
  });
    ';
  }
  return($jquery_toggle_buttons);
}


############################################
## Stores in a string the Alignment table
sub alignment_table {

  my $align_table = '
    <div class="tab alignment_tab" id="alignment_table_--nb--">
		<table>
			<thead>
				<tr>
					<th colspan="8">Cluster information and consensus alignment</th>
				</tr>
				<tr>
					<th class="tab_col">Motif id</th>
                                        <th class="tab_col">Motif name</th>
					<th class="tab_col tab_spacer_2">Cluster number</th>
					<th class="tab_col tab_spacer_2">Orientation</th>
					<th class="tab_col tab_spacer_2">Offset<br>upstream</th>
					<th class="tab_col tab_spacer_2">Offset<br>downstream</th>
					<th class="tab_col tab_spacer_2">Alignment<br>width</th>
					<th class="tab_col">Consensus Alignment</th>
				</tr>
			</thead>
                        <tbody>
                        <!-- Insert rows-->
                        HERE
                        </tbody>
                </table>
     </div>
    ';

  return($align_table);
}


###################################
## Hide/show the alignment table
sub toogle_branch_consensus_table{

    my $toogle_branch_consensus_tab  = 
'
// Slide the branch-motif table
  $(document).ready(function() {
    $(\'#button_branch_consensus_--nb--\').click(function() {
       $(\'.branch_consensus_--nb--\').slideToggle(\'slow\');
     }); 
  $(\'.branch_consensus_--nb--\').css(\'display\', \'none\');
  });
';
    return($toogle_branch_consensus_tab);
}


###################################
## Show selected branch motifs
sub Display_Selected_Branch{

    my $selected_branch  = 
'
  $(document).ready(function() {
    $("#--branch_tab_id--").click(function() {
       showOneRow("--branch_row_id--");
       showOneTable("branch_consensus_--nb--");
     }); 
  }); 
';
    return($selected_branch);
}


###################################
## Hide/show the alignment table
sub hide_branch_motifs {

  my $hide_branch_motifs  = 
      '
// Hide the logo tree
  $(document).ready(function() {
    $(\'#hide_branch_table_--nb--\').click(function() {
         $(\'#branch_consensus_--nb--\').hide();
     }); 
  });
';
  return($hide_branch_motifs);
}


###################################
## Hide/show the alignment table
sub hide_tree {

  my $hide_tree  = 
      '
// Hide the logo tree
  $(document).ready(function() {
    $(\'#hide_tree_--nb--\').click(function() {
       $(\'#--nb--\').hide();
       $(\'#branch_consensus_--nb--\').hide();
       $(\'.head_--nb--\').removeClass(\'selected_cluster\');
       $(\'#hide_tree_--nb--\').hide();
     }); 
  });
';
  return($hide_tree);
}

################################################################
## Insert D3 dynamic logo tree: This is the body of d3 script, 
## each time a new cluster is added to the file the next code 
## is pasted and modified   
## Always Modify this tree     
sub logo_tree_dynamic_portable{
  my $logo_tree = 
      '
	(function() {
        var width = --widthtree--,
	height = --height--;
	;

        var i = 0,
        duration = 750,
        root;

	var cluster = d3.layout.cluster()
		.size([height, --size--])
	        .separation(function(a, b) { return (a.parent == b.parent ? 1 : 1); });


	var diagonal = function elbow(d, i) {
		
		return "M" + d.source.y + "," + d.source.x
		+ "V" + d.target.x + "H" + d.target.y;
	}


	var svg = d3.select("#--cl_id--").append("svg")
		.attr("width", width)
		.attr("height", height)
		.append("g")
		.attr("class","drawarea")
		.attr("transform", "translate(90,0)");
		

       var jsontree = --json_file--;

	root = jsontree;
	root.x0 = height / 2;
	root.y0 = 0;	
	update(root);

function update(source) {

// compute the new height
var levelWidth = [1];
var childCount = function(level, n) {

  if (n.children && n.children.length > 0) {
    if (levelWidth.length <= level + 1) levelWidth.push(0);

    levelWidth[level+1] += n.children.length;
    n.children.forEach(function(d) {
      childCount(level + 1, d);
    });
  }
};
childCount(0, root);  
var newHeight = d3.max(levelWidth) * --sep_motifs--; // 20 pixels per line  // 250 ----------> This number must be calculated 
cluster= cluster.size([newHeight, --size--]);

// Re-draw the tree
svg = d3.select("#--cl_id--").select("svg")
		.attr("width", width)
		.attr("height", newHeight)
		.attr("transform", "translate(90,0)");

  // Compute the new tree layout.
  var nodes = cluster.nodes(root).reverse(),
      links = cluster.links(nodes);

  // Update the nodes…
  var node = svg.selectAll("g.node")
      .data(nodes, function(d) { return d.id || (d.id = ++i); });

  // Enter any new nodes at the parent"s previous position.
  var nodeEnter = node.enter().append("g")
      .attr("class", "node")
      .attr("transform", function(d) { return "translate(" + source.y0 + "," + source.x0 + ")"; })
      .on("click", click);

  nodeEnter.append("circle")
	.attr("r", 5)
        .attr("fill", "--stroke--");

       /*Insert labels*/

       /*Insert consensus*/

	nodeEnter.append("image")
		.attr("xlink:href", function(d) { return d.children ? "" : --insert_image--; }) 
		.attr("width", function(d) { return (d.size + 2)  * --svgwidth--; })
		.attr("height", --svgheight--)
		.attr("x", --x1--)    
		.attr("y", --y1--) 
		.attr("cursor", "default") 
		.attr("preserveAspectRatio", "none");	

/*		
	nodeEnter.append("image")
		.attr("xlink:href", function(d) { return d.children ? "" : d.image_rc; })  
		.attr("width", function(d) { return (d.size + 2)  * --svgwidth--; })
		.attr("height", --svgheight--)
  		.attr("x", function(d) { return (d.size + 2)  * --x2--; })  
		.attr("y", --y1--) 
		.attr("cursor", "default") 
		.attr("preserveAspectRatio", "none");
*/

  // Transition nodes to their new position.
  var nodeUpdate = node.transition()
      .duration(duration)
      .attr("transform", function(d) { return "translate(" + d.y + "," + d.x + ")"; });


  nodeUpdate.select("circle")
	.attr("r", 5)
        .attr("fill", function(d) { return d._children ? "black" : "--stroke--"; })
      .attr("font-size", "15px");


  nodeUpdate.select("text")
      .text(function(d) { return d.children ? d.ic :  d.name; })
      .attr("dx", function(d) { return d.children ? -3 : 20; })
      .attr("dy", function(d) { return d.children ? -6 : 3; })
      .attr("class", function(d) { return d.children ? "show_con_--cl_id--" : ""; })
      .style("display", function(d) { return d.children ? "none" : ""; })
      .attr("fill", function(d) { return d.children ? "blue" : "black"; })
      .attr("text-anchor", function(d) { return d.children ? "end" : "start"; })
      .attr("font-size", "20px");

	nodeUpdate.select("image")
		.attr("xlink:href", function(d) { return d.children ? "" : --insert_image--; }) 
		.attr("width", function(d) { return (d.size + 2)  * --svgwidth--; })
		.attr("height", 80)
		.attr("x", --image_spacer--)    
		.attr("y", -33) 
		.attr("cursor", "default") 
		.attr("preserveAspectRatio", "none");

/*
	node.select("image")
		.attr("xlink:href", function(d) { return d.children ? "" : d.image_rc; })  
		.attr("width", function(d) { return (d.size + 2)  * 25; })
		.attr("height", 80)
 		.attr("x", function(d) { return (d.size + 2)  * 25 + 296 + 25; })  
		.attr("y", -33)
		.attr("cursor", "default") 
		.attr("preserveAspectRatio", "none");
*/


  // Transition exiting nodes to the parent"s new position.
  var nodeExit = node.exit().transition()
      .duration(duration)
      .attr("transform", function(d) { return "translate(" + source.y + "," + source.x + ")"; })
      .remove();

  nodeExit.select("circle")
      .attr("r", 1e-6)
      .attr("font-size", "15px");

  nodeExit.selectAll("image")
      .remove();

  nodeExit.select("text")
      .style("fill-opacity", 1e-6);

  // Update the links…
  var link = svg.selectAll("path.link")
      .data(links, function(d) { return d.target.id; });

  // Enter any new links at the parent"s previous position.
  link.enter().insert("path", "g")
      .attr("class", "link")
      .attr("stroke", "--stroke--")
      .attr("d", function(d) {
        var o = {x: source.x0, y: source.y0};
        return diagonal({source: o, target: o});
      });

  // Transition links to their new position.
  link.transition()
      .duration(duration)
      .attr("d", diagonal);

  // Transition exiting nodes to the parent"s new position.
  link.exit().transition()
      .duration(duration)
      .attr("d", function(d) {
        var o = {x: source.x, y: source.y};
        return diagonal({source: o, target: o});
      })
      .remove();

  // Stash the old positions for transition.
  nodes.forEach(function(d) {
    d.x0 = d.x;
    d.y0 = d.y;
  });


// Toggle children on click.
function click(d) {
  if (d.children) {
    d._children = d.children;
    d.children = null;
  } else {
    d.children = d._children;
    d._children = null;
  }
  update(d);
}
}


})();

// Add the buttons to change the orientation
d3.select("#--cl_id--").append("text")
	.attr("x", 700)             
	.attr("y", 0)   
      .attr("font-size", "10px") 
	.attr("class", "legend")     
	.on("click", function(){
		// change the orientation
		d3.select("#--cl_id--").selectAll("image")
		.attr("xlink:href", function(d) { return d.children ? "" : d.image; }) 
	})
	.text("Direct");  


d3.select("#--cl_id--").append("text")
	.attr("x", 1000)             
	.attr("y", 0)   
      .attr("font-size", "10px") 
	.attr("class", "legend")     
	.on("click", function(){
		// change the orientation
		d3.select("#--cl_id--").selectAll("image")
		.attr("xlink:href", function(d) { return d.children ? "" : d.image_rc; }) 
	})
	.text("Reverse") ; 

	
';

  return($logo_tree);
}



##############################################################
## Insert D3 logo tree: This is the body of d3 script, each 
## time a new cluster is added to the file the next code is 
## pasted and modified           
sub logo_tree{

  my $logo_tree = 
      '
	(function() {
        var width = --widthtree--,
	height = --height--;
	;


	var cluster = d3.layout.cluster()
		.size([height, --size--])
	        .separation(function(a, b) { return (a.parent == b.parent ? 1: 1); });


	var svg = d3.select("#--cl_id--").append("svg")
                //BG_color
		.attr("width", width)
		.attr("height", height)
		.append("g")
		.attr("class","drawarea")
		.attr("transform", "translate(40,0)");
		
d3.json("--jsonfile--", function(json) {
				
	var nodes = cluster.nodes(json);

	var link = svg.selectAll("path.link")
		.data(cluster.links(nodes))
		.enter().append("path")
		.attr("class", "link")
                .attr("stroke", "--stroke--")
		.attr("d", elbow);

	var node = svg.selectAll("g.node")
		.data(nodes)
		.enter().append("g")
		.attr("class", "node")
		.attr("transform", function(d) { return "translate(" + d.y + "," + d.x + ")"; });

	node.append("circle")
		.attr("r", --radius--)
                .attr("fill", "--stroke--")
                --insert--;

       /*Insert labels*/
       --lab--

       /*Insert consensus*/
	
	node.append("svg:image")
                .attr("xlink:href", function(d) { return d.children ? "" : d.image; })
		.attr("width", function(d) { return (d.size + 2)  * --svgwidth--; })
		.attr("height", --svgheight--)
		.attr("x", --x1--)    
		.attr("y", --y1--) 
		.attr("preserveAspectRatio", "none");	

/*--RC_picture_start--		
	node.append("svg:image")
		.attr("xlink:href", function(d) { return d.children ? "" : d.image_rc; })
		.attr("width", function(d) { return (d.size + 2)  * --svgwidth--; })
		.attr("height", --svgheight--)
  		.attr("x", function(d) { return (d.size + 2)  * --x2--; })  
		.attr("y", --y1--) 
		.attr("preserveAspectRatio", "none");
*/--RC_picture_end--				
	});
	
	function elbow(d, i) {
		
		return "M" + d.source.y + "," + d.source.x
		+ "V" + d.target.x + "H" + d.target.y;
	}

})();
	
';

  return($logo_tree);
}


#########################
## Insert D3 logo tree
sub branch_consensus_table{

  my $branch_consensus_table = 
      '
    <div class="hide_show tab cons_tab" id="branch_consensus_--nb--" style="display:none;margin:0px;background-color:white;">
    <div id="hide_branch_table_--nb--" class="Cluster_results buttons_click" style="display:block; clear:both"><strong>--nb--</strong></div>
		<table style="display:block; clear:both;">
			<thead>
				<tr>
					<th colspan="5"><h2>Branch Motifs</h2></th>
				</tr>
				<tr>
					<th class="tab_col">Node</th>
					<th class="tab_col">Consensus</th>
					<th class="tab_col">Logo</th>
                                        <th class="tab_col">Logo (Reverse)</th>
                                        <th class="tab_col">Collections</th>
					<th class="tab_col">Matrix (Transfac format)</th>
					<th class="tab_col">IC</th>
					<th class="tab_col">Nb sites</th>
				</tr>
			</thead>
                        <tbody>
                        <!-- Insert rows-->
                        --here--
                        </tbody>
                </table>
     </div>
';
  return($branch_consensus_table);
}


##############################################################
## When the option -top is used the analysis is restricted 
## to the first X motifs, however the input motif file is 
## splitted on individual files, although not all of them 
## are not. This functions will delete those files
sub Delete_temporal_files {

  foreach my $f (keys %to_delete) {
    unlink($to_delete{$f});
  }

  foreach my $fd (keys %to_delete_folder) {
    rmtree($to_delete_folder{$fd});
  }

}


##################################
## Read the cluster-color table
sub Read_cluster_colors{

  my %hexa_hash = ();

  open(HEXA, $main::outfile{hexa_colors}) || &RSAT::error::FatalError( "Cannot open Hexadecimal code for colors file", $main::outfile{hexa_colors});

  while(<HEXA>) {
    chomp;
    my @string_split = split(/\s+/, $_);
    my $cl = $string_split[0];
    my $hexa = $string_split[1];
    $hexa =~ s/FF$//ig;
    $hexa_hash{$cl} = $hexa;
  }
  close(HEXA);

  return(%hexa_hash);
}


################################################################
## Generate a compressed archive with all the results
sub Archive {

  my ($remove_first, $to_archive) = @_;
  &RSAT::message::TimeWarn("\n; Archiving data and results") if ($main::verbose >= 2);

  ## Delete previous version of the archive to avoid including the old archive in the new one
  $cmd .= "rm -f ".$main::outfile{archive}."; " if ($remove_first);

  ################################################################
  ## Define archiving parameters

  ## By default, archive the whole output directory
  $to_archive = $main::dir{output} unless $to_archive;

  ## Archive all data and results
  my ($archive_dir, $archive) = &SplitFileName($main::outfile{archive});
  my ($archive_dir_dir, $archive_dir_base) = &SplitFileName($archive_dir);
#  $to_archive_rel_path = &RSAT::util::RelativePath($main::outfile{archive}, $to_archive);
  my $to_archive_rel_path = &RSAT::util::RelativePath($archive_dir_dir, $to_archive);
  my $archive_rel_path = &RSAT::util::RelativePath($archive_dir_dir, $main::outfile{archive});

  ## TO CHECK (Jacques)
  if ($main::verbose >= 3) {
    &RSAT::message::Debug("folder to archive", $to_archive);
  }

  ## Avoid crash of the program when run from the "$archive_dir_dir"
  if ($archive_dir_dir eq "") {
    $archive_dir_dir = ".";
    $to_archive_rel_path = $to_archive;
    $archive_rel_path = $main::outfile{archive};	 
  }

  my $cmd = "";
  if ($main::param{archive_format} eq "zip") {
    $cmd .= "(cd ".$archive_dir_dir." ; ";
    $cmd .= " zip -ryq ".$archive_rel_path." ".$to_archive_rel_path;
    $cmd .= " -x ".$archive;
    $cmd .= ")";
  } elsif (($main::param{archive_format} eq "tar") ||
	   ($main::param{archive_format} eq "tgz")) {
    $cmd .= "tar -cpf ".$main::outfile{archive};
    $cmd .= " -z" if ($main::param{archive_format} eq "tgz");
    $cmd .= " -C ".$archive_dir_dir; ## Avoid including the whole path in the archive paths
    $cmd .= " --exclude ".$archive;
    $cmd .= " ".$to_archive_rel_path;
  } else {
    &RSAT::error::FatalError($main::param{archive_format}, "Invalid archive format. Supported: zip, tar, tgz.");
  }

  &one_command($cmd, 1);

  &RSAT::message::TimeWarn("Archive", $main::outfile{archive}) if ($main::verbose >= 2);
}


##########################################
## Open the HTML page for the synthesis
sub OpenSynthesis {

  my $refresh_time;
  if ($main::param{progressive_synthesis}) {
    $refresh_time = 90;
  } else {
     $refresh_time = 0;
  }

  # $main::html_index = &OpenOutputFile($main::outfile{html_index});
  # # my $header = &PrintHtmlResultHeader(program=>"matrix-clustering", "title"=>$main::param{title}, "result_toc"=>1, refresh_time=>$refresh_time);
  # #      &RSAT::message::Debug("header", $header) if ($main::verbose >= 10);
  # print $main::html_index $header;
  
  # ## Report command
  # print $html_index "<p><tt><b>Command:</b> matrix-clustering ";
  # &PrintArguments($main::html_index, 1);
  # print $html_index "</tt></p>\n";

  ## Open the summary HTML file
  $syn = &OpenOutputFile($main::outfile{summary});
  $synthesis_path = `dirname $main::outfile{summary}`;
  chomp($synthesis_path);

  my $html_lib = "";
  if ($root_matrices_flag == 0) {
      ## Add the JS libraries paths
      $html_lib .= '
   <script type="text/javascript" src="'.$d3_base.'"></script>
   <script type="text/javascript" src="'.$jquery_base.'"></script>
   <script type="text/javascript" src="'.$datatable_base.'"></script>
   <link rel="stylesheet" type="text/css" href="'.$datatable_css_base.'">
</head>
     ';
  } 

  ## Add the CSS style for matrix-clustering summary and 
  ## concatenate it to header the CSS sytles
  my $css_matrix_clustering = &ReportStyleCSS();
  $html_lib .= $css_matrix_clustering."\n";
  
  my $head = &PrintHtmlResultHeader(program=>"matrix-clustering", "title"=>$main::param{title}, "result_toc"=>1, refresh_time=>$refresh_time);
  $head =~ s|</head>|$html_lib|;
  
  print $syn $head;

  &ReportCommand();
}


sub ReOpenSynthesis {

  unlink($main::outfile{summary});
  close($syn);

  ## Open the summary HTML file
  $syn = &OpenOutputFile($main::outfile{summary});
  $synthesis_path = `dirname $main::outfile{summary}`;
  chomp($synthesis_path);

  my $html_lib = "";
  if ($root_matrices_flag == 0) {
      ## Add the JS libraries paths
      $html_lib .= '
   <script type="text/javascript" src="'.$d3_base.'"></script>
   <script type="text/javascript" src="'.$jquery_base.'"></script>
   <script type="text/javascript" src="'.$datatable_base.'"></script>
   <link rel="stylesheet" type="text/css" href="'.$datatable_css_base.'">
</head>
     ';
  } 

  ## Add the CSS style for matrix-clustering summary and 
  ## concatenate it to header the CSS sytles
  my $css_matrix_clustering = &ReportStyleCSS();
  $html_lib .= $css_matrix_clustering."\n";
  
  my $head = &PrintHtmlResultHeader(program=>"matrix-clustering", "title"=>$main::param{title});
  $head =~ s|</head>|$html_lib|;
  
  print $syn $head;

  &ReportCommand();
}


##########################################
sub CloseSynthesis {
    print $syn "</body>\n";
    print $syn "</html>\n";
    close $syn;
}

################################################################
## Report the command before running the analysis, for the sake of
## debugging and to facilitate copy-paste of the options.
sub ReportCommand {
  print $syn &open_menu_heading($menu_nb++, "<a name='logs'></a><h3>Command</h3>", 1);
  print $syn "<pre>";
  print $syn "matrix-clustering ";
  &PrintArguments($syn);
  print $syn "</pre>";
  print $syn &close_menu_heading();
}


#################################################
## CSS style for the matrix-clustering summary 
## (dynamic tables + D3 trees)
sub ReportStyleCSS{
    my $CSS_mat_clus = '
<style>
  
  h3 a:hover {
	font-weight: bold;
	text-decoration: none;
  }
  

  .cluster_division {
	background-color: '.$blue_color.';
	float: left;
	margin: 5px 3px 3px 3px;
	width: auto;
	height: 15px;
	position: relative;
	display: inline-block;
	text-align: center;
	color: '.$font_color.';
	font-size: 12px;
	padding: 4px;
	cursor: pointer;
	border-radius:5px;
	border: 1px solid #819FF7;
  }
  
  
  .button_click:active {
  position:relative;
  top:1px;
  }

  .tab{
    font-size: 10px;
    margin-top: 3px;
    text-align: center;
    text-decoration: none;
    display: block;
    background-color: #E6E6E6;
    clear: both;
    float: left;
    position: relative;
    border-radius:5px;
    padding: 0px 10px 10px 10px;
  }
   
  .sep {
  background-color: #B1D4F9;
  height: 17px;
  }
  
  
  .tab_list{
  width: 937px;
  text-align: left;
  color: #000000;
  font-family: Arial;
  text-decoration: none;
  display: none;
  float: left;
  background-color: #E6E6E6;
  font-size: 15px;
  clear: both;
  position: relative;
  border-radius:5px;
  padding: 0px 0px 0px 5px;
  }


  .tab_header {
  border-bottom: 1px solid black;
  width: 175px;
  padding: 7px;
  }

  .tab_col {
    padding: 7px 30px 7px 30px;
    background-color: #B1D4F9 !important;
  }

  .seq {
  font-family: Monospace;
  font-size: 15px;
  }

  .Cluster_results {
  margin-top: 3px;
  width: auto;
  heigth: 80px;
  border: 1px;
  position: relative;
  padding: 1px;
  font-size: 13px;
  margin-top: 20px;
  text-align: center;
  color: #ffffff;
  background:#cc0000;
  border-radius:5px;
  cursor: pointer;
  float: left;
  clear: both;
  display: none;
  }

  .Cluster_results:active {
  position:relative;
  top:1px;
  }

  .Section_button {
  background-color: '.$blue_color.';
  float: left;
  margin-top: 2px;
  margin-bottom: 2px;
  width: 450px;
  height: 20px;
  position: relative;
  display: block;
  text-align: center;
  color: '.$blue_font_color.';
  font-size: 15px;
  padding: 4px;
  clear: both;
  border-radius:5px;
  cursor: pointer;
  }

  .file_link {
  cursor: pointer;
  text-decoration: none;
  }

  .file_link:hover {
  text-decoration: underline;
  }

  #hclust_tree_head {
  width: 900px;
  heigth: 400px;
  margin-top: 15px;
  margin-bottom: 5px;
  display: inline-block;
  position: relative;
  padding: 3px;
  background-color: #B1D4F9;
  float: left;
  border-radius:5px;
  font-size: 12px;
  clear: both;
  }

  .logo {
	position: relative;
	max-width: 100%;
	max-height: 13%;
	width: 120px;
	height: 65px;
	float: left;
	clear: both;
  }

  .logo_tab {
	position: relative;
	max-width: 100%;
	max-height: 10%;
	height: 45px;
	width: 60px
	float: left;
	clear: both;
  }

  .logo_tree {
  position: relative;
  float: left;
  display: none;
  clear: both;
  padding: 0px;
  }

  .branch_motifs_head {
  width: 950px;
  heigth: 500px;
  margin-top: 15px;
  margin-bottom: 5px;
  display: none;
  position: relative;
  padding: 3px;
  background-color: #B1D4F9;
  float: left;
  border-radius:5px;
  font-size: 12px;
  clear: both;
  }

  .spacer {
  heigth: 200px;
  display: block;
  position: relative;
  clear: both;
  float: left;
  background-color: #B1D4F9;
  }


  .tab_spacer_1 {
  padding: 2px 12px 2px 12px;
  font-size: 12px;
  }


  .tab_spacer_2 {
    padding: 3px;
    font-size: 12px;
  }

  #heatmap {
	heigth: 400px;
	width: 450px;
  }
  
  #show_forest {
	heigth: auto;
	width: 97%;
	position: relative;
	float: left;
	clear: both;
	border-radius:5px;
  }

  .display_clusters{
    width: 1000px;
    background-color: #E6E6E6;
    text-align: center;
    padding: 0px 10px 10px 10px;
  }

  .par_text {
    font-size: 12px;
    text-align: center;
  }

  .sep_clusters_div {
    clear: both;
    float: left;
    display: block;
  }

  .display{
	height: auto;
	width: auto;
	border-radius: 5px;
	background-color: #FFFFFF; 
	margin: 10px;
        padding: 7px;
	text-align: left; 
	font-size: 17px;
	border: solid 3px #004F72; 
	clear: both;
	position: relative;
	float: left;
	display: block;
  }

  .individual_results{
	text-align:center; 
	padding: 0px 10px 0px 20px; 
	width: auto;
	height: auto;
	border-radius: 10px; 
	background-color: #E6E6E6; 
        position: relative;
        clear: both;
        margin: 0px 7px 7px 0px;
        display: block;
        float: left;
  } 
 
  .cluster_info_head {
	background-color: #DCE4EC;
	float: left;
	height: 45px;
	width: 630px;
	position: relative;
	display: block;
	text-align: left;
	color: #34373B;
	font-size: 15px;
	padding: 0px;
	border-radius:5px;
	clear: both;
        margin-top: 5px;
  }

  .hide_show_button{
	float: left;
	margin: 5px 3px 3px 3px;
	width: 75px;
	height: 15px;
	position: relative;
	display: inline-block;
	text-align: center;
	color: #34373B;
	font-size: 12px;
	padding: 4px;
	cursor: pointer;
	border-radius:5px;
  }

  #show_all_button{
     background-color: '.$orange_color.';
     border: 1px solid orange;
     color: '.$font_color.';
  }

  #hide_all_button{
    background-color: '.$blue_color.';
    border: 1px solid #819FF7;
     color: '.$font_color.';
  }

  .selected_cluster {
    background-color: '.$orange_color.';
    border: 1px solid orange;
  }

  .selected_header_section {
    color : '.$font_color.';
    background-color: '.$orange_color.' !important;
    border: 1px solid '.$orange_color.';
  }

  #end_report {
  width: 977px;
  heigth: 400px;
  margin-top: 15px;
  margin-bottom: 5px;
  display: inline-block;
  position: relative;
  padding: 3px;
  background-color: #E6E6E6;
  float: left;
  border-radius:5px;
  font-size: 12px;
  clear: both;
  }

  /****************/
  /* D3 CSS sytle */
  /****************/

  div {
  border-radius: 0.5px;
  }


  table {
  border: #2377D2;
  }


  .node circle {
  stroke-width: 0.5px;
  }


  .node {
  font: 10px sans-serif;
  }


  .link {
  fill: none;
  stroke-width: 1px;
  }

  svg {
  pointer-events: all;
  background-color: white;
  overflow: scroll;
  }

</style>
';

    return($CSS_mat_clus);
}


###########################################
## PArameters table of matrix-clustering.
## The values are filled with variables  
## taken from other parts of the code
sub ParametersTable{

  my $hclust_method_link = "http://pedagogix-tagc.univ-mrs.fr/courses/statistics_bioinformatics/pdf_files/09.clustering.pdf";

  my $threshold_values_html = "";

  ## Print the thresholds and their values
  foreach my $par (sort keys %lth) {
    $threshold_values_html .= "<strong>".$par."</strong> = ".$lth{$par}."<br>";
  } 
  foreach my $par (sort keys %uth) {
    $threshold_values_html .= "<strong>".$par."</strong> = ".$uth{$par}."<br>";
  } 


  my $par_table = '
  <!-- Div with the table of selected parameters-->
  <div id="Par_tab_button" class="button_click Section_button selected_header_section"><strong>Results Summary</strong></div>
  <div id="Par_tab" class="tab" style="margin-bottom:15px;">
    <h2 style="margin-top: 0px;margin-bottom: 5px;">Results Summary</h2>
    <table id="parameters_table" style="width:980px;">
      <thead>
	<tr>
	  <th class="tab_col">Nb Input motifs</th>
	  <th class="tab_col">Nb Input collections</th>
	  <th class="tab_col">Nb Clusters Found</th>
	  <th class="tab_col">Linkage method <a target=\'_blank\' href="'.$hclust_method_link.'"><img src="'.&RSAT::util::RelativePath($main::outfile{summary}, $ENV{RSAT}."/public_html/images/question-mark-button-2.png").'" style="width:15px;height:15px;position:relative;float:right;"></a></th>
	  <th class="tab_col">Similarity metric <a target=\'_blank\' href="'.$hclust_method_link.'"><img src="'.&RSAT::util::RelativePath($main::outfile{summary}, $ENV{RSAT}."/public_html/images/question-mark-button-2.png").'" style="width:15px;height:15px;position:relative;float:right;"></a></th>
	  <th class="tab_col">Thresholds to partition the tree<a target=\'_blank\' href="'.$hclust_method_link.'"><img src="'.&RSAT::util::RelativePath($main::outfile{summary}, $ENV{RSAT}."/public_html/images/question-mark-button-2.png").'" style="width:15px;height:15px;position:relative;display:block;clear:both;float:right;"></a></th>
	  <th class="tab_col">Complete results [zip]</th>
	</tr>
      </thead>
      <tbody>
	<tr>
	  <td class="par_text">'.$number_of_motifs.'</td>
	  <td class="par_text">'.$number_of_collections.'</td>
	  <td class="par_text">'.$number_of_clusters.'</td>
	  <td class="par_text">'.$hclust_method.'</td>
	  <td class="par_text">'.$main::param{matrix_compa_score}.'</td>
	  <td class="par_text">'.$threshold_values_html.'</td>
	  <td class="par_text"><a href="'.&RSAT::util::RelativePath($main::outfile{summary}, $main::outfile{archive}).'">Download</a></td>
	</tr>
      </tbody>
    </table>
  </div>
'."\n\n";
  print $syn $par_table;
}


###########################################
## Clusters summary table of matrix-clustering
sub ClustersSummaryTable{

    ## Open the cluster summary table 
    ## Print the header
    my ($cluster_summary_handle) = &RSAT::util::OpenOutputFile($outfile{cluster_summary_table});
    my $header = ";Cluster_ID\tNumber_of_Motifs";
    foreach my $c (keys %motif_collection_count){
	$header .=  "\t$c";
    }
    print $cluster_summary_handle $header."\n";

  my $clust_table = '
  <!-- Div with the table of selected parameters-->
  <div id="Clus_tab_button" class="button_click Section_button"><strong>Clusters Summary</strong></div>
  <div id="Clus_tab" class="tab" style="margin-bottom:15px;display:none;width:auto;">
    <h2 style="margin-top: 0px;margin-bottom: 5px;">Clusters Summary Table</h2> '."\n";

$clust_table .= "\n".'
    <table id="cluster_summary_table" style="width:auto;">
      <thead>
	<tr>
	  <th class="tab_col">Root Motif</th>
	  <th class="tab_col">Root Motif (Reverse)</th>
	  <th class="tab_col">Cluster ID</th>
	  <th class="tab_col"># Motifs</th>
	  <th class="tab_col">Motif_Name::Collection</th>
	  <th class="tab_col">Number of Motifs by Collection</th>
	  <th class="tab_col">Root Motif (transfac Format)</th>
	</tr>
      </thead>
      <tbody>

--clus_tab--

      </tbody>
    </table>
       <ul style="text-align:left;margin:0px 0px 5px 0px;">
          <li type="square" style="color:red">Note: by default the table displays the first 50 clusters. Click on the <i>Show X entries</i> button to display more (or less) clusters.</li>
          <li type="square">Click on the column names to change the order of the data.</li>
          <li type="square">Use the <i>Search</i> window to find your motif (s) of interest.</li>
       </ul>   
  </div>
'."\n\n";


  ## Insert and fill the rows
  my $row_cluster_tab = "";
  foreach my $c (1 .. scalar keys %root_motifs_features){
      $cluster = $cluster_id_hash{$c};

      my $count = $root_motifs_features{$cluster}{collection_count};

      print $count."\t".$cluster."\n";

      $row_cluster_tab .= "
         <tr>
            <th class='tab_spacer_2'><img  width='--width--' src='".&RSAT::util::RelativePath($main::outfile{summary}, $root_motifs_features{$cluster}{logo})."'/></td>
            <th class='tab_spacer_2'><img  width='--width--' src='".&RSAT::util::RelativePath($main::outfile{summary}, $root_motifs_features{$cluster}{logo_RC})."'/></td>
            <td class='tab_spacer_1'>".$cluster."</td>
            <td class='tab_spacer_1'>".$root_motifs_features{$cluster}{size}."</td>
            <td class='tab_spacer_1'>".$root_motifs_features{$cluster}{members}."</td>
            <td class='tab_spacer_2'>".$count."</td> 
            <td class='tab_spacer_1'><a target=\"_blank\" href=\"".&RSAT::util::RelativePath($main::outfile{summary}, $root_motifs_features{$cluster}{file})."\">Show matrix</a></td>
         </tr>"."\n";

      ## The image size depends of the motif width
      my $w = 12 * $cluster_info_width{$cluster}; 
      $row_cluster_tab =~ s/--width--/$w/g;

      ## Print the cluster summary table in a separated file
      my $line_cluster_summary_table = $cluster."\t".$root_motifs_features{$cluster}{size};
      foreach my $c (keys %motif_collection_count){
      	  $line_cluster_summary_table .= "\t".$merged_consensuses_files{$cluster}{counter_collection}{$c};
      }
      print $cluster_summary_handle $line_cluster_summary_table."\n";
  }
    $clust_table =~ s/--clus_tab--/$row_cluster_tab/g;
    print $syn $clust_table;
    close $clust_table;
}


################################################################
## Create the motif richness barplot in D3
sub MotifRichnessPlot {
    
    ## Create a copy of the D3 heatmap template
    $cmd = "cp ".$ENV{RSAT}."/public_html/templates_html/Barplot_motif_richness.html ".$main::outfile{motif_richness_barplot_html};
    &doit($cmd, 0, 1, $verbose, 0, "", $main::out, $main::err);

    my $motif_richness_tsv = &RSAT::util::RelativePath($main::outfile{summary}, $main::outfile{motif_richness_tsv});
    
    ## Read the D3 heatmap file and change the attributes
    open(TEMP, ">".$main::outfile{temp_html_3}) || &RSAT::error::FatalError($main::outfile{temp_html_3}, "Cannot create temporary file");
    my ($motif_richness_temp) = &RSAT::util::OpenInputFile($main::outfile{motif_richness_barplot_html});
    while (<$motif_richness_temp>) {
	chomp;
	my $line = $_;

	$line =~ s/--d3--/$d3_base/;
	$line =~ s/--tsv--/$motif_richness_tsv/;
	print TEMP $line."\n";
    }
    close($motif_richness_temp);
    close(TEMP);

    ## Rename the temporary file
    &RSAT::message::TimeWarn("Exporting Motif Diversity Barplot") if ($main::verbose >= 2);
    $cmd = "mv ".$main::outfile{temp_html_3}." ".$main::outfile{motif_richness_barplot_html};
    &doit($cmd, 0, 1, $verbose, 0, "", $main::out, $main::err);
}


################################################################
## Create the dynamic heatmap showing the complementarity
## between the input motifs. This function is run only when
## two or more Motif collections are clusteres
sub Dynamic_Heatmap_Complementarity {

    my $tbody_exclusive_motifs = "";
    my $tbody_exclusive_motifs_row = '
			<tr>					
					<td class="tab_spacer_1">--collection--</td>
                                        <td class="tab_spacer_1">--collection_size--</td>
					<td class="tab_spacer_1">--exc_motif_nb--</td>
                                        <td class="tab_spacer_1">--DB_percent--</td>
                                        <td class="tab_spacer_1">--Total_percent--</td>					
			</tr>';

    my %attributes_heatmap = ();

    ## Create the attributes table
    &Create_Attributes_for_Heatmap_D3();

    ################################################################
    ## Create the D3 heatmap with the clusters and the motif
    ## collections where they come from

    ## Read attributes table
    my ($attributes_handle) = &RSAT::util::OpenInputFile($main::outfile{heatmap_collections_attributes});
    while (<$attributes_handle>) {
	next if (/^#/); ## Skip header line
	next if (/^;/); ## Skip comment lines
	next unless (/\S/); ## Skip empty lines
	chomp;
	my $line = $_;
	my @split_line = split("\t", $line);
	my $att_name = $split_line[0];
	my $att_content = $split_line[1];
	$attributes_heatmap{$att_name} = $att_content;
    }
    my $tsv_file = &RSAT::util::RelativePath($main::outfile{summary}, $main::outfile{heatmap_collections_d3});
    my $coverage_file = &RSAT::util::RelativePath($main::outfile{summary}, $main::outfile{coverage_table});
    my $exclusive_motif_file = &RSAT::util::RelativePath($main::outfile{summary}, $main::outfile{percent_table});

    ## Create a copy of the D3 heatmap template
    my $cmd = "cp ".$ENV{RSAT}."/public_html/templates_html/dynamic_heatmap_d3.html ".$main::outfile{dynamic_heatmap_html};
    &doit($cmd, 0, 1, $verbose, 0, "", $main::out, $main::err);

    ## Read the D3 heatmap file and change the attributes
    my ($temp_template) = &RSAT::util::OpenOutputFile($main::outfile{temp_html});
    my ($dyn_heatmap) = &RSAT::util::OpenInputFile($main::outfile{dynamic_heatmap_html});
    while (<$dyn_heatmap>) {
	chomp;
	my $line = $_;

	$line =~ s/--d3--/$d3_base/;
	$line =~ s/--left--/$attributes_heatmap{Left_space}/g;
	$line =~ s/--top--/$attributes_heatmap{Top_space}/g;
	$line =~ s/--bottom--/$attributes_heatmap{Left_space}/g;
	$line =~ s/--file--/$tsv_file/;
	$line =~ s/--cell_size--/$attributes_heatmap{Cell_size}/;
	$line =~ s/--c_numb--/$attributes_heatmap{Col_number}/;
	$line =~ s/--r_numb--/$attributes_heatmap{Row_number}/;
	$line =~ s/--gradient--/$attributes_heatmap{Gradient}/;
	$line =~ s/--cluster_number--/$attributes_heatmap{Cluster_number}/;
	# $line =~ s/--average_r_number--/$attributes_heatmap{Average_r_number}/; Aqui
	# $line =~ s/--complete_r_number--/$attributes_heatmap{Complete_r_number}/;
	# $line =~ s/--single_r_number--/$attributes_heatmap{Single_r_number}/;
	# $line =~ s/--ward_r_number--/$attributes_heatmap{Ward_r_number}/;
	# $line =~ s/--average_c_number--/$attributes_heatmap{Average_c_number}/;
	# $line =~ s/--complete_c_number--/$attributes_heatmap{Complete_c_number}/;
	# $line =~ s/--single_c_number--/$attributes_heatmap{Single_c_number}/;
	# $line =~ s/--ward_c_number--/$attributes_heatmap{Ward_c_number}/;
	$line =~ s/--row_order_default--/$attributes_heatmap{Row_order_default}/;
	$line =~ s/--label_order--/$attributes_heatmap{Cluster_names}/;
	$line =~ s/--collections--/$attributes_heatmap{Collections}/;
	$line =~ s/--domain--/$attributes_heatmap{Domain}/;
	$line =~ s/--data_legend--/$attributes_heatmap{Legend}/;
	$line =~ s/--legend_header--/$attributes_heatmap{Legend_Head}/;
	$line =~ s/--body--/$attributes_heatmap{Body}/;

	$line =~ s/--pics--/$attributes_heatmap{Logos}/;
	$line =~ s/--pics_rc--/$attributes_heatmap{Logos_RC}/;

	print $temp_template $line."\n";
    }
    close($temp_template);

    ## Rename the temporary file
    &RSAT::message::TimeWarn("Exporting Dynamic Heatmap") if ($main::verbose >= 2);
    unlink($main::outfile{dynamic_heatmap_html});
    $cmd = "mv ".$main::outfile{temp_html}." ".$main::outfile{dynamic_heatmap_html};
    &doit($cmd, 0, 1, $verbose, 0, "", $main::out, $main::err);


    ################################################################
    ## Create the D3 heatmap representing the contingency table
    ## between the collections showing their coverage among themselves

    ## Read attributes table
    my ($exclusive_motif_handle) = &RSAT::util::OpenInputFile($main::outfile{percent_table});
    while (<$exclusive_motif_handle>) {
	next if (/^#/); ## Skip header line
	next if (/^;/); ## Skip comment lines
	next unless (/\S/); ## Skip empty lines
	chomp;
	my $line = $_;
	my @split_line = split("\t", $line);
	my $collection_name = $split_line[0];
	my $collection_size = $split_line[1];
	my $exc_motif_nb = $split_line[2];
	my $DB_percent = $split_line[3];
	my $Total_percent = $split_line[4];

	my $new_row = $tbody_exclusive_motifs_row."\n";

	## Add the values to the row string
	$new_row =~ s/--collection--/$collection_name/g;
	$new_row =~ s/--collection_size--/$collection_size/g;
	$new_row =~ s/--exc_motif_nb--/$exc_motif_nb/g;
	$new_row =~ s/--DB_percent--/$DB_percent/g;
	$new_row =~ s/--Total_percent--/$Total_percent/g;

	$tbody_exclusive_motifs .= $new_row;
    }

    ## Read attributes table
    my ($coverage_attributes_handle) = &RSAT::util::OpenInputFile($main::outfile{heatmap_coverage_attributes});
    while (<$coverage_attributes_handle>) {
	next if (/^#/); ## Skip header line
	next if (/^;/); ## Skip comment lines
	next unless (/\S/); ## Skip empty lines
	chomp;
	my $line = $_;
	my @split_line = split("\t", $line);
	my $att_name = $split_line[0];
	my $att_content = $split_line[1];
	$attributes_heatmap{$att_name} = $att_content;
    }
    my $tsv_coverage_file = &RSAT::util::RelativePath($main::outfile{summary}, $main::outfile{heatmap_coverage_d3});

    ## Create a copy of the D3 heatmap template
    $cmd = "cp ".$ENV{RSAT}."/public_html/templates_html/dynamic_heatmap_d3_and_tables_motif_collection_coverage.html ".$main::outfile{dynamic_coverage_heatmap_html};
    &doit($cmd, 0, 1, $verbose, 0, "", $main::out, $main::err);

    ## Read the D3 heatmap file and change the attributes
    open(TEMP, ">".$main::outfile{temp_html}) || &RSAT::error::FatalError($main::outfile{temp_html}, "Cannot create temporary file");
    my ($dyn_cov_heatmap) = &RSAT::util::OpenInputFile($main::outfile{dynamic_coverage_heatmap_html});
    while (<$dyn_cov_heatmap>) {
	chomp;
	my $line = $_;

	$line =~ s/--d3--/$d3_base/;
	$line =~ s/--d3_venn--/$d3_venn_base/;
	$line =~ s/--jq--/$jquery_base/;
	$line =~ s/--datatable--/$datatable_base/;
	$line =~ s/--datatablecss--/$datatable_css_base/;
	$line =~ s/--left--/$attributes_heatmap{Left_space}/g;
	$line =~ s/--bottom--/$attributes_heatmap{Bottom_space}/;
	$line =~ s/--file--/$tsv_coverage_file/;
	$line =~ s/--c_numb--/$attributes_heatmap{Col_number}/;
	$line =~ s/--r_numb--/$attributes_heatmap{Row_number}/;
	$line =~ s/--collection_nb--/$attributes_heatmap{Collection_number}/;
	$line =~ s/--collection_labels--/$attributes_heatmap{Collection_labels}/;
	$line =~ s/--legend_header--/$attributes_heatmap{Legend_Head}/;
	$line =~ s/--tbody_exclusive_motifs--/$tbody_exclusive_motifs/;
	$line =~ s/--contingency_table--/$coverage_file/;
	$line =~ s/--exclusive_motif_table--/$exclusive_motif_file/;
	$line =~ s/--comp_average_c_number--/$attributes_heatmap{Average_c_number_comp}/;
	$line =~ s/--comp_complete_c_number--/$attributes_heatmap{Complete_c_number_comp}/;
	$line =~ s/--comp_single_c_number--/$attributes_heatmap{Single_c_number_comp}/;
	$line =~ s/--comp_ward_c_number--/$attributes_heatmap{Ward_c_number_comp}/;
	$line =~ s/--comp_average_r_number--/$attributes_heatmap{Average_r_number_comp}/;
	$line =~ s/--comp_complete_r_number--/$attributes_heatmap{Complete_r_number_comp}/;
	$line =~ s/--comp_single_r_number--/$attributes_heatmap{Single_r_number_comp}/;
	$line =~ s/--comp_ward_r_number--/$attributes_heatmap{Ward_r_number_comp}/;
	$line =~ s/--coverage_json_file--/$attributes_heatmap{Coverage_JSON}/;
	$line =~ s/--heatmap_width--/$attributes_heatmap{Heatmap_width}/;
	$line =~ s/--color_scale--/$attributes_heatmap{Color_scale}/;
	
	$attributes_heatmap{Coverage_pics} =~ s/--return--/\n\n/g;
	$attributes_heatmap{Coverage_pics_buttons} =~ s/--return--/<br>\n\n/g;
	$attributes_heatmap{Hide_show_coverage_pics} =~ s/--return--/\n\n/g;
	$attributes_heatmap{Diagrams} =~ s/--return--/\n\n/g;

	$line =~ s/--insert_diagrams--/$attributes_heatmap{Coverage_pics}/g;
	$line =~ s/--insert_diagram_buttons--/$attributes_heatmap{Coverage_pics_buttons}/g;
	$line =~ s/--hide_show_diagrams--/$attributes_heatmap{Hide_show_coverage_pics}/g;
	$line =~ s/--venn_diagrams--/$attributes_heatmap{Diagrams}/;

	print TEMP $line."\n";
    }

    ## Rename the temporary file
    &RSAT::message::TimeWarn("Exporting Dynamic Heatmap") if ($main::verbose >= 2);
    #unlink($main::outfile{heatmap_coverage_attributes});
    $cmd = "mv ".$main::outfile{temp_html}." ".$main::outfile{dynamic_coverage_heatmap_html};
    &doit($cmd, 0, 1, $verbose, 0, "", $main::out, $main::err);
}

################################################################
## Create the attributes (values+ colors + size) that will be 
## inserted in the D3 Heatmap
sub Create_Attributes_for_Heatmap_D3 {   

    &RSAT::message::TimeWarn("Preparing Dynamic Heatmap") if ($main::verbose >= 2);

    ##################################
    ### Identify the path of the R executable
    my $r_path = &RSAT::server::GetProgramPath("R");

    my $cluster_collection_script  = $ENV{RSAT}."/R-scripts/heatmap_clusters_by_collection.r";
    &RSAT::error::FatalError("Cannot read cluster collection script", $cluster_collection_script) unless (-r $cluster_collection_script);
    $r_verbosity = &RSAT::stats::max(($main::verbose-1), 0);
    
    ## Basic parameters
    my $cluster_collection_cmd = "";
    $cluster_collection_cmd .= " cat ".$cluster_collection_script;
    $cluster_collection_cmd .= " | ".$r_path;
    $cluster_collection_cmd .= " --slave --no-save --no-restore --no-environ";
    $cluster_collection_cmd .= " --args \"";
    $cluster_collection_cmd .= " cluster.counts.file = '".$main::outfile{cluster_summary_table}."'";
    $cluster_collection_cmd .= "; heatmap.table.d3 = '".$main::outfile{heatmap_collections_d3}."'";
    $cluster_collection_cmd .= "; attributes.list.file = '".$main::outfile{heatmap_collections_attributes}."'";
    $cluster_collection_cmd .= "; percent.table.file = '".$main::outfile{percent_table}."'";
    $cluster_collection_cmd .= "; coverage.table.file = '".$main::outfile{coverage_table}."'";
    $cluster_collection_cmd .= "; motif.richness.table = '".$main::outfile{motif_richness_tsv}."'";
    $cluster_collection_cmd .= "; coverage.table.d3 = '".$main::outfile{heatmap_coverage_d3}."'";
    $cluster_collection_cmd .= "; coverage.heatmap.attributes.file = '".$main::outfile{heatmap_coverage_attributes}."'";
    $cluster_collection_cmd .= "; coverage.json.folder = '".$main::outfile{coverage_json_folder}."'";
    $cluster_collection_cmd .= "; heatmap.color.palette = '".$heatmap_color_palette."'";
    $cluster_collection_cmd .= "; heatmap.color.classes = '".$heatmap_color_classes."'";
    $cluster_collection_cmd .= "; root.motifs.table = '".$main::outfile{root_motifs_table}."'";
    $cluster_collection_cmd .= "; \"";
#    $cluster_collection_cmd = "(".$cluster_collection_cmd.") 2> ".$main::outfile{Rlog};

    if ($r_path) {
        &doit($cluster_collection_cmd, 0, 1, $verbose, 0, "", $main::out, $main::err);
    } else {
        &RSAT::message::Warning("Could not run collection clustering because the program R is not available") if ($main::verbose >= 1);
    }
    return();
}


#######################################################################
## Read the alignment table and saves the data in a hash table
## Cluster_ID -> Motif_ID -> [name strand offset consensus logo_path]
sub ReadAlignmentTable {
    my @split_line = ();
    
    ## First read the alignment table and save the results in a hash
    my ($line, $id, $cluster_id);
    my ($cluster_handle) = &RSAT::util::OpenInputFile($outfile{alignment_table});
    
    while (<$cluster_handle>) {
	next if (/^#/); ## Skip header line
	next if (/^;/); ## Skip comment lines
	next unless (/\S/); ## Skip empty lines
	chomp;
	$line = $_;
	@split_line = split("\t", $line);
	$id = $split_line[0];
	$cluster_id = $split_line[2];
	$alignment_table_data{$cluster_id}{$id}{name} = $split_line[1];
	$alignment_table_data{$cluster_id}{$id}{collection} = $motifs_ID_unique{$id};	
	$alignment_table_data{$cluster_id}{$id}{strand} = $split_line[3];
	$alignment_table_data{$cluster_id}{$id}{offset_up} = $split_line[4];
	$alignment_table_data{$cluster_id}{$id}{offset_down} = $split_line[5];
	$alignment_table_data{$cluster_id}{$id}{width} = $split_line[6];
	$alignment_table_data{$cluster_id}{$id}{consensus} = $split_line[7];
	$alignment_table_data{$cluster_id}{$id}{consensus_rc} = $split_line[8];

	my $link_logo_d = $main::outfile{prefix}."_aligned_logos/".$id."_logo.png";
	my $link_logo_r = $main::outfile{prefix}."_aligned_logos/".$id."_logo_rc.png";
	$alignment_table_data{$cluster_id}{$id}{logo} = &RSAT::util::RelativePath($main::outfile{summary}, $link_logo_d);
	$alignment_table_data{$cluster_id}{$id}{logo_rc} = &RSAT::util::RelativePath($main::outfile{summary}, $link_logo_r);

	## Calculate the max nb of characters and the width of the alignment 
	## This numbers will be used to set the logos properly in the logo trees
	if (length($split_line[1]) >= $nb_char) {
	    $nb_char = length($split_line[1]);
	    $alignment_size{$cluster_id}{nb_char} = $nb_char;
	}
	if ($display_collection_name_flag == 1) {
	    if ($longest_title >= $nb_char) {
		$nb_char = $longest_title;
	    }
	}

	$alignment_size{$cluster_id}{width} = $split_line[6];

	$number_of_motifs++;

	$ids_to_cluster{$id} = $cluster_id;
    }
    close $cluster_handle;

}


##############################################
## Insert the Alignment table in the summary 
## HTML file
sub InsertAlignmentTable{

    ## Alignment table skeleton (it is filled in the next lines)
    my $tab = '

  <!-- Div with the aligment table with all the motifs-->
<div id="Motif_Tab_button" class="button_click Section_button"><strong>Individual Motif View</strong></div>	
<div id="Motif_Tab" class="tab" style="padding:7px 7px 0px 7px; margin:0px 0px 20px 0px;width:autopx;display:none">	
          <h2 style="margin:0px 0px 10px 0px;">Individual Motif View</h2>
	  <table id="alignment_dyn_table" class="hover compact">
	    <thead>
	      <tr style="padding:70px">
		<th class="tab_col">Motif id</th>
		<th class="tab_col">Motif name</th>
		<th class="tab_col">Cluster</th>
		<th class="tab_col">Collection</th>
		<th class="tab_col">Consensus</th>
		<th class="tab_col">Consensus (Rev)</th>
		<th class="tab_col">Logo</th>
		<th class="tab_col">Logo (Rev)</th>
	      </tr>
	    </thead>
	    <tbody>
	      --insert_col_here--
	    </tbody>
	  </table>
	  <ul style="text-align:left;margin:0px 0px 5px 0px;">
	     <li type="square">Click on the column names to change the order of the data.</li>
	     <li type="square">Write the name of one cluster, collection or a pattern in the <i>Search</i> window.</li>
	  </ul>          
	</div>
';

    $alignment_table_columns = "";
    my $logo_width = 0;
    ## Fill the column's table 
    foreach my $id (keys %ids_to_cluster) {

	if (length($alignment_table_data{$ids_to_cluster{$id}}{$id}{consensus}) > $motif_width_by_cluster_width){
	    $motif_width_by_cluster_width = length($alignment_table_data{$ids_to_cluster{$id}}{$id}{consensus});
	}

	$logo_width = 10*$alignment_table_data{$ids_to_cluster{$id}}{$id}{width};

	$alignment_table_columns .= '
				<tr>					
					<td class="tab_spacer_1">'.$id.'</td>
                                        <td class="tab_spacer_1">'.$alignment_table_data{$ids_to_cluster{$id}}{$id}{name}.'</td>
					<td class="tab_spacer_1">'.$ids_to_cluster{$id}.'</td>
                                        <td class="tab_spacer_1">'.$alignment_table_data{$ids_to_cluster{$id}}{$id}{collection}.'</td>
					<td class="seq tab_spacer_1">'.&RSAT::SeqUtil::ColorConsensus($alignment_table_data{$ids_to_cluster{$id}}{$id}{consensus}, bold=>1, iupac=>$main::param{iupac_coloring}).'</td>
					<td class="seq tab_spacer_1">'.&RSAT::SeqUtil::ColorConsensus($alignment_table_data{$ids_to_cluster{$id}}{$id}{consensus_rc}, bold=>1, iupac=>$main::param{iupac_coloring}).'</td>
                                        <th class="tab_spacer_2"><a target="_blank" href="'.$alignment_table_data{$ids_to_cluster{$id}}{$id}{logo}.'"><img class="logo_tab" width="--width--" src="'.$alignment_table_data{$ids_to_cluster{$id}}{$id}{logo}.'" /></a></th>
                                        <th class="tab_spacer_2"><a target="_blank" href="'.$alignment_table_data{$ids_to_cluster{$id}}{$id}{logo_rc}.'"><img class="logo_tab" width="--width--" src="'.$alignment_table_data{$ids_to_cluster{$id}}{$id}{logo_rc}.'" /></a></th>
				</tr>
        ';	
    }
    $tab =~ s/--width--/$logo_width/gi;
    $tab =~ s/--insert_col_here--/$alignment_table_columns/;

    ## Print the HTML to the summary file
    print $syn $tab;
}


########################################
## Insert the logo tree in small size
## this div is a link pointing to the 
## logo forest d3 file
sub InsertSmallForest {

    my $label_single_tree_no_link = '
	node.append("text")
	        .text(function(d) { return d.children ? "" :  d.name; })
		.attr("dx", function(d) { return d.children ? 0 : 20; })
		.attr("dy", function(d) { return d.children ? 0 : 3; })
		.attr("font-size", "10px")
		.attr("text-anchor", function(d) { return d.children ? "end" : "start"; });
    ';

    ## D3 values of the parameters of the small trees
    my $svg_width = 8;
    my $svg_height = 16;
    my $svg_x1 = 7 * $nb_char;
    my $svg_y1 = -7;
    my $svg_x2 = '6 + '.$svg_x1.' + 27';
    
    my $div = "";
    ## Open the <div> and the <a> where the small forest will be set
    my $small_forest = '
    <div id="Logo_Forest_button" class="button_click Section_button"><strong>Logo Forest</strong></div>
<div id="show_forest" style="margin:0px 0px 15px 0px;display:none;">'."\n";  
    my $small_tree = '' ;
    my $sum_motifs = 0;
    my $sum = 0;
    my $cluster_sum = 0;
    my $BG_color = ".style(\"background\", \"#E6E6E6\")";

    ## Insert link to the logo forest
    $small_forest .= '

    <div class="display_clusters"><h2>'.$number_of_clusters.' Clusters found</h2>
       <p style="color:red">Sketch picture restricted to the --x-- first clusters.<a target="_blank" href="'.&RSAT::util::RelativePath($main::outfile{summary}, $main::outfile{small_logo_cladogram_html}).'"> Click here to display all the clusters dynamically</a><br><br></p>
    </div>
    ';

    foreach my $num (1..scalar(keys %alignment_table_data)) {
	#foreach my $num (1..2) {

	$cl_id_s = $cluster_id_hash{$num}."_s";
	$cl_id = $cluster_id_hash{$num};
	
	my $cluster_size = scalar(keys %{$alignment_table_data{$cl_id}});
	my $sum = $sum_motifs + $cluster_size;
	if ($sum < 20) {
	    
	    ## Draw the logo forest 
	    $div .= '<div id="'.$cl_id_s.'" style="background-color:#E6E6E6;width:800px;padding:0px 0px 0px 200px;"></div>';
	    
	    my $tree = &logo_tree();
	    $tree =~ s/--RC_picture_start--//g;
	    $tree =~ s/--RC_picture_end--//g;
	    $tree =~ s/\/\/BG_color/$BG_color/g;
	    $tree =~ s/--lab--/$label_single_tree_no_link/;
	    $tree =~ s/--widthtree--/820/g;
	    $tree =~ s/--radius--/3/g;
	    $tree =~ s/--size--/350/g;
	    $tree =~ s/--insert--//g;
	    $tree =~ s/--nb--/$num/g;
	    $tree =~ s/--height--/70 + 9 * $cluster_size/g;
	    $tree =~ s/--cl_id--/$cl_id_s/g;
	    $tree =~ s/--stroke--/$hexa_code{$cl_id}/g;
	    my $json_name = &RSAT::util::RelativePath($main::outfile{summary}, $main::outfile{prefix}."_trees/parsed_tree_".$cluster_id_hash{$num}.".json");
	    $tree =~ s/--jsonfile--/$json_name/g;
	    $tree =~ s/--svgwidth--/$svg_width/g;
	    $tree =~ s/--svgheight--/$svg_height/g;
	    $tree =~ s/--x1--/$svg_x1/g;
	    $tree =~ s/--y1--/$svg_y1/g;
	    $tree =~ s/--x2--/$svg_x2/g;
	    
	    $small_tree .= $tree."\n";
	    
	    $cluster_sum++;
	    $sum_motifs += $cluster_size;
	}
	
	if ($cluster_sum == 3) {
	    last; 
	}
    }
    $small_forest =~ s/--x--/$cluster_sum/;


    ## Insert one <div> </div> + <script> </script> for each cluster depicted  
    $small_forest .= $div."\n".'<script type="text/javascript">'."\n".$small_tree."\n".'</script>'."\n";

    ## Close the <a> and <div>
    $small_forest .= '</a></div>';

    print $syn $small_forest;
}


########################################
## Insert the logo tree in small size
## this div is a link pointing to the 
## logo forest d3 file
sub CreateRadialTree {

    my $label_single_tree_no_link = '
	node.append("text")
	        .text(function(d) { return d.children ? "" :  d.name; })
		.attr("dx", function(d) { return d.children ? 0 : 20; })
		.attr("dy", function(d) { return d.children ? 0 : 3; })
		.attr("font-size", "10px")
		.attr("text-anchor", function(d) { return d.children ? "end" : "start"; });
    ';

    ## D3 values of the parameters of the small trees
    my $svg_width = 8;
    my $svg_height = 16;
    my $svg_x1 = 7 * $nb_char;
    my $svg_y1 = -7;
    my $svg_x2 = '6 + '.$svg_x1.' + 27';
    
    my $div = "";
    ## Open the <div> and the <a> where the small forest will be set
    my $small_forest = '
    <div id="Logo_Forest_button" class="button_click Section_button"><strong>Logo Forest</strong></div>
<div id="show_forest" style="margin:0px 0px 15px 0px;display:none;">'."\n";  
    my $small_tree = '' ;
    my $sum_motifs = 0;
    my $sum = 0;
    my $cluster_sum = 0;
    my $BG_color = ".style(\"background\", \"#E6E6E6\")";

    ## Insert link to the logo forest
    $small_forest .= '

    <div class="display_clusters"><h2>'.$number_of_clusters.' Clusters found</h2>
       <p style="color:red">Sketch picture restricted to the --x-- first clusters.<a target="_blank" href="'.&RSAT::util::RelativePath($main::outfile{summary}, $main::outfile{small_logo_cladogram_html}).'"> Click here to display all the clusters dynamically</a><br><br></p>
    </div>
    ';

    foreach my $num (1..scalar(keys %alignment_table_data)) {
	#foreach my $num (1..2) {

	$cl_id_s = $cluster_id_hash{$num}."_s";
	$cl_id = $cluster_id_hash{$num};
	
	my $cluster_size = scalar(keys %{$alignment_table_data{$cl_id}});
	my $sum = $sum_motifs + $cluster_size;
	if ($sum < 20) {
	    
	    ## Draw the logo forest 
	    $div .= '<div id="'.$cl_id_s.'" style="background-color:#E6E6E6;width:800px;padding:0px 0px 0px 200px;"></div>';
	    
	    my $tree = &logo_tree();
	    $tree =~ s/--RC_picture_start--//g;
	    $tree =~ s/--RC_picture_end--//g;
	    $tree =~ s/\/\/BG_color/$BG_color/g;
	    $tree =~ s/--lab--/$label_single_tree_no_link/;
	    $tree =~ s/--widthtree--/820/g;
	    $tree =~ s/--radius--/3/g;
	    $tree =~ s/--size--/350/g;
	    $tree =~ s/--insert--//g;
	    $tree =~ s/--nb--/$num/g;
	    $tree =~ s/--height--/70 + 9 * $cluster_size/g;
	    $tree =~ s/--cl_id--/$cl_id_s/g;
	    $tree =~ s/--stroke--/$hexa_code{$cl_id}/g;
	    my $json_name = &RSAT::util::RelativePath($main::outfile{summary}, $main::outfile{prefix}."_trees/parsed_tree_".$cluster_id_hash{$num}.".json");
	    $tree =~ s/--jsonfile--/$json_name/g;
	    $tree =~ s/--svgwidth--/$svg_width/g;
	    $tree =~ s/--svgheight--/$svg_height/g;
	    $tree =~ s/--x1--/$svg_x1/g;
	    $tree =~ s/--y1--/$svg_y1/g;
	    $tree =~ s/--x2--/$svg_x2/g;
	    
	    $small_tree .= $tree."\n";
	    
	    $cluster_sum++;
	    $sum_motifs += $cluster_size;
	}
	
	if ($cluster_sum == 3) {
	    last; 
	}
    }
    $small_forest =~ s/--x--/$cluster_sum/;


    ## Insert one <div> </div> + <script> </script> for each cluster depicted  
    $small_forest .= $div."\n".'<script type="text/javascript">'."\n".$small_tree."\n".'</script>'."\n";

    ## Close the <a> and <div>
    $small_forest .= '</a></div>';

    print $syn $small_forest;
}


############################
## Insert Heatmap picture
sub InsertHeatMap {

    my $heat_map = ' 
        <div id="Heatmap_button" class="button_click Section_button"><strong>Heatmap View</strong></div>
	<div id="Heatmap_view" class="tab" style="width:1025px;padding:0px 0px 20px 0px;margin-top:0px;display:none;">
		<h2 style="margin:0px">Heatmap View</h2>
                <p><a target="_blank" href="'.&RSAT::util::RelativePath($main::outfile{summary}, $main::outfile{distance_table}).'">Distance table</a>  |  <a target="_blank" href="'.&RSAT::util::RelativePath($main::outfile{summary}, $main::outfile{heatmap_pdf}).'">PDF</a></p>
		<a target="_blank" href="'.&RSAT::util::RelativePath($main::outfile{summary}, $main::outfile{heatmap_pdf}).'"><img id="heatmap" src="'.&RSAT::util::RelativePath($main::outfile{summary}, $main::outfile{heatmap_jpg}).'"></a>
	</div>
    ';

    print $syn $heat_map;
}


############################
## Insert Heatmap of collections per clusters
sub InsertHeatmapCollectionbyCluster {

    my $heat_map_motifs_by_cluster = ' 
        <div id="Heatmap_motifs_button" class="button_click Section_button"><a target="_blank" href="'.&RSAT::util::RelativePath($main::outfile{summary}, $main::outfile{dynamic_heatmap_html}).'"><strong>Cluster composition by collection</strong></a></div>
    ';

    print $syn $heat_map_motifs_by_cluster;
}


############################
## Insert Heatmap of collections per clusters
sub InsertHeatmapCollectionComplementarity {

    my $heatmap_complementarity = ' 
        <div id="Heatmap_complementarity_button" class="button_click Section_button"><a target="_blank" href="'.&RSAT::util::RelativePath($main::outfile{summary}, $main::outfile{dynamic_coverage_heatmap_html}).'"><strong>Collections Overlap</strong></a></div>
    ';

    print $syn $heatmap_complementarity;
}


############################
## Insert Heatmap of collections per clusters
sub InsertMotifRichnessBarPlot {

    my $motif_richness_section = ' 
        <div id="Motif_richness_button" class="button_click Section_button"><a target="_blank" href="'.&RSAT::util::RelativePath($main::outfile{summary}, $main::outfile{motif_richness_barplot_html}).'"><strong>Motif diversity per collection</strong></a></div>
    ';

    print $syn $motif_richness_section;
}


#########################################
## Open the <scrip> tag for JQuery code
sub OpenScriptJQuery {
  $script_jquery = '<script>

// Dynamic parameter table
$(document).ready( function () {
    $(\'#parameters_table\').DataTable({
        "paging":   false,
        "searching": false,
        "ordering": false,
        "info":     false,
        "columnDefs": [
	    { "width": "5%", "targets": [0,1,2,3,4,5,6] }
	]		
    });
});

// Dynamic cluster summary table
$(document).ready( function () {
    $(\'#cluster_summary_table\').DataTable({
        "info":     true,
        "iDisplayLength": 50,
        "order": [[ 1, "asc" ]],
	"search": {
	    "regex": true,
	    "smart": true
	},
	"aoColumnDefs": [
            { "bSortable": true, "aTargets": [ 0,1,2,3,4,5,6 ] }
	]	
    });
});

// Dynamic alignment table
$(document).ready( function () {
    $(\'#alignment_dyn_table\').DataTable({
        "info":     false,
        "iDisplayLength": 10,
        "order": [[ 2, "asc" ]],
	"search": {
	    "regex": true,
	    "smart": true
	},
	"aoColumnDefs": [
            { "bSortable": true, "aTargets": [ 6,7 ] }
	],
        "columnDefs": [ {
            "targets": -1,
            "data": null,
            "width": "3%", "targets": [0,1,2,3,4,5,6,7]

        } ]	
    });
});

// Show all results button
$(document).ready(function() {
    $(\'#show_all_button\').click(function() {

       $(\'.branch_motifs\').show();
       $(\'.cons_tab\').show();
        $(\'.hide_show\').show();
        $(\'.cluster_division\').addClass(\'selected_cluster\');
    }); 
});

// Hide all results button
$(document).ready(function() {
    $(\'#hide_all_button\').click(function() {
        $(\'.hide_show\').hide();
        $(\'.cluster_division\').removeClass(\'selected_cluster\');
    }); 
});

// Change the color of buttons
$(document).ready(function() {
    
    ///////////////////
    // Hide/Show All
    $(\'#show_all_button\').mouseenter(function() {
        $(this).fadeTo(\'fast\', 0.6); 
    });

    $(\'#show_all_button\').mouseleave(function() {
        $(this).fadeTo(\'fast\',1); 
    });

    $(\'#hide_all_button\').mouseenter(function() {
        $(this).fadeTo(\'fast\', 0.6); 
    });

    $(\'#hide_all_button\').mouseleave(function() {
        $(this).fadeTo(\'fast\',1); 
    });

    /////////////////////
    // Cluster buttons
    $(\'.cluster_division\').mouseenter(function() {
        $(this).fadeTo(\'fast\', 0.6); 
    });

    $(\'.cluster_division\').mouseleave(function() {
        $(this).fadeTo(\'fast\',1); 
    });

    /////////////////////////////
    // Additional files button
    $(\'#List_File_Button\').mouseenter(function() {
        $(this).fadeTo(\'fast\', 0.6); 
    });

    $(\'#List_File_Button\').mouseleave(function() {
        $(this).fadeTo(\'fast\',1); 
    });

});


// Slide the Parameters Table
$(document).ready(function() {
    $(\'#Par_tab_button\').click(function() {
	$(\'#Par_tab\').slideToggle(\'fast\');
        $(this).toggleClass(\'selected_header_section\');
    }); 
});

// Slide the Parameters Table
$(document).ready(function() {
    $(\'#Clus_tab_button\').click(function() {
	$(\'#Clus_tab\').slideToggle(\'fast\');
        $(this).toggleClass(\'selected_header_section\');
    }); 
});

// Slide the Logo Forest Link
$(document).ready(function() {
    $(\'#Logo_Forest_button\').click(function() {
	$(\'#show_forest\').slideToggle(\'fast\');
        $(this).toggleClass(\'selected_header_section\');
    }); 
});

// Slide the Individual Motif View
$(document).ready(function() {
    $(\'#Motif_Tab_button\').click(function() {
	$(\'#Motif_Tab\').slideToggle(\'fast\');
        $(this).toggleClass(\'selected_header_section\');
    }); 
});

// Slide the Individual Cluster View
$(document).ready(function() {
    $(\'#Cluster_Tab_button\').click(function() {
	$(\'#Cluster_Tab\').slideToggle(\'fast\');
        $(this).toggleClass(\'selected_header_section\');
    }); 
});

// Slide the Heatmap View
$(document).ready(function() {
    $(\'#Heatmap_button\').click(function() {
	$(\'#Heatmap_view\').slideToggle(\'fast\');
        $(this).toggleClass(\'selected_header_section\');
    }); 
});

// Slide the Heatmap View
//$(document).ready(function() {
//    $(\'#Motif_richness_button\').click(function() {
//	$(\'#Motif_richness\').slideToggle(\'fast\');
//        $(this).toggleClass(\'selected_header_section\');
//    }); 
//});

// Slide the Motif per clusters View
//$(document).ready(function() {
//    $(\'#Heatmap_motifs_button\').click(function() {
//	$(\'#Heatmap_motifs\').slideToggle(\'fast\');
//        $(this).toggleClass(\'selected_header_section\');
//    }); 
//});

// Slide the Collections Complementarity View
//$(document).ready(function() {
//    $(\'#Heatmap_complementarity_button\').click(function() {
//	$(\'#Heatmap_complementarity\').slideToggle(\'fast\');
//        $(this).toggleClass(\'selected_header_section\');
//    }); 
//});

// Slide the File list
$(document).ready(function() {
    $(\'#List_Files_Button\').click(function() {
	$(\'#File_list\').slideToggle(\'fast\');
        $(this).toggleClass(\'selected_header_section\');
    }); 
});

// Slide the References
$(document).ready(function() {
    $(\'#References_Button\').click(function() {
	$(\'#end_report\').slideToggle(\'fast\');
        $(this).toggleClass(\'selected_header_section\');
    }); 
});
';
}


##########################
## Display single trees
sub InsertTreesAndBranchMotifs {

    my $trees_and_tables = "";
    my  $svg_width = 8.5;
    my  $svg_height = 35;
    my  $svg_x1 = 6.5 * $nb_char + 6.5;
    my  $svg_y1 = -15;
    my  $svg_x2 = '7.5 + '.$svg_x1.' + 42';

    my $test_width = 485 + ($motif_width_by_cluster_width * 26); 

    my $label_single_tree = '
	node.append("a")
	        .attr("xlink:href", function(d) { return d.link_ext; })
	        .append("text")
	        .text(function(d) { return d.children ? "" :  d.name; })
		.attr("dx", function(d) { return d.children ? 0 : 20; })
		.attr("dy", function(d) { return d.children ? 0 : 3; })
		.attr("font-size", "10px")
	        .style("fill", "blue")
		.attr("text-anchor", function(d) { return d.children ? "end" : "start"; });

		node.append("text")
		.text(function(d) { return d.children ? d.branch : ""; })
		.attr("dx", function(d) { return d.children ? -2 : 0; })
		.attr("dy", function(d) { return d.children ? -6 : 0; })
		.attr("fill", function(d) { return d.children ? "blue" : ""; })
		.attr("font-size", "8px")
		.attr("text-anchor", function(d) { return d.children ? "end" : "start"; });
    ';

    if ($display_collection_name_flag == 1) {
	$label_single_tree .= '
        node.append("text")
	.text(function(d) { return d.children ? "" : d.title; })
	.attr("x", function(d) { return d.children ? 0 : 20; })
	.attr("dy", function(d) { return d.children ? 0 : 15; })
	.attr("font-size", "8px")
        .attr("fill", "blue")
	.attr("text-anchor", function(d) { return d.children ? "end" : "start"; })
        ';
    }

    ## The next procces is repeated for each cluster
    foreach my $num (1..scalar(keys %alignment_table_data)) {
	
	## Insert the header of the cluster
	my $head_insert .= &cluster_delim();
	my $cl_id = $cluster_id_hash{$num};
	$head_insert =~ s/--Cluster_id--/$cl_id/g;
	$head_insert =~ s/--Cluster_id_head--/head_$cl_id/g;
	$head_insert =~ s/--nb--/$cluster_id_hash{$num}/g;
	my $insert_div = "\n".$head_insert."\n";

	## Insert Id + Pointer
	my $insert_id = '
                .attr("cursor", function(d) { return d.children ? "pointer" : ""; })
                .attr("id", function(d) { return d.children ? d.id : ""; })
        ';
	
	## Make dynamics the buttons of the cluster header
	my %current_alignment_table_data =  %{$alignment_table_data{$cl_id}};
	my $buttons = &cluster_head_buttons(scalar(keys %current_alignment_table_data));
	my $motifs_nb = scalar(keys %current_alignment_table_data);
	$buttons =~ s/--Cluster_id--/$cl_id/g;
	$buttons =~ s/--Cluster_id_head--/head_$cl_id/g;
	$buttons =~ s/--nb--/$cluster_id_hash{$num}/g;
	$script_jquery .= $buttons."\n";

	## Draw the logo tree
	my $d3_logo_tree .= '       
	              <!--Div containing D3 logo tree-->
                      <div id="hide_tree_--nb--" class="Cluster_results buttons_click hide_show" ><strong>--nb--</strong></div>
                      <div id="--nb--" class="logo_tree hide_show">
		      <script type="text/javascript">
                ';

	$d3_logo_tree .= &logo_tree();

	$d3_logo_tree =~ s/\/\*--RC_picture_start--//g;
	$d3_logo_tree =~ s/\*\/--RC_picture_end--//g;
	$d3_logo_tree =~ s/--lab--/$label_single_tree/;
	$d3_logo_tree =~ s/--cl_id--/$cl_id/;
#	$d3_logo_tree =~ s/--widthtree--/1200/g;
	$d3_logo_tree =~ s/--widthtree--/$test_width/g;
	$d3_logo_tree =~ s/--nb--/$cluster_id_hash{$num}/g;
	$d3_logo_tree =~ s/--insert--/$insert_id/g;
	$d3_logo_tree =~ s/--size--/375/g;
	$d3_logo_tree =~ s/--radius--/4/g;
	$d3_logo_tree =~ s/--height--/100 + 30 * $motifs_nb/g;
	$d3_logo_tree =~ s/--stroke--/$hexa_code{$cl_id}/g;
	my $jname = &RSAT::util::RelativePath($main::outfile{summary}, $main::outfile{prefix}."_trees/parsed_tree_".$cluster_id_hash{$num}.".json");
	$d3_logo_tree =~ s/--jsonfile--/$jname/g;
	$d3_logo_tree =~ s/--svgwidth--/$svg_width/g;
	$d3_logo_tree =~ s/--svgheight--/$svg_height/g;
	$d3_logo_tree =~ s/--x1--/$svg_x1/g;
	$d3_logo_tree =~ s/--y1--/$svg_y1/g;
	$d3_logo_tree =~ s/--x2--/$svg_x2/g;
	$d3_logo_tree .= '
                         </script>
	                 </div>
                 ';
        $all_d3_trees .= "\n".$d3_logo_tree."\n";

	my $hide_single_tree = &hide_tree();
	$hide_single_tree =~ s/--nb--/$cluster_id_hash{$num}/g;

	my $hide_single_branch_table = &hide_branch_motifs();
	$hide_single_branch_table =~ s/--nb--/$cluster_id_hash{$num}/g;

	$script_jquery .= $hide_single_tree."\n\n";
	$script_jquery .= $hide_single_branch_table."\n\n";
	
	## Draw the branch-consensus table
	if (scalar(keys %current_alignment_table_data) > 1) {

	    $consensus_table = "";
	    $consensus_table = &branch_consensus_table();
	    my $consensus_table_columns = "";
	    foreach my $level (1..scalar(keys %current_alignment_table_data)-1) {
		
		my ($cons, $logo_D, $logo_R, $transfac_file, $transfac_file_2);

		$logo_D = &RSAT::util::RelativePath($main::outfile{summary}, $merged_consensuses_files{"node_".$level}{$cluster_id_hash{$num}}{logo});
		$logo_R = &RSAT::util::RelativePath($main::outfile{summary}, $merged_consensuses_files{"node_".$level}{$cluster_id_hash{$num}}{logo_RC});
		$transfac_file = &RSAT::util::RelativePath($main::outfile{summary}, $merged_consensuses_files{"node_".$level}{$cluster_id_hash{$num}}{tf_file});
		## Get the consensus
		$transfac_file_2 = $main::outfile{prefix}."_clusters_information/".$cluster_id_hash{$num}."/merged_consensuses/node_".$level."/".$cluster_id_hash{$num}."_node_".$level."_matrices.tf";
		$cons = `more $transfac_file_2 | grep DE`;
		$cons =~ s/DE\s+//gi;

		## Get the IC for the branch-motif
		my @branch_motifs = &RSAT::MatrixReader::readFromFile($transfac_file_2, "tf");
		my $rounded_ic = 0;
		my $calc_sites = "";
	        my $sites = "";
		foreach my $matrix (@branch_motifs) {
		    		    
		    ## Calculates the IC of the matrix
		    $matrix->calcInformation();
		    $matrix->toString(col_width=>(1+4),
				      decimals=>1,
				      type=>"information",
				      format=>"tf");
                    my $ic = $matrix->get_attribute("total.information");
                    $rounded_ic = sprintf("%.2f", $ic);

	            $calc_sites = $matrix->calcNbSites();
                    $sites = $matrix->getNbSites();
                }		
		
		$consensus_table_columns .= "\n".'<tr id="'.$cluster_id_hash{$num}.'_node_'.$level.'" class="branch_motifs">'."\n";
		$consensus_table_columns .= '   <th class="tab_spacer_2">Node '.$level.'</th>'."\n";
		$consensus_table_columns .= '   <th class="seq tab_spacer_1">'.&RSAT::SeqUtil::ColorConsensus($cons, bold=>1, iupac=>$main::param{iupac_coloring}).'</th>'."\n";
		$consensus_table_columns .= '   <th class="tab_spacer_2"><a target="_blank" href="'.$logo_D.'"><img class="logo" src="'.$logo_D.'" /></a></th>'."\n";
		$consensus_table_columns .= '   <th class="tab_spacer_2"><a target="_blank" href="'.$logo_R.'"><img class="logo" src="'.$logo_R.'" /></a></th>'."\n";
		$consensus_table_columns .= '   <th class="tab_spacer_2" style="text-align:left;font-weight:normal;">'.$merged_consensuses_files{"node_".$level}{$cluster_id_hash{$num}}{collection_counts}.'</th>'."\n";
		$consensus_table_columns .= '   <th class="tab_spacer_2"><a target="_blank" href="'.$transfac_file.'">PSSM</a></th>'."\n";
		$consensus_table_columns .= '   <th class="tab_spacer_2">'.$rounded_ic.'</th>'."\n";
		$consensus_table_columns .= '   <th class="tab_spacer_2">'.$sites.'</th>'."\n";
		$consensus_table_columns .= "</tr>\n";

		## Add the code to hide/show the branch-consensus table
		my $selection_branch = &Display_Selected_Branch();
		my $branch_tab_id = $cluster_id_hash{$num}."_node_".$level;
		my $branch_row_id = $cluster_id_hash{$num}."_node_".$level;
		$selection_branch =~ s/--branch_tab_id--/$branch_tab_id/g;
		$selection_branch =~ s/--branch_row_id--/$branch_row_id/g;
		$selection_branch =~ s/--nb--/$cluster_id_hash{$num}/g;
		$script_jquery .= $selection_branch."\n";

	    }
	    $consensus_table =~ s/--nb--/$cluster_id_hash{$num}/g;
	    $consensus_table =~ s/--here--/$consensus_table_columns/g;
	    $all_consensus_table .= "\n".$consensus_table."\n";
	    
	    ## Add the code to hide/show the branch-consensus table
	    my $cons_tab = &toogle_branch_consensus_table();
	    $cons_tab =~ s/--nb--/$cluster_id_hash{$num}/g;
	    $script_jquery .= $cons_tab."\n";

	## Insert the matrices for singleton clusters here
	} else {
	    
	    $level = 1;
	    $consensus_table = "";
	    $consensus_table = &branch_consensus_table();
	    my $consensus_table_columns = "";
	    
	    ## Get the attributes for the consensus table
	    my ($cons, $logo_D, $logo_R, $transfac_file);
	    $logo_D = &RSAT::util::RelativePath($main::outfile{summary}, $main::outfile{prefix}."_aligned_logos/".$cluster_id_hash{$num}."_logo.png");
	    $logo_R = &RSAT::util::RelativePath($main::outfile{summary}, $main::outfile{prefix}."_aligned_logos/".$cluster_id_hash{$num}."_logo_rc.png");
	    $transfac_file = &RSAT::util::RelativePath($main::outfile{summary}, $main::outfile{prefix}."_clusters_information/".$cluster_id_hash{$num}."/".$cluster_id_hash{$num}."_matrices.tf");
	    $transfac_file_2 = $main::outfile{prefix}."_clusters_information/".$cluster_id_hash{$num}."/".$cluster_id_hash{$num}."_matrices.tf";
	    $cons = `more $transfac_file_2 | grep DE`;
	    $cons =~ s/DE\s+//gi;

           ## Get the IC for the branch-motif
	   @branch_motifs = &RSAT::MatrixReader::readFromFile($transfac_file_2, "tf");
	   $rounded_ic = 0;
	   $calc_sites = "";
	   $sites = "";
	   foreach my $matrix (@branch_motifs) {
	    		    
	     ## Calculates the IC of the matrix
	     $matrix->calcInformation();
	     $matrix->toString(col_width=>(1+4),
			      decimals=>1,
			      type=>"information",
			      format=>"tf");
             my $ic = $matrix->get_attribute("total.information");
             $rounded_ic = sprintf("%.2f", $ic);
	     $calc_sites = $matrix->calcNbSites();
             $sites = $matrix->getNbSites();
            }

	    ## Fill the table
	    $consensus_table_columns .= "\n".'<tr id="'.$cluster_id_hash{$num}.'" class="branch_motifs">'."\n";
	    $consensus_table_columns .= '   <th class="tab_spacer_2">Singleton</th>'."\n";
	    $consensus_table_columns .= '   <th class="seq tab_spacer_1">'.&RSAT::SeqUtil::ColorConsensus($cons, bold=>1, iupac=>$main::param{iupac_coloring}).'</th>'."\n";
	    $consensus_table_columns .= '   <th class="tab_spacer_2"><a target="_blank" href="'.$logo_D.'"><img class="logo" src="'.$logo_D.'" /></a></th>'."\n";
	    $consensus_table_columns .= '   <th class="tab_spacer_2"><a target="_blank" href="'.$logo_R.'"><img class="logo" src="'.$logo_R.'" /></a></th>'."\n";
	    $consensus_table_columns .= '   <th class="tab_spacer_2" style="text-align:left;font-weight:normal;">'.$merged_consensuses_files{"node_".$level}{$cluster_id_hash{$num}}{collection_counts}.'</th>'."\n";
	    $consensus_table_columns .= '   <th class="tab_spacer_2"><a target="_blank" href="'.$transfac_file.'">PSSM</a></th>'."\n";
	    $consensus_table_columns .= '   <th class="tab_spacer_2">'.$rounded_ic.'</th>'."\n";
	    $consensus_table_columns .= '   <th class="tab_spacer_2">'.$sites.'</th>'."\n";
	    $consensus_table_columns .= "</tr>\n";

	    ## Add the code to hide/show the branch-consensus table
	    my $selection_branch = &Display_Selected_Branch();
	    my $branch_tab_id = $cluster_id_hash{$num};
	    my $branch_row_id = $cluster_id_hash{$num};
	    $selection_branch =~ s/--branch_tab_id--/$branch_tab_id/g;
	    $selection_branch =~ s/--branch_row_id--/$branch_row_id/g;
	    $selection_branch =~ s/--nb--/$cluster_id_hash{$num}/g;
	    $script_jquery .= $selection_branch."\n";

	    $consensus_table =~ s/--nb--/$cluster_id_hash{$num}/g;
	    $consensus_table =~ s/--here--/$consensus_table_columns/g;
	    $all_consensus_table .= "\n".$consensus_table."\n";
	}	
	$trees_and_tables .= $insert_div."\n";
    }

    $script_jquery .= "\n".'
    function showOneRow(id) {
       $(".branch_motifs").css("display", "table-row");
       $(".branch_motifs").not("#" + id).hide();
     };

    function showOneTable(id) {
       $(".cons_tab").css("display", "table");
       $(".cons_tab").not("#" + id).hide();
     };
    </script>'."\n";

    return($trees_and_tables);
}


###########################################
## Insert the JQuery script in the report
sub InsertJquery {
    print $syn $script_jquery;
}
  

################################################################
## Insert the code where the single trees and branch-motifs 
## will be displayed
sub DisplaySingleCluster{
    my $div_display = '
    <div id="Cluster_Tab_button" class="button_click Section_button"><strong>Individual Cluster View</strong></div>
    <div class="sep_clusters_div individual_results" id="Cluster_Tab" style="display:none">
	<!--Div with the header of the buttons-->
        <h2 style="display:block;padding:4px;width:986px;">Individual Cluster View</h2>'.
        &hide_show_buttons
        .'<div class="sep_clusters_div">'.
&InsertTreesAndBranchMotifs()
        .'</div>
	<div class="display"><strong style="display:block">Display Logo Trees   </strong>'."\n\n".$all_d3_trees.'</div> 

	<div class="display"><strong style="display:block">Display Branch-Motifs</strong>'."\n\n".$all_consensus_table."\n\n".'</div>

	  <ul style="text-align:left;clear:both;display:block;">
	     <li type="square"><strong>Click on the upper buttons to display separately the information of each cluster.</strong></li>
	     <li type="square"><strong>Click on the circles at each tree to display its corresponding merged motifs.</strong></li>
	  </ul>  
   <ul>
   <p><h3 style="text-align:left;">Definitions</h3>
      <ul>
         <li type="square" style="text-align:left;"><strong>Logo tree. </strong><br>This results shows the hierarchical tree with its logo alignment of one cluster.<br>The logos are shown in Forward (left logo) and Reverse (right logo) orientation.</li>
         <li type="square" style="text-align:left;"><strong>Branch-motifs. </strong><br>On the trees are displayed the branch number that is the number in which the motifs were incorporated in the tree.<br>The Branch-Motifs table shows the logo in both orientations and the link to the file in TRANSFAC format with the branch-motif.</li>
      </ul>
   </p>
   </ul>
    </div> 
    ';
    print $syn $div_display;
}


#######################################
## Insert the list of files exported
sub InsertListOfFiles {

      my $add_files = 
	  '

	<div id="List_Files_Button" class="button_click Section_button"><strong>Additional Files</strong></div>
	<div id="File_list" class="tab_list" style="width:960px">
	<h2 style="text-align:center;margin-top:0px;">Exported files</h2>
	  <table>
	    <thead>

	      <tr>
		<th class="tab_col" style="width:200px">File</th>
		<th class="tab_col" style="width:700px">Description</th>
	      </tr>
	    </thead>
	    <tbody>
<!--		   <tr>
		      <td class="tab_spacer_2"><a target="_blank" class="file_link" href="'.&RSAT::util::RelativePath($main::outfile{summary}, $main::outfile{distance_table}).'"><strong>Distance table</strong></a></td>
		      <td class="tab_spacer_2">This table shows the distances between the motifs based in the selected metric to measure the similarity.</td>
		   </tr>
		   <tr>
		      <td class="tab_spacer_2"><a target="_blank" class="file_link" href="'.&RSAT::util::RelativePath($main::outfile{summary}, $main::outfile{small_logo_cladogram_html}).'"><strong>Logo Forest</strong></a></td>
		      <td class="tab_spacer_2">This file shows the forest with all the logo trees resulting after partition the original tree using the user-selected thresholds.</td>
		   </tr>
                   <tr>
                   <td class="tab_spacer_2"><a target="_blank" class="file_link" href="'.&RSAT::util::RelativePath($main::outfile{summary}, $main::outfile{internal_nodes_attributes_table}).'"><strong>Internal nodes attributes</strong></a></td>
		      <td class="tab_spacer_2">This table shows the grouping steps of the hierarchical tree.</td>
		   </tr>
-->
		   <tr>
		      <td class="tab_spacer_2"><a target="_blank" class="file_link" href="'.&RSAT::util::RelativePath($main::outfile{summary}, $main::outfile{pairwise_compa}).'"><strong>Pairwise comparison</strong></a></td>
		      <td class="tab_spacer_2">This table shows the pairwise comparison between all the input motifs using different metrics. This is the <em>compare-matrices</em> result.</td>
		   </tr>
		   <tr>
		      <td class="tab_spacer_2"><a target="_blank" class="file_link" href="'.&RSAT::util::RelativePath($main::outfile{summary}, $main::outfile{matrix_descriptions}).'"><strong>Matrix description</strong></a></td>
		      <td class="tab_spacer_2">This table shows information of each input motif.</td>
		   </tr>
		   <tr>
		      <td class="tab_spacer_2"><a target="_blank" class="file_link" href="'.&RSAT::util::RelativePath($main::outfile{summary}, $main::outfile{matrix_descriptions}).'"><strong>Cluster-wise Motif Files [zip]</strong></a></td>
		      <td class="tab_spacer_2">One TRANSFAC file is generated for each cluster including all the input motifs grouped in the corresponding cluster.</td>
		   </tr>
                   <tr>
		      <td class="tab_spacer_2"><a target="_blank" class="file_link" href="'.&RSAT::util::RelativePath($main::outfile{summary}, $main::outfile{root_motifs}).'"><strong>Root motifs</strong></a></td>
		      <td class="tab_spacer_2">A file with the root matrix of each cluster.</td>
                   </tr>
                   <tr>
		      <td class="tab_spacer_2"><a target="_blank" class="file_link" href="'.&RSAT::util::RelativePath($main::outfile{summary}, $main::outfile{cluster_summary_table}).'"><strong>Motif collections per cluster</strong></a></td>
		      <td class="tab_spacer_2">A tab separated file containing the counts of motif of each collection on each cluster.</td>
		   </tr>
           <tr>
		      <td class="tab_spacer_2"><a target="_blank" class="file_link" href="'.&RSAT::util::RelativePath($main::outfile{summary}, $main::outfile{clusters_table_motif_names}).'"><strong>Clusters</strong></a></td>
		      <td class="tab_spacer_2">A tab separated file containing the clusters and their correspondng motifs.</td>
		   </tr>
           <tr>
		      <td class="tab_spacer_2"><a target="_blank" class="file_link" href="'.&RSAT::util::RelativePath($main::outfile{summary}, $main::outfile{central_motifs}).'"><strong>Central motifs IDs</strong></a></td>
		      <td class="tab_spacer_2">A tab separated file containing the central motif, that one who is the most similar to all the others motif in the same cluster.</td>
		   </tr>
		   <tr>
		      <td class="tab_spacer_2"><a target="_blank" class="file_link" href="'.&RSAT::util::RelativePath($main::outfile{summary}, $main::outfile{central_motifs_tf}).'"><strong>Central motifs (in TRANSFAC format)</strong></a></td>
		      <td class="tab_spacer_2">A transfac file containing the central motif, that one who is the most similar to all the others motif within the same cluster.</td>
		   </tr>
                         ';
      

      ## If it is specified, add the heatmap
      if ($draw_heatmap == 1 && $number_of_motifs > 1) {
	$add_files .= 
	    '
<!--
		   <tr>
		      <td class="tab_spacer_2"><a target="_blank" class="file_link" href="'.&RSAT::util::RelativePath($main::outfile{summary}, $main::outfile{heatmap_pdf}).'"><strong>Heatmap</strong></a></td>
		      <td class="tab_spacer_2">The heatmap showing the hierarchical tree with the clusters and the alignments.</td>
		   </tr>
-->
                     ';
      }

      ## If it is specified, add the newick tree
      if ($export_newick == 1 && $number_of_motifs > 1) {
	$add_files .= 
	    '
		   <tr>
		      <td class="tab_spacer_2"><a target="_blank" class="file_link" href="'.&RSAT::util::RelativePath($main::outfile{summary}, $main::outfile{consensus_phylogram_newick}).'"><strong>Newick Tree</strong></a></td>
		      <td class="tab_spacer_2">The hierarchical clustering tree in Newick format..</td>
		   </tr>
                     ';
      }

      ## If there are two or more collection of motifs
      if ($single_input_flag == 0) {
	  $add_files .= 
	      '
		   <tr>
		      <td class="tab_spacer_2"><a target="_blank" class="file_link" href="'.&RSAT::util::RelativePath($main::outfile{summary}, $main::outfile{dynamic_heatmap_html}).'"><strong>Collections Complementarity</strong></a></td>
		      <td class="tab_spacer_2">A dynamic heatmap showing how many motifs contribute each collection to each cluster.</td>
		   </tr>
             ';
      }

      # ## If it is specified, add the tree of aligned consensuses
      # if ($align_consensus == 1 && $number_of_motifs > 1) {
      # 	$add_files .= 
      # 		  '<tr>
      # 		      <td class="tab_spacer_2"><a target="_blank" class="file_link" href="'.&RSAT::util::RelativePath($main::outfile{summary}, $main::outfile{prefix}.'_figures/tree_of_consensus.pdf').'"><strong>Tree of consensus</strong></a></td>
      # 		      <td class="tab_spacer_2">A PDF file showing the alignment of the consensus. Each cluster is represented with a different color.</td>
      # 		   </tr>
      #           ';
      # }


      ## If it is specified, add the file with the input motifs
      if ($clone_input_flag == 1) {
	$add_files .= 
	    '

		   <tr>
		      <td class="tab_spacer_2"><a target="_blank" class="file_link" href="'.&RSAT::util::RelativePath($main::outfile{summary}, $main::outfile{prefix}.'_data/input_motifs_processed.tf').'"><strong>Input motifs</strong></a></td>
		      <td class="tab_spacer_2">The input motifs analyzed with matrix-clustering.</td>
		   </tr>
                     ';
      }

      $add_files .= '
	    </tbody>
	  </table>
	</div>
';

      print $syn $add_files;
}

################################################################
## Generate a HTML report summarizing the main results with
## links to the original result files.
sub Synthesis {

    &RSAT::message::TimeWarn("\n; Generating HTML Report") if ($main::verbose >= 2);

    &ReOpenSynthesis();

    ## Initialize the variables
    %ids_to_cluster = ();
    %alignment_table_data = ();
    %alignment_size = ();
    $script_jquery = "";
    $all_d3_trees = "";
    $all_consensus_table = "";
    $number_of_motifs = 0;
    $nb_char = 0;

    $menu_nb = 200; ## Numbering of the IDs for collapsible elements
    
    &ReadAlignmentTable();

    $number_of_clusters = scalar(keys %alignment_table_data); 

    if($radial_tree_flag == 1){
	&create_html_radial_tree_file();
    } else {
	&create_html_small_tree_file();
    }


    &OpenScriptJQuery();
    
    &ReportStyleCSS();

    &ParametersTable();

    if($radial_tree_flag == 0){
	&ClustersSummaryTable();
    }

    ## The heatmap will be created only when two or more collections of
    ## motifs are provided to matrix-clustering
    if ($single_input_flag == 0 && $radial_tree_flag == 0){

	&InsertHeatmapCollectionbyCluster();

	&InsertHeatmapCollectionComplementarity();

    	&Dynamic_Heatmap_Complementarity(); 

#	&MotifRichnessPlot();

#	&InsertMotifRichnessBarPlot();
    }

    if($radial_tree_flag == 1){
	#	&InsertRadialTree();
	$lkkkkk = 0;
    } else {
    
	&InsertSmallForest();

	&InsertAlignmentTable();

	&DisplaySingleCluster();
    
	if ($draw_heatmap == 1 && $number_of_motifs > 1) {
	    &InsertHeatMap();
	}
    }
    
    &InsertListOfFiles();

    &InsertJquery();

    &Text_end_report();
    
    ## End of the HTML file
    &CloseSynthesis();
     
    &RSAT::message::TimeWarn("Report", $main::outfile{summary}) if ($main::verbose >= 2);
}

#######################################
## Trim the ends of the matrix with 
## very low IC
sub trim_matrix_low_IC_columns {

    ## Read the matrix file name
    my $matrix_to_trim = shift;
    my $trimmed_matrix = shift;
    my $IC_threshold = shift;
    my $motif_ac = shift;
    my $motif_id = shift;
    my $motif_type = shift;
    my $merge_type = shift;
    my $merge_nb = shift;
    
    my $temp_IC_file = &RSAT::util::make_temp_file("","IC_test", 1);
    my $IC_info = "";
    my @IC_info_array = ();
    my $trim_up = 0; 
    my $trim_dw = 0;
  

    ## Calculate the IC of the matrix,
    ## save this info in a file
    my $cmd = $SCRIPTS."/convert-matrix -i ".$matrix_to_trim." -from tf -return info,header,margins -o ".$temp_IC_file;
    &doit($cmd, 0, $die_on_error, $verbose, 0, "", $main::out, $main::err);

    ## Read the IC file
    ## Select the line with the sum of IC of each column
    my ($IC_file) = &OpenInputFile($temp_IC_file);
    while (<$IC_file>) {
	chomp;
	if ($_ =~ /; i\.sum/) {
	    $IC_info = $_;
	    $IC_info =~ s/;\s+i.sum\s+//g;
	    @IC_info_array = split(/\s+/, $IC_info);
	    last;
	} else {
	    next;
	}
    }
    close($IC_file);
    unlink($IC_file);

    ## Calculate the number of trimmed columns 
    ## in the upstream side of the motif
    foreach my $IC (@IC_info_array) {
	if ($IC <= $IC_threshold) {
	    $trim_up++;
	} else {
	    last;
	}
    }

    ## Calculate the number of trimmed columns 
    ## in the downstream side of the motif
    @IC_info_array = reverse(@IC_info_array);
    ## Delete the last element which correspond to the sum of IC
    shift @IC_info_array;
    foreach my $IC (@IC_info_array) {
	if ($IC <= $IC_threshold) {
	    $trim_dw++;
	} else {
	    last;
	}
    }

    ## Trim the matrix
    $cmd = $SCRIPTS."/convert-matrix -i ".$matrix_to_trim." -from tf -to tf";
    $cmd .= " -trim_col_left ".$trim_up." -trim_col_right ".$trim_dw." -return counts,consensus -o ".$trimmed_matrix;
    $cmd .= " -set_attr type ".$motif_type;
    $cmd .= " -set_attr merge_type ".$merge_type;
    $cmd .= " -set_attr merge_nb ".$merge_nb;
    $cmd .= " -set_attr merged_AC ".$motif_ac;
    $cmd .= " -set_attr merged_ID ".$motif_id;

    &doit($cmd, 0, $die_on_error, $verbose, 0, "", $main::out, $main::err);
    return $trimmed_matrix;
}


#######################################
## Trim the ends of the matrix with 
## very low IC (pre-process step)
sub trim_matrix_low_IC_columns_preprocess {

    ## Read the matrix file name
    my $matrix_to_trim = shift;
    my $trimmed_matrix = shift;
    my $IC_threshold = shift;
    
    my $temp_IC_file = &RSAT::util::make_temp_file("","IC_test", 1);
    my $IC_info = "";
    my @IC_info_array = ();
    my $trim_up = 0; 
    my $trim_dw = 0;
  

    ## Calculate the IC of the matrix,
    ## save this info in a file
    my $cmd = $SCRIPTS."/convert-matrix -i ".$matrix_to_trim." -from tf -return info,header,margins -o ".$temp_IC_file;
    &doit($cmd, 0, $die_on_error, $verbose, 0, "", $main::out, $main::err);

    ## Read the IC file
    ## Select the line with the sum of IC of each column
    my ($IC_file) = &OpenInputFile($temp_IC_file);
    while (<$IC_file>) {
	chomp;
	if ($_ =~ /; i\.sum/) {
	    $IC_info = $_;
	    $IC_info =~ s/;\s+i.sum\s+//g;
	    @IC_info_array = split(/\s+/, $IC_info);
	    last;
	} else {
	    next;
	}
    }
    close($IC_file);
    unlink($IC_file);

    ## Calculate the number of trimmed columns 
    ## in the upstream side of the motif
    foreach my $IC (@IC_info_array) {
	if ($IC <= $IC_threshold) {
	    $trim_up++;
	} else {
	    last;
	}
    }

    ## Calculate the number of trimmed columns 
    ## in the downstream side of the motif
    @IC_info_array = reverse(@IC_info_array);
    ## Delete the last element which correspond to the sum of IC
    shift @IC_info_array;
    foreach my $IC (@IC_info_array) {
	if ($IC <= $IC_threshold) {
	    $trim_dw++;
	} else {
	    last;
	}
    }

    ## Trim the matrix
    $cmd = $SCRIPTS."/convert-matrix -i ".$matrix_to_trim." -from tf -to tf";
    $cmd .= " -trim_col_left ".$trim_up." -trim_col_right ".$trim_dw." -return counts,consensus -o ".$trimmed_matrix;

    &doit($cmd, 0, $die_on_error, $verbose, 0, "", $main::out, $main::err);
    return $trimmed_matrix;
}

####################################################
## This function calls the program convert-matrix
## to add empty columns to the selected file.
sub Add_Empty_Col {

    my ($file_name, $offset_left, $offset_right, $return_fields, $out_file) = @_;

    ## Add the empty columns
    my $cmd = $SCRIPTS."/convert-matrix -i ".$file_name;
    $cmd .= " -from tf -to tf -return ".$return_fields;
    $cmd .= " -insert_col_left ".$offset_left;
    $cmd .= " -insert_col_right ".$offset_right;
    $cmd .= " -o ".$out_file;
    &doit($cmd, 0, $die_on_error, $verbose, 0, "", $main::out, $main::err);
}


####################################################
## This function calls the program convert-matrix
## to add empty columns to the selected file.
sub Produce_logos {

    &RSAT::message::TimeWarn("Generating Logos") if ($main::verbose >= 2);

    ## Add the empty columns
    my $cmd = $SCRIPTS."/convert-matrix -i ".$main::outfile{all_concatenated_motifs};
    $cmd .= " -from tf -to tf -return logo -logo_no_title -logo_program seqlogo";
    $cmd .= " -o ".$main::outfile{prefix}."_aligned_logos/test";
    &doit($cmd, 0, $die_on_error, $verbose, 0, "", $main::out, $main::err);

    unlink($main::outfile{all_concatenated_motifs});
}

#########################################################
## This function calls the program convert-matrix
## to get the reverse complement of the input motif (s)
sub Rev_Comp_Motif {

    my ($file_name, $out_file) = @_;

    my $cmd = $SCRIPTS."/convert-matrix -i ".$file_name;
    $cmd .= " -from tf -to tf -rc -return counts,consensus";
    $cmd .= " -o ".$out_file;
    &doit($cmd, 0, $die_on_error, $verbose, 0, "", $main::out, $main::err);
}


#########################################################
## For each cluster creates a file incluiding all the
## original (input) motifs corresponding to that cluster
sub Clustered_PSSMS_TRANSFAC_format(){

    my $file_names = "";

    my ($clusters_table) = &OpenInputFile($main::outfile{clusters_table});
    while (<$clusters_table>) {
	chomp;
	next if (/^#/); ## Skip header line
	next if (/^;/); ## Skip comment lines	
	my $line = $_;
	my @split_line = split("\t", $line);

	## Get the cluster name and motif IDs
	my $cluster = $split_line[0];
	my $cluster_motif_ids = $split_line[1];
	$cluster_motif_ids =~ s/,/\n/g;

	## Create a temporary file
	$main::outfile{clusters_id_temp} = $main::outfile{prefix}."_tables/".$cluster."_motif_IDs.tab";
	$main::outfile{clusters_transfac} = $main::outfile{prefix}."_data/".$cluster."_transfac_motifs.tf";
	my ($motifs_id_handle) = &OpenOutputFile($main::outfile{clusters_id_temp});
	print $motifs_id_handle $cluster_motif_ids."\n";
	close($motifs_id_handle);

	## Separate the files (calling convert-matrix)
	my $separate_motifs_cmd = $SCRIPTS."/convert-matrix";
	$separate_motifs_cmd .= " -i ".$main::outfile{input_matrices};
	$separate_motifs_cmd .= " -from tf -to tf";
	$separate_motifs_cmd .= " -matrix_id_file ".$main::outfile{clusters_id_temp};
	$separate_motifs_cmd .= " -o ".$main::outfile{clusters_transfac};
	&doit($separate_motifs_cmd, 0, 1, $verbose, 0, "", $main::out, $main::err);

	## Delete the temporal files
	unlink($main::outfile{clusters_id_temp});
    }
}


sub Generate_matrix_description_table {

    ################################################################
    ## Export a description of the matrices
    @matrices = &RSAT::MatrixReader::readFromFile($main::outfile{input_matrices}, "tf");
    &RSAT::message::TimeWarn("Generating description table for the input matrices") if ($main::verbose >= 2);
    my $desc = &OpenOutputFile($main::outfile{matrix_descriptions});
    
    ## Print header
    print $desc join ("\t", 
			     "#n",
			     "id",
			     "name",
			     "width",
			     "consensus",
			     "rc_consensus",
			     "label",
		         "IC",
                 "nb_sites"
	), "\n";
    
    my $m=0;

    foreach my $matrix (@matrices) {
	my $c = "";
	my $c_rc = "";
	my $s = 0;
	$m ++;

	$matrix->calcConsensus();
	$c = $matrix->get_attribute("consensus.IUPAC");
	$c_rc = $matrix->get_attribute("consensus.IUPAC.rc");

	## JvH: Jaime: this variable ($ss) is not used anywhere else in the script. Can you check if it can be suppressed ? 
	#$ss = $matrix->calcNbSites();
        $s = $matrix->getNbSites();

	## Calculates the IC of the matrix
	$matrix->calcInformation();
	$matrix->toString(col_width=>(1+4),
					    decimals=>1,
					    type=>"information",
					    format=>"tf");
        my $ic = $matrix->get_attribute("total.information");
        my $rounded_ic = sprintf("%.2f", $ic);


	my $matrix_desc_string = join ("\t", 
				       $m,
				       $matrix->get_attribute("id"),
				       $matrix->get_attribute("name"),
				       $matrix->get_attribute("ncol"),
				       $c,
				       $c_rc,
                                       $rounded_ic,
                                       $s
	    );
	print $desc $matrix_desc_string."\n";
    }
    close $desc;
}

sub Export_central_motif_per_cluster {
	
	## Read Central Motif ID table
	my $central_motif_parser_cmd = "more ".$main::outfile{central_motifs}." | cut -f2 > ".$main::outfile{central_motifs_IDs_temp};
	system($central_motif_parser_cmd);
	
	my $get_central_motifs_cmd = $SCRIPTS."/convert-matrix -v 2 -i ".$main::outfile{input_matrices}." -from tf -to tf -matrix_id_file ".$main::outfile{central_motifs_IDs_temp}." -o ".$main::outfile{central_motifs_tf};
	system($get_central_motifs_cmd);
	

}
__END__
