def next(self, input, result, prev_notes):
        prob_model= ProbModel(self.ec.narmour_features_prob, input.notes_distr, use_narmour=True)
        if self.ec.first_notes is None:
            self.ec.first_notes= self._pick_first_notes(prob_model, input.min_pitch, input.max_pitch)
        
        if len(prev_notes) == 0:
            result.pitch= self.ec.first_notes[0]
        elif len(prev_notes) == 1:
            result.pitch= self.ec.first_notes[1]
        else:
            n1, n2= prev_notes[-2], prev_notes[-1]
            d= {}
            for n3 in xrange(input.min_pitch, input.max_pitch + 1):
                d[n3]= prob_model.get_prob(n1, n2, n3)
            #import ipdb;ipdb.set_trace()

            #with open('distr', 'a') as f:
            #    f.write('*'*15 + '\n')
            #    s= sum(d.values())
            #    for k, v in sorted(d.items(), key=lambda x:x[1]):
            #        f.write('%s\t\t%.02f\n' % (k, v/s))

            #import pylab
            #dir= "distrs/wo_nar_w_ch"
            #if not os.path.exists(dir): os.mkdir(dir)
            #s= sum(d.values())
            #x, y= zip(*d.items())
            #y= [v/s for v in y]
            #pylab.plot(x,y)
            #pylab.savefig(os.path.join(dir, "%s.png" % self.n))
            #pylab.close()
            #self.n+=1

            n3= RandomPicker(values=d, random=self.random).get_value(normalize=True)
            result.pitch= n3
    def generate_list(self, input, result, prev_notes):
        self.ec.input= input
        #XXX
        #print "GUARDA!!! use_harmony=False"
        now_prob_model= ProbModel(self.ec.narmour_features_prob, input.notes_distr, use_harmony=True)
        prox_prob_model= ProbModel(self.ec.narmour_features_prob, input.prox_notes_distr, use_harmony=True)
        # XXX

        remaining_notes= input.rythm_phrase_len - (self.ec.last_support_note is not None)
        t= TimeMeasurer()
        #if input.now == 2048: import ipdb;ipdb.set_trace()
        print "rythm_phrase_len =", input.rythm_phrase_len
        if self.ec.last_support_note is not None and input.rythm_phrase_len > 1:
            context= (prev_notes[-1].pitch, self.ec.last_support_note)
            end_pitch_candidates= possible_support_notes(now_prob_model, prox_prob_model, 
                                                         input.min_pitch, input.max_pitch, 
                                                         self.params['support_note_percent'], self.params['middle_note_percent'], 
                                                         input.rythm_phrase_len, # la proxima nota de apoyo, esta una nota despues
                                                         context= context, now_chord= input.now_chord, prox_chord=input.prox_chord)
                                                                     
            t.measure('possible_support_notes')
            #if input.rythm_phrase_len == 2: import ipdb;ipdb.set_trace()
        else:
            end_pitch_candidates= set(range(input.min_pitch, input.max_pitch+1))

        support_note_percent= self.params['support_note_percent']
        try:
            end_pitch= self.pick_support_note(input.prox_chord, end_pitch_candidates) 
        except:
            end_pitch_candidates= possible_support_notes(now_prob_model, prox_prob_model, 
                                                         input.min_pitch, input.max_pitch, 
                                                         self.params['alternate_support_note_percent'], self.params['middle_note_percent'], 
                                                         input.rythm_phrase_len, # la proxima nota de apoyo, esta una nota despues
                                                         context= context, now_chord= input.now_chord, prox_chord=input.prox_chord)
            support_note_percent= self.params['alternate_support_note_percent']
            t.measure('ERROR possible_support_notes(alternate_support_note_percent)')
            end_pitch= self.pick_support_note(input.prox_chord, end_pitch_candidates) 
        #for k, v in sorted(input.prox_pitches_distr, key=lambda x:x[1]):
        #    print k, v
        #print Note(end_pitch)

        must= build_must_dict(now_prob_model, prox_prob_model, end_pitch, 
                              input.min_pitch, input.max_pitch, 
                              support_note_percent, self.params['middle_note_percent'], 
                              remaining_notes)
        t.measure('must')


        def pick_context():
            d= {}
            for context, candidates in must[remaining_notes].iteritems():
                context_prob= 0
                util= False
                for pitch, prob in candidates.iteritems():
                    context_prob+= prob
                    util= util or Note(pitch).get_canonical_note() in input.now_chord.notes 

                if util: d[context]= context_prob

            if len(d) == 0:
                # no pude empezar
                import ipdb;ipdb.set_trace()
                raise Exception('no pude empezar')
            context= RandomPicker(values=d, random=self.random).get_value(normalize=True)
            return context
        if self.ec.last_support_note is None:
            #if len(prev_notes) == 1:
            #    # quiero los contextos que sean de la nota que acabo de tocar
            #    p= lambda c:c[1]  == prev_notes[0].pitch
            #else:
            #    # quiero todos los contextos
            #    p= lambda c: True
            context= pick_context()                

        pitches= []
        if input.rythm_phrase_len == 1:
            if self.ec.last_support_note is None:
                candidates= must[1][context]
                candidates_distr= dict((c, now_prob_model.get_prob(context[0], context[1], c)) for c in candidates)
                pitch= RandomPicker(values=must[1][context], random=self.random).get_value(normalize=True)
            else:
                pitch= self.ec.last_support_note
            pitches.append(pitch)
        else:
            if self.ec.last_support_note is not None:
                pitches.append(self.ec.last_support_note)
            else:
                pass
                #import ipdb;ipdb.set_trace()
            #now_prob_model= ProbModel(self.ec.narmour_features_prob, input.notes_distr, use_harmony=True)
            for i in xrange(remaining_notes, 0, -1):
                candidates= must[i].get(context)
                if candidates is None or len(candidates)==0: 
                    import ipdb;ipdb.set_trace()
                    raise Exception('no candidates!')
                candidates_distr= dict((c, now_prob_model.get_prob(context[0], context[1], c, use_harmony=True)) for c in candidates)
                pitch= RandomPicker(random=self.random,values=candidates).get_value(normalize=True)
                pitches.append(pitch)

                context= (context[-1], pitch)


        self.ec.last_support_note= end_pitch
        res= []
        for pitch in pitches:
            child_result= result.copy()
            child_input= input.copy()
            child_result.pitch= pitch
            res.append((child_input, child_result))
        
        if len(res) != input.rythm_phrase_len: 
            import ipdb;ipdb.set_trace()
            raise Exception('maal ahi')
        
        return res