def run
      raise NotEnoughHitsError if hits.length < opt[:min_blast_hits]
      raise unless prediction.is_a?(Query) && hits[0].is_a?(Query)

      start = Time.now

      pairs = hits.map do |hit|
        Pair.new(hit.hsp_list.map(&:match_query_from).min,
                 hit.hsp_list.map(&:match_query_to).max)
      end
      xx_0 = pairs.map(&:x)
      yy_0 = pairs.map(&:y)

      # minimum start shoud be at 'boundary' residues
      xx = xx_0.map { |x| x < @boundary ? @boundary : x }

      # maximum end should be at length - 'boundary' residues
      yy = yy_0.map do |y|
        if y > @prediction.raw_sequence.length - @boundary
          @prediction.raw_sequence.length - @boundary
        else
          y
        end
      end

      line_slope = slope(xx, yy, (1..hits.length).map { |x| 1 / (x + 0.0) })
      ## YW - what is this weighting?

      unimodality = false
      if unimodality_test(xx, yy)
        unimodality = true
        lm_slope = 0.0
      else
        lm_slope = line_slope[1]
      end

      y_intercept = line_slope[0]

      @validation_report = GeneMergeValidationOutput.new(@short_header, @header,
                                                         @description, lm_slope,
                                                         unimodality)
      plot1 = if unimodality
                plot_2d_start_from
              else
                plot_2d_start_from(lm_slope, y_intercept)
              end

      @validation_report.plot_files.push(plot1)
      plot2 = plot_matched_regions
      @validation_report.plot_files.push(plot2)
      @validation_report.run_time = Time.now - start
      @validation_report
    rescue NotEnoughHitsError
      @validation_report = ValidationReport.new('Not enough evidence', :warning,
                                                @short_header, @header,
                                                @description)
    rescue StandardError
      @validation_report = ValidationReport.new('Unexpected error', :error,
                                                @short_header, @header,
                                                @description)
      @validation_report.errors.push 'Unexpected Error'
    end
def run
      raise NotEnoughHitsError if hits.length < opt[:min_blast_hits]
      raise unless prediction.is_a?(Query) && hits[0].is_a?(Query)

      start = Time.now

      pairs = hits.map do |hit|
        Pair.new(hit.hsp_list.map(&:match_query_from).min,
                 hit.hsp_list.map(&:match_query_to).max)
      end
      xx_0 = pairs.map(&:x)
      yy_0 = pairs.map(&:y)

      # minimum start shoud be at 'boundary' residues
      xx = xx_0.map { |x| x < @boundary ? @boundary : x }

      # maximum end should be at length - 'boundary' residues
      yy = yy_0.map do |y|
        if y > @prediction.raw_sequence.length - @boundary
          @prediction.raw_sequence.length - @boundary
        else
          y
        end
      end

      line_slope = slope(xx, yy, (1..hits.length).map { |x| 1 / (x + 0.0) })
      ## YW - what is this weighting?

      unimodality = false
      if unimodality_test(xx, yy)
        unimodality = true
        lm_slope = 0.0
      else
        lm_slope = line_slope[1]
      end

      y_intercept = line_slope[0]

      @validation_report = GeneMergeValidationOutput.new(@short_header, @header,
                                                         @description, lm_slope,
                                                         unimodality)
      plot1 = if unimodality
                plot_2d_start_from
              else
                plot_2d_start_from(lm_slope, y_intercept)
              end

      @validation_report.plot_files.push(plot1)
      plot2 = plot_matched_regions
      @validation_report.plot_files.push(plot2)
      @validation_report.run_time = Time.now - start
      @validation_report
    rescue NotEnoughHitsError
      @validation_report = ValidationReport.new('Not enough evidence', :warning,
                                                @short_header, @header,
                                                @description)
    rescue StandardError
      @validation_report = ValidationReport.new('Unexpected error', :error,
                                                @short_header, @header,
                                                @description)
      @validation_report.errors.push 'Unexpected Error'
    end
Initilizes the object
 Params:
 +prediction+: a +Sequence+ object representing the blast query
 +hits+: a vector of +Sequence+ objects (representing blast hits)
 +plot_path+: name of the input file, used when generatig the plot files
 +boundary+: the offset of the hit from which we start analysing the hit

 Validation test for gene merge
 Output:
 +GeneMergeValidationOutput+ object