Exemplo n.º 1
0
def kappa(X, Y, mode=None):
    '''
    Kappa statistic
    @param X    Raster array.
    @param Y    Raster array.
    @param mode Kappa sttistic to compute:
        mode = None:    classic kappa
        mode = loc:     kappa location
        mode = histo    kappa histogram
    '''
    table = CrossTable(X, Y)
    rows, cols = table.shape
    if rows != cols:
        raise CoeffError('Kappa is applicable for NxN crosstable only!')
    t_expect =  table.getProbtable()
    pa = 0
    for i in range(rows):
        pa = pa + t_expect[i,i]
    prows = table.getProbRows()
    pcols = table.getProbCols()
    pexpect = sum(prows * pcols)
    pmax = sum(np.min([prows, pcols], axis=0))

    if mode == None:
        result = (pa - pexpect)/(1-pexpect)
    elif mode == "loc":
        result = (pa - pexpect)/(pmax - pexpect)
    elif mode == "histo":
        result = (pmax - pexpect)/(1 - pexpect)
    else:
        raise CoeffError('Unknown mode of kappa statistics!')
    return result
Exemplo n.º 2
0
    def test_getTransition(self):
        self.table = CrossTable(self.X, self.Y)

        fromClass, toClass = 1, 2
        self.assertEqual(self.table.getTransition(fromClass, toClass), 0)
        fromClass, toClass = 1, 3
        self.assertEqual(self.table.getTransition(fromClass, toClass), 3)
Exemplo n.º 3
0
def jiu(X, Y):
    '''
    Define Joint Information Uncertainty coef., based on entropy., for discrete values
    Coefficient change between [0, 1]
    0 - no connection
    1 - full connection
    @param X    First raster's array
    @param Y    Second raster's array
    '''
    #T, sum_r, sum_s, total, r, s = compute_table(X, Y)
    table = CrossTable(X, Y)
    T = table.getProbtable()             #Pij = Tij / total
    sum_rows = table.getProbRows()       #Pi. = Ti. / total  i=[0,(r-1)]
    sum_cols = table.getProbCols()       #P.j = T.j / total  j=[0,(s-1)]

    #to calculate the entropy we take the logarithm,
    #logarithm of zero does not exist, so we must mask zero values
    sum_rows = np.compress(sum_rows != 0, sum_rows)
    sum_cols = np.compress(sum_cols != 0, sum_cols)
    #Compute the entropy coeff. of two raster
    H_x = -np.sum(sum_rows * np.log(sum_rows))
    H_y = -np.sum(sum_cols * np.log(sum_cols))
    #Compute the joint entropy coeff.
    T = np.ma.array(T, mask=(T == 0))
    T = np.ma.compressed(T)
    H_xy = -np.sum(T * np.log(T))
    # Compute the Joint Information Uncertainty
    U = 2.0 * ((H_x + H_y - H_xy)/(H_x + H_y))

    return U
Exemplo n.º 4
0
 def test_init(self):
     mess = 'compute table failed'
     table = CrossTable(self.X, self.Y)
     for i in range(self.r):
         self.assertEqual(all(table.T[i]), all(self.T[i]), mess)
     self.assertEqual(all(table.getSumRows()), all(self.sum_r), mess)
     self.assertEqual(all(table.getSumCols()), all(self.sum_s), mess)
     self.assertEqual(table.n, self.total, mess)
     r,s = table.shape
     self.assertEqual(r, self.r, mess)
     self.assertEqual(s, self.s, mess)
Exemplo n.º 5
0
    def test_getTransition(self):
        self.table = CrossTable(self.X, self.Y)

        fromClass, toClass = 1, 2
        self.assertEqual(self.table.getTransition(fromClass, toClass), 0)
        fromClass, toClass = 1, 3
        self.assertEqual(self.table.getTransition(fromClass, toClass), 3)
Exemplo n.º 6
0
    def __init__(self, initRaster, finalRaster):
        QObject.__init__(self)

        if not initRaster.geoDataMatch(finalRaster):
            raise CrossTabManagerError('Geometries of the raster maps are different!')

        if initRaster.getBandsCount() + finalRaster.getBandsCount() != 2:
            raise CrossTabManagerError("An input raster has more then one band. Use 1-band rasters!")

        self.pixelArea = initRaster.getPixelArea()

        self.crosstable = CrossTable(initRaster.getBand(1), finalRaster.getBand(1))

        self.crosstable.rangeChanged.connect(self.__crosstableProgressRangeChanged)
        self.crosstable.updateProgress.connect(self.__crosstableProgressChanged)
        self.crosstable.crossTableFinished.connect(self.__crosstableFinished)
        self.crosstable.errorReport.connect(self.__crosstableError)
Exemplo n.º 7
0
 def calculateCrosstable(self):
     try:
         self.rangeChanged.emit('Initialization...', 2)
         self.updateProgress.emit()
         self.crosstable = CrossTable(self.X, self.Y, expand=self.expand)
         self.updateProgress.emit()
         self.__propagateCrossTableSignals()
         self.crosstable.computeCrosstable()
     except MemoryError:
         self.errorReport.emit(
             self.tr(
                 "The system out of memory during cross table calculation"))
         raise
     except:
         self.errorReport.emit(
             self.tr(
                 "An unknown error occurs during cross table calculation"))
         raise
     finally:
         self.processFinished.emit()
Exemplo n.º 8
0
    def test_init(self):
        mess = 'compute table failed'
        table = CrossTable(self.X, self.Y)
        crTab = table.getCrosstable()
        for i in range(self.r):
            self.assertEqual(all(crTab[i]), all(self.T[i]), mess)
        self.assertEqual(all(table.getSumRows()), all(self.sum_r), mess)
        self.assertEqual(all(table.getSumCols()), all(self.sum_s), mess)
        self.assertEqual(table.n, self.total, mess)
        r,s = table.shape
        self.assertEqual(r, self.r, mess)
        self.assertEqual(s, self.s, mess)

        x = np.ma.array([1,2,3,4,5,5])
        y = np.ma.array([1,2,3,3,5,6])
        self.assertRaises(CrossTable(x,y))

        table = CrossTable(x,y, expand=True)
        for i in [1,2,3,4,5,6]:
            assert i in table.graduation_x
            assert i in table.graduation_y
Exemplo n.º 9
0
def cramer(X, Y):
    '''
    Define Cramer's relationship coefficient of the rasters for discrete values
    Coefficient change between [0, 1]
    0 - no dependence
    1 - full connection
    @param X    First raster's array
    @param Y    Second raster's array
    '''
    table = CrossTable(X, Y)
    rows, cols = table.shape
    t_expect =  table.getExpectedTable()

    # Mask T* to prevent division by zero
    t_expect = np.ma.array(t_expect, mask=(t_expect == 0))
    # chi-square coeff = sum((T-T*)^2/T*)
    x2 = np.sum(np.square(table.T - t_expect)/t_expect)
    # CRAMER CONTINGENCY COEF. = sqrt(chi-square / (total * min(s-1,r-1)))
    # s, r - raster grauations
    Cramer = math.sqrt(x2/(table.n*min(cols-1, rows-1)))

    return Cramer
Exemplo n.º 10
0
    def test_expectedTable(self):
        # CrossTable:
        # [2, 0, 3],
        # [2, 1, 0],

        table = CrossTable(self.X, self.Y)
        tab = table.getExpectedTable()
        answer = [
            [20/8.0, 5/8.0, 15/8.0],
            [12/8.0, 3/8.0,  9/8.0]
        ]
        np.testing.assert_array_equal(answer, tab)

        tab = table.getExpectedProbtable()
        answer = [
            [20/64.0, 5/64.0, 15/64.0],
            [12/64.0, 3/64.0,  9/64.0]
        ]
        np.testing.assert_array_equal(answer, tab)

        np.testing.assert_array_equal(table.getProbCols(), [4.0/8, 1.0/8, 3.0/8])
        np.testing.assert_array_equal(table.getProbRows(), [5.0/8, 3.0/8])
Exemplo n.º 11
0
 def calculateCrosstable(self):
     try:
         self.rangeChanged.emit("Initialization...", 2)
         self.updateProgress.emit()
         self.crosstable = CrossTable(self.X, self.Y, expand=self.expand)
         self.updateProgress.emit()
         self.__propagateCrossTableSignals()
         self.crosstable.computeCrosstable()
     except MemoryError:
         self.errorReport.emit(self.tr("The system out of memory during cross table calculation"))
         raise
     except:
         self.errorReport.emit(self.tr("An unknown error occurs during cross table calculation"))
         raise
     finally:
         self.processFinished.emit()
Exemplo n.º 12
0
    def test_init(self):
        mess = 'compute table failed'
        table = CrossTable(self.X, self.Y)
        crTab = table.getCrosstable()
        for i in range(self.r):
            self.assertEqual(all(crTab[i]), all(self.T[i]), mess)
        self.assertEqual(all(table.getSumRows()), all(self.sum_r), mess)
        self.assertEqual(all(table.getSumCols()), all(self.sum_s), mess)
        self.assertEqual(table.n, self.total, mess)
        r, s = table.shape
        self.assertEqual(r, self.r, mess)
        self.assertEqual(s, self.s, mess)

        x = np.ma.array([1, 2, 3, 4, 5, 5])
        y = np.ma.array([1, 2, 3, 3, 5, 6])
        self.assertRaises(CrossTable(x, y))

        table = CrossTable(x, y, expand=True)
        for i in [1, 2, 3, 4, 5, 6]:
            assert i in table.graduation_x
            assert i in table.graduation_y
Exemplo n.º 13
0
    def test_expectedTable(self):
        # CrossTable:
        # [2, 0, 3],
        # [2, 1, 0],

        table = CrossTable(self.X, self.Y)
        tab = table.getExpectedTable()
        answer = [[20 / 8.0, 5 / 8.0, 15 / 8.0], [12 / 8.0, 3 / 8.0, 9 / 8.0]]
        np.testing.assert_array_equal(answer, tab)

        tab = table.getExpectedProbtable()
        answer = [[20 / 64.0, 5 / 64.0, 15 / 64.0],
                  [12 / 64.0, 3 / 64.0, 9 / 64.0]]
        np.testing.assert_array_equal(answer, tab)

        np.testing.assert_array_equal(table.getProbCols(),
                                      [4.0 / 8, 1.0 / 8, 3.0 / 8])
        np.testing.assert_array_equal(table.getProbRows(), [5.0 / 8, 3.0 / 8])
Exemplo n.º 14
0
class DependenceCoef(QObject):

    rangeChanged = pyqtSignal(str, int)
    updateProgress = pyqtSignal()
    processFinished = pyqtSignal()
    logMessage = pyqtSignal(str)
    errorReport = pyqtSignal(str)

    def __init__(self, X, Y, expand=False):
        """
        @param band1    First band (numpy masked array)
        @param band2    Second band (numpy masked array)
        @param expand   If the param is True, use union of categories of the bands and compute NxN crosstable
        """

        QObject.__init__(self)

        self.X = X
        self.Y = Y
        self.expand = expand

        self.crosstable = None

    def getCrosstable(self):
        if self.crosstable == None:
            self.calculateCrosstable()
        return self.crosstable

    def calculateCrosstable(self):
        try:
            self.rangeChanged.emit('Initialization...', 2)
            self.updateProgress.emit()
            self.crosstable = CrossTable(self.X, self.Y, expand=self.expand)
            self.updateProgress.emit()
            self.__propagateCrossTableSignals()
            self.crosstable.computeCrosstable()
        except MemoryError:
            self.errorReport.emit(
                self.tr(
                    "The system out of memory during cross table calculation"))
            raise
        except:
            self.errorReport.emit(
                self.tr(
                    "An unknown error occurs during cross table calculation"))
            raise
        finally:
            self.processFinished.emit()

    def correlation(self):
        '''
        Define correlation coefficient of the rasters.
        '''
        x, y = masks_identity(self.X.flatten(), self.Y.flatten())
        x, y = np.ma.compressed(x), np.ma.compressed(y)
        R = np.corrcoef(x, y)
        del x
        del y
        # function np.corrcoef returns array of coefficients
        # R[0][0] = R[1][1] = 1.0 - correlation X--X and Y--Y
        # R[0][1] = R[1][0] - correlation X--Y and Y--X

        return R[0][1]

    def correctness(self, percent=True):
        """
        % (or count) of correct results
        """
        table = self.getCrosstable()
        crosstable = table.getCrosstable()
        rows, cols = table.shape
        if rows != cols:
            raise CoeffError(
                'The method is applicable for NxN crosstable only!')
        n = table.n
        s = 0.0
        for i in range(rows):
            s = s + crosstable[i][i]

        if percent:
            return 100.0 * s / n
        else:
            return s / n

    def cramer(self):
        '''
        Define Cramer's relationship coefficient of the rasters for discrete values
        Coefficient change between [0, 1]
        0 - no dependence
        1 - full connection
        @param X    First raster's array
        @param Y    Second raster's array
        '''
        table = self.getCrosstable()
        crosstable = table.getCrosstable()
        rows, cols = table.shape
        t_expect = table.getExpectedTable()

        # Mask T* to prevent division by zero
        t_expect = np.ma.array(t_expect, mask=(t_expect == 0))
        # chi-square coeff = sum((T-T*)^2/T*)
        x2 = np.sum(np.square(crosstable - t_expect) / t_expect)
        # CRAMER CONTINGENCY COEF. = sqrt(chi-square / (total * min(s-1,r-1)))
        # s, r - raster grauations
        Cramer = math.sqrt(x2 / (table.n * min(cols - 1, rows - 1)))

        return Cramer

    def jiu(self):
        '''
        Define Joint Information Uncertainty coef., based on entropy., for discrete values
        Coefficient change between [0, 1]
        0 - no connection
        1 - full connection
        @param X    First raster's array
        @param Y    Second raster's array
        '''
        #T, sum_r, sum_s, total, r, s = compute_table(X, Y)
        table = self.getCrosstable()
        T = table.getProbtable()  #Pij = Tij / total
        sum_rows = table.getProbRows()  #Pi. = Ti. / total  i=[0,(r-1)]
        sum_cols = table.getProbCols()  #P.j = T.j / total  j=[0,(s-1)]

        #to calculate the entropy we take the logarithm,
        #logarithm of zero does not exist, so we must mask zero values
        sum_rows = np.compress(sum_rows != 0, sum_rows)
        sum_cols = np.compress(sum_cols != 0, sum_cols)
        #Compute the entropy coeff. of two raster
        H_x = -np.sum(sum_rows * np.log(sum_rows))
        H_y = -np.sum(sum_cols * np.log(sum_cols))
        #Compute the joint entropy coeff.
        T = np.ma.array(T, mask=(T == 0))
        T = np.ma.compressed(T)
        H_xy = -np.sum(T * np.log(T))
        # Compute the Joint Information Uncertainty
        U = 2.0 * ((H_x + H_y - H_xy) / (H_x + H_y))

        return U

    def kappa(self, mode=None):
        '''
        Kappa statistic
        @param X    Raster array.
        @param Y    Raster array.
        @param mode Kappa sttistic to compute:
            mode = None:    classic kappa
            mode = loc:     kappa location
            mode = histo    kappa histogram
        '''
        table = self.getCrosstable()
        rows, cols = table.shape
        if rows != cols:
            raise CoeffError('Kappa is applicable for NxN crosstable only!')
        t_expect = table.getProbtable()
        pa = 0
        for i in range(rows):
            pa = pa + t_expect[i, i]
        prows = table.getProbRows()
        pcols = table.getProbCols()
        pexpect = sum(prows * pcols)
        pmax = sum(np.min([prows, pcols], axis=0))

        if mode == None:
            result = (pa - pexpect) / (1 - pexpect)
        elif mode == "loc":
            result = (pa - pexpect) / (pmax - pexpect)
        elif mode == "histo":
            result = (pmax - pexpect) / (1 - pexpect)
        elif mode == "all":
            result = {
                "loc": (pa - pexpect) / (pmax - pexpect),
                "histo": (pmax - pexpect) / (1 - pexpect),
                "overal": (pa - pexpect) / (1 - pexpect)
            }
        else:
            raise CoeffError('Unknown mode of kappa statistics!')

        return result

    def __propagateCrossTableSignals(self):
        self.crosstable.rangeChanged.connect(
            self.__crosstableProgressRangeChanged)
        self.crosstable.updateProgress.connect(
            self.__crosstableProgressChanged)
        self.crosstable.crossTableFinished.connect(self.__crosstableFinished)
        self.crosstable.errorReport.connect(self.__crosstableError)

    def __crosstableFinished(self):
        self.crosstable.rangeChanged.disconnect(
            self.__crosstableProgressRangeChanged)
        self.crosstable.updateProgress.disconnect(
            self.__crosstableProgressChanged)
        self.crosstable.crossTableFinished.disconnect(
            self.__crosstableFinished)

    def __crosstableProgressChanged(self):
        QCoreApplication.processEvents()
        self.updateProgress.emit()

    def __crosstableProgressRangeChanged(self, message, maxValue):
        self.rangeChanged.emit(message, maxValue)

    def __crosstableError(self, message):
        self.errorReport.emit(message)
Exemplo n.º 15
0
class DependenceCoef(QObject):

    rangeChanged = pyqtSignal(str, int)
    updateProgress = pyqtSignal()
    processFinished = pyqtSignal()
    logMessage = pyqtSignal(str)
    errorReport = pyqtSignal(str)

    def __init__(self, X, Y, expand=False):
        """
        @param band1    First band (numpy masked array)
        @param band2    Second band (numpy masked array)
        @param expand   If the param is True, use union of categories of the bands and compute NxN crosstable
        """

        QObject.__init__(self)

        self.X = X
        self.Y = Y
        self.expand = expand

        self.crosstable = None

    def getCrosstable(self):
        if self.crosstable == None:
            self.calculateCrosstable()
        return self.crosstable

    def calculateCrosstable(self):
        try:
            self.rangeChanged.emit("Initialization...", 2)
            self.updateProgress.emit()
            self.crosstable = CrossTable(self.X, self.Y, expand=self.expand)
            self.updateProgress.emit()
            self.__propagateCrossTableSignals()
            self.crosstable.computeCrosstable()
        except MemoryError:
            self.errorReport.emit(self.tr("The system out of memory during cross table calculation"))
            raise
        except:
            self.errorReport.emit(self.tr("An unknown error occurs during cross table calculation"))
            raise
        finally:
            self.processFinished.emit()

    def correlation(self):
        """
        Define correlation coefficient of the rasters.
        """
        x, y = masks_identity(self.X.flatten(), self.Y.flatten())
        x, y = np.ma.compressed(x), np.ma.compressed(y)
        R = np.corrcoef(x, y)
        del x
        del y
        # function np.corrcoef returns array of coefficients
        # R[0][0] = R[1][1] = 1.0 - correlation X--X and Y--Y
        # R[0][1] = R[1][0] - correlation X--Y and Y--X

        return R[0][1]

    def correctness(self, percent=True):
        """
        % (or count) of correct results
        """
        table = self.getCrosstable()
        crosstable = table.getCrosstable()
        rows, cols = table.shape
        if rows != cols:
            raise CoeffError("The method is applicable for NxN crosstable only!")
        n = table.n
        s = 0.0
        for i in range(rows):
            s = s + crosstable[i][i]

        if percent:
            return 100.0 * s / n
        else:
            return s / n

    def cramer(self):
        """
        Define Cramer's relationship coefficient of the rasters for discrete values
        Coefficient change between [0, 1]
        0 - no dependence
        1 - full connection
        @param X    First raster's array
        @param Y    Second raster's array
        """
        table = self.getCrosstable()
        crosstable = table.getCrosstable()
        rows, cols = table.shape
        t_expect = table.getExpectedTable()

        # Mask T* to prevent division by zero
        t_expect = np.ma.array(t_expect, mask=(t_expect == 0))
        # chi-square coeff = sum((T-T*)^2/T*)
        x2 = np.sum(np.square(crosstable - t_expect) / t_expect)
        # CRAMER CONTINGENCY COEF. = sqrt(chi-square / (total * min(s-1,r-1)))
        # s, r - raster grauations
        Cramer = math.sqrt(x2 / (table.n * min(cols - 1, rows - 1)))

        return Cramer

    def jiu(self):
        """
        Define Joint Information Uncertainty coef., based on entropy., for discrete values
        Coefficient change between [0, 1]
        0 - no connection
        1 - full connection
        @param X    First raster's array
        @param Y    Second raster's array
        """
        # T, sum_r, sum_s, total, r, s = compute_table(X, Y)
        table = self.getCrosstable()
        T = table.getProbtable()  # Pij = Tij / total
        sum_rows = table.getProbRows()  # Pi. = Ti. / total  i=[0,(r-1)]
        sum_cols = table.getProbCols()  # P.j = T.j / total  j=[0,(s-1)]

        # to calculate the entropy we take the logarithm,
        # logarithm of zero does not exist, so we must mask zero values
        sum_rows = np.compress(sum_rows != 0, sum_rows)
        sum_cols = np.compress(sum_cols != 0, sum_cols)
        # Compute the entropy coeff. of two raster
        H_x = -np.sum(sum_rows * np.log(sum_rows))
        H_y = -np.sum(sum_cols * np.log(sum_cols))
        # Compute the joint entropy coeff.
        T = np.ma.array(T, mask=(T == 0))
        T = np.ma.compressed(T)
        H_xy = -np.sum(T * np.log(T))
        # Compute the Joint Information Uncertainty
        U = 2.0 * ((H_x + H_y - H_xy) / (H_x + H_y))

        return U

    def kappa(self, mode=None):
        """
        Kappa statistic
        @param X    Raster array.
        @param Y    Raster array.
        @param mode Kappa sttistic to compute:
            mode = None:    classic kappa
            mode = loc:     kappa location
            mode = histo    kappa histogram
        """
        table = self.getCrosstable()
        rows, cols = table.shape
        if rows != cols:
            raise CoeffError("Kappa is applicable for NxN crosstable only!")
        t_expect = table.getProbtable()
        pa = 0
        for i in range(rows):
            pa = pa + t_expect[i, i]
        prows = table.getProbRows()
        pcols = table.getProbCols()
        pexpect = sum(prows * pcols)
        pmax = sum(np.min([prows, pcols], axis=0))

        if mode == None:
            result = (pa - pexpect) / (1 - pexpect)
        elif mode == "loc":
            result = (pa - pexpect) / (pmax - pexpect)
        elif mode == "histo":
            result = (pmax - pexpect) / (1 - pexpect)
        elif mode == "all":
            result = {
                "loc": (pa - pexpect) / (pmax - pexpect),
                "histo": (pmax - pexpect) / (1 - pexpect),
                "overal": (pa - pexpect) / (1 - pexpect),
            }
        else:
            raise CoeffError("Unknown mode of kappa statistics!")

        return result

    def __propagateCrossTableSignals(self):
        self.crosstable.rangeChanged.connect(self.__crosstableProgressRangeChanged)
        self.crosstable.updateProgress.connect(self.__crosstableProgressChanged)
        self.crosstable.crossTableFinished.connect(self.__crosstableFinished)
        self.crosstable.errorReport.connect(self.__crosstableError)

    def __crosstableFinished(self):
        self.crosstable.rangeChanged.disconnect(self.__crosstableProgressRangeChanged)
        self.crosstable.updateProgress.disconnect(self.__crosstableProgressChanged)
        self.crosstable.crossTableFinished.disconnect(self.__crosstableFinished)

    def __crosstableProgressChanged(self):
        QCoreApplication.processEvents()
        self.updateProgress.emit()

    def __crosstableProgressRangeChanged(self, message, maxValue):
        self.rangeChanged.emit(message, maxValue)

    def __crosstableError(self, message):
        self.errorReport.emit(message)
Exemplo n.º 16
0
class TestCrossTable (unittest.TestCase):

    def setUp(self):

        self.X = np.array([
            [1, 2, 1,],
            [1, 2, 1,],
            [0, 1, 2,]
        ])

        self.Y = np.array([
            [1, 1, 3,],
            [3, 2, 1,],
            [0, 3, 1,]
        ])

        self.T = np.array([
            [2, 0, 3],
            [2, 1, 0],
        ])
        self.sum_r = [5, 3]
        self.sum_s = [4, 1, 3]
        self.total = 8
        self.r = 2
        self.s = 3

        self.X = np.ma.array(self.X, mask=(self.X == 0))
        self.Y = np.ma.array(self.Y, mask=(self.Y == 0))

    def test_init(self):
        mess = 'compute table failed'
        table = CrossTable(self.X, self.Y)
        crTab = table.getCrosstable()
        for i in range(self.r):
            self.assertEqual(all(crTab[i]), all(self.T[i]), mess)
        self.assertEqual(all(table.getSumRows()), all(self.sum_r), mess)
        self.assertEqual(all(table.getSumCols()), all(self.sum_s), mess)
        self.assertEqual(table.n, self.total, mess)
        r,s = table.shape
        self.assertEqual(r, self.r, mess)
        self.assertEqual(s, self.s, mess)

        x = np.ma.array([1,2,3,4,5,5])
        y = np.ma.array([1,2,3,3,5,6])
        self.assertRaises(CrossTable(x,y))

        table = CrossTable(x,y, expand=True)
        for i in [1,2,3,4,5,6]:
            assert i in table.graduation_x
            assert i in table.graduation_y


    def test_getTransition(self):
        self.table = CrossTable(self.X, self.Y)

        fromClass, toClass = 1, 2
        self.assertEqual(self.table.getTransition(fromClass, toClass), 0)
        fromClass, toClass = 1, 3
        self.assertEqual(self.table.getTransition(fromClass, toClass), 3)

    def test_expectedTable(self):
        # CrossTable:
        # [2, 0, 3],
        # [2, 1, 0],

        table = CrossTable(self.X, self.Y)
        tab = table.getExpectedTable()
        answer = [
            [20/8.0, 5/8.0, 15/8.0],
            [12/8.0, 3/8.0,  9/8.0]
        ]
        np.testing.assert_array_equal(answer, tab)

        tab = table.getExpectedProbtable()
        answer = [
            [20/64.0, 5/64.0, 15/64.0],
            [12/64.0, 3/64.0,  9/64.0]
        ]
        np.testing.assert_array_equal(answer, tab)

        np.testing.assert_array_equal(table.getProbCols(), [4.0/8, 1.0/8, 3.0/8])
        np.testing.assert_array_equal(table.getProbRows(), [5.0/8, 3.0/8])
Exemplo n.º 17
0
class CrossTableManager(QObject):
    '''
    Provides statistic information about transitions InitState->FinalState.
    '''

    rangeChanged = pyqtSignal(str, int)
    updateProgress = pyqtSignal()
    crossTableFinished = pyqtSignal()
    logMessage = pyqtSignal(str)
    errorReport = pyqtSignal(str)

    def __init__(self, initRaster, finalRaster):
        QObject.__init__(self)

        if not initRaster.geoDataMatch(finalRaster):
            raise CrossTabManagerError('Geometries of the raster maps are different!')

        if initRaster.getBandsCount() + finalRaster.getBandsCount() != 2:
            raise CrossTabManagerError("An input raster has more then one band. Use 1-band rasters!")

        self.pixelArea = initRaster.getPixelArea()

        self.crosstable = CrossTable(initRaster.getBand(1), finalRaster.getBand(1))

        self.crosstable.rangeChanged.connect(self.__crosstableProgressRangeChanged)
        self.crosstable.updateProgress.connect(self.__crosstableProgressChanged)
        self.crosstable.crossTableFinished.connect(self.__crosstableFinished)
        self.crosstable.errorReport.connect(self.__crosstableError)

    def __crosstableFinished(self):
        self.crosstable.rangeChanged.disconnect(self.__crosstableProgressRangeChanged)
        self.crosstable.updateProgress.disconnect(self.__crosstableProgressChanged)
        self.crosstable.crossTableFinished.disconnect(self.__crosstableFinished)
        self.crossTableFinished.emit()
    def __crosstableProgressChanged(self):
        self.updateProgress.emit()
    def __crosstableProgressRangeChanged(self, message, maxValue):
        self.rangeChanged.emit(message, maxValue)
    def __crosstableError(self, message):
        self.errorReport.emit(message)

    def computeCrosstable(self):
        try:
            self.crosstable.computeCrosstable()
        except MemoryError:
            self.errorReport.emit(self.tr("The system out of memory during calculation of cross table"))
            raise
        except:
            self.errorReport.emit(self.tr("An unknown error occurs during calculation of cross table"))
            raise

    def getCrosstable(self):
        return self.crosstable

    def getTransitionMatrix(self):
        tab = self.getCrosstable().getCrosstable()
        s = 1.0/np.sum(tab, axis=1)
        return tab*s[:,None]

    def getTransitionStat(self):
        pixelArea = self.pixelArea['area']
        stat = {'unit': self.pixelArea['unit']}
        tab = self.getCrosstable()

        initArea = tab.getSumRows()
        initArea = pixelArea * initArea
        initPerc = 100.0 * initArea / sum(initArea)
        stat['init'] = initArea
        stat['initPerc'] = initPerc

        finalArea = tab.getSumCols()
        finalArea = pixelArea * finalArea
        finalPerc = 100.0 * finalArea / sum(finalArea)
        stat['final'] = finalArea
        stat['finalPerc'] = finalPerc

        deltas = finalArea - initArea
        deltasPerc = finalPerc - initPerc
        stat['deltas'] = deltas
        stat['deltasPerc'] = deltasPerc

        return stat
Exemplo n.º 18
0
class TestCrossTable(unittest.TestCase):
    def setUp(self):

        self.X = np.array([[
            1,
            2,
            1,
        ], [
            1,
            2,
            1,
        ], [
            0,
            1,
            2,
        ]])

        self.Y = np.array([[
            1,
            1,
            3,
        ], [
            3,
            2,
            1,
        ], [
            0,
            3,
            1,
        ]])

        self.T = np.array([
            [2, 0, 3],
            [2, 1, 0],
        ])
        self.sum_r = [5, 3]
        self.sum_s = [4, 1, 3]
        self.total = 8
        self.r = 2
        self.s = 3

        self.X = np.ma.array(self.X, mask=(self.X == 0))
        self.Y = np.ma.array(self.Y, mask=(self.Y == 0))

    def test_init(self):
        mess = 'compute table failed'
        table = CrossTable(self.X, self.Y)
        crTab = table.getCrosstable()
        for i in range(self.r):
            self.assertEqual(all(crTab[i]), all(self.T[i]), mess)
        self.assertEqual(all(table.getSumRows()), all(self.sum_r), mess)
        self.assertEqual(all(table.getSumCols()), all(self.sum_s), mess)
        self.assertEqual(table.n, self.total, mess)
        r, s = table.shape
        self.assertEqual(r, self.r, mess)
        self.assertEqual(s, self.s, mess)

        x = np.ma.array([1, 2, 3, 4, 5, 5])
        y = np.ma.array([1, 2, 3, 3, 5, 6])
        self.assertRaises(CrossTable(x, y))

        table = CrossTable(x, y, expand=True)
        for i in [1, 2, 3, 4, 5, 6]:
            assert i in table.graduation_x
            assert i in table.graduation_y

    def test_getTransition(self):
        self.table = CrossTable(self.X, self.Y)

        fromClass, toClass = 1, 2
        self.assertEqual(self.table.getTransition(fromClass, toClass), 0)
        fromClass, toClass = 1, 3
        self.assertEqual(self.table.getTransition(fromClass, toClass), 3)

    def test_expectedTable(self):
        # CrossTable:
        # [2, 0, 3],
        # [2, 1, 0],

        table = CrossTable(self.X, self.Y)
        tab = table.getExpectedTable()
        answer = [[20 / 8.0, 5 / 8.0, 15 / 8.0], [12 / 8.0, 3 / 8.0, 9 / 8.0]]
        np.testing.assert_array_equal(answer, tab)

        tab = table.getExpectedProbtable()
        answer = [[20 / 64.0, 5 / 64.0, 15 / 64.0],
                  [12 / 64.0, 3 / 64.0, 9 / 64.0]]
        np.testing.assert_array_equal(answer, tab)

        np.testing.assert_array_equal(table.getProbCols(),
                                      [4.0 / 8, 1.0 / 8, 3.0 / 8])
        np.testing.assert_array_equal(table.getProbRows(), [5.0 / 8, 3.0 / 8])