def load_bigimbaz_blocks(input_pattern, d = -1):    
    block = 0
    fv = None
    while True:
        fname = input_pattern % block
        if os.access(fname, os.R_OK):
            fvi = ynumpy.fvecs_read(fname)
            if fvi.shape[0] == 0:
                pass
            elif fv == None:
                fv = fvi
            else:
                try:
                    fv = np.vstack((fv, fvi))
                except ValueError:
                    pdb.set_trace()
        else:
            break
        block += 1 

    if block == 0 or fv == None:
        print "!! warn empty video", input_pattern
        fv = np.zeros((1, d))
    else:
        assert d == -1 or fv.shape[1] == d
    return fv
Exemple #2
0
def readFeatFileYael(fName):
    """read a fvec yael format file """
    print "\tReading feature file:", fName,
    sys.stdout.flush()
    feats = ynumpy.fvecs_read(fName)
    print "size", feats.shape
    return feats
Exemple #3
0
def readFeatFileYael(fName):   
    """read a fvec yael format file """
    print '\tReading feature file:', fName, 
    sys.stdout.flush()
    feats = ynumpy.fvecs_read(fName)
    print 'size', feats.shape
    return feats 
Exemple #4
0
def load_BOW(group, k, nclass, nex):
  """ Load BOW descriptors in dimension k, for at most nclass classes,
  keeping just nex training examples per class"""

  # basedir = '/scratch2/clear/paulin/datasets/%s/descs/dense_siftnonorm_bof%d/' % (group, k)
  basedir = '../example_data/%s_BOW%d/' % (group, k)

  # classes = nXXX numbers in alphabetical order
  nx = [f for f in os.listdir(basedir) if f.endswith('.fvecs')]
  nx.sort()

  # define train and test 
  Xtrain = []
  Xtest = []

  Ltrain = []
  Ltest = []
  
  for i, fname in enumerate(nx[:nclass]):

    print fname
    
    descs = ynumpy.fvecs_read(basedir + fname)
    assert descs.shape[1] == k 

    ni = descs.shape[0]

    # normalizations: power norm + L1 normalization
    descs = numpy.sqrt(descs)
    norm = descs.sum(axis = 1).reshape(ni, 1)
    norm[norm==0] = 1
    descs /= norm

    
    ntrain = ni / 2
    # keep only nex of the ntrain learning parameters
    Xtrain.append(descs[0:min(ntrain,nex), :])
    Ltrain.append(i * numpy.ones((min(ntrain,nex)), dtype = numpy.int32))

    assert Ltrain[-1].shape[0] == Xtrain[-1].shape[0],"%d %d"%(Ltrain[-1].shape[0], Xtrain[-1].shape[0])

    # the rest is for testing
    Xtest.append(descs[ntrain:ni, :])
    Ltest.append(i * numpy.ones((ni - ntrain), dtype = numpy.int32))

  # stack the matrices
  Xtrain = numpy.vstack(Xtrain)
  Ltrain = numpy.concatenate(Ltrain)

  Xtest = numpy.vstack(Xtest)
  Ltest = numpy.concatenate(Ltest)

  print Xtrain.shape, Ltrain.shape
  assert Xtrain.shape[0]==Ltrain.shape[0]

  return Xtrain, Ltrain.T, Xtest, Ltest.T
def load_descriptors_sift(dataset, collection, desctype, clipids = None):
  """
  dataset = tv14dryrun, tv14ps, tv14ah (option to early_fusion)
  collection = "Event-BG"
  desctype = siftXXXXX
  clipids = list of clip ids
  """
  print clipids
  # if desctype in ("sift_1024", "sift_2048") and dataset == "tv11":
  if (desctype, dataset) != ("sift", "tv11"):
      k = int(desctype.split("_")[1])
      desc_key = "framestep60_dense_siftnonorm_lpca64_gmm%d_sfv2" % k
      if dataset == "tv11": 
          return load_aggregated_descriptors("/home/clear/dataset/trecvid14/tv11/%s/SIFT/%s/block" % (collection, desc_key) , clipids)
      elif dataset == "tv14ps" or dataset == "tv14ah":  
          return load_aggregated_descriptors("/home/clear/dataset/trecvid14/eval/%s/SIFT/%s/block" % (collection, desc_key) , clipids)       
      else: 
          assert False

  
  desc_key = "framestep60_dense_siftnonorm_lpca64_gmm256_sfv2"

  if dataset == 'tv14dryrun': 
      datadir = "/home/clear/dataset/trecvid14/dryrun/%s/SIFT/%s" % (collection, desc_key)
  elif dataset == "tv14test": 
      datadir = "/home/clear/dataset/trecvid14/MED14-Test/%s/SIFT/%s" % (collection, desc_key)
  elif dataset == "tv11":
      datadir = "/home/clear/dataset/trecvid14/tv11/%s/SIFT/%s" % (collection, desc_key)
  else:
      assert False
  
  index = cache_descriptors_sift(datadir)


  if clipids == None:
      print "    reading %d descriptors" % len(index)
      cache_fname = index[0][1]
      
      return ynumpy.fvecs_read(cache_fname), [vidname for (vidname, fname, offset) in index]
  else:                                                                 
      cache_map = {vidname: (cache_fname, int(offset)) for vidname, cache_fname, offset in index}
      print "    picking %d / %d  descriptors from cache" % (len(clipids), len(cache_map))
      tocat = []
      cur_cache_fname = None  
      for clipid in clipids:
        print "      Loading", clipid, "\r",
        sys.stdout.flush()    
        (cache_fname, offset) = cache_map["HVC" + clipid]
        if cache_fname != cur_cache_fname:
          cache_file = open(cache_fname, "r")
          cur_cache_fname = cache_fname
        cache_file.seek(offset)
        desc = fvec_fread(cache_file)
        tocat.append(desc)
      return np.vstack(tocat), clipids
Exemple #6
0
def read_descs(infiles, fmt):
  """ read and concatenate matrices from a list of files"""
  vl = []

  for fname in infiles:
    print "reading", fname, "\r",
    sys.stdout.flush()
    
    if fmt == 'fvecs':
      v = ynumpy.fvecs_read(fname)
    elif fmt == 'siftgeo':
      v, meta = ynumpy.siftgeo_read(fname)
      v = v.astype(numpy.float32)
    else: assert False, "unknown format %s" % informat

    if v.shape[1] != 0: vl.append(v.T)

  return numpy.vstack(vl).T
Exemple #7
0
def read_descs(infiles, fmt):
    """ read and concatenate matrices from a list of files"""
    vl = []

    for fname in infiles:
        print "reading", fname, "\r",
        sys.stdout.flush()

        if fmt == 'fvecs':
            v = ynumpy.fvecs_read(fname)
        elif fmt == 'siftgeo':
            v, meta = ynumpy.siftgeo_read(fname)
            v = v.astype(numpy.float32)
        else:
            assert False, "unknown format %s" % informat

        if v.shape[1] != 0: vl.append(v.T)

    return numpy.vstack(vl).T
def main():
	infisherdir = ""
	infilename = ""
	outfilename = ""
	videolist = ""
	
	args=sys.argv[1:]
	while args:
		a=args.pop(0)
		if a in ('-h','--help'):
			usage()
			sys.exit(0)
		elif a=='--infisherdir':
			infisherdir = args.pop(0)
		elif a=='--infilename':
			infilename = args.pop(0)
		elif a=='--outfilename':
			outfilename = args.pop(0)
		elif a=='--videolist':
			videolist = args.pop(0)
		else:
			print "unknown option", a
			usage()
			sys.exit(1)

	if infisherdir == "" or infilename == "" or outfilename == "" or videolist == "":
		usage()
		print "err: missing options"
		sys.exit(1)

	lines = [line.strip() for line in open(videolist)]
	it = 1
	total = len(lines)
	a = []
	for i in lines:
		print i, it, "/", total
		a.append(ynumpy.fvecs_read(infisherdir + "/" + i + "/" + infilename)[0])
		it += 1
	
	x = np.vstack(a)
	ynumpy.fvecs_write(outfilename, x)
Exemple #9
0
def all_jochen(dimslice):
    if dimslice in all_jochen_cache:
        return all_jochen_cache[dimslice]

    data = []
    video_names = []
    for split2 in 'training', 'validation':
        datadir = (
            "/scratch/clear/douze/data_tv12/jochen_audio_descs/TV_MED_2011/" +
            split2)
        
        for eno in range(0, 16):
            ename = "E%03d" % eno if eno > 0 else "NULL"
            fname = datadir + "/fisher_vectors_%s.fvecs" % ename
            fname_txt = datadir + "/%s_%s.txt" % (split2, ename)
            print "load", fname
            descs = ynumpy.fvecs_read(fname)
            descs = descs[:, dimslice * 5055 : (dimslice + 1) * 5055]       
            ntxt = 0
            for l in open(fname_txt, "r"):
                vidname = l.split('/')[-1].split('.')[0]
                video_names.append(vidname)
                ntxt += 1
            if (split2, eno) != ('training', 0): 
                if ntxt != descs.shape[0]:
                    print "ntxt=%d shape=%d" % (ntxt, descs.shape[0])
                    video_names = video_names[:descs.shape[0] - ntxt]
            else:
                # train/fisher_vectors_NULL.fvecs just a link....
                descs = descs[:ntxt, :]
            data.append(descs)
    data = np.vstack(data)
            
    all_jochen_cache[dimslice] = video_names, data

    return video_names, data
Exemple #10
0
from yael import ynumpy, yael
from jsgd import *

# mini-problem: 10 fungus classes, 10 examples / class, 4096D descriptors
# basename = "../example_data/groupFungus_k64_nclass10_nex10"

# medium: all fungus classes, 50 examples / class, 4096D descriptors
basename = "../example_data/groupFungus_k64_nclass134_nex50"

# 50 imagenet classes, 50 images / class (+50 for testing), 128 k-dimensional descriptors
# basename = 'data/imagenet_cache/k1024_nclass50_nex50'

# load training data
Xtrain = ynumpy.fvecs_read(basename + '_Xtrain.fvecs')
Ltrain = ynumpy.ivecs_read(basename + '_Ltrain.ivecs')
# shift to get 0-based labels
Ltrain = Ltrain - 1

# load test data
Xtest = ynumpy.fvecs_read(basename + '_Xtest.fvecs')
Ltest = ynumpy.ivecs_read(basename + '_Ltest.ivecs')
Ltest = Ltest - 1

# random permutation of train
n = Xtrain.shape[0]

numpy.random.seed(0)
perm = numpy.random.permutation(n)

Xtrain = Xtrain[perm, :]
Ltrain = Ltrain[perm, :]
Exemple #11
0
def get_per_video_sift_data(split, desc_key = 'framestep60_dense_siftnonorm_lpca32_gmm256_w_mu_sigma',
                            dimensions = (255, 255 + 32 * 256), **kwargs):
    """
    The descriptor key is a directory name. The dimensions can be used to select mu/w/sigma
    """
    temporal_spm = kwargs.get('temporal_spm', None)
    if temporal_spm:
        suffix = '_T%dt%d' % temporal_spm
        nr_bags, bag_idx = temporal_spm
    else:
        suffix = ''
        nr_bags, bag_idx = 1, 0

    # cache
    filename = ("/home/lear/oneata/data/trecvid12/scripts/"
                "fusion/data/per_video_cache/SIFT_%s_%s%s.raw" %
                (desc_key, split, suffix))

    if os.path.exists(filename):
        # Load data from cache file.
        print "Load per video data", filename
        with open(filename, "r") as ff:
            video_data = np.load(ff)
            video_labels = np.load(ff)
            video_names = cPickle.load(ff)
        d0, d1 = dimensions
        return video_data[:, d0:d1], video_labels, video_names

    basedir = "/scratch2/clear/dataset/trecvid11/med//desc/frames/" + desc_key
    name_map = {
        fname[:9] : d0 + '/' + d1
        for d0 in ['training', 'validation']
        for d1 in ['NULL'] + ['E%03d' % no for no in range(1, 16)]
        for fname in os.listdir(basedir + '/' + d0 + '/' + d1)
        if fname.endswith('_0.fvecs')}      

    video_names = []
    video_labels = []
    video_data = []

    for l in open("data/%s.list" % split, "r"):
        l = l[:-1]
        vidname = l.split('-')[0]  
        classname = l.split(' ')[-1]
        video_names.append(vidname)
        video_labels.append(rev_label_map[classname])

        # Fisher descriptors of a video may be spread over several blocks
            
        block = 0
        fv = None
        while True:
            fname = "%s/%s/%s_%d.fvecs" % (basedir, name_map[vidname], vidname, block)
            if os.access(fname, os.R_OK):
                fvi = ynumpy.fvecs_read(fname)
                if fvi.shape[0] == 0:
                    pass
                elif fv == None:
                    fv = fvi
                else:
                    try:
                        fv = np.vstack((fv, fvi))
                    except ValueError:
                        pdb.set_trace()
            else:
                break
            block += 1 
        assert block > 0
        print vidname, "%d * %d" % fv.shape     

        fv = normalize_fisher(fv)

        # average of descriptors        
        nr_slices = fv.shape[0]
        bag_idx = np.minimum(bag_idx, nr_slices - 1)
        idxs = list(chunker(np.arange(nr_slices), nr_bags))[bag_idx]
        desc = fv[idxs].sum(axis = 0) / fv[idxs].shape[0]
        video_data.append(desc)
    
    video_data = np.vstack(video_data)
    video_labels = np.array(video_labels)
    
    with open(filename, "w") as ff:
        np.save(ff, video_data)
        np.save(ff, video_labels)
        cPickle.dump(video_names, ff)
    d0, d1 = dimensions
    return video_data[:, d0:d1], video_labels, video_names
Exemple #12
0

    print "best params found: score %.3f" % (best_score * 100)
    for params, epoch in best_op: 
      print params, epoch

    return [(params, epoch) for params, epoch in best_op]
    

if __name__ == '__main__': 
  # where to load the data from 
  basename = "../example_data/groupFungus_k64_nclass134_nex50"
   
  print "Loading train data %s" % basename

  Xtrain = ynumpy.fvecs_read(basename + '_Xtrain.fvecs')
  Ltrain = ynumpy.ivecs_read(basename + '_Ltrain.ivecs')
  
  # correct Matlab indices
  Ltrain = Ltrain - 1
  
  n, d = Xtrain.shape
  nclass = max(Ltrain) + 1

  print "train size %d vectors in %dD, %d classes " % (n, d, nclass)
  
  # random permutation of data
  
  numpy.random.seed(0)
  perm = numpy.random.permutation(n)
  
                fname = d1 + f[:-4] + '.fvecs'
                for i, l in enumerate(open(fname_txt, "r")):
                    vidname = l[-15:-6]
                    video_to_file[vidname] = (fname, i)
            
        jochen_index[channel] = video_to_file

        print "  indexed %d videos for Jochen's audio channel %s" % (len(video_to_file), channel)

        return video_to_file

def get_jochen_vector(jochen_cache, (fname, i)):

    if fname not in jochen_cache:
        print "   loading", fname
        descs = ynumpy.fvecs_read(fname)
        if '1024_SNS_NULL' in fname and descs.shape[1] != 80894:
            print "   has weird size %s, transposing" % (descs.shape,)
            descs = descs.T.copy()
        jochen_cache[fname] = descs

    return jochen_cache[fname][i]
            

def get_audio_data_jochen(split, channel, ssl = None):
    " read Jochen's audio descriptors"

    video_to_file = init_jochen_index(channel)
    video_names = []
    labels = []
    data = []
  from yael import ynumpy, yael

  print "loading..."

  # basename = 'data/fuv_cache/cache_groupFungus_k64_nclass132_nex50'
  # basename = 'data/BOW_florent/vehicle262_train_50ex'
  # basename = 'data/BOW_florent/vehicle262_train_50ex'
  # basename = 'data/BOW_florent/ungulate183_train_50ex'
  # basename = 'data/fuv_cache/cache_groupFungus_k64_nclass134_nex10000'
  # basename = 'data/fuv_cache/cache_groupFungus_k64_nclass132_nex50'
  # basename = 'data/fuv_cache/cache_groupFungus_k256_nclass134_nex10000'
  # basename = 'data/fuv_cache/cache_groupFungus_k256_nclass134_nex10000'
  # basename = 'data/fuv_cache/cache_groupVehicle_k256_nclass262_nex50'
  basename = 'data/imagenet_cache/k1024_nclass50_nex50'
  
  Xtrain = ynumpy.fvecs_read(basename + '_Xtrain.fvecs')
  Ltrain = ynumpy.ivecs_read(basename + '_Ltrain.ivecs')

  Ltrain = Ltrain - 1

  
  # basename = "data/BOW_florent/vehicle262_train_first50"
  # basename = "data/BOW_florent/ungulate183_train"
  
  Xvalid = ynumpy.fvecs_read(basename + '_Xtest.fvecs')
  Lvalid = ynumpy.ivecs_read(basename + '_Ltest.ivecs')
  Lvalid = Lvalid - 1

  # Xvalid = Xvalid[:10,:]
  # Lvalid = Lvalid[:10,:]
def load_descs_fvecs(filename):
    content = ynumpy.fvecs_read(filename)
    return content.tolist()[0]
def load_aggregated_descriptors(prefix, clipids = None):
    prefix = local_prefix(prefix)
    # print prefix
    indexname = prefix + "_000.index"
    
    if os.access(indexname, os.R_OK): # try multipart index first
        index = []
        for i in range(1000):
            indexname = prefix + "_%03d.index" % i 
            if not os.access(indexname, os.R_OK): break
            dataname = prefix + "_%03d.fvecs" % i
            idx = [l.split() for l in open(indexname, "r")]
            index += [(vidname, dataname, int(offset)) for vidname, offset in idx]
    else:
        indexname = prefix + ".index"
        dataname = prefix + ".fvecs"
        idx = [l.split() for l in open(indexname, "r")]
        index = [(vidname, dataname, int(offset)) for vidname, offset in idx]

    if clipids == "nodata":
        print "    just loading index of %d videos" % len(index)
        vidnames = []
        for vidname, fname, offset in index:
            vidnames.append(vidname)
        return None, vidnames
    elif clipids == None:
        print "    reading %d descriptors" % len(index)
        vidnames = []
        fname_prev = None
        tocat = []
        for vidname, fname, offset in index:
            vidnames.append(vidname)
            if fname != fname_prev:
                print "      loading", fname
                descs = ynumpy.fvecs_read(fname)
                tocat.append(descs)
                fname_prev = fname
        alldescs = np.vstack(tocat)
        assert alldescs.shape[0] == len(index)
        return alldescs, vidnames
    else:                                                                 
        cache_map = {vidname: (cache_fname, int(offset)) for vidname, cache_fname, offset in index}
        print "    picking %d / %d  descriptors from cache" % (len(clipids), len(cache_map))
        tocat = []
        cur_cache_fname = None  
        for clipid in clipids:
            # print "      Loading", clipid, "\r",
            sys.stdout.flush()
            (cache_fname, offset) = cache_map[clipid]
            if cache_fname != cur_cache_fname:
                cache_file = open(cache_fname, "r")
                cur_cache_fname = cache_fname
            cache_file.seek(offset)
            desc = fvec_fread(cache_file)
            tocat.append(desc)
            """if not all([d.shape[0] == tocat[0].shape[0] for d in tocat]):
                print [d.shape[0] == tocat[0].shape[0] for d in tocat].index(False)
                print [d.shape for d in tocat]
                print tocat[[d.shape[0] == tocat[0].shape[0] for d in tocat].index(False)].shape
                print cache_fname"""
        
        return np.vstack(tocat), clipids
def load_selection_train(event_class, selection, normalizers_in = None, power = 0.5, kernel_cache_path = None, just_kernel_matrix = False, needs_sorting = True):

    Kxx = []
    tr_data = []

    nchannel = 0
    normalizers = {}

    for cname in selection:
        
        print "  (%d/%d) - %s" % ( nchannel + 1, len(selection), time.ctime() )

        kernel_cache_fname = None
        Kxx_i = None
        
        if kernel_cache_path != None:        
            kernel_cache_fname = kernel_cache_path + cname + ".fvecs"
            if os.access(kernel_cache_fname, os.R_OK): 
                print "Load precomputed kernel from", kernel_cache_fname
                Kxx_i = ynumpy.fvecs_read(kernel_cache_fname)        

        no_train_matrix = just_kernel_matrix and Kxx_i != None
        
        tr_data_i, tr_labels_i, tr_vidnames_i = video_descriptors_tv14.get_train_descriptors(
            event_class, cname, no_train_matrix = no_train_matrix)
        if tr_vidnames_i != list(sorted(tr_vidnames_i)) and needs_sorting:
            print "sorting vidnames..."
            sv = [(vidname, i) for i, vidname in enumerate(tr_vidnames_i)]
            sv.sort()
            tr_vidnames_i = [vidname for vidname, i in sv]
            perm = np.array([i for vidname, i in sv])
            tr_labels_i = tr_labels_i[perm]
            if tr_data_i != None: 
                tr_data_i = tr_data_i[perm,:]
        
        if tr_data_i == None: 
            pass
        elif type(tr_data_i) == dense_type: #dense matrix
            #print "Using dense matrix"
            if not no_train_matrix: 

                nandescs = np.nonzero(np.any(np.logical_not(is_good(tr_data_i)), axis = 1))[0]
                if nandescs.size > 0:
                    print "WARN %d/%d nan descriptors. Replacing with 0." % (nandescs.size, tr_data_i.shape[0])
                    tr_data_i[nandescs, :] = 0

                    print "data range: [%g, %g]"%(tr_data_i.min(), tr_data_i.max())
                    
                if not normalizers_in:        
                    #print "normalizing (computing normalizers)"
                    # normalizers computed only on background videos

                    background_vids = (tr_labels_i <= 0)
                    print "normalizing from %d videos, power norm %g" % (background_vids.sum(), power)
                    nvid = background_vids.size
                    nbg = background_vids.sum()
                    if np.all(background_vids[-nbg:]):
                        background_vids = slice(nvid - nbg, nvid)
                    mu, sigma = data_normalize_inplace(tr_data_i, power = power, compute_norm_subset = background_vids)          

                    # tr_data_i, mu, sigma = data_normalize(tr_data_i, power=power, compute_norm_subset = background_vids)

                    normalizers[cname] = (mu, sigma)
                else:
                    print "normalizing (provided mu, sigma)"
                    (mu, sigma) = normalizers_in[cname] 

                    tr_data_i, _, _ = standardize(tr_data_i, mu, sigma)
                    tr_data_i = power_normalize(tr_data_i, power)
                    tr_data_i = L2_normalize(tr_data_i)
                    tr_data_i = tr_data_i.astype(np.float32)


                assert np.all(np.isfinite(tr_data_i))

                print "compute kernels train %d*%d" % tr_data_i.shape
            
                
                if Kxx_i == None or check_kernel(tr_data_i, Kxx_i) == False:     
                    Kxx_i = np.dot(tr_data_i, tr_data_i.T)
                    if kernel_cache_fname and tr_data_i.shape[1] > tr_data_i.shape[0]:
                        print "storing kernel cache to", kernel_cache_fname
                        ynumpy.fvecs_write(kernel_cache_fname, Kxx_i)
        else: #sparse matrix (for ocr and such)
            row_norms = np.sqrt(np.array(tr_data_i.multiply(tr_data_i).sum(axis=1))[:,0])
            row_indices, col_indices = tr_data_i.nonzero()
            tr_data_i.data /= row_norms[row_indices]

            Kxx_i = tr_data_i.dot(tr_data_i.T).toarray().astype(np.float32)
            if kernel_cache_fname and tr_data_i.shape[1] > tr_data_i.shape[0]:
                print "storing kernel cache to", kernel_cache_fname
                ynumpy.fvecs_write(kernel_cache_fname, Kxx_i)
                

        Kxx.append(Kxx_i)

        tr_data.append(tr_data_i)
        
        if nchannel == 0:
            tr_labels, tr_vidnames = tr_labels_i, tr_vidnames_i
        else:
            assert np.all(tr_labels == tr_labels_i)
            assert tr_vidnames_i == tr_vidnames

        nchannel += 1

        sys.stdout.flush()

    if not normalizers_in: 
            return Kxx, tr_data, tr_vidnames, tr_labels, normalizers
    else:
            return Kxx, tr_data, tr_vidnames, tr_labels, None
def main():

    infisher = ""
    output_directory = ""
    
    eventList = []
    videoList = []
    

    # parse arguments
    args=sys.argv[1:]
    while args:
        a=args.pop(0)
        if a in ('-h','--help'):
            usage()
            sys.exit(0)
        elif a in ('--videos','-v'):
            f = open(args.pop(0))
            for vid in f.read().splitlines():
                videoList.append(vid)
            f.close()
        elif a in ('--events','-e'):
            f = open(args.pop(0))
            for ev in f.read().splitlines():
                eventList.append(ev)
            f.close()
        elif a in ('--infisher','-i'):   infisher = args.pop(0)
        elif a in ('--output-directory','-o'):    output_directory = args.pop(0)
        else:
            print "unknown option", a
            usage()
    """
    if vidname == "" or collection == "" or infisher == "" or output_directory == "":
        print "ERROR - missing options"
        usage()
        sys.exit(1)
    """
    """
    if not os.path.isdir(infisher) or not os.path.isdir(output_directory):
        print "ERROR - specified path not a directory - Exiting..."
        sys.exit(1)
    """
    
    if len(eventList) < 1:
        print "ERROR: need at least one event."
        sys.exit(1)
    elif len(videoList) < 1:
        print "ERROR: need at least one video."
        sys.exit(1)
    elif output_directory == "":
        print "ERROR: need to specify an output directory for the score files"
        sys.exit(1)
    
    # Setup
    # -------
    
    events = {} # eventName -> Event
    unionRequiredDescs = []

    # for all events, load classifier + normalizer, compile list of required descriptors
    for eventName in eventList:
        print "Loading classifier and normalizer for", eventName
        eventObj = Event(eventName)
        eventNameShort = eventName.split('/')[-1:][0]
        eventObj.classifier = pickle.load(open(MED_DIR + "../events/" + eventName + "/classifiers/" + eventNameShort + "_classifier.pickle"))
        eventObj.normalizer = pickle.load(open(MED_DIR + "../events/" + eventName + "/classifiers/" + eventNameShort + "_classifier_normalizer.pickle"))
        
        # append the required descs for this event
        channelList = open(MED_DIR + "../events/" + eventName + "/workdir/channels.list")
        for c in channelList.read().splitlines():
            
            listDesc = open(MED_DIR + "compute_descriptors/" + c + "/" + c + "_descriptors.list")
            for desc in listDesc.read().splitlines():
                
                eventObj.descriptors.append(desc)
                if desc not in unionRequiredDescs:
                    print "Appending", desc, "to the list of required descriptors."
                    unionRequiredDescs.append(desc)
                    
        events[eventName] = eventObj
    # {unionRequiredDescs == union of required descs for all events}
    
    # Process videos
    # --------------
    
    curVid = 0
    for vid in videoList:
        curVid += 1
        print "(%d/%d) Computing scores" % (curVid, len(videoList)), vid
        
        # Find location of descriptors
        descriptorsLocation = ""
        oneFilePerShot = False
        
        # TODO: properly test one-file-per-shot
        if os.path.exists(MED_DIR + "videos_workdir/" + vid + "/shots/%09d/" % (1) + unionRequiredDescs[0] + ".fvecs"):
            oneFilePerShot = True
            descriptorsLocation = MED_DIR + "videos_workdir/" + vid + "/shots/"
        elif os.path.exists(MED_DIR + "videos_workdir/" + vid + "/shots/" + unionRequiredDescs[0] + ".fvecs"):
            descriptorsLocation = MED_DIR + "videos_workdir/" + vid + "/shots/"
        elif os.path.exists(MED_DIR + "videos_workdir/" + vid + "/" + unionRequiredDescs[0] + ".fvecs"):
            descriptorsLocation = MED_DIR + "videos_workdir/" + vid + "/"
        else:
            print "Error: couldn't find descriptors for " + vid + "."
            pdb.set_trace()
            continue
            
        # Load all required channels
        vidDescs = {}
        if oneFilePerShot:
            
            for desc in unionRequiredDescs:
                vidDescs[desc] = []
            shotNb = 1
            while os.path.exists(descriptorsLocation + "%09d/" % shotNb + unionRequiredDescs[0] + ".fvecs"):
                for desc in unionRequiredDescs:
                    vidDescs[desc].append(ynumpy.fvecs_read(descriptorsLocation + "%09d/" % shotNb + desc + ".fvecs"))
                shotNb += 1
                    
        else:
            for desc in unionRequiredDescs:
                vidDescs[desc] = ynumpy.fvecs_read(descriptorsLocation + desc + ".fvecs")
        
        
        # For every event:
        for eventName in eventList:
            
            event = events[eventName]
            
            # Normalize fisher vectors
            normalizedVidDescs = {}            
            for desc in event.descriptors:
                mu = event.normalizer[desc][0]
                sigma = event.normalizer[desc][1]
                
                normalizedVidDescs[desc] = vd_utils.standardize(vidDescs[desc], mu, sigma)
                normalizedVidDescs[desc] = vd_utils.normalize_fisher(normalizedVidDescs[desc])
                normalizedVidDescs[desc] = normalizedVidDescs[desc].astype(np.float32)
            
            # Retrieve classifier data
            weights, bias = event.classifier[:2]
            
            # Compute score for every shot
            for shotNb in range(len(normalizedVidDescs[event.descriptors[0]])):
                
                score = 0.0
                # Accumulate scores for all descriptor channels
                for descNb in range(len(event.descriptors)):
                    score += np.dot(weights[descNb], normalizedVidDescs[event.descriptors[descNb]][shotNb])
                
                event.scores.append([score, shotNb+1, vid])
    # {processed all videos}            
    
    # save results
    for eventName in events:
        event = events[eventName]
        print "Saving scores for", event.name
        
        scorePath = output_directory + "/" + event.name
        scorePath = scorePath.split('/')[:-1]
        scorePath = '/'.join(scorePath)
        try: 
            os.makedirs(scorePath)
        except OSError:
            if not os.path.isdir(scorePath):
                raise
                
        f = open(output_directory + "/" + event.name + ".scores", 'w')
        for s in sorted(event.scores, reverse=True):
            print s
            f.write("%f %d %s\n" % (s[0], s[1], s[2]))
        f.close()

    return 0
def load_oxford_2013():
    """
    Found this data in README of SMK publication
    https://hal.inria.fr/hal-00864684/document
    http://people.rennes.inria.fr/Herve.Jegou/publications.html
    with download script

    CommandLine:
        # Download oxford13 data
        cd ~/work/Oxford
        mkdir -p smk_data_iccv_2013
        cd smk_data_iccv_2013
        wget -nH --cut-dirs=4 -r -Pdata/ ftp://ftp.irisa.fr/local/texmex/corpus/iccv2013/

    This dataset has 5063 images wheras 07 has 5062
    This dataset seems to contain an extra junk image:
        ashmolean_000214

    # Remember that matlab is 1 indexed!
    # DONT FORGET TO CONVERT TO 0 INDEXING!
    """
    from yael.ynumpy import fvecs_read
    from yael.yutils import load_ext
    import scipy.io
    import vtool as vt
    from os.path import join

    dbdir = ut.truepath('/raid/work/Oxford/')
    datadir = dbdir + '/smk_data_iccv_2013/data/'

    # we are not retraining, so this is unused
    # # Training data descriptors for Paris6k dataset
    # train_sift_fname = join(datadir, 'paris_sift.uint8')  # NOQA
    # # File storing visual words of Paris6k descriptors used in our ICCV paper
    # train_vw_fname = join(datadir, 'clust_preprocessed/oxford_train_vw.int32')

    # Pre-learned quantizer used in ICCV paper (used if docluster=false)
    codebook_fname = join(datadir, 'clust_preprocessed/oxford_codebook.fvecs')

    # Files storing descriptors/geometry for Oxford5k dataset
    test_sift_fname = join(datadir, 'oxford_sift.uint8')
    test_geom_fname = join(datadir, 'oxford_geom_sift.float')
    test_nf_fname = join(datadir, 'oxford_nsift.uint32')

    # File storing visual words of Oxford5k descriptors used in our ICCV paper
    test_vw_fname = join(datadir, 'clust_preprocessed/oxford_vw.int32')
    # Ground-truth for Oxford dataset
    gnd_fname = join(datadir, 'gnd_oxford.mat')

    oxford_vecs = load_ext(test_sift_fname, ndims=128, verbose=True)
    oxford_nfeats = load_ext(test_nf_fname, verbose=True)
    oxford_words = fvecs_read(codebook_fname)
    oxford_wids = load_ext(test_vw_fname, verbose=True) - 1

    test_geom_invV_fname = test_geom_fname + '.invV.pkl'
    try:
        all_kpts = ut.load_data(test_geom_invV_fname)
        logger.info('loaded invV keypoints')
    except IOError:
        oxford_kptsZ = load_ext(test_geom_fname, ndims=5, verbose=True)
        logger.info('converting to invV keypoints')
        all_kpts = vt.convert_kptsZ_to_kpts(oxford_kptsZ)
        ut.save_data(test_geom_invV_fname, all_kpts)

    gnd_ox = scipy.io.loadmat(gnd_fname)
    imlist = [x[0][0] for x in gnd_ox['imlist']]
    qx_to_dx = gnd_ox['qidx'] - 1

    data_uri_order = imlist
    query_uri_order = ut.take(data_uri_order, qx_to_dx)

    offset_list = np.hstack(([0], oxford_nfeats.cumsum())).astype(np.int64)

    # query_gnd = gnd_ox['gnd'][0][0]
    # bboxes = query_gnd[0]
    # qx_to_ok_gtidxs1 = [x[0] for x in query_gnd[1][0]]
    # qx_to_junk_gtidxs2 = [x[0] for x in query_gnd[2][0]]
    # # ut.depth_profile(qx_to_gtidxs1)
    # # ut.depth_profile(qx_to_gtidxs2)

    assert sum(oxford_nfeats) == len(oxford_vecs)
    assert offset_list[-1] == len(oxford_vecs)
    assert len(oxford_wids) == len(oxford_vecs)
    assert oxford_wids.max() == len(oxford_words) - 1

    data = {
        'offset_list': offset_list,
        'all_kpts': all_kpts,
        'all_vecs': oxford_vecs,
        'words': oxford_words,
        'idx_to_wx': oxford_wids,
        'data_uri_order': data_uri_order,
        'query_uri_order': query_uri_order,
    }
    return data
def computeScoresSingleVideo(vid):
    # Load video descriptors
    print "Computing scores for %s" % vid
    
    # Find location of descriptors
    descriptorsLocation = ""
    oneFilePerShot = False
    
    # TODO: properly test one-file-per-shot
    if os.path.exists(COLLECTION_DIR + "/processing/videos_workdir/" + vid + "/shots/%09d/" % (1) + unionRequiredDescs[0] + ".fvecs"):
        oneFilePerShot = True
        descriptorsLocation = COLLECTION_DIR + "/processing/videos_workdir/" + vid + "/shots/"
    elif os.path.exists(COLLECTION_DIR + "/processing/videos_workdir/" + vid + "/shots/" + unionRequiredDescs[0] + ".fvecs"):
        descriptorsLocation = COLLECTION_DIR + "/processing/videos_workdir/" + vid + "/shots/"
    elif os.path.exists(COLLECTION_DIR + "/processing/videos_workdir/" + vid + "/" + unionRequiredDescs[0] + ".fvecs"):
        descriptorsLocation = COLLECTION_DIR + "/processing/videos_workdir/" + vid + "/"
    else:
        print "Error: couldn't find descriptors for " + vid + "."
        return 1
        
    # Load all required channels
    vidDescs = {}
    if oneFilePerShot:
        
        for desc in unionRequiredDescs:
            vidDescs[desc] = []
        shotNb = 1
        while os.path.exists(descriptorsLocation + "%09d/" % shotNb + unionRequiredDescs[0] + ".fvecs"):
            for desc in unionRequiredDescs:
                vidDescs[desc].append(ynumpy.fvecs_read(descriptorsLocation + "%09d/" % shotNb + desc + ".fvecs"))
            shotNb += 1
                
    else:
        for desc in unionRequiredDescs:
            vidDescs[desc] = ynumpy.fvecs_read(descriptorsLocation + desc + ".fvecs")
    
    # Compute
    # For every event:
    eventScores = {}
    for eventName in eventList:
        
        event = events[eventName]
        eventScores[eventName] = []
        
        # Normalize fisher vectors
        normalizedVidDescs = {}            
        for desc in event.descriptors:
            mu = event.normalizer[desc][0]
            sigma = event.normalizer[desc][1]
            
            normalizedVidDescs[desc] = vd_utils.standardize(vidDescs[desc], mu, sigma)
            normalizedVidDescs[desc] = vd_utils.normalize_fisher(normalizedVidDescs[desc])
            normalizedVidDescs[desc] = normalizedVidDescs[desc].astype(np.float32)
        
        # Retrieve classifier data
        weights, bias = event.classifier[:2]
        
        # Compute score for every shot
        for shotNb in range(len(normalizedVidDescs[event.descriptors[0]])):
            
            score = 0.0
            # Accumulate scores for all descriptor channels
            for descNb in range(len(event.descriptors)):
                score += np.dot(weights[descNb], normalizedVidDescs[event.descriptors[descNb]][shotNb])
            
            eventScores[eventName].append([score, shotNb+1, vid])
            
    # Lock score files
    subprocess.call('lockfile -0 /tmp/compute_scores_%s.lock' % processUUID, shell=True)
    #while (subprocess.call('set -o noclobber; echo locked > /tmp/compute_scores_%s.lock' % processUUID, shell=True)
    
    # Output scores
    # FOR EVERY EVENT    
    for eventName in events:
        event = events[eventName]
                
        f = open(output_directory + "/" + event.name + ".scores", 'a')
        #for s in sorted(event.scores, reverse=True):
        for s in eventScores[eventName]:
            #print s
            f.write("%f %d %s\n" % (s[0], s[1], s[2]))
        f.close()
    
    # Unlock score files
    subprocess.call('rm -f /tmp/compute_scores_%s.lock' % processUUID, shell=True)
    return 0