<jupyter_start><jupyter_text>[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/worldbank/OpenNightLights/blob/master/onl/tutorials/mod3_5_expressions-PartA.ipynb) Expressions (10 min)In the previous sub-module, {doc}`mod3_4_cell_statistics_band_math`, we executed some simple mathmatical operations on Images; however, sometimes we have multi-step operations or more complicated expressions we wish to apply.For that, we can use the `.expression()` method built-in to the Image class.In this tutorial we'll shift back to DMSP-OLS data and take a sneak peak at a process for intercalibrating DMSP data. As noted in {doc}`mod1_2_introduction_to_nighttime_light_data`, this is necessary when analyzing a DMSP-OLS time series. We get into this in much more detail in a later tutorial on DMSP-OLS intercalibration, but for now, we'll introduce the use of expressions in Google Earth Engine.In order to manage memory for our interactive maps when publishing, we'll split this into two notebooks, A and B -- but consider them a single exercise.**Our tasks in this exercise:**Part A:1. Invert a 1996 DMSP-OLS composite using built-in functions.Part B:2. Conduct an equivalent operation using `.expression()`3. Apply a simple polynomial formula for DMSP-OLS intercalibration co-efficients to a 1996 composite. Invert an image with Image functions Initialize map with DMSP-OLS layerFirst, as we've often done, let's initialize a map object.Here we'll center our scene on Mexico City.And we'll pull the annual DMSP-OLS nightime lights composite for 1996, using the "stable lights" band.<jupyter_code># reminder that if you are installing libraries in a Google Colab instance you will be prompted to restart your kernal

try:
    import geemap, ee
except ModuleNotFoundError:
    if 'google.colab' in str(get_ipython()):
        print("package not found, installing w/ pip in Google Colab...")
        !pip install geemap
    else:
        print("package not found, installing w/ conda...")
        !conda install mamba -c conda-forge -y
        !mamba install geemap -c conda-forge -y
    import geemap, ee
try:
        ee.Initialize()
except Exception as e:
        ee.Authenticate()
        ee.Initialize()

# # initialize our map and center on Mexico City, Mexico
lat = 19.43
lon = -99.13
map1 = geemap.Map(center=[lat,lon],zoom=6)
map1.add_basemap('SATELLITE')

# get 1996 composite, apply mask, and add as layer
dmsp1996 = ee.Image("NOAA/DMSP-OLS/NIGHTTIME_LIGHTS/F121996").select('stable_lights')
map1.addLayer(dmsp1996.mask(dmsp1996), {}, "DMSP-OLS 1996", opacity=0.75)
map1.addLayerControl()
map1<jupyter_output><empty_output><jupyter_text>Invert an imageLet's say we want to invert an image. We know our max value (our Digital Number, if you recall) for DMSP-OLS images is 63. So if we multiply everything by -1 and then add 63. So, for example what was a DN of 63 before (the max) is now a 0 and vice versa.We can do this using the built-in functions `.multiply` and `.add()`**Note**: we selected our band, `stable_lights` above and saved to our variable `dmsp1996`, but if we didnt before we would have to do that here to explicitly apply our operation, including expression, to a specific band.<jupyter_code>dmsp1996_inv = dmsp1996.multiply(-1).add(63)<jupyter_output><empty_output><jupyter_text>Visualize the inverse imageWe'll view the transformed (inverted) image we just created and compare it to the original image with a split map.**Note:** to ensure we're comparing them on the same scale, we're using the visual parameters in the `.addLayer()` function, which allows us to do a few things to our image, such as clip the image to "min" and "max" values.Warning, this is based on `ipyleaflet` a Python library that does not play well with Google Colab, so the split panel display will not work in the Google Colab environment but should on your local machine.<jupyter_code>map2 = geemap.Map(center=[lat,lon],zoom=6)
map2.addLayerControl()

dmsp96_tile = geemap.ee_tile_layer(dmsp1996, {'min':0,'max':63}, 'DMSP NTL 1996', opacity=0.75)
dmsp96inv_tile = geemap.ee_tile_layer(dmsp1996_inv, {'min':0,'max':63}, 'DMSP NTL 1996 inverse', opacity=0.75)

map2.split_map(left_layer=dmsp96_tile, right_layer=dmsp96inv_tile)

map2<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.08832369942196532, 'fraction_numerical': 0.03005780346820809, 'mean_word_length': 4.861788617886178, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 13, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '3', 'dir': 'jupyter-structured-clean-dedup', 'id': '409108', 'license': 'CC-BY-4.0', 'n_tokens_mistral': 1423, 'n_tokens_neox': 1317, 'n_words': 527, 'path': 'onl/tutorials/mod3_5_expressions-PartA.ipynb', 'repo_name': 'rajtimsina07/OpenNightLights', 'size': '4325'}