/** Retrieve transcriptions most similar to the query */
  public SearchResult[] retrieveMostSimilar(Signal likelihoodSignal) throws noMetadataException {
    if (this.Files == null) {
      this.finaliseIndex();
    }
    ArrayList results = new ArrayList();

    // get features
    double[] features =
        likelihoodSignal.getData()[likelihoodSignal.getColumnIndex(Signal.PROP_LIKELIHOODS)];
    double queryRootSquareSum = 0.0;

    for (int j = 0; j < features.length; j++) {
      queryRootSquareSum += Math.pow(features[j] / featureStds[j], 2.0);
    }
    queryRootSquareSum = Math.sqrt(queryRootSquareSum);

    // iterate through all files
    for (int i = 0; i < Files.length; i++) {
      float score = 0.0f;

      // get features
      double[] testFeatures = ((double[]) this.FileLocationToFeaturesMap.get(Files[i]));

      // Normalised Cosine distance between likelihoods
      double prodSum = 0.0;
      double testSum = 0.0;
      for (int j = 0; j < features.length; j++) {
        prodSum += (features[j] / featureStds[j]) * (testFeatures[j] / featureStds[j]);
        testSum += Math.pow(testFeatures[j] / featureStds[j], 2.0);
      }
      score = (float) (prodSum / (queryRootSquareSum * Math.sqrt(testSum)));

      Signal outSig = (Signal) FileLocationToSignalMap.get((String) Files[i]);
      results.add(new SearchResult(outSig, score));
    }
    SearchResult[] outputResults =
        (SearchResult[]) results.toArray(new SearchResult[results.size()]);
    java.util.Arrays.sort((Object[]) outputResults);
    return outputResults;
  }