Skip to content

Commit

Permalink
adds baseline functionality to other product types
Browse files Browse the repository at this point in the history
  • Loading branch information
kim committed Dec 5, 2023
1 parent fa21107 commit 6eb8ab4
Show file tree
Hide file tree
Showing 12 changed files with 186 additions and 56 deletions.
10 changes: 7 additions & 3 deletions asf_search/ASFProduct.py
Original file line number Diff line number Diff line change
Expand Up @@ -143,9 +143,9 @@ def get_stack_opts(self) -> ASFSearchOptions:
:return: ASFSearchOptions describing appropriate options for building a stack from this product
"""
from .search.baseline_search import get_stack_opts
# from .search.baseline_search import get_stack_opts

return get_stack_opts(reference=self)
return {}

def centroid(self) -> Point:
"""
Expand Down Expand Up @@ -212,7 +212,8 @@ def _get_property_paths() -> dict:
def get_baseline_calc_properties(self) -> dict:
return {}

def get_default_product_type(self):
@staticmethod
def get_default_product_type():
# scene_name = product.properties['sceneName']

# if get_platform(scene_name) in ['AL']:
Expand All @@ -224,3 +225,6 @@ def get_default_product_type(self):
# return 'BURST'
# return 'SLC'
return None

def is_valid_reference(self):
return False
22 changes: 15 additions & 7 deletions asf_search/Products/ALOSProduct.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,17 +31,17 @@ def get_baseline_calc_properties(self) -> dict:

return None

def get_stack_opts(self, reference: ASFProduct,
def get_stack_opts(self,
opts: ASFSearchOptions = None):

stack_opts = (ASFSearchOptions() if opts is None else copy(opts))
stack_opts.processingLevel = self.get_default_product_type(reference)
stack_opts.processingLevel = ALOSProduct.get_default_product_type()

if reference.properties['insarStackId'] not in [None, 'NA', 0, '0']:
stack_opts.insarStackId = reference.properties['insarStackId']
if self.properties.get('insarStackId') not in [None, 'NA', 0, '0']:
stack_opts.insarStackId = self.properties['insarStackId']
return stack_opts

raise ASFBaselineError(f'Requested reference product needs a baseline stack ID but does not have one: {reference.properties["fileID"]}')
raise ASFBaselineError(f'Requested reference product needs a baseline stack ID but does not have one: {self.properties["fileID"]}')

@staticmethod
def _get_property_paths() -> dict:
Expand All @@ -50,5 +50,13 @@ def _get_property_paths() -> dict:
**ALOSProduct.base_properties
}

def get_default_product_type(self):
return 'L1.1'
@staticmethod
def get_default_product_type():
return 'L1.1'

def is_valid_reference(self):
# we don't stack at all if any of stack is missing insarBaseline, unlike stacking S1 products(?)
if 'insarBaseline' not in self.baseline:
raise ValueError('No baseline values available for precalculated dataset')

return True
5 changes: 3 additions & 2 deletions asf_search/Products/ARIAS1GUNWProduct.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,6 @@ def _get_property_paths() -> dict:
**ARIAS1GUNWProduct.base_properties
}

def get_default_product_type(self):
return 'BURST'
@staticmethod
def get_default_product_type():
return None
37 changes: 36 additions & 1 deletion asf_search/Products/ERSProduct.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import copy
from asf_search import ASFSession, ASFProduct
from asf_search import ASFSearchOptions, ASFSession, ASFProduct
from asf_search.CMR.translate import get_state_vector, get as umm_get, cast as umm_cast, try_parse_float, try_parse_int, try_round_float
from asf_search.constants import PLATFORM
from asf_search.exceptions import ASFBaselineError

class ERSProduct(ASFProduct):
base_properties = {
Expand All @@ -20,10 +21,44 @@ class ERSProduct(ASFProduct):

def __init__(self, args: dict = {}, session: ASFSession = ASFSession()):
super().__init__(args, session)
self.baseline = self.get_baseline_calc_properties()

def get_baseline_calc_properties(self) -> dict:
insarBaseline = umm_cast(float, umm_get(self.umm, 'AdditionalAttributes', ('Name', 'INSAR_BASELINE'), 'Values', 0))

if insarBaseline is not None:
return {
'insarBaseline': insarBaseline
}

return None

def get_stack_opts(self,
opts: ASFSearchOptions = None):

stack_opts = (ASFSearchOptions() if opts is None else copy(opts))
stack_opts.processingLevel = ERSProduct.get_default_product_type()

if self.properties.get('insarStackId') not in [None, 'NA', 0, '0']:
stack_opts.insarStackId = self.properties['insarStackId']
return stack_opts

raise ASFBaselineError(f'Requested reference product needs a baseline stack ID but does not have one: {self.properties["fileID"]}')

@staticmethod
def _get_property_paths() -> dict:
return {
**ASFProduct._get_property_paths(),
**ERSProduct.base_properties
}

@staticmethod
def get_default_product_type():
return 'L0'

def is_valid_reference(self):
# we don't stack at all if any of stack is missing insarBaseline, unlike stacking S1 products(?)
if 'insarBaseline' not in self.baseline:
raise ValueError('No baseline values available for precalculated dataset')

return True
37 changes: 36 additions & 1 deletion asf_search/Products/JERSProduct.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import copy
from asf_search import ASFSession, ASFProduct
from asf_search import ASFSearchOptions, ASFSession, ASFProduct
from asf_search.CMR.translate import get_state_vector, get as umm_get, cast as umm_cast, try_parse_float, try_parse_int
from asf_search.constants import PLATFORM
from asf_search.exceptions import ASFBaselineError

class JERSProduct(ASFProduct):
base_properties = {
Expand All @@ -20,10 +21,44 @@ class JERSProduct(ASFProduct):

def __init__(self, args: dict = {}, session: ASFSession = ASFSession()):
super().__init__(args, session)
self.baseline = self.get_baseline_calc_properties()

def get_baseline_calc_properties(self) -> dict:
insarBaseline = umm_cast(float, umm_get(self.umm, 'AdditionalAttributes', ('Name', 'INSAR_BASELINE'), 'Values', 0))

if insarBaseline is not None:
return {
'insarBaseline': insarBaseline
}

return None

@staticmethod
def _get_property_paths() -> dict:
return {
**ASFProduct._get_property_paths(),
**JERSProduct.base_properties
}

def get_stack_opts(self,
opts: ASFSearchOptions = None):

stack_opts = (ASFSearchOptions() if opts is None else copy(opts))
stack_opts.processingLevel = JERSProduct.get_default_product_type()

if self.properties.get('insarStackId') not in [None, 'NA', 0, '0']:
stack_opts.insarStackId = self.properties['insarStackId']
return stack_opts

raise ASFBaselineError(f'Requested reference product needs a baseline stack ID but does not have one: {self.properties["fileID"]}')

@staticmethod
def get_default_product_type():
return 'L0'

def is_valid_reference(self):
# we don't stack at all if any of stack is missing insarBaseline, unlike stacking S1 products(?)
if 'insarBaseline' not in self.baseline:
raise ValueError('No baseline values available for precalculated dataset')

return True
10 changes: 9 additions & 1 deletion asf_search/Products/OPERAS1Product.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,5 +54,13 @@ def _get_property_paths() -> dict:
**OPERAS1Product.base_properties
}

def get_default_product_type(self):
@staticmethod
def get_default_product_type():
return 'CSLC'

def is_valid_reference(self):
# we don't stack at all if any of stack is missing insarBaseline, unlike stacking S1 products(?)
if 'insarBaseline' not in self.baseline:
raise ValueError('No baseline values available for precalculated dataset')

return True
29 changes: 25 additions & 4 deletions asf_search/Products/RadarsatProduct.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
from asf_search import ASFSession, ASFProduct
import copy
from asf_search import ASFSearchOptions, ASFSession, ASFProduct
from asf_search.CMR.translate import get as umm_get, cast as umm_cast, try_parse_float, try_parse_int
from asf_search.exceptions import ASFBaselineError

class RadarsatProduct(ASFProduct):
base_properties = {
Expand Down Expand Up @@ -29,13 +31,32 @@ def get_baseline_calc_properties(self) -> dict:

return None

def get_stack_opts(self,
opts: ASFSearchOptions = None):

stack_opts = (ASFSearchOptions() if opts is None else copy(opts))
stack_opts.processingLevel = RadarsatProduct.get_default_product_type()

if self.properties.get('insarStackId') not in [None, 'NA', 0, '0']:
stack_opts.insarStackId = self.properties['insarStackId']
return stack_opts

raise ASFBaselineError(f'Requested reference product needs a baseline stack ID but does not have one: {self.properties["fileID"]}')

@staticmethod
def _get_property_paths() -> dict:
return {
**ASFProduct._get_property_paths(),
**RadarsatProduct.base_properties
}

def get_default_product_type(self):
# if get_platform(scene_name) in ['R1', 'E1', 'E2', 'J1']:
return 'L0'
@staticmethod
def get_default_product_type():
return 'L0'

def is_valid_reference(self):
# we don't stack at all if any of stack is missing insarBaseline, unlike stacking S1 products(?)
if 'insarBaseline' not in self.baseline:
raise ValueError('No baseline values available for precalculated dataset')

return True
16 changes: 13 additions & 3 deletions asf_search/Products/S1BURSTProduct.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from asf_search import ASFSession
import copy
from asf_search import ASFSearchOptions, ASFSession
from asf_search.Products import S1Product
from asf_search.CMR.translate import get, try_parse_int
from asf_search.CMR.translate import get_state_vector, get as umm_get, cast as umm_cast
Expand All @@ -17,7 +18,7 @@ class S1BURSTProduct(S1Product):
def __init__(self, args: dict = {}, session: ASFSession = ASFSession()):
super().__init__(args, session)
self.properties['sceneName'] = self.properties['fileID']
self.properties['bytes'] = umm_get(self.umm, ['AdditionalAttributes', ('Name', 'BYTE_LENGTH'), 'Values', 0])
self.properties['bytes'] = umm_get(self.umm, 'AdditionalAttributes', ('Name', 'BYTE_LENGTH'), 'Values', 0)
self.properties['burst'] = {
'absoluteBurstID': self.properties.pop('absoluteBurstID'),
'relativeBurstID': self.properties.pop('relativeBurstID'),
Expand All @@ -35,12 +36,21 @@ def __init__(self, args: dict = {}, session: ASFSession = ASFSession()):
self.properties['fileName'] = self.properties['fileID'] + '.' + urls[0].split('.')[-1]
self.properties['additionalUrls'] = [urls[1]]

def get_stack_opts(self, opts: ASFSearchOptions = None):
stack_opts = (ASFSearchOptions() if opts is None else copy(opts))

stack_opts.processingLevel = S1BURSTProduct.get_default_product_type()
stack_opts.fullBurstID = self.properties['burst']['fullBurstID']
stack_opts.polarization = [self.properties['polarization']]
return stack_opts

@staticmethod
def _get_property_paths() -> dict:
return {
**S1Product._get_property_paths(),
**S1BURSTProduct.base_properties
}

def get_default_product_type(self):
@staticmethod
def get_default_product_type():
return 'BURST'
47 changes: 34 additions & 13 deletions asf_search/Products/S1Product.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import copy
from asf_search import ASFSession, ASFProduct
from asf_search import ASFSearchOptions, ASFSession, ASFProduct
from asf_search.CMR.translate import get_state_vector, get as umm_get, cast as umm_cast, try_parse_int
from asf_search.constants import PLATFORM

Expand Down Expand Up @@ -48,18 +48,29 @@ def get_state_vectors(self) -> dict:
'velocities': velocities
}

def get_stack_opts(self):
def get_stack_opts(self,
opts: ASFSearchOptions = None):

# stack_opts = (ASFSearchOptions() if opts is None else copy(opts))
return {
'processingLevel': 'SLC',
'beamMode': [self.properties['beamModeType']],
'flightDirection': self.properties['flightDirection'],
'relativeOrbit': [int(self.properties['pathNumber'])], # path
'platform': [PLATFORM.SENTINEL1A, PLATFORM.SENTINEL1B],
'polarization': ['HH','HH+HV'] if self.properties['polarization'] in ['HH','HH+HV'] else ['VV', 'VV+VH'],
'intersectsWith': self.centroid().wkt
}
stack_opts = (ASFSearchOptions() if opts is None else copy(opts))

stack_opts.processingLevel = S1Product.get_default_product_type()
stack_opts.beamMode = [self.properties['beamModeType']]
stack_opts.flightDirection = self.properties['flightDirection']
stack_opts.relativeOrbit = [int(self.properties['pathNumber'])], # path
stack_opts.platform = [PLATFORM.SENTINEL1A, PLATFORM.SENTINEL1B]
stack_opts.polarization = ['HH','HH+HV'] if self.properties['polarization'] in ['HH','HH+HV'] else ['VV', 'VV+VH']
stack_opts.intersectsWith = self.centroid().wkt

return stack_opts
# return {
# 'processingLevel': 'SLC',
# 'beamMode': [self.properties['beamModeType']],
# 'flightDirection': self.properties['flightDirection'],
# 'relativeOrbit': [int(self.properties['pathNumber'])], # path
# 'platform': [PLATFORM.SENTINEL1A, PLATFORM.SENTINEL1B],
# 'polarization': ['HH','HH+HV'] if self.properties['polarization'] in ['HH','HH+HV'] else ['VV', 'VV+VH'],
# 'intersectsWith': self.centroid().wkt
# }
# if reference.properties['processingLevel'] == 'BURST':
# stack_opts.processingLevel = 'BURST'
# else:
Expand Down Expand Up @@ -93,5 +104,15 @@ def _get_property_paths() -> dict:
**S1Product.base_properties
}

def get_default_product_type(self):
@staticmethod
def get_default_product_type():
return 'SLC'

def is_valid_reference(self):
return self.valid_state_vectors()

def valid_state_vectors(self):
for key in ['postPosition', 'postPositionTime', 'prePosition', 'postPositionTime']:
if key not in self.baseline['stateVectors']['positions'] or self.baseline['stateVectors']['positions'][key] == None:
return False
return True
Loading

0 comments on commit 6eb8ab4

Please sign in to comment.