def allFeatures_random_neg(features, labels, n_neg):
    j=0
    for i in range(0,len(features)-1):
        for k in labels[i]:
            if j == 0:
                x = getFeatures(features[i],features[i+1],k[0],k[1])
                j+=1
            else:
                x = np.vstack((x,getFeatures(features[i],features[i+1],k[0],k[1])))
        #negative examples
        count_negative = 0
        while(count_negative < n_neg):
            m = np.random.randint(1, max(labels[i][0])-10,size=2)
            if m not in labels[i]:
                count_negative+=1
                x = np.vstack((x,getFeatures(features[i],features[i+1],m[0],m[1])))
    return x
def allFeatures(features, labels, neg_labels):
    j=0
    lab=[]
    for i in range(0,len(features)-1):
        for k in labels[i]:
            if j == 0:
                x = getFeatures(features[i],features[i+1],k[0],k[1])
                j+=1
            else:
                x = np.vstack((x,getFeatures(features[i],features[i+1],k[0],k[1])))
            lab.append(1)
        for k in neg_labels[i]:
            if k not in labels[i].tolist():
                x = np.vstack((x,getFeatures(features[i],features[i+1],k[0],k[1])))
                lab.append(0)
    x = x[:,~np.isnan(x).any(axis=0)] #now removing the nans
    return x,np.asarray(lab)
    def addSample(self, f1, f2, label, pluginManager):
        # if self.labels == []:
        self.labels.append(label)
        # else:
        #    self.labels = np.concatenate((np.array(self.labels),label)) # for adding batches of features
        features = self.constructSampleFeatureVector(f1, f2, pluginManager)

        if self._numSamples is None:
            # use vstack
            if self.mydata is None:
                self.mydata = features
            else:
                self.mydata = np.vstack((self.mydata, features))
        else:
            # allocate full array once, then fill in row by row
            if self.mydata is None:
                self.mydata = np.zeros((self._numSamples, features.shape[0]))

            assert(self._nextIdx < self._numSamples)
            self.mydata[self._nextIdx, :] = features
            self._nextIdx += 1
    def addSample(self, f1, f2, label, pluginManager):
        # if self.labels == []:
        self.labels.append(label)
        # else:
        #    self.labels = np.concatenate((np.array(self.labels),label)) # for adding batches of features
        features = self.constructSampleFeatureVector(f1, f2, pluginManager)

        if self._numSamples is None:
            # use vstack
            if self.mydata is None:
                self.mydata = features
            else:
                self.mydata = np.vstack((self.mydata, features))
        else:
            # allocate full array once, then fill in row by row
            if self.mydata is None:
                self.mydata = np.zeros((self._numSamples, features.shape[0]))

            assert(self._nextIdx < self._numSamples)
            self.mydata[self._nextIdx, :] = features
            self._nextIdx += 1
    def addSample(self, f1, f2, label):
        #if self.labels == []:
        self.labels.append(label)
        #else:
        #    self.labels = np.concatenate((np.array(self.labels),label)) # for adding batches of features
        res=[]
        res2=[]
        
        for key in selectedFeatures:
            if key == "Global<Maximum >" or key=="Global<Minimum >":
                # the global min/max intensity is not interesting
                continue
            elif key == 'RegionCenter':
                res.append(np.linalg.norm(f1[key]-f2[key])) #difference of features
                res2.append(np.linalg.norm(f1[key]*f2[key])) #product of features
            elif key == 'Histogram': #contains only zeros, so trying to see what the prediction is without it
                continue
            elif key == 'Polygon': #vect has always another length for different objects, so center would be relevant
                continue
            else:
                if not isinstance(f1[key], np.ndarray):
                    res.append(float(f1[key]) - float(f2[key]) )  #prepare for flattening
                    res2.append(float(f1[key]) * float(f2[key]) )  #prepare for flattening
                else:
                    res.append((f1[key]-f2[key]).tolist() )  #prepare for flattening
                    res2.append((f1[key]*f2[key]).tolist() )  #prepare for flattening

        x= np.asarray(flatten(res)) #flatten
        x2= np.asarray(flatten(res2)) #flatten
        assert(np.any(np.isnan(x)) == False)
        assert(np.any(np.isnan(x2)) == False)
        assert(np.any(np.isinf(x)) == False)
        assert(np.any(np.isinf(x2)) == False)
        #x= x[~np.isnan(x)]
        #x2= x2[~np.isnan(x2)] #not getting the nans out YET
        features = np.concatenate((x,x2))
        if self.mydata is None:
            self.mydata = features
        else:
            self.mydata = np.vstack((self.mydata, features))
    endFrame = 20

    #read in raw images  - here ALL
    filepath = '/net/hciserver03/storage/lparcala/mitocheck_006--01--06/manual_tracking2/'
    gt_rawimage_filename = '/net/hciserver03/storage/lparcala/mitocheck_006--01--06/mitocheck_94570_2D+t_00-92.h5'
    gt_rawimage = vigra.impex.readHDF5(gt_rawimage_filename, 'volume/data')

    #this are the features for the first 5 time frames
    features = compute_features(gt_rawimage,read_in_images(initFrame,endFrame, filepath),initFrame,endFrame)
    mylabels = read_positiveLabels(initFrame,endFrame,filepath)
    neg_labels = negativeLabels(features,mylabels)
    mydata, endlabels =  allFeatures(features, mylabels, neg_labels)
    rf = vigra.learning.RandomForest()
    rf.learnRF(mydata.astype("float32"), (np.asarray(endlabels)).astype("uint32").reshape(-1,1))

    # Cross Validation
    X, Y = allFeatures(features, mylabels, neg_labels)
    total_number_of_samples = Y.shape[0]
    kf = KFold(total_number_of_samples, 4, shuffle=True)
    print "Starting cross validation"

    final_measure = []
    for train, test in kf:
        rf = vigra.learning.RandomForest()
        print "oob=",rf.learnRF(X[train].astype("float32"),Y[train].astype("uint32").reshape(-1,1))
        test_error = precision_recall_fscore_support(Y[test],rf.predictLabels(X[test].astype("float32")),average='weighted')
        print "test error=",test_error
        final_measure.append(test_error[:3])
    print np.vstack(tuple(final_measure))
    print np.mean(np.vstack(tuple(final_measure)),axis=0)