Commit c08f4096 authored by Christian Hohmann's avatar Christian Hohmann
Browse files

Merge branch 'dev' into 'master'

Added optional boolean argument to gts2_client - ‘onlytime’

See merge request !10
parents e853fc9a 5b71871e
Pipeline #10190 passed with stages
in 25 minutes and 31 seconds
...@@ -64,9 +64,12 @@ class Gts2Request(dict): ...@@ -64,9 +64,12 @@ class Gts2Request(dict):
assert opts["sensor"] in ["S2A", "S2B", "S2all"] assert opts["sensor"] in ["S2A", "S2B", "S2all"]
assert opts["level"] in ["L1C", "L2A"] assert opts["level"] in ["L1C", "L2A"]
# onlytime=False seems to act as onlytime=True, therefore it has to be omitted completelly if false
onlytime = "&onlytime=True" if opts["onlytime"] else ""
self.api_fmt = "{address}/{bands}/{date_from}_{date_to}/{ll_lon:.5f}_{ur_lon:.5f}_{ll_lat:.5f}_{ur_lat:.5f}" \ self.api_fmt = "{address}/{bands}/{date_from}_{date_to}/{ll_lon:.5f}_{ur_lon:.5f}_{ll_lat:.5f}_{ur_lat:.5f}" \
"?minimum_fill={minimum_fill}&sensor={sensor}&level={level}&version={version}&suffix={suffix}" \ "?minimum_fill={minimum_fill}&sensor={sensor}&level={level}&version={version}&suffix={suffix}" \
"&max_cloudy={max_cloudy}&utm_zone={utm_zone}" "&max_cloudy={max_cloudy}&utm_zone={utm_zone}" + onlytime
# construct api call # construct api call
self.api_call = self.api_fmt.format(address=address, bands=opts["bands"], date_from=opts["date_from"], self.api_call = self.api_fmt.format(address=address, bands=opts["bands"], date_from=opts["date_from"],
...@@ -711,7 +714,7 @@ def __get_auth(logger=None): ...@@ -711,7 +714,7 @@ def __get_auth(logger=None):
def client(outpath="", out_prefix="", out_mode="json", geo_ll=(), geo_ur=(), sensor="S2A", bands="", max_cloudy="0.5", def client(outpath="", out_prefix="", out_mode="json", geo_ll=(), geo_ur=(), sensor="S2A", bands="", max_cloudy="0.5",
level="L2A", start_date="", end_date="", version="0.13", suffix="", minimum_fill="", level="L2A", start_date="", end_date="", version="0.13", suffix="", minimum_fill="",
only_tile="", stack_resolution="10", quiet=False, rgb_extension="jpg", rgb_bands_selection="realistic", only_tile="", stack_resolution="10", quiet=False, rgb_extension="jpg", rgb_bands_selection="realistic",
merge_tifs=False, merge_tile=None): merge_tifs=False, merge_tile=None, onlytime=False):
""" """
Downloads data via API and saves it in a wanted file format (.json, .tiff or .nc) or alternatively returns a python Downloads data via API and saves it in a wanted file format (.json, .tiff or .nc) or alternatively returns a python
dictionary. dictionary.
...@@ -765,6 +768,9 @@ def client(outpath="", out_prefix="", out_mode="json", geo_ll=(), geo_ur=(), sen ...@@ -765,6 +768,9 @@ def client(outpath="", out_prefix="", out_mode="json", geo_ll=(), geo_ur=(), sen
if out_mode != "rgb" and bands == "": if out_mode != "rgb" and bands == "":
raise AssertionError("Please provide at least one band.") raise AssertionError("Please provide at least one band.")
if onlytime and out_mode not in ["json", "python"]:
raise AssertionError("Invalid output mode. If onlytime==True, choose either 'python' or 'json'")
valid_out_modes = ["json", "nc", "single", "stack", "python", "rgb"] valid_out_modes = ["json", "nc", "single", "stack", "python", "rgb"]
try: try:
assert out_mode in valid_out_modes assert out_mode in valid_out_modes
...@@ -782,7 +788,8 @@ def client(outpath="", out_prefix="", out_mode="json", geo_ll=(), geo_ur=(), sen ...@@ -782,7 +788,8 @@ def client(outpath="", out_prefix="", out_mode="json", geo_ll=(), geo_ur=(), sen
# options # options
opts = {"ll": geo_ll, "ur": geo_ur, "sensor": sensor, "bands": bands, opts = {"ll": geo_ll, "ur": geo_ur, "sensor": sensor, "bands": bands,
"max_cloudy": max_cloudy, "auth": auth, "level": level, "date_from": start_date, "date_to": end_date, "max_cloudy": max_cloudy, "auth": auth, "level": level, "date_from": start_date, "date_to": end_date,
"version": version, "suffix": suffix, "minimum_fill": minimum_fill, "utm_zone": only_tile, "logger": logger} "version": version, "suffix": suffix, "minimum_fill": minimum_fill, "utm_zone": only_tile, "logger": logger,
"onlytime": onlytime}
# actual API request # actual API request
logger.info("Requesting data from the GTS2 server ...", ) logger.info("Requesting data from the GTS2 server ...", )
...@@ -808,9 +815,9 @@ def client(outpath="", out_prefix="", out_mode="json", geo_ll=(), geo_ur=(), sen ...@@ -808,9 +815,9 @@ def client(outpath="", out_prefix="", out_mode="json", geo_ll=(), geo_ur=(), sen
if out_mode == "json": if out_mode == "json":
logger.info("Saving data to json file ...", ) logger.info("Saving data to json file ...", )
json_outfile = "{path}/S2_{level}_{pref}_{lla}_{llo}_{ura}_{uro}_{sdate}_{edate}_{band}.json".format( json_outfile = "{path}/S2_{level}_{pref}_{lla}_{llo}_{ura}_{uro}_{sdate}_{edate}_{band}{onlytime}.json".format(
path=outpath, pref=out_prefix, sdate=start_date, edate=end_date, band=bands, level=level, path=outpath, pref=out_prefix, sdate=start_date, edate=end_date, band=bands, level=level,
lla=geo_ll[0], llo=geo_ll[1], ura=geo_ur[0], uro=geo_ur[1]) lla=geo_ll[0], llo=geo_ll[1], ura=geo_ur[0], uro=geo_ur[1], onlytime="_onlytime" if onlytime else "")
with open(json_outfile, 'w') as f: with open(json_outfile, 'w') as f:
json.dump(api_result, f, indent=4) json.dump(api_result, f, indent=4)
...@@ -910,6 +917,8 @@ if __name__ == "__main__": ...@@ -910,6 +917,8 @@ if __name__ == "__main__":
help="Merge tifs and RGBs if area in two or more MGRS tiles per time step (True or False).") help="Merge tifs and RGBs if area in two or more MGRS tiles per time step (True or False).")
parser.add_argument("-x", "--merge_tile", action="store", required=False, type=str, default=None, parser.add_argument("-x", "--merge_tile", action="store", required=False, type=str, default=None,
help="Choose MGRS tile into which the merge of files is performed (e.g. 33UUV).") help="Choose MGRS tile into which the merge of files is performed (e.g. 33UUV).")
parser.add_argument("-p", "--onlytime", action="store", required=False, type=str2bool, default=False,
help="get the available timestamps for a specific request without downloading any rasterdata")
args = parser.parse_args() args = parser.parse_args()
...@@ -934,4 +943,5 @@ if __name__ == "__main__": ...@@ -934,4 +943,5 @@ if __name__ == "__main__":
rgb_extension=args.rgb_extension, rgb_extension=args.rgb_extension,
rgb_bands_selection=args.rgb_bands_selection, rgb_bands_selection=args.rgb_bands_selection,
merge_tifs=args.merge_tifs, merge_tifs=args.merge_tifs,
merge_tile=args.merge_tile) merge_tile=args.merge_tile,
onlytime=args.onlytime)
...@@ -40,13 +40,14 @@ class TestGts2Client(unittest.TestCase): ...@@ -40,13 +40,14 @@ class TestGts2Client(unittest.TestCase):
:return: :return:
""" """
out_modes = ["json", "single", "stack", "stack", "nc", "nc", "rgb", "rgb"] out_modes = ["json", "single", "stack", "stack", "nc", "nc", "rgb", "rgb", "json"]
out_formats = ["json", "tif", "tif", "tif", "nc", "nc", "jpg", "jpg"] out_formats = ["json", "tif", "tif", "tif", "nc", "nc", "jpg", "jpg", "json"]
levels = ["L2A", "L2A", "L2A", "L1C", "L2A", "L1C", "L2A", "L1C"] levels = ["L2A", "L2A", "L2A", "L1C", "L2A", "L1C", "L2A", "L1C", "L2A"]
onlytime = [False] * (len(levels) - 1) + [True]
for ii, out_mode in enumerate(out_modes): for ii, out_mode in enumerate(out_modes):
with tempfile.TemporaryDirectory() as tmpdir: with tempfile.TemporaryDirectory() as tmpdir:
print("#### Testing {om}".format(om=out_mode)) print("#### Testing {om}".format(om=out_mode) + " - onlytime" if onlytime[ii] else "")
gts2_client.client( gts2_client.client(
outpath=tmpdir, outpath=tmpdir,
out_prefix=out_mode, out_prefix=out_mode,
...@@ -60,7 +61,8 @@ class TestGts2Client(unittest.TestCase): ...@@ -60,7 +61,8 @@ class TestGts2Client(unittest.TestCase):
level=levels[ii], level=levels[ii],
max_cloudy=max_cloudy, max_cloudy=max_cloudy,
minimum_fill=minimum_fill, minimum_fill=minimum_fill,
stack_resolution=stack_res) stack_resolution=stack_res,
onlytime=onlytime[ii])
list_of_files = glob(os.path.join(tmpdir, "*.{form}".format(form=out_formats[ii]))) list_of_files = glob(os.path.join(tmpdir, "*.{form}".format(form=out_formats[ii])))
if len(list_of_files) == 0: if len(list_of_files) == 0:
...@@ -168,24 +170,36 @@ class TestGts2Client(unittest.TestCase): ...@@ -168,24 +170,36 @@ class TestGts2Client(unittest.TestCase):
necessary_keys = ["Acknowledgement", "ControlValues", "Metadata", "Request", "RequestGeoInfo", "Results"] necessary_keys = ["Acknowledgement", "ControlValues", "Metadata", "Request", "RequestGeoInfo", "Results"]
out_mode = "python" out_mode = "python"
print("#### Testing {om}".format(om=out_mode))
res = gts2_client.client( for onlytime in [False, True]:
out_mode=out_mode, print("#### Testing {om} - onlytime={onlytime}".format(om=out_mode,onlytime=onlytime))
geo_ll=geo_ll, res = gts2_client.client(
geo_ur=geo_ur, out_mode=out_mode,
bands=bands, geo_ll=geo_ll,
start_date=start_date, geo_ur=geo_ur,
end_date=end_date, bands=bands,
version=version, start_date=start_date,
level=level, end_date=end_date,
max_cloudy=max_cloudy, version=version,
minimum_fill=minimum_fill, level=level,
stack_resolution=stack_res, max_cloudy=max_cloudy,
quiet=True) minimum_fill=minimum_fill,
stack_resolution=stack_res,
for ki in necessary_keys: quiet=True,
if not (ki in res.keys()): onlytime=onlytime)
raise KeyError("{key} is not in returned results.".format(key=ki))
for ki in necessary_keys:
if not (ki in res.keys()):
raise KeyError("{key} is not in returned results.".format(key=ki))
else:
print("Test OK.")
any_band_downloaded = any([band in list(res["Results"].values())[0].keys()
for band in ['B02_10m', 'B05_20m']])
if onlytime and any_band_downloaded:
raise AssertionError("onlytime=True but data retrieved anyway")
elif (not onlytime) and (not any_band_downloaded):
raise AssertionError("onlytime=False but not any data downloaded")
else: else:
print("Test OK.") print("Test OK.")
...@@ -383,7 +397,7 @@ class TestGts2Client(unittest.TestCase): ...@@ -383,7 +397,7 @@ class TestGts2Client(unittest.TestCase):
print_run(subprocess.run( print_run(subprocess.run(
["{python} {script} -o {outpath} -r test -l {lat_ll} -k {lon_ll} -i {lat_ur} -j {lon_ur} " ["{python} {script} -o {outpath} -r test -l {lat_ll} -k {lon_ll} -i {lat_ur} -j {lon_ur} "
"-b {bands} -s {start_date} -e {end_date} -m {out_mode} -a {sensor} -t {level} -v {version} " "-b {bands} -s {start_date} -e {end_date} -m {out_mode} -a {sensor} -t {level} -v {version} "
"-c {coreg} -z {max_cloudy} -f {minimum_fill} -d {utm_zone} -g {stack_res}".format( "-c {coreg} -z {max_cloudy} -f {minimum_fill} -d {utm_zone} -g {stack_res} -h {onlytime}".format(
python=sys.executable, python=sys.executable,
script=fn_bin, script=fn_bin,
outpath=tmpdir, outpath=tmpdir,
...@@ -402,7 +416,8 @@ class TestGts2Client(unittest.TestCase): ...@@ -402,7 +416,8 @@ class TestGts2Client(unittest.TestCase):
max_cloudy=max_cloudy, max_cloudy=max_cloudy,
minimum_fill=minimum_fill, minimum_fill=minimum_fill,
stack_res=stack_res, stack_res=stack_res,
utm_zone="33UUV")], utm_zone="33UUV",
onlytime=False)],
shell=True, check=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=env)) shell=True, check=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=env))
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment