@@ -148,8 +148,10 @@ def list_poly_from_list_string_coords(str_coords_list):
148
148
'satellite' : (scalar , '//safe:platform/safe:number' ),
149
149
'start_date' : (date_converter , '//safe:acquisitionPeriod/safe:startTime' ),
150
150
'stop_date' : (date_converter , '//safe:acquisitionPeriod/safe:stopTime' ),
151
- 'aux_cal' : (scalar ,
152
- '//metadataSection/metadataObject/metadataWrap/xmlData/safe:processing/safe:resource/safe:processing/safe:resource[@role="AUX_CAL"]/@name' ),
151
+
152
+ 'aux_cal' : (scalar , '//metadataSection/metadataObject/metadataWrap/xmlData/safe:processing/safe:resource/safe:processing/safe:resource[@role="AUX_CAL"]/@name' ),
153
+ 'aux_pp1' : (scalar , '//metadataSection/metadataObject/metadataWrap/xmlData/safe:processing/safe:resource/safe:processing/safe:resource[@role="AUX_PP1"]/@name' ),
154
+
153
155
'aux_cal_sl2' : (scalar ,'//metadataSection/metadataObject/metadataWrap/xmlData/safe:processing/safe:resource[@role="AUX_CAL"]/@name' ),
154
156
'annotation_files' : (
155
157
normpath , '/xfdu:XFDU/dataObjectSection/*[@repID="s1Level1ProductSchema"]/byteStream/fileLocation/@href' ),
@@ -302,8 +304,32 @@ def list_poly_from_list_string_coords(str_coords_list):
302
304
'fmrate_azimuthFmRatePolynomial' : (
303
305
list_of_float_1D_array_from_string ,
304
306
'//product/generalAnnotation/azimuthFmRateList/azimuthFmRate/azimuthFmRatePolynomial' ),
305
-
306
- },
307
+
308
+ 'ap_azimuthTime' : (
309
+ datetime64_array , '/product/antennaPattern/antennaPatternList/antennaPattern/azimuthTime' ),
310
+ 'ap_roll' : (float_array , '/product/antennaPattern/antennaPatternList/antennaPattern/roll' ),
311
+ 'ap_swath' : (lambda x : np .array (x ), '/product/antennaPattern/antennaPatternList/antennaPattern/swath' ),
312
+
313
+ 'ap_elevationAngle' : (
314
+ list_of_float_1D_array_from_string , '/product/antennaPattern/antennaPatternList/antennaPattern/elevationAngle' ),
315
+ 'ap_incidenceAngle' : (
316
+ list_of_float_1D_array_from_string , '/product/antennaPattern/antennaPatternList/antennaPattern/incidenceAngle' ),
317
+ 'ap_slantRangeTime' : (
318
+ list_of_float_1D_array_from_string , '/product/antennaPattern/antennaPatternList/antennaPattern/slantRangeTime' ),
319
+ 'ap_terrainHeight' : (
320
+ float_array , '/product/antennaPattern/antennaPatternList/antennaPattern/terrainHeight' ),
321
+ 'ap_elevationPattern' : (
322
+ list_of_float_1D_array_from_string , '/product/antennaPattern/antennaPatternList/antennaPattern/elevationPattern' ),
323
+
324
+ 'sm_nbPerSwat' : (int_array , '/product/swathMerging/swathMergeList/swathMerge/swathBoundsList/@count' ),
325
+ 'sm_swath' : (lambda x : np .array (x ), '/product/swathMerging/swathMergeList/swathMerge/swath' ),
326
+ 'sm_azimuthTime' : (datetime64_array , '/product/swathMerging/swathMergeList/swathMerge/swathBoundsList/swathBounds/azimuthTime' ),
327
+ 'sm_firstAzimuthLine' : (int_array , '/product/swathMerging/swathMergeList/swathMerge/swathBoundsList/swathBounds/firstAzimuthLine' ),
328
+ 'sm_lastAzimuthLine' : (int_array , '/product/swathMerging/swathMergeList/swathMerge/swathBoundsList/swathBounds/lastAzimuthLine' ),
329
+ 'sm_firstRangeSample' : (int_array , '/product/swathMerging/swathMergeList/swathMerge/swathBoundsList/swathBounds/firstRangeSample' ),
330
+ 'sm_lastRangeSample' : (int_array , '/product/swathMerging/swathMergeList/swathMerge/swathBoundsList/swathBounds/lastRangeSample' ),
331
+
332
+ },
307
333
'xsd' : {'all' : (str , '/xsd:schema/xsd:complexType/xsd:sequence/xsd:element/xsd:annotation/xsd:documentation' ),
308
334
'names' : (str , '/xsd:schema/xsd:complexType/xsd:sequence/xsd:element/@name' ),
309
335
'sensingtime' : (str , '/xsd:schema/xsd:complexType/xsd:sequence/xsd:element/sensingTime' )
@@ -694,6 +720,7 @@ def doppler_centroid_estimates(nb_dcestimate,
694
720
'source' : xpath_mappings ['annotation' ]['dc_rmserrAboveThres' ][
695
721
1 ]},
696
722
coords = {'azimuthTime' : dc_azimuth_time })
723
+
697
724
return ds
698
725
699
726
@@ -716,6 +743,147 @@ def geolocation_grid(line, sample, values):
716
743
values = np .reshape (values , shape )
717
744
return xr .DataArray (values , dims = ['line' , 'sample' ], coords = {'line' : line , 'sample' : sample })
718
745
746
+ def antenna_pattern (ap_swath ,ap_roll ,ap_azimuthTime ,ap_terrainHeight ,ap_elevationAngle ,ap_elevationPattern ,ap_incidenceAngle ,ap_slantRangeTime ):
747
+ """
748
+
749
+ Parameters
750
+ ----------
751
+ ap_swath
752
+ ap_roll
753
+ ap_azimuthTime
754
+ ap_terrainHeight
755
+ ap_elevationAngle
756
+ ap_elevationPattern
757
+ ap_incidenceAngle
758
+ ap_slantRangeTime
759
+
760
+ Returns
761
+ -------
762
+ xarray.DataSet
763
+ """
764
+ # Fonction to convert string 'EW1' ou 'IW3' as int
765
+ def convert_to_int (swath ):
766
+ return int (swath [- 1 ])
767
+ vectorized_convert = np .vectorize (convert_to_int )
768
+ swathNumber = vectorized_convert (ap_swath )
769
+
770
+ dim_azimuthTime = max (np .bincount (swathNumber ))
771
+ dim_slantRangeTime = max (array .shape [0 ] for array in ap_elevationAngle )
772
+
773
+ include_roll = len (ap_roll ) != 0
774
+
775
+ # Create 2Ds arrays
776
+ elevAngle2d = np .full ((len (ap_elevationAngle ), dim_slantRangeTime ), np .nan )
777
+ gain2d = np .full ((len (ap_elevationPattern ), dim_slantRangeTime ), np .nan )
778
+ slantRangeTime2d = np .full ((len (ap_slantRangeTime ), dim_slantRangeTime ), np .nan )
779
+ incAngle2d = np .full ((len (ap_incidenceAngle ), dim_slantRangeTime ), np .nan )
780
+
781
+
782
+ for i in range (len (ap_elevationAngle )):
783
+ elevAngle2d [i , :ap_elevationAngle [i ].shape [0 ]] = ap_elevationAngle [i ]
784
+
785
+ if ap_elevationAngle [i ].shape [0 ] != ap_elevationPattern [i ].shape [0 ] :
786
+ gain2d [i , :ap_elevationAngle [i ].shape [0 ]] = np .sqrt (ap_elevationPattern [i ][::2 ]** 2 + ap_elevationPattern [i ][1 ::2 ]** 2 )
787
+ else :
788
+ #logging.warn("antenna pattern is not given in complex values. You probably use an old file\n" + e)
789
+ gain2d [i , :ap_elevationAngle [i ].shape [0 ]] = ap_elevationPattern [i ]
790
+
791
+ slantRangeTime2d [i , :ap_slantRangeTime [i ].shape [0 ]] = ap_slantRangeTime [i ]
792
+ incAngle2d [i , :ap_incidenceAngle [i ].shape [0 ]] = ap_incidenceAngle [i ]
793
+
794
+
795
+ swath_number_2d = np .full ((len (np .unique (swathNumber )), dim_azimuthTime ), np .nan )
796
+ roll_angle_2d = np .full ((len (np .unique (swathNumber )), dim_azimuthTime ), np .nan )
797
+ azimuthTime_2d = np .full ((len (np .unique (swathNumber )), dim_azimuthTime ), np .nan )
798
+ terrainHeight_2d = np .full ((len (np .unique (swathNumber )), dim_azimuthTime ), np .nan )
799
+
800
+ slantRangeTime_2d = np .full ((len (np .unique (swathNumber )), dim_slantRangeTime ), np .nan )
801
+
802
+ elevationAngle_3d = np .full ((len (np .unique (swathNumber )), dim_azimuthTime , dim_slantRangeTime ), np .nan )
803
+ incidenceAngle_3d = np .full ((len (np .unique (swathNumber )), dim_azimuthTime , dim_slantRangeTime ), np .nan )
804
+ gain3d = np .full ((len (np .unique (swathNumber )), dim_azimuthTime , dim_slantRangeTime ), np .nan )
805
+
806
+
807
+ for i , swath_number in enumerate (np .unique (swathNumber )):
808
+ length_dim0 = len (ap_azimuthTime [swathNumber == swath_number ])
809
+ swath_number_2d [i , :length_dim0 ] = swathNumber [swathNumber == swath_number ]
810
+ azimuthTime_2d [i , :length_dim0 ] = ap_azimuthTime [swathNumber == swath_number ]
811
+ terrainHeight_2d [i , :length_dim0 ] = ap_terrainHeight [swathNumber == swath_number ]
812
+ slantRangeTime_2d [i , :] = slantRangeTime2d [i , :]
813
+
814
+ if include_roll :
815
+ roll_angle_2d [i , :length_dim0 ] = ap_roll [swathNumber == swath_number ]
816
+
817
+ for j in range (0 , dim_slantRangeTime ):
818
+ elevationAngle_3d [i ,:length_dim0 ,j ]= elevAngle2d [swathNumber == swath_number ,j ]
819
+ incidenceAngle_3d [i ,:length_dim0 ,j ]= incAngle2d [swathNumber == swath_number ,j ]
820
+ gain3d [i ,:length_dim0 ,j ]= gain2d [swathNumber == swath_number ,j ]
821
+
822
+ azimuthTime_2d = azimuthTime_2d .astype ('datetime64[ns]' )
823
+
824
+ # return a Dataset
825
+ ds = xr .Dataset ({
826
+ 'slantRangeTime' : (['swath_nb' , 'dim_slantRangeTime' ], slantRangeTime_2d ),
827
+ 'swath' : (['swath_nb' , 'dim_azimuthTime' ], swath_number_2d ),
828
+ 'roll' : (['swath_nb' , 'dim_azimuthTime' ], roll_angle_2d ),
829
+ 'azimuthTime' : (['swath_nb' , 'dim_azimuthTime' ], azimuthTime_2d ),
830
+ 'terrainHeight' : (['swath_nb' , 'dim_azimuthTime' ], terrainHeight_2d ),
831
+ 'elevationAngle' : (['swath_nb' , 'dim_azimuthTime' ,'dim_slantRangeTime' ],elevationAngle_3d ),
832
+ 'incidenceAngle' : (['swath_nb' , 'dim_azimuthTime' ,'dim_slantRangeTime' ],incidenceAngle_3d ),
833
+ 'gain' : (['swath_nb' , 'dim_azimuthTime' ,'dim_slantRangeTime' ],gain3d ),
834
+ },
835
+ coords = {'swath_nb' : np .unique (swathNumber )}
836
+ )
837
+ ds .attrs ["dim_azimuthTime" ] = "max dimension of azimuthTime for a swath"
838
+ ds .attrs ["dim_slantRangeTime" ] = "max dimension of slantRangeTime for a swath"
839
+ ds .attrs ["comment" ] = "The antenna pattern data set record contains a list of vectors of the \
840
+ antenna elevation pattern values that have been updated along track\
841
+ and used to correct the radiometry during image processing."
842
+ ds .attrs ["example" ] = "for example, if swath Y is smaller than swath X, user has to remove nan to get the dims of the swath"
843
+ ds .attrs ["source" ] = "Sentinel-1 Product Specification"
844
+
845
+ return ds
846
+
847
+ def swath_merging (sm_swath ,sm_nbPerSwat ,sm_azimuthTime ,sm_firstAzimuthLine ,sm_lastAzimuthLine ,sm_firstRangeSample ,sm_lastRangeSample ):
848
+ """
849
+
850
+ Parameters
851
+ ----------
852
+ sm_swath
853
+ sm_nbPerSwat
854
+ sm_azimuthTime
855
+ sm_firstAzimuthLine
856
+ sm_lastAzimuthLine
857
+ sm_firstRangeSample
858
+ sm_lastRangeSample
859
+
860
+ Returns
861
+ -------
862
+ xarray.DataSet
863
+ """
864
+ # Fonction to convert string 'EW1' ou 'IW3' as int
865
+ def convert_to_int (swath ):
866
+ return int (swath [- 1 ])
867
+ vectorized_convert = np .vectorize (convert_to_int )
868
+ repeated_swaths = np .repeat (sm_swath , sm_nbPerSwat )
869
+ swathNumber = vectorized_convert (repeated_swaths )
870
+
871
+ ds = xr .Dataset ({
872
+ 'swaths' : (['dim_azimuthTime' ], swathNumber ),
873
+ 'azimuthTime' : (['dim_azimuthTime' ], sm_azimuthTime ),
874
+ 'firstAzimuthLine' : (['dim_azimuthTime' ], sm_firstAzimuthLine ),
875
+ 'lastAzimuthLine' : (['dim_azimuthTime' ], sm_lastAzimuthLine ),
876
+ 'firstRangeSample' : (['dim_azimuthTime' ], sm_firstRangeSample ),
877
+ 'lastRangeSample' : (['dim_azimuthTime' ], sm_lastRangeSample ),
878
+ },
879
+ )
880
+ ds .attrs ["comment" ] = "The swath merging data set record contains information about how \
881
+ multiple swaths were stitched together to form one large contiguous \
882
+ swath. This data set record only applies to IW and EW GRD \
883
+ products"
884
+ ds .attrs ["source" ] = "Sentinel-1 Product Specification"
885
+
886
+ return ds
719
887
720
888
# dict of compounds variables.
721
889
# compounds variables are variables composed of several variables.
@@ -732,7 +900,8 @@ def geolocation_grid(line, sample, values):
732
900
'start_date' : 'manifest.start_date' ,
733
901
'stop_date' : 'manifest.stop_date' ,
734
902
'footprints' : 'manifest.footprints' ,
735
- 'aux_cal' : 'manifest.aux_cal'
903
+ 'aux_cal' : 'manifest.aux_cal' ,
904
+ 'aux_pp1' : 'manifest.aux_pp1'
736
905
},
737
906
'safe_attributes_sl2' : {
738
907
'ipf_version' : 'manifest.ipf_version' ,
@@ -856,4 +1025,17 @@ def geolocation_grid(line, sample, values):
856
1025
857
1026
),
858
1027
},
1028
+ 'antenna_pattern' : {
1029
+ 'func' : antenna_pattern ,
1030
+ 'args' : ('annotation.ap_swath' ,'annotation.ap_roll' ,'annotation.ap_azimuthTime' ,'annotation.ap_terrainHeight' ,
1031
+ 'annotation.ap_elevationAngle' ,'annotation.ap_elevationPattern' ,'annotation.ap_incidenceAngle' ,
1032
+ 'annotation.ap_slantRangeTime'
1033
+ )
1034
+ },
1035
+ 'swath_merging' : {
1036
+ 'func' : swath_merging ,
1037
+ 'args' : ('annotation.sm_swath' ,'annotation.sm_nbPerSwat' ,'annotation.sm_azimuthTime' ,'annotation.sm_firstAzimuthLine' ,
1038
+ 'annotation.sm_lastAzimuthLine' ,'annotation.sm_firstRangeSample' ,'annotation.sm_lastRangeSample'
1039
+ )
1040
+ },
859
1041
}
0 commit comments