Ejemplo n.º 1
0
    def test_init_with_iterable(self):
        N = 1000
        items = '*' * N
        header = 'Initialized with Iterable'
        chrono = Chronometer(items, header=header)
        self.assertEqual(chrono.get_total_count(), N)
        for i in range(N):
            if i % 100 == 0:
                chrono.issue(i)
            sleep(0.005)
            chrono.loop_and_show()

        chrono.resumee()
Ejemplo n.º 2
0
    def test_loop_and_show(self):
        N = 1000
        header = 'Initialized with integer'
        chrono = Chronometer(N, header=header)
        for i in range(N):
            if i % 100 == 0:
                chrono.issue(i)
            sleep(0.005)
            chrono.loop_and_show()

        chrono.resumee()
Ejemplo n.º 3
0
 def test_in_context(self):
     N = 3
     print('-----')
     print('Test context management')
     with Chronometer(N) as chrono:
         for n in range(N):
             print('Inside context, loop %i/%i' % (n + 1, N))
             chrono.loop_and_show()
     print('Outside context.')
     chrono.resumee()
     print('Outside context.')
     sleep(1)
Ejemplo n.º 4
0
 def test_exit_via_resumee(self):
     N = 3
     print('-----')
     print('Test exit function')
     chrono = Chronometer(N)
     for n in range(N):
         print('Inside context, loop %i/%i' % (n + 1, N))
         chrono.loop()
     print('Inside context.')
     chrono.resumee()
     print('Outside context.')
     sleep(1)
Ejemplo n.º 5
0
def compute_brightness_with_shadows(
        data, meta, height_factor, sun_zenith_angle, sun_azimuth_angle,
        ):
    """Cast shadows from higher tips to lower areas.

        Paramters
        ---------
        sun_zenith_angle
            (deg)
        sun_azimuth_angle
            (deg)
    """
    brightness = compute_brightness(
            data, meta, height_factor=height_factor,
            sun_zenith_angle=sun_zenith_angle,
            sun_azimuth_angle=sun_azimuth_angle,
            )
    if sun_zenith_angle == 0:
        return brightness

    # retrieve variables
    # =====================================================
    x, y, z = get_xyz(data, meta, height_factor)
    sun_x, sun_y, sun_z = get_sun_vector(sun_zenith_angle, sun_azimuth_angle)
    # =====================================================
    
    shadow_max = copy(z)
    z_min = np.nanmin(z)

    J, I = np.shape(data)
    header = 'Compute shadows'
    count = 0
    with Chronometer(J*I, header=header) as chrono:
        for j_obstacle, i_obstacle in itertools.product(range(J), range(I)):

            # chrono
            # ----------------------
            if count % 100 == 0:
                chrono.show()
            count += 1
            chrono.loop()
            # ----------------------

            # coordinates of the shadow-casting point
            # ---------------------------------------
            z_obstacle = z[j_obstacle, i_obstacle]
            y_obstacle = y[j_obstacle, i_obstacle]
            x_obstacle = x[j_obstacle, i_obstacle]
            # ---------------------------------------

            if np.abs(sun_x) >= np.abs(sun_y):
                # traverse in x-direction

                # ray of light
                # -------------------
                dx = x[j_obstacle, :] - x_obstacle
                dy = dx / sun_x * sun_y
                dz = dx / sun_x * sun_z

                y_ray = y_obstacle + dy
                z_ray = z_obstacle + dz
                # -------------------

                # index of i-positions that need to be checked
                # --------------------------------------------
                with warnings.catch_warnings():
                    warnings.simplefilter('ignore', RuntimeWarning)

                    # ray of light must be above ground
                    idx = z_ray > z_min

                    # ray of light must have hit the object (be below it)
                    idx &= dz < 0

                iterator = np.arange(I)[idx]
                # --------------------------------------------

                for i in iterator:
                    z_point = z_ray[i]

                    y_point = y_ray[i]
                    y_choice = y[:, i]

                    jlos = np.where(y_choice >= y_point)[0]
                    jhis = np.where(y_choice <= y_point)[0]

                    # check if ray of light/shadow is above the point
                    j_neighbours = []
                    if np.any(jlos):
                        j_neighbours.append(jlos[-1])
                    if np.any(jhis):
                        j_neighbours.append(jhis[0])

                    for j in j_neighbours:
                        if z_point > shadow_max[j, i]:
                            shadow_max[j, i] = z_point

            else:
                # traverse in y-direction

                # ray of light
                # -----------------------
                dy = y[:, i_obstacle] - y_obstacle
                dx = dy / sun_y * sun_x
                dz = dy / sun_y * sun_z

                x_ray = x_obstacle + dx
                z_ray = z_obstacle + dz
                # -----------------------

                # index of j-positions that need to be checked
                # --------------------------------------------
                with warnings.catch_warnings():
                    warnings.simplefilter('ignore', RuntimeWarning)

                    # ray of light must be above ground
                    jdx = z_ray > z_min

                    # ray of light must have hit the object (be below it)
                    jdx &= dz < 0

                iterator = np.arange(J)[jdx]
                # --------------------------------------------

                for j in iterator:
                    z_point = z_ray[j]

                    x_point = x_ray[j]
                    x_choice = x[j, :]

                    ilos = np.where(x_choice >= x_point)[0]
                    ihis = np.where(x_choice <= x_point)[0]

                    # check if ray of light/shadow is above the point
                    i_neighbours = []
                    if np.any(ilos):
                        i_neighbours.append(ilos[0])
                    if np.any(ihis):
                        i_neighbours.append(ihis[-1])

                    for i in i_neighbours:
                        if z_point > shadow_max[j, i]:
                            shadow_max[j, i] = z_point

        idx_dark = shadow_max > z
        brightness[idx_dark] = 0.
        return brightness
Ejemplo n.º 6
0
def interpolate_2d_linear_v2(
        x_in,
        y_in,
        samples,
        x_out,
        y_out,
        x_tolerance=0.,
        y_tolerance=0.,
        out_of_bounds = 'nan',
        info_on_screen=True,
        prefix='interpolate_2D_linear: ',
        assume_sorted=False,
        dtype=float,
        ):
    """Linear 2D-interpolation for numericals or datetime.
    
        Parameters
        ----------
        x_in, y_in
            the sample grid. They can both either be 1D-arrays of numercials or
            of instances of datetime
        samples: 2d-array
            the function values on the (x_in,y_in)-grid. Must be given in the
            form samples[x_in, y_in]
        x_out, y_out
            the grid on which samples will be interpolated. If the elements of
            x_in are instances of datetime, the those of x_out should be, too.
            The same holds for y_in and y_out.
        out_of_bounds : {'nan', 'zero'}
            if x_out or y_out are outside the input grid, then the output will
            be assigned this value
        dtype
            datatype of the output array.
       
        Returns
        -------
        The function returns a 2D-array which is a linear interpolation
        between the sample values in the form samples_out[x_out,y_out]
        
        To do
        -----
        implement `assume_sorted`
       
        Written in 2014
        by Andreas Anhaeuser
        Insitute for Geophysics and Meteorology
        University of Cologne
        Germany
        <*****@*****.**>
    """
    #### INPUT CHECK ###
    if not (len(x_in), len(y_in)) == np.shape(samples):
        raise AssertionError('Dimensions of x_in, y_in and samples do ' + \
            'not match.')
    xi = np.array(x_in)
    yi = np.array(y_in)
    xo = np.array(x_out)
    yo = np.array(y_out)
    zi = np.array(samples)
    
    # convert datetime_list into a numerical list:
    for c in [xi, yi, xo, yo]:
        if c[0].__class__ == dt.datetime:
            c[:] = np.array(du.datetime_to_seconds(c))

    # 2D linear interpolation function:
    f = interpolate_2d_one_point

    # out of bounds value:
    if out_of_bounds in ['zero', 'Zero', 'zeros', 'Zeros', '0', 0]:
        oob = 0
    elif out_of_bounds in ['nan', 'nans', 'NaN', 'NaNs', np.nan]:
        oob = np.nan

    X = len(xo)
    Y = len(yo)
    zo = np.zeros([X, Y], dtype=dtype)

    Ntotal = X * Y
    header = 'interpolate 2D'
    silent = not info_on_screen
    with Chronometer(Ntotal, header=header, silent=silent) as chrono:
        if silent:
            chrono.exit()

        for i, j in itertools.product(range(X), range(Y)):
            if not silent:
                chrono.show().loop()

            z = f(xi, yi, zi, xo[i], yo[j], oob, assume_sorted=assume_sorted)
            zo[i, j] = dtype(z)
                
    return zo 
Ejemplo n.º 7
0
def interpolate_1d_linear(
        x_in,
        val_in,
        x_out,
        x_tolerance=0,
        out_of_bounds='nearest',
        assume_sorted=True,
        many_nans=False,
        ):
    """Linear 1D-interpolation for numbers or datetime.

        x_in and x_out can be floats or datetime.datetime instances.
       
        Parameters
        ----------
        x_in : array of floats or list of datetime.datetime
        x_out : array of floats or list of datetime.datetime
        val_in : array of floats
            same length as x_in
        x_tolerance : float or datetime.timedelta, optional
            only nearest neighbours that are close than x_tolerance are
            considered. 0 causes infinite tolerance! Default: 0.
        out_of_bounds : {'zero', 'nan', 'nearest', 'ext', float}
            out of bounds value are replaced by this
            'ext' : extrapolate
        assume_sorted : bool
            if True, the function assumes that x_in be sorted in rising order
        many_nans : bool
            no effect (kept for backwards compatibility)
        
        Returns
        -------
        val_out : array
            The output is a linear interpolation between the sample values
            given in values_sample at the times given in val_in.     

        Notes
        -----
        float vs datetime.datetime:
            If some of x_in, x_out, or x_tolerance are given in numerical
            values and others as instances of datetime.datetime (or
            datetime.timedelta in the case of x_tolerance), the numericals are
            considered as seconds (since 1970).

        x_tolercance:
            if 0, this is interpreted as infinite tolerance!
       
        Author
        ------
        Written in 2014-2016
        by Andreas Anhaeuser
        Insitute for Geophysics and Meteorology
        University of Cologne
        Germany
        <*****@*****.**>
    """
    ###################################################
    # INPUT CHECK                                     #
    ###################################################
    assert len(x_in) == len(val_in)

    ###################################################
    # CONVERSIONS                                     #
    ###################################################
    if isinstance(x_in[0], dt.datetime):
        x_in = du.datetime_to_seconds(x_in)
    if isinstance(x_out[0], dt.datetime):
        x_out = du.datetime_to_seconds(x_out)
    if isinstance(x_tolerance, dt.timedelta):
        x_tolerance = x_tolerance.total_seconds()

    xis = np.array(x_in)
    xos = np.array(x_out)
    vis = np.array(val_in)
    tol = x_tolerance

    # tol: 0 --> inf
    if tol == 0:
        tol = np.inf

    ###################################################
    # SORT                                            #
    ###################################################
    # (recursively call function if unsorted)
    if not assume_sorted:
        idx = np.argsort(xis)
        xis = xis[idx]
        vis  = vis[idx]
        
        return interpolate_1d_linear(xis=xis,
            vis=vis, xos=xos, x_tolerance=tol, 
            out_of_bounds=out_of_bounds, assume_sorted=True)
        
    ###################################################
    # OUT OF BOUNDS                                   #
    ###################################################
    if out_of_bounds in ['nan', 'NaN']:
        oob  = 'val'
        oobv = np.nan
    elif out_of_bounds in ['zero', 'zeros', '0']:
        oob  = 'val'
        oobv = 0.
    elif isinstance(out_of_bounds, numbers.Number):
        oob  = 'val'
        oobv = out_of_bounds
    elif out_of_bounds == 'nearest':
        oob  = 'nn'
        oobv = None
    elif out_of_bounds == 'ext':
        raise NotImplementedError(
                'Current implementation seems buggy (AA 2016-09-25.)')
        oob  = 'ex'
        oobv = None
    else:
        raise ValueError('Uncrecognized out_of_bounds value: ' + 
                str(out_of_bounds))
    
    ###################################################
    # SPECIAL CASES                                   #
    ###################################################
    # special case: empty input array:
    if len(x_in) == 0:
        return np.array([oobv] * len(x_out))
    
    # special case: empty output array:
    if len(xos) == 0:
        return np.array([])
    
    ###################################################
    # MANY                                            #
    ###################################################
    neg = np.isnan(xis) | np.isnan(vis)
    use = ~neg
    xis = xis[use]
    vis = vis[use]

    ###################################################
    # SPECIAL CASES                                   #
    ###################################################
    # special case: input array length 0
    if len(xis) == 0:
        return np.nan * xos

    # special case: input array length 1
    if len(xis) == 1:
        if oobv is not None:
            # idea: all entries which are close enough (indices `pos`), are
            # assigned vis[0], all others are oobv

            # default
            vos = oobv * np.ones(len(xos))

            # find positions close enough
            diff = np.abs(xos - xis)
            pos = diff <= tol

            # assign them the only existing value
            vos[pos] = vis[0]
        else:
            # all out-values are equal to the single in-value
            vos = vis[0] * np.ones(len(xos))
        return vos
            
    ###################################################
    # INTERPOLATION FUNCTION                          #
    ###################################################
    def f(x1, x2, y1, y2, x):
        """Linear interpolation function."""
        # special case
        if x1 == x2:
            return y1

        # regular case
        m = (y2 - y1) / (x2 - x1)
        return y1 + m * (x - x1)        

    ###################################################
    # INITIALIZATION                                  #
    ###################################################
    N = len(xos)
    I = len(xis)
    vos = np.nan * np.empty(N)
    xlos = np.nan * np.empty(N)
    xhis = np.nan * np.empty(N)

    chrono = Chronometer(N, header='Interpolation')
    for n in range(N):
        chrono.loop_and_show()
        ###################################################
        # FIND NEAREST NEIGHBOUR                          #
        ###################################################
        xo = xos[n]
        xlo, ilo, vlo = nearest_neighbour(
            xis, xo,
            direction='down', values=vis, skip_nans=False, assume_sorted=True)
            
        xhi, ihi, vhi = nearest_neighbour(
                xis, xo, direction='up', values=vis,
                skip_nans=True, assume_sorted=True)

        # out of bounds:
        if xlo is None:
            xlo = -np.inf
        if xhi is None:
            xhi = +np.inf

        # out of tolerance:
        if xo - xlo > tol:
            xlo = -np.inf
        if xhi - xo > tol:
            xhi = +np.inf
        
        # distances:
        dlo = xo - xlo
        dhi = xhi - xo

        ###################################################
        # REGULAR CASE                                    #
        ###################################################
        if np.isfinite(dlo) and np.isfinite(dhi):
            vos[n] = f(xlo, xhi, vlo, vhi, xo)
            continue
      
        ###################################################
        # OUT OF TOLERANCE ON BOTH SIDES                  #
        ###################################################
        if ~np.isfinite(dlo) and ~np.isfinite(dhi):
            if oob == 'val':
                vos[n] = oobv
            continue

        ###################################################
        # OUT OF BOUNDS ON LOWER SIDE                     #
        ###################################################
        if ~np.isfinite(dlo) and np.isfinite(dhi):
            # constant value
            if oob == 'val':
                vos[n] = oobv
                continue

            # nearest neighbour
            elif oob == 'nn':
                vos[n] = vhi
                continue

            # extrapolate
            elif oob  == 'ex':
                # upper bound
                if ihi == I - 1:
                    vos[n] = vhi
                    continue

                # get next higher x
                xhi2 = xis[ihi+1]
                vhi2 = vis[ihi+1]
                dhi2 = xhi2 - xhi

                # xhi2 out of tolerance
                if dhi2 > tol:
                    vos[n] = vhi
                    continue

                # extrapolate
                vos[n] = f(xhi, xhi2, vhi, vhi2, xo)
                continue

        ###################################################
        # OUT OF BOUNDS ON UPPER SIDE                     #
        ###################################################
        if np.isfinite(dlo) and ~np.isfinite(dhi):
            # constant value
            if oob == 'val':
                vos[n] = oobv
                continue

            # nearest neighbour
            elif oob == 'nn':
                vos[n] = vlo
                continue

            # extrapolate
            elif oob  == 'ex':
                # lower bound
                if ilo == 0:
                    vos[n] = vlo
                    continue

                # get next higher x
                xlo2 = xis[ilo-1]
                vlo2 = vis[ilo-1]
                dlo2 = xlo - xlo2

                # xhi2 out of tolerance
                if dlo2 > tol:
                    vos[n] = vlo
                    continue

                # extrapolate
                vos[n] = f(xlo, xlo2, vlo, vlo2, xo)
                continue
    chrono.resumee()

    return vos
Ejemplo n.º 8
0
 def setUp(self):
     self.N = 300
     self.sleep_time = 0.005
     self.chrono = Chronometer(self.N)