Пример #1
0
    def _new_adb(self):
        """
        ::

            Make a new audioDB instance in the adb_path location
            Make database L2norm and Power compliant
        """
        self.adb_path = self._gen_adb_path()
        if self.adb_path == None:
            print("self.adb_path must have a string value")
            raise error.BregmanError()
        else:
            f = None
            try:
                f = open(self.adb_path, "rb")
            except:
                print("Making new audioDB database: ", self.adb_path)
            finally:
                if f:
                    f.close()
                    print("AudioDB database already exists: ", self.adb_path)
                    return 0

        # create a NEW audiodb database instance
        command = [
            "audioDB", "--NEW", "-d", self.adb_path, "--datasize",
            "%d" % self.adb_data_size, "--ntracks",
            "%d" % self.adb_ntracks
        ]
        self._do_subprocess(command)

        # make L2NORM compliant
        command = ["audioDB", "--L2NORM", "-d", self.adb_path]
        self._do_subprocess(command)

        # make POWER compliant
        command = ["audioDB", "--POWER", "-d", self.adb_path]
        self._do_subprocess(command)
        return 1
Пример #2
0
    def rank_by_distance_bhatt(self, qkeys, ikeys, rkeys, dists):
        """
        ::

            Reduce timbre-channel distances to ranks list by ground-truth key indices
            Bhattacharyya distance on timbre-channel probabilities and Kullback distances
        """
        # timbre-channel search using pre-computed distances
        ranks_list = []
        t_keys, t_lens = self.get_adb_lists(0)
        rdists = pylab.ones(len(t_keys)) * float('inf')
        qk = self._get_probs_tc(qkeys)
        for i in range(len(ikeys[0])):  # number of include keys
            ikey = []
            dk = pylab.zeros(self.timbre_channels)
            for t_chan in range(self.timbre_channels):  # timbre channels
                ikey.append(ikeys[t_chan][i])
                try:
                    # find dist of key i for query
                    i_idx = rkeys[t_chan].index(
                        ikey[t_chan])  # dataset include-key match
                    # the reduced distance function in include_keys order
                    # distance is Bhattacharyya distance on probs and dists
                    dk[t_chan] = dists[t_chan][i_idx]
                except:
                    print "Key not found in result list: ", ikey, "for query:", qkeys[
                        t_chan]
                    raise error.BregmanError()
            rk = self._get_probs_tc(ikey)
            a_idx = t_keys.index(ikey[0])  # audiodb include-key index
            rdists[a_idx] = distance.bhatt(pylab.sqrt(pylab.absolute(dk)),
                                           pylab.sqrt(pylab.absolute(qk * rk)))
        #search for the index of the relevant keys
        rdists = pylab.absolute(rdists)
        sort_idx = pylab.argsort(rdists)  # Sort fields into database order
        for r in self.ground_truth:  # relevant keys
            ranks_list.append(
                pylab.where(sort_idx == r)[0][0])  # Rank of the relevant key
        return ranks_list, rdists
Пример #3
0
    def _get_extract_lists(self, key=None, keyrepl=None, wave_suffix=".wav"):
        """
        ::

            Map from self.audio_collection to aList, fList, pList, kList
        """
        # The audio queue
        aList = list(self.audio_collection)
        aList.sort()
        # The keys that will identify managed items
        if key == None:
            kList = aList # use the audio file names as keys
        else:
            # replace keyrepl with key as database key
            if not keyrepl: 
                print "key requires keyrepl for filename substitution"
                raise error.BregmanError()
            kList = [a.replace(keyrepl,key) for a in aList]
        feature_suffix= self._get_feature_suffix()
        power_suffix=self.feature_params['power_ext']
        fList = [k.replace(wave_suffix, feature_suffix) for k in kList]
        pList = [k.replace(wave_suffix, power_suffix) for k in kList]
        return (aList, fList, pList, kList)
Пример #4
0
    def rank_by_distance_avg(self, qkeys, ikeys, rkeys, dists):
        """
        ::

            Reduce timbre-channel distances to ranks list by ground-truth key indices
            Kullback distances
        """
        # timbre-channel search using pre-computed distances
        ranks_list = []
        t_keys, t_lens = self.get_adb_lists(0)
        rdists = pylab.ones(len(t_keys)) * float('inf')
        for t_chan in range(self.timbre_channels):  # timbre channels
            t_keys, t_lens = self.get_adb_lists(t_chan)
            for i, ikey in enumerate(ikeys[t_chan]):  # include keys, results
                try:
                    # find dist of key i for query
                    i_idx = rkeys[t_chan].index(
                        ikey)  # lower_bounded include-key index
                    a_idx = t_keys.index(ikey)  # audiodb include-key index
                    # the reduced distance function in include_keys order
                    # distance is the sum for now
                    if t_chan:
                        rdists[a_idx] += dists[t_chan][i_idx]
                    else:
                        rdists[a_idx] = dists[t_chan][i_idx]
                except:
                    print "Key not found in result list: ", ikey, "for query:", qkeys[
                        t_chan]
                    raise error.BregmanError()
        #search for the index of the relevant keys
        rdists = pylab.absolute(rdists)
        sort_idx = pylab.argsort(rdists)  # Sort fields into database order
        for r in self.ground_truth:  # relevant keys
            ranks_list.append(
                pylab.where(sort_idx == r)[0][0])  # Rank of the relevant key
        return ranks_list, rdists
 def _extract_error(self):
     error.BregmanError("unrecognized feature in Features.extract()")
Пример #6
0
    def evaluate(self,
                 seq_length=None,
                 query_duration=None,
                 tempo=1.0,
                 gt_only=True,
                 ground_truth=None,
                 res_name=None):
        """
        ::

            Evaluate ranks and distances for each ground-truth pattern for retrieval of other GT patterns.
            Overridden method from Evaluator for timbre channels
             Map distances and weights for each query in each channel
             Reduce using Bhattacharyya distance metric and base-line averaging metric.

             Sets self.ranks_list, self.dists_list
             Display ranked results as in print_results()

            Returns a tuple (ranks,dists)
            Each element of the tuple contains len(test_set_list) lists, 
             each list contains ground-truth ranks, and whole-dataset distances, of each test-set 
             in the test_set_list
        """
        if ground_truth is None:
            ground_truth = self.ground_truth
        if not tempo: tempo = 1.0
        self.seq_length = self.set_seq_length(seq_length, query_duration)
        self.avg_ranks = []
        self.bhatt_ranks = []
        self.avg_dists = []
        self.bhatt_dists = []
        qkeys, qlens = zip(*self.adb.liszt())
        for gt_item in ground_truth:
            t_qkeys = []
            t_ikeys = []
            t_rkeys = []
            t_dists = []
            print "Evaluating gt_item: ", gt_item
            for t_chan in range(self.timbre_channels):
                print "\tc ", t_chan
                qkey = qkeys[t_chan::self.timbre_channels][
                    gt_item]  # gt query timbre-channel key
                qlen = qlens[t_chan::self.timbre_channels][
                    gt_item]  # gt query timbre-channel len
                t_qkeys.append(qkey)
                self.initialize_search(t_chan, min(
                    [self.seq_length,
                     qlen]), tempo)  # setup per-timbre-channel include list
                t_ikeys.append(self.adb.configQuery['includeKeys']
                               )  # timbre-channel search keys
                res = self.adb.query(
                    key=qkey).rawData  # get the search results
                if len(res):
                    rkeys, dst, qpos, rpos = zip(*res)
                    t_rkeys.append(
                        rkeys)  # timbre-channel distance-sorted keys
                    t_dists.append(dst)  # All result distances
                else:
                    print "Empty result list: ", qkey
                    raise error.BregmanError()
            avg_ranks, avg_dists = self.rank_by_distance_avg(
                t_qkeys, t_ikeys, t_rkeys, t_dists)
            bhatt_ranks, bhatt_dists = self.rank_by_distance_bhatt(
                t_qkeys, t_ikeys, t_rkeys, t_dists)
            self.avg_ranks.append(avg_ranks)
            self.avg_dists.append(avg_dists)
            self.bhatt_ranks.append(bhatt_ranks)
            self.bhatt_dists.append(bhatt_dists)
            if res_name is None:
                res_name = tempfile.mktemp(suffix=".dat",
                                           prefix="results_",
                                           dir=".")
            f = open(res_name, "w")
            pickle.dump((self.avg_ranks, self.avg_dists, self.bhatt_ranks,
                         self.bhatt_dists), f)
            f.close()
        return True