function pt_mkPseudoGt(idlist, audiodir, audioext, pgtdir, ptlist, ptdir, minagree, verbose, rf0)
% pt_mkPseudoGt(idlist, audiodir, audioext, pgtdir, ptlist, ptdir,
% minagree, verbose, rf0)
%     Generate pseudo-ground-truth by voting with pitch trackers.
%     <idlist> is a cell array of file roots (or the name of a
%     file listing those roots), which are found
%     within <audiodir> bearing extension <audioext>.
%     Corresponding files with the pseudo 
%     ground truth are written into <pgtdir>.  <ptlist> is a cell
%     array of pitch tracking algorithms to use; each is run to
%     generate pitch tracks into <ptdir>.
%     <minagree> is how many pitch trackers must agree to count as
%     consensus; default is simple majority.
%     <verbose> as 1 to report progress.
%     <rf0> as 1 causes restore_f0 to be run on audio, which
%     attempts to restore energy between around 100 and 300 Hz with
%     a nonlinearly-distorted version of the higher harmonics, to
%     replace fundamentals that have been filtered out.
% 2013-02-04 Dan Ellis dpwe@ee.columbia.edu

VERSION = 0.23;
VERDATE = 20130824;

% example usage
%makePseudoGt({'rl001','rl002','sb001','sb002'},'audio','.wav','ptk/pgt',{'yin','wu','getf0','swipe','sacc'},'ptk');

if nargin < 7; minagree = 0; end
if nargin < 8; verbose = 0; end
if nargin < 9; rf0 = 0; end

% handle arguments passed via command line
if ischar(minagree); minagree = sscanf(minagree,'%f'); end
if ischar(verbose);  verbose = sscanf(verbose,'%f'); end
if ischar(rf0);      rf0 = sscanf(rf0,'%f'); end


% ptlist can be one string with commas or spaces separating PTs
if ischar(ptlist)
  % split it into a list on any strings of spaces and/or commas
  ptlist = regexp(ptlist, '[ ,]+','split');
end

% How many pitch trackers specified?
npts = length(ptlist);

if minagree == 0
  % How many must agree for consensus
  %minagree = npts;  % full consensus
  minagree = ceil(npts/2);  % simple majority
end

% threshold for pitches to be considered agreeing
thr = 0.1; % 0.1 = +/- 10% of median

% Is idlist actually a file to read?
if ischar(idlist)
  idlist = textread(idlist, '%s', 'commentstyle', 'shell');
end

% Run pitch trackers on all waveforms
audfilelist = addprefixsuffix(idlist, [audiodir,'/'], audioext);

% Only run pitch trackers if audio dir is given; otherwise, assume
% ptdirs are already populated
if length(audiodir) > 0
  for ptn = 1:npts
    pt = ptlist{ptn};
    % build the output file list
    thisptdir = [fullfile(ptdir, pt)];
    mymkdir(thisptdir);
    ptoutlist = addprefixsuffix(idlist, [thisptdir, '/'], ...
                                ['-', pt, '.txt']);
    % run the pitch tracker
    dt = 0.010;
    %rf0 = 0;
    ptfn = eval(['@ptrack_',pt]);
    pt_wrap(audfilelist, ptoutlist, dt, ptfn, rf0, verbose);
  end
end

% Now calculate the consensus pitch labels for each

mymkdir(pgtdir);

nframes = 0;
nconsensus = 0;

for i = 1:length(idlist)

  % read all the pitch tracks
  pts = zeros(npts,0);
  for ptn = 1:npts
    pt = ptlist{ptn};
    ptfile = fullfile(ptdir, pt, [idlist{i}, '-', pt, '.txt']);
    [tt,thispt] = pt_read(ptfile);
    if length(thispt) > size(pts,2)
      pts = [pts, zeros(size(pts,1), size(pts,2)-length(thispt))];
    end
    pts(ptn,1:length(thispt)) = thispt;
  end

  % calculate the consensus - within thr of the median
  medpt = median(pts);
  lomed = (1 - thr) * medpt;
  himed = (1 + thr) * medpt;
  agree = ( (pts >= repmat(lomed, npts, 1)) ...
            & (pts <= repmat(himed, npts, 1)));
  
  % debug plots
%  subplot(311)
%  imgsc(pts);
%  colorbar;
%  subplot(312)
%  plot(1:length(lomed),lomed,1:length(himed),himed);
%  subplot(313)
%  imgsc(agree)
  
  % Which frames achieve consensus?
  consensus = (sum(agree) >= minagree);
  
  % so pseudo ground truth
  %pseudogt = medpt; 
  % (or average of all matching points?)
  pseudogt = sum(agree .* pts)./(sum(agree) + (sum(agree)==0));
  
  % but write the non-consensus frames as -1
  pseudogt(find(~consensus)) = -1;
  
  % Save the pseudogt
  pgtfile = fullfile(pgtdir, [idlist{i}, '-pgt.txt']);
  tt = median(diff(tt)) * [0:length(pseudogt)-1];
  pvx = double(pseudogt > 0);
  pvx(find(~consensus)) = -1;
  pt_write(pgtfile, tt, pseudogt, pvx);

  if verbose; disp(['wrote ', pgtfile]); end

  % Track total number of frames, and how many had a consensus
  nframes = nframes + length(consensus);
  nconsensus = nconsensus + sum(consensus);
  
end

if verbose
  disp(sprintf(['makePseudoGt v',num2str(VERSION), ' of ', ...
                num2str(VERDATE), ': %d total frames, %d (%.1f%%) have ', ...
                'consensus (%d of %d)'], nframes, nconsensus, ...
               100*nconsensus/nframes, minagree, npts));
end
