void ComputeErrorMetrics() {
		metrics_.constructed_metrics.num_errors = 0;
		for(auto it = constructed_clusters_.clusters_begin(); it != constructed_clusters_.clusters_end(); it++) {
			if(!IsConstructedClusterNotErroneous(it->first))
				metrics_.constructed_metrics.num_errors++;
			else {
				size_t orig_supercluster = GetOriginalSuperCluster(it->first);
				if(constructed_clusters_.ClusterSize(it->first) > original_clusters_.ClusterSize(orig_supercluster))
				metrics_.constructed_metrics.num_errors++;
			}
		}
	}
	void ComputeMaxClusterMetrics() {
		size_t max_orig_cluster = 0;
		for(auto it = original_clusters_.clusters_begin(); it != original_clusters_.clusters_end(); it++)
			if(metrics_.original_metrics.max_cluster < original_clusters_.ClusterSize(it->first)) {
				metrics_.original_metrics.max_cluster = original_clusters_.ClusterSize(it->first);
				max_orig_cluster = it->first;
			}

		for(auto it = constructed_clusters_.clusters_begin(); it != constructed_clusters_.clusters_end(); it++) {
			metrics_.constructed_metrics.max_cluster = max<size_t>(metrics_.constructed_metrics.max_cluster,
					constructed_clusters_.ClusterSize(it->first));
		}

		metrics_.max_cluster_fillin = ComputeNotMergedFillin(max_orig_cluster);
	}
	double ComputeNotMergedFillin(size_t orig_cluster_ind) {
		vector<string> read_names = GetReadNamesFromCluster(orig_cluster_ind, original_clusters_, original_reads_);
		map<size_t, vector<size_t> > constr_subclusters;
		for(auto it = read_names.begin(); it != read_names.end(); it++) {
			size_t cluster_ind = constructed_clusters_.GetCluster(*it);
			constr_subclusters[constructed_clusters_.ClusterSize(cluster_ind)].push_back(cluster_ind);
		}

		for(auto it = constr_subclusters.rbegin(); it != constr_subclusters.rend(); it++) {
			auto clusters = it->second;
			for(auto cluster_ind = clusters.begin(); cluster_ind != clusters.end(); cluster_ind++)
				if(IsConstructedClusterNotErroneous(*cluster_ind)) {
					return double(constructed_clusters_.ClusterSize(*cluster_ind)) / original_clusters_.ClusterSize(orig_cluster_ind);
				}
		}
		return 0;
	}
	void ComputeLostClustersMetrics() {
		size_t lost_cluster_size = 0;
		for(auto it = original_clusters_.clusters_begin(); it != original_clusters_.clusters_end();
				it++) {
			if(IsOriginalClusterLost(it->first)) {
				metrics_.lost_clusters_number++;
				lost_cluster_size += original_clusters_.ClusterSize(it->first);
			}
		}
		metrics_.lost_clusters_size = double(lost_cluster_size) / original_reads_.size();
	}
	void ComputeNotMergedMetrics() {
		double sum_fill = 0;

		for(auto it = original_clusters_.clusters_begin(); it != original_clusters_.clusters_end(); it++) {
			size_t orig_cluster_ind = it->first;
			if(original_clusters_.IsClusterSingleton(orig_cluster_ind))
				continue;

			// for each non trivial cluster we compute it "not merged"
			if(!IsClusterNotMerged(orig_cluster_ind))
				continue;

			metrics_.original_metrics.num_not_merged++;
			if(IsClusterBigAndSingletons(orig_cluster_ind))
				metrics_.original_metrics.num_nm_big_singletons++;

			size_t orig_cluster_size = original_clusters_.ClusterSize(orig_cluster_ind);
			double orig_cluster_fill = ComputeNotMergedFillin(orig_cluster_ind);

			sum_fill += orig_cluster_fill;
		}
		metrics_.avg_fillin = sum_fill / metrics_.original_metrics.num_not_merged;
	}