Exemple #1
0
def woe(factor, sites, unit_cell=1):
    '''Weight of evidence method (multiclass form).

    @param factor     Multiclass pattern array used for prediction of point objects (sites).
    @param sites      Array layer consisting of the locations at which the point objects are known to occur.
    @param unit_cell  Method parameter, pixelsize of resampled rasters.

    @return masked array  Array of total weights of each factor.
    '''

    # Get list of categories from the factor raster
    categories = get_gradations(factor.compressed())

    # Try to binarize sites:
    sCategories = get_gradations(sites.compressed())
    if len(sCategories) != 2:
        raise WoeError('Site raster must be binary!')
    sites = binaryzation(sites, [sCategories[1]])

    # List of the weights of evidence:
    # weights[0] is (wPlus, wMinus) for the first category, weights[1] is (wPlus, wMinus) for the second category, ...
    weights = []
    if len(categories) >= 2:
        for cat in categories:
            fct = binaryzation(factor, [cat])
            weights.append(_binary_woe(fct, sites, unit_cell))
    else:
        raise WoeError('Wrong count of categories in the factor raster!')

    wTotalMin = sum([w[1] for w in weights])
    # List of total weights of evidence of the categories:
    # wMap[0] is the total weight of the first category, wMap[1] is the total weight of the second category, ...
    wMap = [w[0] + wTotalMin - w[1] for w in weights]

    # If len(categories) = 2, then [w[0] + wTotalMin - w[1] for w in weights] increases the answer.
    # In this case:
    if len(categories) == 2:
        wMap = [w/2 for w in wMap]

    resultMap =np.zeros(ma.shape(factor))
    for i,cat in enumerate(categories):
        resultMap[factor==cat] = wMap[i]

    resultMap = ma.array(data=resultMap, mask=factor.mask)
    result = {'map': resultMap, 'categories': categories, 'weights': wMap}
    return result
 def resetMask(self, maskVals = None):
     '''
     Set mask of _ALL_ bands.  maskVals is a list of masked values.
     '''
     for i in range(self.getBandsCount()):
         r = self.getBand(i)
         if maskVals != None:
             mask = binaryzation(r, maskVals)
         else:
             mask = False
         r = ma.array(data = r, mask=mask)
         self.setBand(r, i)
Exemple #3
0
    def train(self):
        '''
        Train the model
        '''
        self.transitionPotentials = {}
        try:
            iterCount = len(self.codes)*len(self.factors)
            self.rangeChanged.emit(self.tr("Training WoE... %p%"), iterCount)
            changeMap = self.changeMap.getBand(1)
            for code in self.codes:
                sites = binaryzation(changeMap, [code])
                # Reclass factors (continuous factor -> ordinal factor)
                wMap = np.ma.zeros(changeMap.shape) # The map of summary weight of the all factors
                self.weights[code] = {}             # Dictionary for storing wheights of every raster's band
                for k in xrange(len(self.factors)):
                    fact = self.factors[k]
                    self.weights[code][k] = {}      # Weights of the factor
                    factorW = self.weights[code][k]
                    if self.bins: # Get bins of the factor
                        bin = self.bins[k]
                        if (bin != None) and fact.getBandsCount() != len(bin):
                            raise WoeManagerError("Count of bins list for multiband factor is't equal to band count!")
                    else: bin = None
                    for i in range(1, fact.getBandsCount()+1):
                        band = fact.getBand(i)
                        if bin and bin[i-1]: #
                            band = reclass(band, bin[i-1])
                        band, sites = masks_identity(band, sites, dtype=np.uint8)   # Combine masks of the rasters
                        woeRes = woe(band, sites, self.unit_cell)   # WoE for the 'code' (initState->finalState) transition and current 'factor'.
                        weights = woeRes['map']
                        wMap = wMap + weights
                        factorW[i] = woeRes['weights']
                    self.updateProgress.emit()

                # Reclassification finished => set WoE coefficients
                self.woe[code]=wMap             # WoE for all factors and the transition code.

                # Potentials are WoE map rescaled to 0--100 percents
                band = (sigmoid(wMap)*100).astype(np.uint8)
                p = Raster()
                p.create([band], self.geodata)
                self.transitionPotentials[code] = p
                gc.collect()
        except MemoryError:
            self.errorReport.emit('The system out of memory during WoE trainig')
            raise
        except:
            self.errorReport.emit(self.tr("An unknown error occurs during WoE trainig"))
            raise
        finally:
            self.processFinished.emit()
Exemple #4
0
    def __init__ (self, referenceMap, simulatedMap):
        """
        @param referenceMap     Reference raster
        @param simulatedMap     Simulated raster
        """

        QObject.__init__(self)

        if referenceMap.getBandsCount() + simulatedMap.getBandsCount() !=2:
            raise EBError('The reference and simulated rasters must be 1-band rasters!')
        if not referenceMap.geoDataMatch(simulatedMap):
            raise EBError('Geometries of the reference and simulated rasters are different!')

        self.categories = referenceMap.getBandGradation(1)
        for s in simulatedMap.getBandGradation(1):
            if not s in self.categories:
                raise EBError('Categories in the reference and simulated rasters are different!')

        R = referenceMap.getBand(1)
        S = simulatedMap.getBand(1)
        self.shape = R.shape
        R, S = masks_identity(R,S, dtype=np.uint8)

        # Array for weight
        self.W = np.ones(self.shape)
        self.W = self.W - np.ma.getmask(R)

        R = np.ma.filled(R, 0)
        S = np.ma.filled(S, 0)

        # Proportion of category j in pixel n at the beginning resolution of the reference map
        self.Rj = {}
        for j in self.categories:
            self.Rj[j] = 1.0*binaryzation(R, [j])
        # Proportion of category j in pixel n at the beginning resolution of the simulated map
        self.Sj = {}
        for j in self.categories:
            self.Sj[j] = 1.0*binaryzation(S, [j])
    def _read(self):
        try:
            data = gdal.Open( self.filename )
        except RuntimeError:
            raise ProviderError("Can't read the file '%s'" % self.filename)
        if data is None:
            raise ProviderError("Can't read the file '%s'" % self.filename)

        self.geodata = {}
        self.geodata['xSize'] = data.RasterXSize
        self.geodata['ySize'] = data.RasterYSize
        self.geodata['proj']  = data.GetProjection()
        self.geodata['transform']  = data.GetGeoTransform()

        # Get units of the projection
        sr = osr.SpatialReference()
        sr.ImportFromWkt(self.geodata['proj'])
        self.geodata['units'] = sr.GetLinearUnitsName()

        self.bands = np.ma.zeros((data.RasterCount,self.geodata['ySize'], self.geodata['xSize']), dtype=float)
        self.bandcount = data.RasterCount
        if self.maskVals != None and len(self.maskVals) != self.bandcount:
            raise ProviderError("Band count of the file '%s' does't match nodata values count" % self.filename)

        for i in range(1, data.RasterCount+1):
            r = data.GetRasterBand(i)
            nodataValue =  r.GetNoDataValue()
            if nodataValue != None:
                nodataValues = [nodataValue]
            else:
                nodataValues = []
            r = r.ReadAsArray()
            #self.bandgradation[i] = None
            try:
                userNodataValues =  self.maskVals[i]
            except TypeError:
                userNodataValues = []
            nodataValues += userNodataValues
            if nodataValues != []:
                mask = binaryzation(r, nodataValues)
                r = ma.array(data = r, mask=mask)
            else:
                r = ma.array(data = r, mask=False)
            self.bands[i-1, :, :] = r
        self.isNormalazed = False
 def binaryzation(self, trueVals, bandNum):
     '''Reclass band bandNum to true/false mode. Set true for pixels from trueVals.'''
     r = self.getBand(bandNum)
     r = binaryzation(r, trueVals)
     self.setBand(r, bandNum)