Exemplo n.º 1
0
    def _send_to_plpy(self, level, text, exception=None):
        # exception might also be a tuple generated by sys.exc_info
        if exception:
            if isinstance(exception, tuple) and len(exception) > 1:
                exception = exception[1]
            exception_message = '. Exception: {}'.format(exception)
        else:
            exception_message = ''

        # Adding trace breaks tests
        # trace = traceback.format_exc(15)
        # message = '{}{}. Trace: {}'.format(text, exception_message, trace)
        message = '{}{}'.format(text, exception_message)

        if self._check_plpy():
            if level == 'debug':
                plpy.debug(message)
            elif level == 'info':
                plpy.info(message)
            elif level == 'warning':
                plpy.warning(message)
            elif level == 'error':
                # Plpy.error and fatal raises exceptions and we only want to
                # log an error, exceptions should be raise explicitly
                plpy.warning(message)
Exemplo n.º 2
0
def spatial_markov_trend(
    subquery,
    time_cols,
    num_classes=7,
    w_type="knn",
    num_ngbrs=5,
    permutations=0,
    geom_col="the_geom",
    id_col="cartodb_id",
):
    """
        Predict the trends of a unit based on:
        1. history of its transitions to different classes (e.g., 1st quantile -> 2nd quantile)
        2. average class of its neighbors

        Inputs:
        @param subquery string: e.g., SELECT the_geom, cartodb_id,
          interesting_time_column FROM table_name
        @param time_cols list of strings: list of strings of column names
        @param num_classes (optional): number of classes to break distribution
          of values into. Currently uses quantile bins.
        @param w_type string (optional): weight type ('knn' or 'queen')
        @param num_ngbrs int (optional): number of neighbors (if knn type)
        @param permutations int (optional): number of permutations for test
          stats
        @param geom_col string (optional): name of column which contains the
          geometries
        @param id_col string (optional): name of column which has the ids of
          the table

        Outputs:
        @param trend_up float: probablity that a geom will move to a higher
          class
        @param trend_down float: probablity that a geom will move to a lower
          class
        @param trend float: (trend_up - trend_down) / trend_static
        @param volatility float: a measure of the volatility based on
          probability stddev(prob array)
    """

    if len(time_cols) < 2:
        plpy.error("More than one time column needs to be passed")

    qvals = {
        "id_col": id_col,
        "time_cols": time_cols,
        "geom_col": geom_col,
        "subquery": subquery,
        "num_ngbrs": num_ngbrs,
    }

    try:
        query_result = plpy.execute(pu.construct_neighbor_query(w_type, qvals))
        if len(query_result) == 0:
            return zip([None], [None], [None], [None], [None])
    except plpy.SPIError, e:
        plpy.debug("Query failed with exception %s: %s" % (err, pu.construct_neighbor_query(w_type, qvals)))
        plpy.error("Analysis failed: %s" % e)
        return zip([None], [None], [None], [None], [None])
Exemplo n.º 3
0
def spatial_markov_trend(subquery,
                         time_cols,
                         num_classes=7,
                         w_type='knn',
                         num_ngbrs=5,
                         permutations=0,
                         geom_col='the_geom',
                         id_col='cartodb_id'):
    """
        Predict the trends of a unit based on:
        1. history of its transitions to different classes (e.g., 1st quantile -> 2nd quantile)
        2. average class of its neighbors

        Inputs:
        @param subquery string: e.g., SELECT the_geom, cartodb_id,
          interesting_time_column FROM table_name
        @param time_cols list of strings: list of strings of column names
        @param num_classes (optional): number of classes to break distribution
          of values into. Currently uses quantile bins.
        @param w_type string (optional): weight type ('knn' or 'queen')
        @param num_ngbrs int (optional): number of neighbors (if knn type)
        @param permutations int (optional): number of permutations for test
          stats
        @param geom_col string (optional): name of column which contains the
          geometries
        @param id_col string (optional): name of column which has the ids of
          the table

        Outputs:
        @param trend_up float: probablity that a geom will move to a higher
          class
        @param trend_down float: probablity that a geom will move to a lower
          class
        @param trend float: (trend_up - trend_down) / trend_static
        @param volatility float: a measure of the volatility based on
          probability stddev(prob array)
    """

    if len(time_cols) < 2:
        plpy.error('More than one time column needs to be passed')

    qvals = {
        "id_col": id_col,
        "time_cols": time_cols,
        "geom_col": geom_col,
        "subquery": subquery,
        "num_ngbrs": num_ngbrs
    }

    try:
        query_result = plpy.execute(pu.construct_neighbor_query(w_type, qvals))
        if len(query_result) == 0:
            return zip([None], [None], [None], [None], [None])
    except plpy.SPIError, e:
        plpy.debug('Query failed with exception %s: %s' %
                   (err, pu.construct_neighbor_query(w_type, qvals)))
        plpy.error('Analysis failed: %s' % e)
        return zip([None], [None], [None], [None], [None])
Exemplo n.º 4
0
 def _send_to_plpy(self, level, text):
     if self._check_plpy():
         if level == 'debug':
             plpy.debug(text)
         elif level == 'info':
             plpy.info(text)
         elif level == 'warning':
             plpy.warning(text)
         elif level == 'error':
             # Plpy.error and fatal raises exceptions and we only want to
             # log an error, exceptions should be raise explicitly
             plpy.warning(text)
Exemplo n.º 5
0
 def _send_to_plpy(self, level, text):
     if self._check_plpy():
         if level == 'debug':
             plpy.debug(text)
         elif level == 'info':
             plpy.info(text)
         elif level == 'warning':
             plpy.warning(text)
         elif level == 'error':
             # Plpy.error and fatal raises exceptions and we only want to
             # log an error, exceptions should be raise explicitly
             plpy.warning(text)
Exemplo n.º 6
0
def get_dyn_transfo_params_form_1(params_column, params, time):
    ''' Return the dynamic transfo parameters.
    '''
    if isinstance(time, datetime.datetime):
        plpy.error('times as strings unsupported for dynamic transforms of form 1')

    schema, table, column = tuple(map(plpy.quote_ident, params_column.split('.')))
    params = params[0]

    select = []
    for param in params.values():
        if isinstance(param, list):
            for dim in param:
                append_dim_select(dim, select)
        else:
            dim = param
            append_dim_select(dim, select)
    select = ', '.join(select)

    q = ('''
        with patch as (
            select pc_interpolate({column}, 'time', {time:f}, true) point
            from {schema}.{table}
            where pc_patchmin({column}, 'time') <= {time:f} and
                  pc_patchmax({column}, 'time') >  {time:f}
        ) select %s from patch
        ''' % select).format(schema=schema, table=table, column=column, time=time)
    plpy.debug(q)
    rv = plpy.execute(q)
    if len(rv) == 0:
        plpy.warning('no parameters for the provided time ({:f})'.format(time))
        return None
    if len(rv) != 1:
        plpy.error('multiple rows returned from time interpolation')
    values = rv[0]

    for key, param in params.items():
        if isinstance(param, list):
            for i, dim in enumerate(param):
                val = values[dim]
                param[i] = val
        else:
            dim = param
            val = values[dim]
            params[key] = val

    return params
Exemplo n.º 7
0
def get_transform(transfoid, time):
    ''' Return information about the transfo whose id is transfoid. A dict with keys "name",
        "params", "func_name", and "func_sign".
    '''
    if not isinstance(time, (float, str)):
        plpy.error('unexpected type for "time" parameter ({})'.format(type(time)))
    if isinstance(time, str):
        # if time is a string parse it to a datetime object
        time = dateutil.parser.parse(time)
    q = '''
        select t.name as name,
               t.parameters_column as params_column, t.parameters as params,
               tt.name as func_name, tt.func_signature as func_sign
        from li3ds.transfo t
        join li3ds.transfo_type tt on t.transfo_type = tt.id
        where t.id = {:d}
        '''.format(transfoid)
    plpy.debug(q)
    rv = plpy.execute(q)
    if len(rv) < 1:
        plpy.error('no transfo with id {:d}'.format(transfoid))
    transfo = rv[0]
    params_column = transfo['params_column']
    params = json.loads(transfo['params'])
    if params_column:
        # dynamic transform form 1
        if not time:
            plpy.error('no time value provided for dynamic transfo "{}"'
                       .format(transfo['name']))
        params = get_dyn_transfo_params_form_1(params_column, params, time)
    elif params:
        if len(params) > 1:
            # dynamic tranform form 2
            if not time:
                plpy.error('no time value provided for dynamic transfo "{}"'
                           .format(transfo['name']))
            params = get_dyn_transfo_params_form_2(params, time)
        else:
            # static transform
            params = params[0]
    if params is None:
        return None
    return transfo['name'], params, transfo['func_name'], transfo['func_sign']
Exemplo n.º 8
0
def _transform(obj, type_, func_name, func_sign, params):
    ''' Transform obj, whose type is type_, using func_name, func_sign and params.
    '''
    if func_name not in func_names:
        plpy.error('function {} is unknown'.format(func_name))
    func_name = func_names[func_name]
    if isinstance(params, basestring):  # NOQA
        params = json.loads(params)
    args = [params[p] for p in func_sign if p != '_time']
    args_str, args_val = args_to_array_string(args)
    q = 'select {}(\'{}\'::{}{}) r'.format(func_name, obj, type_, args_str)
    plpy.debug(q, args_val)
    plan = plpy.prepare(q, ['numeric'] * len(args_val))
    rv = plpy.execute(plan, args_val)
    if len(rv) != 1:
        plpy.error('unexpected number of rows ({}) returned from {}'.format(len(rv), q))
    result = rv[0].get('r')
    if result is None:
        plpy.error('unexpected value None returned from {}'.format(q))
    return result
Exemplo n.º 9
0
        )
        if len(query_result) == 0:
            return zip([None], [None], [None], [None], [None])
    except plpy.SPIError, err:
        plpy.debug('Query failed with exception %s: %s' % (err, pu.construct_neighbor_query(w_type, qvals)))
        plpy.error('Query failed, check the input parameters')
        return zip([None], [None], [None], [None], [None])

    ## build weight
    weights = pu.get_weight(query_result, w_type)
    weights.transform = 'r'

    ## prep time data
    t_data = get_time_data(query_result, time_cols)

    plpy.debug('shape of t_data %d, %d' % t_data.shape)
    plpy.debug('number of weight objects: %d, %d' % (weights.sparse).shape)
    plpy.debug('first num elements: %f' % t_data[0, 0])

    sp_markov_result = ps.Spatial_Markov(t_data,
                                         weights,
                                         k=num_classes,
                                         fixed=False,
                                         permutations=permutations)

    ## get lag classes
    lag_classes = ps.Quantiles(
        ps.lag_spatial(weights, t_data[:, -1]),
        k=num_classes).yb

    ## look up probablity distribution for each unit according to class and lag class
Exemplo n.º 10
0
        query_result = plpy.execute(pu.construct_neighbor_query(w_type, qvals))
        if len(query_result) == 0:
            return zip([None], [None], [None], [None], [None])
    except plpy.SPIError, e:
        plpy.debug("Query failed with exception %s: %s" % (err, pu.construct_neighbor_query(w_type, qvals)))
        plpy.error("Analysis failed: %s" % e)
        return zip([None], [None], [None], [None], [None])

    ## build weight
    weights = pu.get_weight(query_result, w_type)
    weights.transform = "r"

    ## prep time data
    t_data = get_time_data(query_result, time_cols)

    plpy.debug("shape of t_data %d, %d" % t_data.shape)
    plpy.debug("number of weight objects: %d, %d" % (weights.sparse).shape)
    plpy.debug("first num elements: %f" % t_data[0, 0])

    sp_markov_result = ps.Spatial_Markov(t_data, weights, k=num_classes, fixed=False, permutations=permutations)

    ## get lag classes
    lag_classes = ps.Quantiles(ps.lag_spatial(weights, t_data[:, -1]), k=num_classes).yb

    ## look up probablity distribution for each unit according to class and lag class
    prob_dist = get_prob_dist(sp_markov_result.P, lag_classes, sp_markov_result.classes[:, -1])

    ## find the ups and down and overall distribution of each cell
    trend_up, trend_down, trend, volatility = get_prob_stats(prob_dist, sp_markov_result.classes[:, -1])

    ## output the results
Exemplo n.º 11
0
        if len(query_result) == 0:
            return zip([None], [None], [None], [None], [None])
    except plpy.SPIError, e:
        plpy.debug('Query failed with exception %s: %s' %
                   (err, pu.construct_neighbor_query(w_type, qvals)))
        plpy.error('Analysis failed: %s' % e)
        return zip([None], [None], [None], [None], [None])

    ## build weight
    weights = pu.get_weight(query_result, w_type)
    weights.transform = 'r'

    ## prep time data
    t_data = get_time_data(query_result, time_cols)

    plpy.debug('shape of t_data %d, %d' % t_data.shape)
    plpy.debug('number of weight objects: %d, %d' % (weights.sparse).shape)
    plpy.debug('first num elements: %f' % t_data[0, 0])

    sp_markov_result = ps.Spatial_Markov(t_data,
                                         weights,
                                         k=num_classes,
                                         fixed=False,
                                         permutations=permutations)

    ## get lag classes
    lag_classes = ps.Quantiles(ps.lag_spatial(weights, t_data[:, -1]),
                               k=num_classes).yb

    ## look up probablity distribution for each unit according to class and lag class
    prob_dist = get_prob_dist(sp_markov_result.P, lag_classes,