YashMK89 commited on
Commit
4c16148
·
verified ·
1 Parent(s): ce3b002

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +47 -44
app.py CHANGED
@@ -251,60 +251,59 @@ def aggregate_data_yearly(collection):
251
  # return 0
252
  # return ee.Number(cloudy_pixels).divide(ee.Number(total_pixels)).multiply(100)
253
 
254
- def filter_images_by_cloud_percentage(collection, max_cloud_percentage):
255
- def calculate_cloud_percentage(image):
256
- # Extract the QA60 band
 
257
  qa60 = image.select('QA60')
258
-
259
- # Identify opaque and cirrus clouds
260
  opaque_clouds = qa60.bitwiseAnd(1 << 10)
261
  cirrus_clouds = qa60.bitwiseAnd(1 << 11)
262
  cloud_mask = opaque_clouds.Or(cirrus_clouds)
263
-
264
- # Count total pixels and cloudy pixels
265
- total_pixels = qa60.reduceRegion(
266
- reducer=ee.Reducer.count(),
267
- geometry=image.geometry(),
268
- scale=60,
269
- maxPixels=1e13
270
- ).get('QA60')
271
-
272
- cloudy_pixels = cloud_mask.reduceRegion(
273
- reducer=ee.Reducer.sum(),
274
- geometry=image.geometry(),
275
- scale=60,
276
- maxPixels=1e13
277
- ).get('QA60')
278
-
279
- # Calculate cloud percentage
280
- cloud_percentage = ee.Number(cloudy_pixels).divide(ee.Number(total_pixels)).multiply(100)
281
-
282
- # Return the cloud percentage as a property of the image
283
- return image.set('cloud_percentage', cloud_percentage)
284
-
285
- # Map the cloud percentage calculation over the collection
286
- collection_with_clouds = collection.map(calculate_cloud_percentage)
287
-
288
- # Filter out images with cloud percentage exceeding the threshold
289
- filtered_collection = collection_with_clouds.filter(ee.Filter.lt('cloud_percentage', max_cloud_percentage))
290
 
291
- return filtered_collection
292
-
293
- # Preprocessing function
294
  def preprocess_collection(collection, pixel_cloud_threshold):
295
  def mask_cloudy_pixels(image):
296
- qa60 = image.select('QA60')
297
- opaque_clouds = qa60.bitwiseAnd(1 << 10)
298
- cirrus_clouds = qa60.bitwiseAnd(1 << 11)
299
- cloud_mask = opaque_clouds.Or(cirrus_clouds)
 
 
 
 
 
 
 
 
300
  clear_pixels = cloud_mask.Not()
301
  return image.updateMask(clear_pixels)
302
-
303
  if pixel_cloud_threshold > 0:
304
  return collection.map(mask_cloudy_pixels)
305
  return collection
306
 
307
- # Process single geometry
308
  # Process single geometry
309
  def process_single_geometry(row, start_date_str, end_date_str, dataset_id, selected_bands, reducer_choice, shape_type, aggregation_period, custom_formula, original_lat_col, original_lon_col, kernel_size=None, include_boundary=None, user_scale=None, pixel_cloud_threshold=0):
310
  if shape_type.lower() == "point":
@@ -423,10 +422,14 @@ def process_aggregation(locations_df, start_date_str, end_date_str, dataset_id,
423
 
424
  st.write(f"Original Collection Size: {raw_collection.size().getInfo()}")
425
 
426
- # Apply cloud filtering at the image level
427
  if pixel_cloud_threshold > 0:
428
- raw_collection = filter_images_by_cloud_percentage(raw_collection, pixel_cloud_threshold)
429
- st.write(f"Filtered Collection Size (After Cloud Masking): {raw_collection.size().getInfo()}")
 
 
 
 
430
 
431
  # Use ThreadPoolExecutor to process each geometry
432
  with ThreadPoolExecutor(max_workers=10) as executor:
 
251
  # return 0
252
  # return ee.Number(cloudy_pixels).divide(ee.Number(total_pixels)).multiply(100)
253
 
254
+ def calculate_cloud_percentage(image):
255
+ # Check if QA60 band exists (Level-1C)
256
+ bands = image.bandNames().getInfo()
257
+ if 'QA60' in bands:
258
  qa60 = image.select('QA60')
 
 
259
  opaque_clouds = qa60.bitwiseAnd(1 << 10)
260
  cirrus_clouds = qa60.bitwiseAnd(1 << 11)
261
  cloud_mask = opaque_clouds.Or(cirrus_clouds)
262
+ elif 'SCL' in bands: # Check if SCL band exists (Level-2A)
263
+ scl = image.select('SCL')
264
+ cloud_mask = scl.eq(8).Or(scl.eq(9)).Or(scl.eq(10)) # Cloud, cirrus, snow/ice
265
+ else:
266
+ raise ValueError("Cloud masking bands (QA60 or SCL) not found in the dataset.")
267
+
268
+ total_pixels = cloud_mask.reduceRegion(
269
+ reducer=ee.Reducer.count(),
270
+ geometry=image.geometry(),
271
+ scale=60,
272
+ maxPixels=1e13
273
+ ).get('constant') # Use 'constant' for renamed bands
274
+
275
+ cloudy_pixels = cloud_mask.reduceRegion(
276
+ reducer=ee.Reducer.sum(),
277
+ geometry=image.geometry(),
278
+ scale=60,
279
+ maxPixels=1e13
280
+ ).get('constant')
281
+
282
+ if total_pixels == 0:
283
+ return 0
284
+ return ee.Number(cloudy_pixels).divide(ee.Number(total_pixels)).multiply(100)
 
 
 
 
285
 
 
 
 
286
  def preprocess_collection(collection, pixel_cloud_threshold):
287
  def mask_cloudy_pixels(image):
288
+ bands = image.bandNames().getInfo()
289
+ if 'QA60' in bands: # Level-1C
290
+ qa60 = image.select('QA60')
291
+ opaque_clouds = qa60.bitwiseAnd(1 << 10)
292
+ cirrus_clouds = qa60.bitwiseAnd(1 << 11)
293
+ cloud_mask = opaque_clouds.Or(cirrus_clouds)
294
+ elif 'SCL' in bands: # Level-2A
295
+ scl = image.select('SCL')
296
+ cloud_mask = scl.eq(8).Or(scl.eq(9)).Or(scl.eq(10)) # Cloud, cirrus, snow/ice
297
+ else:
298
+ raise ValueError("Cloud masking bands (QA60 or SCL) not found in the dataset.")
299
+
300
  clear_pixels = cloud_mask.Not()
301
  return image.updateMask(clear_pixels)
302
+
303
  if pixel_cloud_threshold > 0:
304
  return collection.map(mask_cloudy_pixels)
305
  return collection
306
 
 
307
  # Process single geometry
308
  def process_single_geometry(row, start_date_str, end_date_str, dataset_id, selected_bands, reducer_choice, shape_type, aggregation_period, custom_formula, original_lat_col, original_lon_col, kernel_size=None, include_boundary=None, user_scale=None, pixel_cloud_threshold=0):
309
  if shape_type.lower() == "point":
 
422
 
423
  st.write(f"Original Collection Size: {raw_collection.size().getInfo()}")
424
 
425
+ # Apply cloud filtering if applicable
426
  if pixel_cloud_threshold > 0:
427
+ try:
428
+ raw_collection = preprocess_collection(raw_collection, pixel_cloud_threshold)
429
+ st.write(f"Filtered Collection Size (After Cloud Masking): {raw_collection.size().getInfo()}")
430
+ except Exception as e:
431
+ st.error(f"Cloud masking failed: {str(e)}")
432
+ st.stop()
433
 
434
  # Use ThreadPoolExecutor to process each geometry
435
  with ThreadPoolExecutor(max_workers=10) as executor: