Page MenuHomec4science

rooftop_handling.py
No OneTemporary

File Metadata

Created
Wed, Apr 30, 23:29

rooftop_handling.py

import numpy as np
import pandas as pd
import xarray as xr
import util
from scipy.spatial.distance import cdist
import os
def create_mask( meteo_xr, var = 'SIS', sum_dim = 'timestamp' ):
# create a mask boolean mask indicating all sums greater than 0 (i.e. values inside CH) summed over multiple timesteps
# NOTE: xarray dataframe spatial coordinates must be labelled "x" and "y"
mask = meteo_xr[ var ].sum( dim = sum_dim ).where(meteo_xr[ var ].sum( dim = sum_dim ) > 0) * 0 + 1
mask = mask.rename('CH')
mask_idx = mask.assign_coords( x = range(len( mask.x )) )
mask_idx = mask_idx.assign_coords( y = range(len( mask.y )) )
return mask_idx.to_dataset()
def link_rooftops_with_pixels( rooftop_frame, meteo_xarray,
rooftop_coords = ['XCOORD', 'YCOORD'],
meteo_coords = ['x', 'y'],
new_columns = ['x_idx', 'y_idx']):
# creates columns 'x_idx' and 'y_idx' on rooftop_frame, giving the index for the x- and y- coordinate of each
x_link = pd.DataFrame(data = meteo_xarray[meteo_coords[0]].values, columns = [meteo_coords[0]]).reset_index()
y_link = pd.DataFrame(data = meteo_xarray[meteo_coords[1]].values, columns = [meteo_coords[1]]).reset_index()
for roof_coord, meteo_coord, new_column,link in zip(rooftop_coords, meteo_coords, new_columns, [x_link, y_link]):
# merge on one coordinate (first on x, then on y):q
rooftop_frame = pd.merge_asof(rooftop_frame.sort_values( roof_coord ), link.sort_values( meteo_coord ),
left_on= roof_coord , right_on= meteo_coord ,
direction = 'nearest' )
rooftop_frame.drop(meteo_coord, axis=1, inplace=True)
rooftop_frame.rename(index=str, columns={"index": new_column}, inplace = True)
## CHECK FOR COORDINATES THAT ARE OUTSIDE CH AND ASSIGN TO CLOSEST PIXEL IN CH
# create a pandas dataframe with a list of all coordinates that are in CH
index_mask = create_mask( meteo_xarray )
idx_CH = util.to_pandas( index_mask )
# merge that information to the linked dataframe, so there is a column "CH" that is [0, 1]
check_CH = rooftop_frame.merge(idx_CH, left_on = ['x_idx', 'y_idx'], right_on = ['x', 'y'], how = 'left')
check_CH.CH.fillna(0, inplace = True)
# get points outside CH and coordinates of CH
outside_CH = check_CH.loc[ check_CH.CH == 0 ]
CH_coords = idx_CH.drop('CH', axis = 1)
# calcualte distances and get index for coordinates of closest pixels
distance_matrix = cdist( outside_CH.loc[:,['x_idx', 'y_idx']], CH_coords )
min_distances = np.argmin( distance_matrix, axis = 1 )
# fill data in linked dataframe and drop unnecessary columns
check_CH.loc[ check_CH.CH == 0, ['x_idx', 'y_idx'] ] = CH_coords.loc[ min_distances, : ].values
corrected_frame = check_CH.drop( columns = ['x', 'y', 'CH'])
return corrected_frame
def get_tilt_category(column):
# define different categories of NEIGUNG (= rooftop tilt)
if column.NEIGUNG < 5 : return 'flat'
elif column.NEIGUNG < 20 : return 'shallow_tilt'
elif column.NEIGUNG < 45 : return 'medium_tilt'
else : return 'steep_tilt'
def get_orientation_category(column):
# define different categories of AUSRICHTUNG (= rooftop orientation, 0 = S, 90 = W, -90 = E)
if abs(column.AUSRICHTUNG) < 22.5 : return 'S'
elif column.AUSRICHTUNG > 22.5 and column.AUSRICHTUNG < 67.5 : return 'SW'
elif column.AUSRICHTUNG < -22.5 and column.AUSRICHTUNG > -67.5 : return 'SE'
elif column.AUSRICHTUNG > 67.5 and column.AUSRICHTUNG < 112.5 : return 'W'
elif column.AUSRICHTUNG < -67.5 and column.AUSRICHTUNG > -112.5 : return 'E'
else : return 'N'

Event Timeline