<s> """<STR_LIT>""" <EOL> import param <EOL> from . . core . operation import ElementOperation <EOL> from . . element import Raster <EOL> from . . core import Overlay <EOL> from . . core . util import match_spec <EOL> class Normalization ( ElementOperation ) : <EOL> """<STR_LIT>""" <EOL> data_range = param . Boolean ( default = False , doc = """<STR_LIT>""" ) <EOL> ranges = param . ClassSelector ( default = { } , allow_None = True , <EOL> class_ = ( dict , list ) , doc = """<STR_LIT>""" ) <EOL> keys = param . List ( default = None , allow_None = True , doc = """<STR_LIT>""" ) <EOL> def __call__ ( self , element , ranges = { } , keys = None , ** params ) : <EOL> params = dict ( params , ranges = ranges , keys = keys ) <EOL> return super ( Normalization , self ) . __call__ ( element , ** params ) <EOL> def process_element ( self , element , key , ranges = { } , keys = None , ** params ) : <EOL> params = dict ( params , ranges = ranges , keys = keys ) <EOL> self . p = param . ParamOverrides ( self , params ) <EOL> return self . _process ( element , key ) <EOL> def get_ranges ( self , element , key ) : <EOL> """<STR_LIT>""" <EOL> keys = self . p [ '<STR_LIT>' ] <EOL> ranges = self . p [ '<STR_LIT>' ] <EOL> if ranges == { } : <EOL> return { d . name : element . range ( d . name , self . data_range ) <EOL> for d in element . dimensions ( ) } <EOL> if keys is None : <EOL> specs = ranges <EOL> elif keys and not isinstance ( ranges , list ) : <EOL> raise ValueError ( "<STR_LIT>" <EOL> "<STR_LIT>" ) <EOL> elif len ( keys ) == len ( ranges ) : <EOL> try : <EOL> index = keys . index ( key ) <EOL> specs = ranges [ index ] <EOL> except : <EOL> raise KeyError ( "<STR_LIT>" ) <EOL> else : <EOL> raise ValueError ( "<STR_LIT>" ) <EOL> return match_spec ( element , specs ) <EOL> def _process ( self , view , key = None ) : <EOL> raise NotImplementedError ( "<STR_LIT>" ) <EOL> class raster_normalization ( Normalization ) : <EOL> """<STR_LIT>""" <EOL> def _process ( self , raster , key = None ) : <EOL> if isinstance ( raster , Raster ) : <EOL> return self . _normalize_raster ( raster , key ) <EOL> elif isinstance ( raster , Overlay ) : <EOL> overlay_clone = raster . clone ( shared_data = False ) <EOL> for k , el in raster . items ( ) : <EOL> overlay_clone [ k ] = self . _normalize_raster ( el , key ) <EOL> return overlay_clone <EOL> else : <EOL> raise ValueError ( "<STR_LIT>" ) <EOL> def _normalize_raster ( self , raster , key ) : <EOL> if not isinstance ( raster , Raster ) : return raster <EOL> norm_raster = raster . clone ( raster . data . copy ( ) ) <EOL> ranges = self . get_ranges ( raster , key ) <EOL> for depth , name in enumerate ( d . name for d in raster . vdims ) : <EOL> depth_range = ranges . get ( name , ( None , None ) ) <EOL> if None in depth_range : continue <EOL> if depth_range and len ( norm_raster . data . shape ) == <NUM_LIT:2> : <EOL> depth_range = ranges [ name ] <EOL> norm_raster . data [ : , : ] -= depth_range [ <NUM_LIT:0> ] <EOL> range = ( depth_range [ <NUM_LIT:1> ] - depth_range [ <NUM_LIT:0> ] ) <EOL> if range : <EOL> norm_raster . data [ : , : ] /= range <EOL> elif depth_range : <EOL> norm_raster . data [ : , : , depth ] -= depth_range [ <NUM_LIT:0> ] <EOL> range = ( depth_range [ <NUM_LIT:1> ] - depth_range [ <NUM_LIT:0> ] ) <EOL> if range : <EOL> norm_raster . data [ : , : , depth ] /= range <EOL> return norm_raster </s>
