annotate collect_all_mirex_annotations.m @ 6:e2337cd691b1 tip

Finishing writing the matlab code to replicate all observations made in the article. Added the article to the repository. Renamed the two main scripts ("1-get_mirex_estimates.rb" and "2-generate_smith2013_ismir.m") to not have dashes (since this was annoying within Matlab) Added new Michael Jackson figure.
author Jordan Smith <jordan.smith@eecs.qmul.ac.uk>
date Wed, 05 Mar 2014 01:02:26 +0000
parents 92b5a46bc67b
children
rev   line source
jordan@1 1 function [data dset_origin] = collect_all_mirex_annotations(base_directory, dsets, algos)
jordan@1 2 % function [data dset_origin] = collect_all_mirex_annotations(base_directory, dsets, algos)
jordan@1 3 %
jordan@1 4 % GET ALL THE DATA!
jordan@1 5 % This function collects annotations from all years of MIREX evaluation.
jordan@1 6 % Annotation data (onsets and labels) all go in a single structure, including file
jordan@1 7 % locations.
jordan@1 8 %
jordan@1 9 % BASE_DIRECTORY should be the "mirex_path" specified in "get_mirex_estimates.rb",
jordan@1 10 % or whatever directory contains all the downloaded MIREX data. For example:
jordan@2 11 % "/Users/me/Desktop/MIREX_data"
jordan@1 12 %
jordan@1 13 % DSETS should contain the names of the datasets. The default value is all of them:
jordan@1 14 % {'mrx09','mrx10_1','mrx10_2','sal'}
jordan@1 15 % Keep the DSETS in a consistent order across your work, because the index of the dataset
jordan@1 16 % is important for some of the other functions.
jordan@1 17 %
jordan@1 18 % ALGOS should contain the name of at least one algorithm, so that the data can be
jordan@1 19 % accessed correctly. (Only the first algo is used, since the annotation is the same
jordan@1 20 % for each.) The default value is {'KSP1'}.
jordan@1 21 %
jordan@1 22 % The output DATA structure contains the following fields:
jordan@1 23 %
jordan@1 24 % DATA(i).TIM = onset times of annotation
jordan@1 25 % DATA(i).LAB = labels of sections
jordan@1 26 % DATA(i).FILE = file from which the above information derives
jordan@1 27 % DATA(i).DSET = numerical index of the dataset
jordan@1 28 %
jordan@1 29 % Dependencies:
jordan@1 30 % - load_annotation.m
jordan@1 31
jordan@1 32 % YEAR(i).NAMES will contain the NAMES of all the individual song files from YEAR i.
jordan@1 33 year = {};
jordan@1 34
jordan@1 35 % MRXTRUTH will contain an entry for every song in the MIREX evaluation, containing information about the
jordan@1 36 mrxtruth = {};
jordan@1 37
jordan@1 38 % Collect one CSV file from each year (the song names are identical in each algo CSV, so it is only necessary to have one valid ALGO here)
jordan@1 39 algos = {'KSP1','KSP2','KSP3','MHRAF1','OYZS1','SBV1','SMGA1','SMGA2','SP1'};
jordan@1 40 dsets = {'mrx09','mrx10_1','mrx10_2','sal'};
jordan@1 41 csv_files = {};
jordan@1 42 for i=1:length(dsets),
jordan@1 43 csv_files{end+1} = fullfile(base_directory,dsets{i},algos{1},'per_track_results.csv');
jordan@1 44 end
jordan@1 45
jordan@1 46
jordan@1 47 % Use the CSV files to discover the names of all the songs.
jordan@1 48 fprintf('About to open some CSV files to extract the names of the songs in MIREX. If you see lots of errors, please ensure that the files exist in the correct location.\n')
jordan@1 49 for i=1:length(csv_files),
jordan@1 50 try
jordan@1 51 fid = fopen(csv_files{i});
jordan@1 52 names_tmp = textscan(fid,'%s%s%*[^\n]','Delimiter',',');
jordan@1 53 fclose(fid);
jordan@1 54 year(i).names = names_tmp{2}(2:end);
jordan@1 55 catch
jordan@1 56 fprintf('Error opening or reading the following CSV file:\n %s\n',csv_files{i});
jordan@1 57 end
jordan@1 58 end
jordan@1 59
jordan@4 60 fprintf('OK, done with that.\n\n')
jordan@4 61
jordan@1 62 % For every dataset (DSET), look through all the names (YEAR(k).NAMES), and load the annotation.
jordan@1 63 fprintf('About to load all the ground truth files published by MIREX. If you see lots of errors, please ensure that the files exist in the correct location, and that the function ''load_annotation'' exists.\n')
jordan@1 64 for k=1:length(dsets),
jordan@1 65 dset = dsets{k};
jordan@1 66 algo = algos{1};
jordan@1 67 for i=1:length(year(k).names),
jordan@1 68 % FYI: GT stands for 'ground truth', in contrast to PRED for 'prediction'.
jordan@1 69 gt = fullfile(base_directory,dset,algo,strcat(year(k).names{i},'_gt.txt'));
jordan@1 70 try
jordan@1 71 [mrxtruth(end+1).tim mrxtruth(end+1).lab] = load_annotation(gt,'two_column');
jordan@1 72 mrxtruth(end).file = gt;
jordan@1 73 mrxtruth(end).dset = k;
jordan@1 74 if isempty(mrxtruth(end).tim),
jordan@1 75 % Sometimes the annotation might be empty! This can be bad news.
jordan@1 76 % If this happens, print out the name of the offending file, and delete this from the structure of annotations.
jordan@1 77 fprintf(mrxtruth(end).file)
jordan@1 78 fprintf('\n')
jordan@1 79 mrxtruth = mrxtruth(1:end-1);
jordan@1 80 end
jordan@1 81 catch
jordan@1 82 fprintf('Error opening the following ground truth file:\n %s\n',gt);
jordan@1 83 end
jordan@1 84 end
jordan@1 85 end
jordan@1 86
jordan@4 87 fprintf('OK, done with that.\n\n')
jordan@4 88
jordan@1 89 % It can be useful to have a separate structure pointing to the index of the dataset.
jordan@1 90 % This is an optional output of the function.
jordan@1 91
jordan@1 92 data = mrxtruth;
jordan@1 93 dset_origin = zeros(length(data),1);
jordan@1 94 for i=1:length(data),
jordan@1 95 dset_origin(i) = data(i).dset;
jordan@1 96 end
jordan@1 97
jordan@1 98
jordan@1 99 % Did this actually happen? That some of the onset times are in the incorrect order?
jordan@1 100 % Why yes, it did. It happens probably due to some floating point error...
jordan@1 101 % What you would see is two boundaries a tiny distance apart, where the later one
jordan@1 102 % appeared first, like: "145.0000468 silence; 145.0000000 end".
jordan@1 103 % In such cases, a perfectly acceptable fix is to just resort the times. They should
jordan@1 104 % be in sorted order anyway!
jordan@1 105
jordan@1 106 for i=1:length(data),
jordan@1 107 data(i).tim = sort(data(i).tim);
jordan@1 108 end