esa-snappy 1.1.0__cp313-none-any.whl → 1.1.2__cp313-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -3,6 +3,7 @@ import subprocess
3
3
  import tempfile
4
4
  import platform
5
5
  import lxml.etree as etree
6
+ import re
6
7
  from esa_snappy import GPF
7
8
  from xml.sax.saxutils import unescape
8
9
  from esa_snappy.snapista.binning.output_bands import BinningOutputBands
@@ -19,7 +20,6 @@ class Graph:
19
20
  Attributes:
20
21
  None.
21
22
  """
22
-
23
23
  def __init__(self, wdir=".", root=None):
24
24
 
25
25
  if root is None:
@@ -27,7 +27,6 @@ class Graph:
27
27
 
28
28
  version = etree.SubElement(self.root, "version")
29
29
  version.text = "1.0"
30
-
31
30
  else:
32
31
  self.root = root
33
32
 
@@ -37,7 +36,6 @@ class Graph:
37
36
  self.gpt_path = self.get_gpt_cmd()
38
37
 
39
38
  if not self.gpt_path:
40
-
41
39
  raise Exception("gpt not found")
42
40
 
43
41
  def __str__(self):
@@ -65,11 +63,8 @@ class Graph:
65
63
  gpt_executable = "gpt"
66
64
 
67
65
  for p in os.getenv("PATH").split(path_split_char):
68
-
69
66
  if os.path.exists(os.path.join(p, gpt_executable)):
70
-
71
67
  gpt_cmd = os.path.join(p, gpt_executable)
72
-
73
68
  break
74
69
 
75
70
  return gpt_cmd
@@ -99,11 +94,11 @@ class Graph:
99
94
  snap_operators = []
100
95
 
101
96
  while op_spi_it.hasNext():
102
-
103
97
  op_spi = op_spi_it.next()
104
-
105
98
  snap_operators.append(op_spi.getOperatorAlias())
106
99
 
100
+ print('Number of operators provided by SNAP: ' + str(len(snap_operators)))
101
+
107
102
  return snap_operators
108
103
 
109
104
  @staticmethod
@@ -132,45 +127,19 @@ class Graph:
132
127
  )
133
128
 
134
129
  while op_spi_it.hasNext():
135
-
136
130
  op_spi = op_spi_it.next()
137
-
138
131
  alias = op_spi.getOperatorDescriptor().getAlias()
139
132
  description = op_spi.getOperatorDescriptor().getDescription()
133
+ src_prod_descriptors = op_spi.getOperatorDescriptor().getSourceProductDescriptors()
134
+ if src_prod_descriptors is not None and len(src_prod_descriptors) > 0:
135
+ src_prod_id = src_prod_descriptors.get(0)
136
+ print('describe_operators src_prod_id: ' + src_prod_id)
140
137
 
141
138
  desc_dict[alias] = description
142
139
  print("{} - {}".format(alias, description))
143
140
 
144
141
  return desc_dict
145
142
 
146
- # todo: seems that this is not needed. Check.
147
- def nice_view(self):
148
-
149
- try:
150
- from pygments import highlight
151
- from pygments.lexers import XmlLexer
152
- from pygments.formatters import HtmlFormatter
153
- import IPython
154
- from IPython.display import HTML
155
-
156
- def display_xml_nice(xml):
157
- formatter = HtmlFormatter()
158
- IPython.display.display(
159
- HTML(
160
- '<style type="text/css">{}</style> {}'.format(
161
- formatter.get_style_defs(".highlight"),
162
- highlight(xml, XmlLexer(), formatter),
163
- )
164
- )
165
- )
166
-
167
- display_xml_nice(etree.tostring(self.root, pretty_print=True))
168
-
169
- except ModuleNotFoundError:
170
-
171
- print(etree.tostring(self.root, pretty_print=True).decode("utf-8")).replace(
172
- "\\n", "\n"
173
- )
174
143
 
175
144
  def view(self):
176
145
  """This method prints SNAP Graph
@@ -184,8 +153,74 @@ class Graph:
184
153
  Raises:
185
154
  None.
186
155
  """
156
+ #print(unescape(etree.tostring(self.root, pretty_print=True).decode("utf-8")).replace("&amp;", "&"))
187
157
  print(unescape(etree.tostring(self.root, pretty_print=True).decode("utf-8")))
188
158
 
159
+
160
+ @staticmethod
161
+ def remove_duplicate_tag(parameter_elem, root_tag):
162
+ """This method removes duplicated tags in a xml etree element with a given root tag
163
+
164
+ Args:
165
+ parameter_elem: the XML element
166
+ root_tag: the root tag of the element
167
+ Returns
168
+ None.
169
+
170
+ Raises:
171
+ None.
172
+ """
173
+ for tagn in parameter_elem.iter(root_tag):
174
+ if tagn.getparent().getparent() is not None and tagn.getparent().getparent().tag == root_tag:
175
+ ipar_of_parent = tagn.getparent().getparent()
176
+ i_parent = tagn.getparent()
177
+ if ipar_of_parent.text is None:
178
+ ipar_of_parent.addnext(i_parent)
179
+ ipar_of_parent.getparent().remove(ipar_of_parent)
180
+ elif tagn.getparent() is not None and tagn.getparent().tag == root_tag:
181
+ i_parent = tagn.getparent()
182
+ if i_parent.text is None:
183
+ i_parent.addnext(tagn)
184
+ i_parent.getparent().remove(i_parent)
185
+
186
+
187
+ def append_merge_op_nested_param(self, operator, parameter_elem, param):
188
+ print('special case: nested parameter <' + param + '>' )
189
+ # we want to get this:
190
+ # '<exclude><productId>Read</productId><namePattern>Oa.*radiance</namePattern></exclude><exclude><productId>vicarious</productId><namePattern>Oa12_radiance</namePattern></exclude>'
191
+ # transformed to:
192
+ # <excludes>
193
+ # <exclude>
194
+ # <productId>Read</productId>
195
+ # <namePattern>Oa.*radiance</namePattern>
196
+ # </exclude>
197
+ # <exclude>
198
+ # <productId>vicarious</productId>
199
+ # <namePattern>Oa12_radiance</namePattern>
200
+ # </exclude>
201
+ # </excludes>
202
+
203
+ open_tag = '<' + param + '>'
204
+ close_tag = '</' + param + '>'
205
+ nested_param = open_tag + getattr(operator, param) + close_tag
206
+ if nested_param is not None:
207
+ nested_param_elems = nested_param.split('</' + param + '>')
208
+
209
+ pattern = '<' + param + '>' + '<' + param[:-1] + '>' + \
210
+ '<productId>.*</productId><namePattern>.*</namePattern>' + '</' + param[:-1] + '>'
211
+ valid = True
212
+ for elem in nested_param_elems:
213
+ x = re.match(pattern, elem)
214
+ print (elem)
215
+ if x is None and len(elem) > 0:
216
+ valid = False
217
+ print('WARNING: malforatted nested parameter: ' + elem)
218
+
219
+ if valid:
220
+ parameter_elem.append(etree.fromstring(nested_param))
221
+ self.remove_duplicate_tag(parameter_elem, param)
222
+
223
+
189
224
  def add_node(self, operator, node_id, source=None):
190
225
  """This method adds or overwrites a node to the SNAP Graph
191
226
 
@@ -200,13 +235,14 @@ class Graph:
200
235
  Raises:
201
236
  None.
202
237
  """
238
+ #print('entering add_node...')
239
+
203
240
  xpath_expr = '/graph/node[@id="%s"]' % node_id
204
241
 
205
242
  if len(self.root.xpath(xpath_expr)) != 0:
206
243
 
207
244
  node_elem = self.root.xpath(xpath_expr)[0]
208
245
  operator_elem = self.root.xpath(xpath_expr + "/operator")[0]
209
- sources_elem = self.root.xpath(xpath_expr + "/sources")[0]
210
246
  parameters_elem = self.root.xpath(xpath_expr + "/parameters")
211
247
 
212
248
  for param in [
@@ -236,7 +272,11 @@ class Graph:
236
272
  "productCustomizerConfig",
237
273
  ]:
238
274
 
239
- if (param in ["bandConfigurations", "variableConfigs", "postProcessorConfig", "productCustomizerConfig" ] and not getattr(operator, param)): continue
275
+ if param in ["bandConfigurations",
276
+ "variableConfigs",
277
+ "postProcessorConfig",
278
+ "productCustomizerConfig"] and not getattr(operator, param):
279
+ continue
240
280
 
241
281
  if (
242
282
  isinstance(getattr(operator, param), TargetBandDescriptors)
@@ -247,12 +287,8 @@ class Graph:
247
287
  parameters_elem.append(getattr(operator, param).to_xml())
248
288
 
249
289
  elif isinstance(getattr(operator, param), str):
250
-
251
- parameters_elem.append(
252
- etree.fromstring(getattr(operator, param))
253
- )
290
+ parameters_elem.append(etree.fromstring(getattr(operator, param)))
254
291
  else:
255
-
256
292
  raise ValueError()
257
293
 
258
294
  else:
@@ -263,9 +299,8 @@ class Graph:
263
299
  if getattr(operator, param)[0] != "<":
264
300
  p_elem.text = getattr(operator, param)
265
301
  else:
266
- p_elem.text.append(
267
- etree.fromstring(getattr(operator, param))
268
- )
302
+ if param != 'excludes':
303
+ p_elem.text.append(etree.fromstring(getattr(operator, param)))
269
304
  except IndexError:
270
305
  pass
271
306
 
@@ -274,31 +309,24 @@ class Graph:
274
309
  node_elem = etree.SubElement(self.root, "node")
275
310
  operator_elem = etree.SubElement(node_elem, "operator")
276
311
  sources_elem = etree.SubElement(node_elem, "sources")
312
+
313
+ src_prod_id = operator.get_src_product_id()
314
+ if src_prod_id is None:
315
+ src_prod_id = 'source'
277
316
 
278
317
  if isinstance(source, list):
279
-
280
318
  for index, s in enumerate(source):
281
319
  if index == 0:
282
- source_product_elem = etree.SubElement(
283
- sources_elem, "sourceProduct"
284
- )
285
-
320
+ source_product_elem = etree.SubElement(sources_elem, src_prod_id)
286
321
  else:
287
- source_product_elem = etree.SubElement(
288
- sources_elem, "sourceProduct.%s" % str(index)
289
- )
290
-
322
+ source_product_elem = etree.SubElement(sources_elem, "source.%s" % str(index))
291
323
  source_product_elem.attrib["refid"] = s
292
-
293
324
  elif isinstance(source, dict):
294
-
295
325
  for key, value in source.iteritems():
296
-
297
326
  source_product_elem = etree.SubElement(sources_elem, key)
298
327
  source_product_elem.text = value
299
-
300
328
  elif source is not None:
301
- source_product_elem = etree.SubElement(sources_elem, "sourceProduct")
329
+ source_product_elem = etree.SubElement(sources_elem, src_prod_id)
302
330
  source_product_elem.attrib["refid"] = source
303
331
 
304
332
  parameters_elem = etree.SubElement(node_elem, "parameters")
@@ -331,46 +359,48 @@ class Graph:
331
359
  "productCustomizerConfig",
332
360
  ]:
333
361
  print(param, getattr(operator, param))
334
- if (param in ["bandConfigurations", "variableConfigs", "postProcessorConfig", "productCustomizerConfig" ] and not getattr(operator, param)): continue
362
+ if param in ["bandConfigurations",
363
+ "variableConfigs",
364
+ "postProcessorConfig",
365
+ "productCustomizerConfig"] and not getattr(operator, param): continue
335
366
 
336
367
  print('Instance TargetBandDescriptors: ' + str(isinstance(getattr(operator, param), TargetBandDescriptors)))
337
368
  print('Instance Aggregators: ' + str(isinstance(getattr(operator, param), Aggregators)))
338
369
  print('Instance BinningOutputBands: ' + str(isinstance(getattr(operator, param), BinningOutputBands)))
339
370
  print('Instance BinningVariables: ' + str(isinstance(getattr(operator, param), BinningVariables)))
340
371
  print('Instance str: ' + str(isinstance(getattr(operator, param), str)))
372
+
341
373
  if (
342
374
  isinstance(getattr(operator, param), TargetBandDescriptors)
343
375
  or isinstance(getattr(operator, param), Aggregators)
344
376
  or isinstance(getattr(operator, param), BinningOutputBands)
345
377
  or isinstance(getattr(operator, param), BinningVariables)
346
378
  ):
347
-
348
379
  parameters_elem.append(getattr(operator, param).to_xml())
349
-
350
380
  elif isinstance(getattr(operator, param), str):
351
-
352
- parameters_elem.append(
353
- etree.fromstring(getattr(operator, param))
354
- )
381
+ parameters_elem.append(etree.fromstring(getattr(operator, param)))
355
382
  else:
356
383
 
357
384
  raise ValueError()
358
385
 
359
386
  else:
360
-
361
387
  parameter_elem = etree.SubElement(parameters_elem, param)
362
-
363
388
  if getattr(operator, param) is not None:
364
- if getattr(operator, param)[0] != "<":
365
- parameter_elem.text = getattr(operator, param)
389
+ # special case: 'Merge' operator which has nested parameters 'excludes' and 'includes'
390
+ if operator.operator == 'Merge' and (param == 'excludes' or param == 'includes'):
391
+ self.append_merge_op_nested_param(operator, parameter_elem, param)
366
392
  else:
367
- parameter_elem.append(
368
- etree.fromstring(getattr(operator, param))
369
- )
393
+ if getattr(operator, param)[0] != "<":
394
+ parameter_elem.text = getattr(operator, param)
395
+ else:
396
+ parameter_elem.append(
397
+ etree.fromstring(getattr(operator, param))
398
+ )
370
399
 
371
400
  node_elem.attrib["id"] = node_id
372
401
 
373
402
  operator_elem.text = operator.operator
403
+
374
404
 
375
405
  def save_graph(self, filename):
376
406
  """This method saves the SNAP Graph
@@ -387,9 +417,10 @@ class Graph:
387
417
 
388
418
  with open(filename, "w") as file:
389
419
  file.write('<?xml version="1.0" encoding="UTF-8"?>\n')
420
+ #file.write(unescape(etree.tostring(self.root, pretty_print=True).decode()).replace("&amp;", "&"))
390
421
  file.write(unescape(etree.tostring(self.root, pretty_print=True).decode()))
391
422
 
392
- def run(self, gpt_options=["-x", "-c", "1024M"]):
423
+ def run(self, gpt_options=None):
393
424
  """This method runs the SNAP Graph using gpt
394
425
 
395
426
  Args:
@@ -403,14 +434,17 @@ class Graph:
403
434
  None.
404
435
  """
405
436
 
406
- def _run_command(command, **kwargs):
437
+ if gpt_options is None:
438
+ gpt_options = ["-x", "-c", "1024M"]
407
439
 
408
- #process = subprocess.Popen(args=command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, **kwargs)
440
+ def _run_command(command, **kwargs):
441
+ process = subprocess.Popen(args=command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, **kwargs)
409
442
  # todo: this hangs in the while loop. Check why!
410
443
  #while True:
411
444
  # output = process.stdout.readline()
412
445
  # err = process.stderr.readline()
413
- # if output.decode() == "" and process.poll() is not None:
446
+ # return_code = process.poll()
447
+ # if output.decode() == "" and return_code is not None:
414
448
  # break
415
449
  # if output:
416
450
  # print(output.strip().decode())
@@ -418,35 +452,29 @@ class Graph:
418
452
  # print(err.strip().decode())
419
453
 
420
454
  # this works, but output (i.e. gpt progress) is not written before subprocess finished. todo: try to improve
421
- process = subprocess.Popen(args=command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, **kwargs)
422
455
  out, err = process.communicate()
423
456
  if out:
424
- #print ('standard output of subprocess: ')
457
+ print ('standard output of subprocess: ')
425
458
  print (out.strip().decode())
426
459
  if err:
427
- #print ('standard error of subprocess: ')
460
+ print ('standard error of subprocess: ')
428
461
  print (err.strip().decode())
429
462
 
430
- rc = process.poll()
463
+ return_code = process.poll()
431
464
 
432
- return rc
465
+ return return_code
433
466
 
434
467
  os.environ["LD_LIBRARY_PATH"] = "."
435
468
 
436
469
  print("Processing the graph, this may take a while. Please wait...")
437
470
 
438
471
  fd, path = tempfile.mkstemp()
439
-
440
472
  rc = None
441
473
 
442
474
  try:
443
-
444
475
  self.save_graph(filename=path)
445
-
446
476
  options = [self.gpt_path, *gpt_options, path]
447
-
448
477
  rc = _run_command(options)
449
-
450
478
  finally:
451
479
  try:
452
480
  os.remove(path)
@@ -5,36 +5,31 @@ from .operatorparams import OperatorParams
5
5
 
6
6
  class Operator(SimpleNamespace):
7
7
  def __init__(self, operator, **kwargs):
8
-
9
8
  self.operator = operator
10
9
  self._params = {**OperatorParams(self.operator).params, **kwargs}
11
10
 
12
11
  return super().__init__(**self._params)
13
12
 
14
13
  def __str__(self):
15
-
16
14
  return "{}:\n\t{}".format(
17
15
  self.operator, "\n\t".join(["{}='{}'".format(key, value) for key, value in self.to_dict().items()])
18
16
  )
19
17
 
20
18
  def __repr__(self):
21
-
22
19
  return "Operator('{}', {})".format(
23
20
  self.operator, ", ".join(["{}='{}'".format(key, value) for key, value in self.to_dict().items()])
24
21
  )
25
22
 
26
23
  def to_dict(self):
27
-
28
24
  return dict([(name, getattr(self, name)) for name in list(self._params.keys())])
29
25
 
30
26
  def describe(self):
31
- """This function prints the human readable information about a SNAP operator
27
+ """This function prints the human-readable information about a SNAP operator
32
28
 
33
29
  Args:
34
- operator: SNAP operator
35
30
 
36
31
  Returns
37
- The human readable information about the provided SNAP operator.
32
+ The human-readable information about the provided SNAP operator.
38
33
 
39
34
  Raises:
40
35
  None.
@@ -46,10 +41,15 @@ class Operator(SimpleNamespace):
46
41
  print("Authors: {}\n".format(op_spi.getOperatorDescriptor().getAuthors()))
47
42
  print("{}".format(op_spi.getOperatorDescriptor().getName()))
48
43
  print("Version: {}\n".format(op_spi.getOperatorDescriptor().getVersion()))
44
+ print("Sources:\n")
45
+ source_desc = op_spi.getOperatorDescriptor().getSourceProductDescriptors()
46
+ for src in source_desc:
47
+ print('getSourceProductDescriptors src name: ' + src.getName())
48
+
49
49
  print("Parameters:\n")
50
- param_Desc = op_spi.getOperatorDescriptor().getParameterDescriptors()
50
+ param_desc = op_spi.getOperatorDescriptor().getParameterDescriptors()
51
51
 
52
- for param in param_Desc:
52
+ for param in param_desc:
53
53
  print(
54
54
  "\t{}: {}\n\t\tDefault Value: {}\n".format(
55
55
  param.getName(), param.getDescription(), param.getDefaultValue()
@@ -57,20 +57,59 @@ class Operator(SimpleNamespace):
57
57
  )
58
58
 
59
59
  if self.operator == "Write" and param.getName() == "formatName":
60
-
61
60
  print("\t\tPossible values: {}\n".format(self._get_formats("Write")))
62
-
63
61
  elif self.operator == "Read" and param.getName() == "formatName":
64
-
65
62
  print("\t\tPossible values: {}\n".format(self._get_formats("Read")))
66
-
67
63
  else:
68
-
69
64
  print("\t\tPossible values: {}\n".format(list(param.getValueSet())))
65
+
66
+
67
+ def get_src_product_id(self):
68
+ """This function returns the reference single source product identifier as specified in the Operator.
69
+ It is not unique in SNAP, can be e.g. 'source', 'sourceProduct', 'l1BProduct' etc.
70
+
71
+ Args:
72
+
73
+ Returns
74
+ The source product identifier as specified in the SNAP Operator.
75
+
76
+ Raises:
77
+ None.
78
+ """
79
+ op_spi = GPF.getDefaultInstance().getOperatorSpiRegistry().getOperatorSpi(self.operator)
80
+ source_descr = op_spi.getOperatorDescriptor().getSourceProductDescriptors()
81
+ if len(source_descr) > 0:
82
+ return source_descr[0].getName()
83
+ else:
84
+ return None
85
+
86
+ def get_src_product_ids(self):
87
+ """This function returns the source product identifiers as specified in the Operator.
88
+ They are not unique in SNAP, can be e.g. 'source', 'sourceProduct', 'l1BProduct' etc.
89
+ There can be more than one, e.g. for 'Collocate' operator: 'reference' and 'secondary'
90
+
91
+ Args:
92
+
93
+ Returns
94
+ The source product identifier as specified in the SNAP Operator.
95
+
96
+ Raises:
97
+ None.
98
+ """
99
+ op_spi = GPF.getDefaultInstance().getOperatorSpiRegistry().getOperatorSpi(self.operator)
100
+ source_descr = op_spi.getOperatorDescriptor().getSourceProductDescriptors()
101
+ if len(source_descr) > 0:
102
+ src_descr_names = []
103
+ for index, src in enumerate(source_descr):
104
+ src_descr_names.append(src[index].getName())
105
+ return src_descr_names
106
+ else:
107
+ return None
108
+
70
109
 
71
110
  @staticmethod
72
111
  def _get_formats(method):
73
- """This function provides a human readable list of SNAP Read or Write operator formats.
112
+ """This function provides a human-readable list of SNAP Read or Write operator formats.
74
113
 
75
114
  Args:
76
115
  None.
@@ -81,12 +120,12 @@ class Operator(SimpleNamespace):
81
120
  Raises:
82
121
  None.
83
122
  """
84
- ProductIOPlugInManager = jpy.get_type("org.esa.snap.core.dataio.ProductIOPlugInManager")
123
+ product_io_plug_in_manager = jpy.get_type("org.esa.snap.core.dataio.product_io_plug_in_manager")
85
124
 
86
125
  if method == "Read":
87
- plugins = ProductIOPlugInManager.getInstance().getAllReaderPlugIns()
126
+ plugins = product_io_plug_in_manager.getInstance().getAllReaderPlugIns()
88
127
  elif method == "Write":
89
- plugins = ProductIOPlugInManager.getInstance().getAllWriterPlugIns()
128
+ plugins = product_io_plug_in_manager.getInstance().getAllWriterPlugIns()
90
129
  else:
91
130
  raise ValueError
92
131
 
@@ -12,7 +12,6 @@ class OperatorParams:
12
12
  """This function returns the SNAP operator ParameterDescriptors (snappy method op_spi.getOperatorDescriptor().getParameterDescriptors())
13
13
 
14
14
  Args:
15
- operator: SNAP operator
16
15
 
17
16
  Returns
18
17
  The snappy object returned by op_spi.getOperatorDescriptor().getParameterDescriptors().
@@ -30,7 +29,6 @@ class OperatorParams:
30
29
  """This function returns a Python dictionary with the SNAP operator parameters and their default values, if available.
31
30
 
32
31
  Args:
33
- operator: SNAP operator
34
32
 
35
33
  Returns
36
34
  A Python dictionary with the SNAP operator parameters and their default values.
@@ -15,30 +15,26 @@ class TargetBand(object):
15
15
 
16
16
 
17
17
  def __str__(self):
18
-
19
18
  return self.__repr__()
20
19
 
21
20
  def __repr__(self):
22
-
23
21
  return "TargetBand({})".format(
24
22
  ", ".join(["{}='{}'".format(key, value) for key, value in self.to_dict().items()])
25
23
  )
26
24
 
27
25
  def to_dict(self):
28
-
29
26
  return attr.asdict(self)
30
27
 
31
28
  def to_xml(self):
32
-
33
29
  root = etree.Element("targetBand")
34
30
 
35
31
  for key, value in self.to_dict().items():
36
-
37
32
  elem = etree.SubElement(root, key)
38
33
 
39
- if key == 'expression':
40
- elem.text = escape(value)
41
- else:
42
- elem.text = value
34
+ elem.text = value
35
+ #if key == 'expression':
36
+ # elem.text = escape(value)
37
+ #else:
38
+ # elem.text = value
43
39
 
44
40
  return root
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: esa_snappy
3
- Version: 1.1.0
3
+ Version: 1.1.2
4
4
  Summary: The Python part of the SNAP Java-Python bridge.
5
5
  Author: Olaf Danne, Norman Fomferra (Brockmann Consult GmbH)
6
6
  License: MIT
@@ -14,11 +14,11 @@ esa_snappy/lib/jpy-1.0.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch6
14
14
  esa_snappy/lib/jpy-1.0.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl,sha256=XvMUPXT8EPjfw2vlwZDYb6ZNsrRE9WjR6EyQDzBYkZQ,346792
15
15
  esa_snappy/lib/jpy-1.0.0-cp313-cp313-win_amd64.whl,sha256=5P9b_FzQbo6ps3-oIGCit1aedtaUQS0H5ksioP_ITbU,74843
16
16
  esa_snappy/snapista/__init__.py,sha256=UoFdyRO7zKbvdzCK9PeRb2EgChNPso3DbwypPztG0cw,230
17
- esa_snappy/snapista/graph.py,sha256=YFbC5fgF53NDexKpirVNSjiJsKAx_tIn3y1BqjpRdTo,15202
17
+ esa_snappy/snapista/graph.py,sha256=zXUq_0SLzYrOuGSZfr4dwNlAHRpuaV7N-4G8eyvGH94,18101
18
18
  esa_snappy/snapista/graph_io.py,sha256=tk5lUG9Wg6PtGeJTO7fi8Wvm-kagbvAdlowTdAKWSn4,377
19
- esa_snappy/snapista/operator.py,sha256=hgWbu-fAc-DVcYD7TnWwlWpLsp_4pnKU92SzNqVS1Dw,3356
20
- esa_snappy/snapista/operatorparams.py,sha256=_tBMtg5ndV1VeuuZ6Iv103Gcsh_hi_yOmwXhovK-YHY,1381
21
- esa_snappy/snapista/target_band.py,sha256=zLl3UDgBXImkQXUgSFd_CZx1oVAjYAZKLWX5rHBwt48,991
19
+ esa_snappy/snapista/operator.py,sha256=_C5qSXaIHm-p9aEmli2uC2t3SNIBojORGrpS2FfbFRg,5245
20
+ esa_snappy/snapista/operatorparams.py,sha256=kN0yNfxPUEffHX81d-3jxzHfhTupGVrWMigfY6z1tnQ,1307
21
+ esa_snappy/snapista/target_band.py,sha256=xi9PA_ab3T0w9_eBbRmgnBeuBjuNidICMfNXGiGi1Tk,1001
22
22
  esa_snappy/snapista/target_band_descriptors.py,sha256=PRFSjJCB7Lgy0IESFnIased1Cj6J3A-iT5SoG9UP3S0,412
23
23
  esa_snappy/snapista/binning/__init__.py,sha256=iRK9Q63y-tMastSzG1F6JDZJg-u_VMEVCnnl5kelYao,219
24
24
  esa_snappy/snapista/binning/aggregator_avg.py,sha256=rBaDK060oiiQvo2V2kJUZr4oFgZFaTFlP9HfyfcyL5M,1707
@@ -108,8 +108,8 @@ esa_snappy/tests/__init__.py,sha256=F4oR5lxuvk4xsRSJ65fkZPrsrfPD8fNVbhSuAyHox7Q,
108
108
  esa_snappy/tests/test_snappy_mem.py,sha256=5UeN4A5-kgV534eRforf6OqO0UbqcTbREeRVvUqeU9A,971
109
109
  esa_snappy/tests/test_snappy_perf.py,sha256=W1nlzDzvmbhDNc4ma4u5m4qRjEjLIU-gCbKzLkHdIwM,1710
110
110
  esa_snappy/tests/test_snappy_product.py,sha256=zCPMOTQ3zoRN0OLLMy7NsHd7YuZnsa2loYGcD9Ehf3A,3564
111
- esa_snappy-1.1.0.dist-info/licenses/LICENSE,sha256=WhZlPzkdURd2lAAvpQrjy1tIXgkmxrKFS45OPs2PxPM,1105
112
- esa_snappy-1.1.0.dist-info/METADATA,sha256=AMBLiATmd817J96BwL7eJHg_akoaZ0yYjetxiLM7qRw,2545
113
- esa_snappy-1.1.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
114
- esa_snappy-1.1.0.dist-info/top_level.txt,sha256=Rp5J9LQi3dYksBH5aChaVvqyd0FecQA5byHcDTal2vk,11
115
- esa_snappy-1.1.0.dist-info/RECORD,,
111
+ esa_snappy-1.1.2.dist-info/licenses/LICENSE,sha256=WhZlPzkdURd2lAAvpQrjy1tIXgkmxrKFS45OPs2PxPM,1105
112
+ esa_snappy-1.1.2.dist-info/METADATA,sha256=03WGGIDrrteYBIsQ24LOJWzDXvf9jLX8tPOSXvvBiug,2545
113
+ esa_snappy-1.1.2.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
114
+ esa_snappy-1.1.2.dist-info/top_level.txt,sha256=Rp5J9LQi3dYksBH5aChaVvqyd0FecQA5byHcDTal2vk,11
115
+ esa_snappy-1.1.2.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (80.9.0)
2
+ Generator: setuptools (80.10.2)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5