<jupyter_start><jupyter_text>Sentinel-2 Mineral RGB Composite  Service definition<jupyter_code>service = dict([('title', 'Sentinel-2 Mineral RGB Composite'),
                ('abstract', 'Sentinel-2 Mineral RGB Composite'),
                ('id', 'ewf-s2-mineral-composite')])<jupyter_output><empty_output><jupyter_text>Service parameters  Runtime parameter definition **Input identifiers**This is the Sentinel-1 stack of products' identifiers<jupyter_code>input_identifiers = ['A8204ADAC1D07DE1AAFCC0C87CFDB6CB1DDAD310',
                     '<KEY>'] 

aoi = dict([('id', 'aoi'),
            ('title', 'Area of interest (bbox)'),
            ('abstract', 'Area of interest defined as a bounding box'),
            ('value', '-70.5659,-13.0922,-69.1411,-12.4567')])<jupyter_output><empty_output><jupyter_text>**Input references**This is the Sentinel-1 stack catalogue references<jupyter_code>input_references = ['https://catalog.terradue.com/sen2cor/search?format=atom&uid=A8204ADAC1D07DE1AAFCC0C87CFDB6CB1DDAD310',
                     'https://catalog.terradue.com/sen2cor/search?format=atom&uid=57D0F4788C1C7DB2898D9F1C256F2D391B184453']<jupyter_output><empty_output><jupyter_text>**Data path**This path defines where the data is staged-in.<jupyter_code>data_path = '/workspace/data'
username = dict([('id', '_T2Username'),
              ('title', 'Ellip username'),
              ('abstract', 'Ellip username'),
              ('value', '')])
api_key = dict([('id', '_T2ApiKey'),
              ('title', 'Ellip API key for data pipeline'),
              ('abstract', 'Ellip API key for data pipeline'),
              ('value', '')])<jupyter_output><empty_output><jupyter_text>Workflow<jupyter_code>import cioppy
from shapely.wkt import loads
import pandas as pd
import os
import sys
sys.path.append('/application/notebook/libexec/') 
sys.path.append(os.getcwd())

sys.path.append('/opt/OTB/lib/python')
sys.path.append('/opt/OTB/lib/libfftw3.so.3')
os.environ['OTB_APPLICATION_PATH'] = '/opt/OTB/lib/otb/applications'
os.environ['LD_LIBRARY_PATH'] = '/opt/OTB/lib'
os.environ['ITK_AUTOLOAD_PATH'] = '/opt/OTB/lib/otb/applications'

import otbApplication
from helpers import *
import geopandas as gpd
import requests
%load_ext autoreload
%autoreload 2
ciop = cioppy.Cioppy()
creds = '{0}:{1}'.format(username['value'], api_key['value'])
for index, reference in enumerate(input_references):
    print reference
                                        
                                           
temp_searches = []

for index, reference in enumerate(input_references):

    temporary_item =ciop.search(end_point=reference,
                                      params=[],
                                       output_fields='self,track,enclosure,identifier,wkt,startdate,enddate,platform,cc', 
                                       model='EOP',creds=creds)

    
        
    search_temp = gpd.GeoDataFrame(temporary_item)
    if 'https://catalog.terradue.com/sentinel2/' in temporary_item[0]['self'] :
        original_identifier= temporary_item[0]['identifier']   
        
    else: 
        original_identifier = get_original_identifier(temporary_item[0]['self'],username['value'], api_key['value'])
    search_temp['local_path'] = os.path.join(data_path, original_identifier)
    search_temp['original_identifier'] = original_identifier
    temp_searches.append(search_temp)
    
search = gpd.GeoDataFrame(pd.concat(temp_searches, ignore_index=True)) 

search['geometry'] = search['wkt'].apply(loads)
search['cc'] = pd.to_numeric(search['cc'])
search['startdate'] = pd.to_datetime(search['startdate'])
search['enddate'] = pd.to_datetime(search['enddate'])                                           
                                           
                                           

    
    
search
search = search.merge(search.apply(lambda row: analyse(row ), axis=1),
                                    left_index=True,
                                  right_index=True)
search


aoi_wkt = box(*[float(i) for i in aoi['value'].split(',')]).wkt

min_lon, min_lat,  max_lon, max_lat = [float(i) for i in aoi['value'].split(',')]

bands = ['B02', 'B04', 'B11', 'B12', 'SCL']
for index, band in enumerate(bands):
    
    vrt_bands = []
    
    for j, row in search.iterrows():
        
        vrt_bands.append(get_band_path(row, band))
    
    vrt = '{0}.vrt'.format(band)
    ds = gdal.BuildVRT(vrt,
                       vrt_bands,
                       #srcNodata=0,
                       xRes=10, 
                       yRes=10)

    ds.FlushCache()
    
    
    gdal.Translate(band + '.tif', 
                   ds, 
                   outputType=gdal.GDT_Float32, 
                   projWin=[min_lon, max_lat, max_lon, min_lat],
                   projWinSRS='EPSG:4326')
r_channel = 'im4b1 !=0 ? im3b1 / im4b1 : 0'
g_channel = 'im1b1 !=0 ? im2b1 / im1b1 : 0'
b_channel = 'im3b1 !=0 ? im2b1 / im3b1 : 0'
alpha_channel = '{0} == 0 || {0} == 1 || {0} == 3 || {0} == 8 || {0} == 9 ? 0 : 1'.format('im5b1') 
band_expressions = [r_channel, 
                    g_channel, 
                    b_channel,
                    alpha_channel]
BandMathX = otbApplication.Registry.CreateApplication("BandMathX")

BandMathX.SetParameterStringList('il', [b + '.tif' for b in bands])

BandMathX.SetParameterString('out', 'temp.tif')

BandMathX.SetParameterString('exp', ';'.join(band_expressions))

BandMathX.ExecuteAndWriteOutput()
output_startdate = min(search['startdate'])
output_stopdate = max(search['enddate'])
date_format = '%Y%m%dT%H%m%S'

output_name = 'MINERAL-COMPOSITE-{0}-{1}'.format(output_startdate.strftime(date_format), 
                                                 output_stopdate.strftime(date_format))
Convert = otbApplication.Registry.CreateApplication('Convert')


Convert.SetParameterString('in', 'temp.tif')

Convert.SetParameterString('out', 'temp_{}.tif'.format(output_name))

Convert.SetParameterString('type', 'linear')

Convert.SetParameterString('channels', 'all')

Convert.ExecuteAndWriteOutput()
cog('temp_{}.tif'.format(output_name),
    '{}.tif'.format(output_name))<jupyter_output><empty_output><jupyter_text>Clean-up<jupyter_code>for band in bands:
    for extension in ['.tif', '.vrt']:
        os.remove(band + extension)
        
os.remove('temp.tif')<jupyter_output><empty_output><jupyter_text>Create RGB (4bands) with Mask of changes (0-255 values)<jupyter_code>from helpers import *
out_rgb = '{}-rgb'.format(output_name)

create_rgb('{}.tif'.format(output_name), '{}.tif'.format(out_rgb))<jupyter_output><empty_output><jupyter_text>Metadata about results<jupyter_code>for properties_file in ['result', 'stage-in', output_name, out_rgb]:

    date_format = '%Y-%m-%dT%H:%m:%SZ'
    
    if properties_file == 'result':
        
        title = 'Reproducibility notebook used for generating {0}'.format(output_name)
   
    elif properties_file == 'stage-in':

        title = 'Reproducibility stage-in notebook for Sentinel-2 data for generating {0}'.format(output_name)
    
    
        
    elif properties_file == out_rgb:
        
        title = 'RGB composite for {0} to {1}'.format(output_startdate.strftime(date_format),
                                                                  output_stopdate.strftime(date_format))
    
    else: 
      
        title = 'Mineral alteration index from {0} to {1}'.format(output_startdate.strftime(date_format),
                                                                  output_stopdate.strftime(date_format))
        
    with open(properties_file + '.properties', 'wb') as file:
        file.write('title={0}\n'.format(title))
        file.write('date={0}/{1}\n'.format(output_startdate.strftime(date_format),
                                           output_stopdate.strftime(date_format)))
        file.write('geometry={0}'.format(get_image_wkt(output_name + '.tif')))<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.14031545741324922, 'fraction_numerical': 0.022712933753943218, 'mean_word_length': 2.7923444976076555, 'pattern_counts': {'":': 0, '<': 34, '<?xml version=': 0, '>': 34, 'https://': 3, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 18, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '8', 'dir': 'jupyter-structured-clean-dedup', 'id': '171493', 'license': 'Apache-2.0', 'n_tokens_mistral': 2655, 'n_tokens_neox': 2500, 'n_words': 412, 'path': 'src/main/app-resources/notebook/libexec/input.ipynb', 'repo_name': 'ec-better/ewf-satcen-02-02-01-', 'size': '7960'}