9 from scipy.interpolate
import RegularGridInterpolator, griddata
10 from shapely.geometry
import Point
11 from shapely.geometry.polygon
import Polygon
12 from scipy.ndimage
import uniform_filter
14 from copy
import deepcopy
15 from inspect
import currentframe, getframeinfo
17 from scipy
import optimize
18 from typing
import List, Dict
20 PROGRAM_NAME =
'geo_eval'
23 running_time = datetime.datetime.now()
24 RUNNING_TIME = running_time.strftime(
"%Y-%m-%dT%H%M%S")
25 subpixels_default_max = 30
26 subpixels_default = 15
27 window_size_defalut = 5
28 min_number_of_points = 100
30 filename_script = getframeinfo(cf).filename
33 if coord[0] == bad_float
or np.isnan(coord[0]):
35 if coord[1] == bad_float
or np.isnan(coord[1]):
40 if not os.path.exists(cld_file):
42 f
"File {cld_file} does not exist. See line {get_linenumber()} in {filename_script}. Exiting")
44 with nc.Dataset(cld_file)
as f:
45 return f[
"geophysical_data/cloud_flag"][:]
49 with open(path_chips)
as file_txt:
50 file_list_chip = file_txt.read().splitlines()
51 for file
in file_list_chip:
52 if not os.path.exists(file):
54 f
"File {file} does not exist. See line {get_linenumber()} in {filename_script}. Exiting")
59 def get_scantime(year: List[int], day: List[int], msec: List[int]) -> np.ndarray:
60 scantime = np.zeros(len(year))
61 for i, (iyear, iday, imsec)
in enumerate(zip(year, day, msec)):
62 date_scan = datetime.datetime.strptime(f
'{iyear} {iday}',
'%Y %j')
63 scantime[i] = time.mktime(date_scan.timetuple(
64 )) + date_scan.microsecond / 1.0e6 +
float(imsec) / 1.0e3
69 lat = np.array(f[
"navigation_data/latitude"][:], dtype=np.float64)
70 lon = np.array(f[
"navigation_data/longitude"][:], dtype=np.float64)
71 year: list[int] =
list(
72 np.array(f[
"scan_line_attributes/year"][:], dtype=np.int32))
73 day: list[int] =
list(
74 np.array(f[
"scan_line_attributes/day"][:], dtype=np.int32))
75 msec: list[int] =
list(
76 np.array(f[
"scan_line_attributes/msec"][:], dtype=np.int32))
78 return lat, lon, scantime
83 return cf.f_back.f_lineno
87 with nc.Dataset(path)
as f:
88 if f.instrument ==
"MODIS":
90 f[
"geophysical_data/Lt_645"][:], dtype=np.float64)
92 return lat, lon, data, scantime,
None
93 if f.instrument ==
"VIIRS":
94 if f.platform ==
"Suomi-NPP":
99 f[f
"geophysical_data/Lt_{wave}"][:], dtype=np.float64)
100 l2_flags_var = f[
"geophysical_data/l2_flags"]
101 flag_masks = l2_flags_var.flag_masks
102 flag_meanings = l2_flags_var.flag_meanings.split(sep=
' ')
104 for bit, name
in zip(flag_masks, flag_meanings):
105 if name ==
"BOWTIEDEL":
107 mask = (l2_flags_var[:] & bit_bowtie) > 0
110 return lat, lon, data, scantime,
None
111 if f.instrument ==
"OCI" or f.instrument ==
"OCIS":
113 red_wavelength = f[
"sensor_band_parameters/red_wavelength"][:]
114 index = np.abs(red_wavelength - red_wv).argmin()
116 f[
"observation_data/rhot_red"][:][index, :, :], dtype=np.float64)
117 lat = np.array(f[
"geolocation_data/latitude"][:], dtype=np.float64)
118 lon = np.array(f[
"geolocation_data/longitude"]
119 [:], dtype=np.float64)
120 scantime = np.array(f[
"scan_line_attributes/time"]
121 [:], dtype=np.float64)
122 time_coverage_start = f.time_coverage_start
123 if time_coverage_start[-1] ==
'Z':
124 time_coverage_start = time_coverage_start[:-1]
125 date_scan = datetime.datetime.strptime(
126 time_coverage_start,
'%Y-%m-%dT%H:%M:%S.%f')
127 scantime += time.mktime(datetime.datetime(date_scan.year, date_scan.month, date_scan.day).timetuple(
129 tilt = f[
"navigation_data/tilt_angle"][:]
130 return lat, lon, data, scantime, tilt
132 f
"-Error- : instrument {f.instrument} not found. See line {get_linenumber()} in {filename_script}")
136 def get_position(lat: np.ndarray, lon: np.ndarray, feature_lat, feature_lon):
137 diff = np.abs(lat - feature_lat) + np.abs(lon - feature_lon)
138 (x, y) = np.unravel_index(diff.argmin(), diff.shape)
139 point =
Point(feature_lat, feature_lon)
142 i_min = max(0, x - w)
143 i_max = min(lat.shape[0] - 1, x + w)
144 j_min = max(0, y - w)
145 j_max = min(lat.shape[1] - 1, y + w)
146 for i
in range(i_min, i_max):
147 for j
in range(j_min, j_max):
148 p_0 = (lat[i, j], lon[i, j])
149 p_1 = (lat[i, j + 1], lon[i, j + 1])
150 p_2 = (lat[i + 1, j + 1], lon[i + 1, j + 1])
151 p_3 = (lat[i + 1, j], lon[i + 1, j])
153 print(f
"Bad geolocation in lat, lon array for line {i}, pixel {j}")
155 polygon = Polygon([p_0, p_1, p_2, p_3, p_0])
157 if polygon.contains(point):
159 min_dist = point.distance(
Point(p_0))
162 dist_dict[(i, j + 1)] = point.distance(
Point(p_1))
163 dist_dict[(i + 1, j + 1)] = point.distance(
Point(p_2))
164 dist_dict[(i + 1, j)] = point.distance(
Point(p_3))
165 for (i_k, j_k), dist
in dist_dict.items():
170 return i_min, j_min, p_0, p_1, p_2, p_3, point
173 f
"-Warning- : Could not locate the chip with lat={feature_lat} and lon={feature_lon} within the granule. See {get_linenumber()} in {filename_script}")
177 def lorentzian(latlon, x0, y0, GammaX, GammaY, Factor, alpha, Amplitude, offset):
181 x = lat * np.cos(alpha) + lon * np.sin(alpha)
182 y = - lat * np.sin(alpha) + lon * np.cos(alpha)
183 val: np.ndarray = offset + Amplitude / \
184 ((x - x0) ** 2 / GammaX ** 2 + (y - y0) ** 2 / GammaY ** 2 + Factor)
189 with nc.Dataset(path)
as f:
190 ecrx = f[
"ECR_x_coordinate_array"][:]
191 ecry = f[
"ECR_y_coordinate_array"][:]
192 ecrz = f[
"ECR_z_coordinate_array"][:]
193 ecef = {
'proj':
'geocent',
'ellps':
'WGS84',
'datum':
'WGS84'}
194 lla = {
'proj':
'latlong',
'ellps':
'WGS84',
'datum':
'WGS84'}
195 transformer = pyproj.Transformer.from_crs(ecef, lla)
196 lon, lat, _ = transformer.transform(ecrx, ecry, ecrz)
197 return f[
"Band_1"][:], lat, lon, f.FEATURELATITUDE, f.FEATURELONGITUDE
201 parser = argparse.ArgumentParser(
206 granule - input L1B granules
207 chip - input chip file
208 feature_latitude - latitude of the center of the chip
209 feature_longitude - longitude of the center of the chip
210 delta_latitude - latitude shift, latitude coordinate of the peak of NCC
211 delta_longitude - longitude shift, longitude coordinate of the peak of NCC
212 pixel_number - pixel number between 0 and pixels_per_line-1 (or ccd_pixels-1 for OCI)
213 confidence_level - the maximum value of the normalized cross correlation (NCC) within a sliding lat/lon window
215 fit_delta_latitude - latitude shift from the Lorentzian fit of NCC
216 fit_delta_longitude - longitude shift from the Lorentzian fit of NCC
217 r_squared - R_squared of the the Lorentzian fit
219 formatter_class=argparse.RawDescriptionHelpFormatter,
221 Additional output info:
222 scantime is a scantime of the line where the feature pixel was found.
223 delta_latitude and delta_longitude mean that a point in the chip with (lat,lon) coordinates correspond to a point in the granule with (lat + delta_latitude, lon + delta_longitude).
224 The maximum possible value of confidence_level is 1 which means 100% match. Higher value is better. Values lower 0.5 indicate poor match.
225 fit_delta_latitude, fit_delta_longitude and r_squared can be NaN if the fit does not converge.
227 parser.add_argument(
"-v",
"--version", action=
"version", version=VERSION)
229 "--ifile", help=
"input L1B netcdf file", type=str, required=
True)
232 help=
"input chip file list, each filename should be separated by a new line terminator. No two filenames can be put in the same line",
233 type=str, required=
True)
234 parser.add_argument(
"--ofile", help=
"output csv", type=str, required=
True)
235 parser.add_argument(
"--cloudmask", help=
"input cloudmask file", type=str)
236 parser.add_argument(
"--odebugfile", help=
"output debug file", type=str)
237 parser.add_argument(
"--subpixels", help=
"number of subpixels", type=int)
239 "--window_size", help=
"the size of sliding window in sensor pixels", type=int)
241 "--confidence", help=
"minimum confidence level to be included. Default is 0.5", type=float, default=0.5)
242 parser.add_argument(
'--debug', action=
'store_true')
243 parser.add_argument(
'--no-debug', dest=
'debug', action=
'store_false')
244 parser.set_defaults(debug=
False)
245 if len(sys.argv) == 1:
248 args = parser.parse_args()
253 tm_band, lat_chip, lon_chip, feature_lat, feature_lon =
read_chip_file(
255 return get_position(lat, lon, feature_lat, feature_lon), tm_band, lat_chip, lon_chip
259 len_x, len_y = lat.shape
261 lat_dir = lat[1, 0] - lat[0, 0] > 0
262 lon_dir = lon[0, 1] - lon[0, 0] > 0
264 lat_max = np.min(lat.max(axis=0))
265 lat_min = np.max(lat.min(axis=0))
266 lon_max = np.min((lon.max(axis=1)))
267 lon_min = np.max((lon.min(axis=1)))
279 lat_lin = np.linspace(lat_st, lat_end, len_x, endpoint=
True)
280 lon_lin = np.linspace(lon_st, lon_end, len_x, endpoint=
True)
282 lon_grid, lat_grid = np.meshgrid(lon_lin, lat_lin)
283 data_gridded = griddata((lat.flatten(), lon.flatten()), data.flatten(),
284 (lat_grid.flatten(), lon_grid.flatten()), method=
"nearest")
285 return data_gridded.reshape(len_x, len_y), lat_lin, lon_lin
289 sc_lat = deepcopy(lat[i:i + w, j:j + h])
290 sc_lon = deepcopy(lon[i:i + w, j:j + h])
291 if image
is not None:
292 sc_image = deepcopy(image[i:i + w, j:j + h])
293 return sc_lat, sc_lon, sc_image
295 return sc_lat, sc_lon
300 sc_lon_shift = sc_lon - point.y - shift_lon
301 sc_lat_shift = sc_lat - point.x - shift_lat
302 sc_image_copy = deepcopy(sc_image)
303 tm_sc_band_n = rbs(np.column_stack(
304 [sc_lat_shift.flatten(), sc_lon_shift.flatten()]))
305 tm_sc_band_n = tm_sc_band_n.reshape(sc_image_copy.shape)
306 sc_image_copy[np.isnan(tm_sc_band_n)] = np.NaN
307 tm_sc_band_n[np.isnan(sc_image_copy)] = np.NaN
308 return sc_image_copy, tm_sc_band_n
313 sc_image_copy, tm_sc_band_n =
get_match_layers(rbs, point, sc_lon, sc_lat, sc_image, shift_lon,
316 valid_pnts = np.sum(np.isfinite(tm_sc_band_n))
317 if valid_pnts < min_number_of_points:
320 sc_image_copy = sc_image_copy - np.nanmean(sc_image_copy)
321 tm_sc_band_n = tm_sc_band_n - np.nanmean(tm_sc_band_n)
322 sc_image_copy /= np.nanstd(sc_image_copy)
323 tm_sc_band_n /= np.nanstd(tm_sc_band_n)
324 ncc = np.nansum(sc_image_copy * tm_sc_band_n) / \
325 np.sum(~np.isnan(tm_sc_band_n))
330 ncc_fit = 1 / (1 - ncc_original)
331 gamma_lat = np.abs(lat_grid[1] - lat_grid[0]) * 100
332 gamma_lon = np.abs(lon_grid[1] - lon_grid[0]) * 100
333 latlon = np.meshgrid(lat_grid, lon_grid)
335 p0 = delta_latitude, delta_longitude, gamma_lat, gamma_lon, 1, 0, 100, 0
336 popt, pcov = optimize.curve_fit(lorentzian, latlon, ncc_fit.ravel(),
337 p0=p0, bounds=((-0.1, -0.1, -1, -1, -np.inf, -np.pi / 2, 0, -np.inf),
338 (0.1, 0.1, 1, 1, np.inf, np.pi / 2, np.inf, np.inf)))
339 x0, y0, GammaX, GammaY, Factor, alpha, Amplitude, offset = popt
340 fit =
lorentzian(latlon, x0, y0, GammaX, GammaY,
341 Factor, alpha, Amplitude, offset)
342 fit = fit.reshape(ncc_fit.shape)
343 residual = ncc_fit - fit
345 ss_res = np.sum(residual)
346 ss_data = np.sum((ncc_fit - np.mean(ncc_fit)) ** 2)
347 r_squared = 1 - ss_res / ss_data
348 return x0, y0, GammaX, GammaY, Factor, alpha, Amplitude, offset, fit, r_squared
349 except Exception
as e:
354 def get_lat_lon_shift(l1b_path: str, chips_list: List[str], output_file_name: str, debug_mode=
False, **kwargs):
355 lat, lon, image, scantime, tilt_angle =
read_file_l1b(l1b_path)
356 subpixels_set = subpixels_default
358 window_size_set = window_size_defalut
360 min_included_ncc = -1
361 if "confidence" in kwargs:
362 if not kwargs[
"confidence"]
is None:
363 min_included_ncc = kwargs[
"confidence"]
367 if "subpixels" in kwargs:
368 if not kwargs[
"subpixels"]
is None:
369 if kwargs[
"subpixels"] > subpixels_default_max:
370 print(
"Warning: the subpixel count can't exceed {}".format(
371 subpixels_default_max))
373 subpixels_set = kwargs[
"subpixels"]
374 if "window_size" in kwargs:
375 if not kwargs[
"window_size"]
is None:
376 if kwargs[
"window_size"] > w:
377 print(
"Warning: the window_size count can't exceed {}".format(w))
379 window_size_set = kwargs[
"window_size"]
381 if "odebugfile" in kwargs:
382 if not kwargs[
"odebugfile"]
is None:
385 len_ncc = ((subpixels_set * window_size_set) // 2) * 2 + \
387 coeff_scale = subpixels_default_max / subpixels_set
391 if "cloud_mask_file" in kwargs:
392 if not kwargs[
"cloud_mask_file"]
is None:
394 image[cld_mask == 1] = np.NaN
396 data_out: List[Dict] = []
398 for chip_path
in chips_list:
399 start_time = time.time()
401 position_of_the_chip, tm_band, lat_chip, lon_chip =
ini_input_data(lat, lon,
403 if position_of_the_chip
is None:
404 print(f
"Skipping the chip {chip_path} ...")
406 i_cell, j_cell, p0, p1, p2, p3, point = position_of_the_chip
407 if i_cell < 2 * w
or (lat.shape[0] - i_cell) < 2 * w:
409 f
"The chip {chip_path} is too close to the swath edge : line_number={i_cell}. Skipping ...")
411 if j_cell < 2 * h
or (lat.shape[1] - j_cell) < 2 * h:
413 f
"The chip {chip_path} is too close to the swath edge : pixel_number={j_cell}. Skipping ...")
416 lat=lat_chip, lon=lon_chip, data=tm_band)
418 tb_band_gridded_original = deepcopy(tb_band_gridded)
420 tb_band_gridded = uniform_filter(tb_band_gridded, 33)
421 step_size_lat = np.abs(lat_lin[1] - lat_lin[0]) * coeff_scale
422 step_size_lon = np.abs(lon_lin[1] - lon_lin[0]) * coeff_scale
423 shift_lon_array = np.linspace(
424 step_size_lon * (-wide), step_size_lon * wide, len_ncc)
425 shift_lat_array = np.linspace(
426 step_size_lat * (-wide), step_size_lat * wide, len_ncc)
427 rbs = RegularGridInterpolator(
428 (lat_lin - point.x, lon_lin - point.y), tb_band_gridded, method=
"linear", bounds_error=
False)
430 lat, lon, i_cell - w, j_cell - h, w * 2 + 1, h * 2 + 1, image)
431 ncc_array = np.ones((len_ncc, len_ncc)) * -1.0
433 valid_pnts = np.sum(np.isfinite(sc_image))
434 if valid_pnts < min_number_of_points:
436 f
"Number of valid (cloud free) points in the scene {valid_pnts} is too low. Skipping the chip {chip_path}")
438 for ind_lat
in range(len_ncc):
439 for ind_lon
in range(len_ncc):
440 shift_lat = shift_lat_array[ind_lat]
441 shift_lon = shift_lon_array[ind_lon]
445 ncc_array[ind_lat, ind_lon] = ncc
447 print(
"--- Execution time: {} seconds ---".format(time.time() - start_time))
448 print(f
"Chip {chip_path} has been processed.")
449 (ilat, ilon) = np.unravel_index(ncc_array.argmax(), ncc_array.shape)
450 delta_latitude = shift_lat_array[ilat]
451 delta_longitude = shift_lon_array[ilon]
452 ncc_array[np.isnan(ncc_array)] = -1.0
453 max_ncc = np.nanmax(ncc_array)
454 if max_ncc < min_included_ncc:
456 f
"The confidence level is {max_ncc} which is lower than the threshold = {min_included_ncc}. Skipping ..")
458 if tilt_angle
is None:
461 tilt = tilt_angle[i_cell]
464 ncc_array, shift_lat_array, shift_lon_array, delta_latitude, delta_longitude)
466 x0_fit, y0_fit, GammaX, GammaY, Factor, alpha, Amplitude, offset, fit, r_squared = result_out
468 print(f
"Warning: lorentzian fit for {chip_path} has not converged")
472 fit = np.ones(ncc_array.shape) * np.NAN
481 out_ncc_filename = f
"ncc_{RUNNING_TIME}_{os.path.basename(l1b_path)}.nc"
482 out_ncc_filename = os.path.join(
483 os.path.dirname(output_file_name), out_ncc_filename)
484 if "odebugfile" in kwargs:
485 if not kwargs[
"odebugfile"]
is None:
486 out_ncc_filename = kwargs[
"odebugfile"]
487 if not os.path.exists(out_ncc_filename):
489 with nc.Dataset(out_ncc_filename, mode=mode)
as out_ncc:
490 out_ncc: nc.Dataset = out_ncc
492 out_ncc.createDimension(
"x", len_ncc)
493 out_ncc.createDimension(
"y", len_ncc)
494 out_ncc.createDimension(
"lat", sc_image.shape[1])
495 out_ncc.createDimension(
"lon", sc_image.shape[0])
496 out_ncc.version = VERSION
497 out_ncc.runtime = RUNNING_TIME
498 out_ncc.setncattr(
"l1b_file", l1b_path)
499 out_ncc.setncattr(
"chips",
",".join(chips_list))
500 for key,val
in kwargs.items():
502 out_ncc.setncattr(key,val)
504 out_ncc.setncattr(key,
"")
505 grp: nc.Group = out_ncc.createGroup(
506 os.path.basename(chip_path))
507 grp.delta_latitude = delta_latitude
508 grp.delta_longitude = delta_longitude
511 wkt_polygon_str : str = Polygon([p0, p1, p2, p3]).wkt
512 wkt_point_str : str = point.wkt
513 grp.setncattr(
"Point",wkt_point_str)
514 grp.setncattr(
"Bounding_polygon",wkt_polygon_str)
518 grp.Amplitude = Amplitude
523 grp.r_squared = r_squared
525 grp.feature_latitude = point.x
526 grp.feature_longitude = point.y
527 grp.createDimension(
"chip_lat_len", lat_lin.size)
528 grp.createDimension(
"chip_lon_len", lon_lin.size)
529 var_grp_local = grp.createVariable(varname=
"lat_lin", dimensions=
'chip_lat_len',
530 datatype=
'f4', zlib=
True)
531 var_grp_local[:] = lat_lin
532 var_grp_local = grp.createVariable(varname=
"lon_lin", dimensions=
'chip_lon_len',
533 datatype=
'f4', zlib=
True)
534 var_grp_local[:] = lon_lin
535 var_grp_local = grp.createVariable(varname=
"tm_band", dimensions=(
'chip_lat_len',
'chip_lon_len'),
536 datatype=
'f4', zlib=
True)
537 var_grp_local[:] = tb_band_gridded_original
538 mat_ncc = grp.createVariable(varname=
"ncc", dimensions=(
'x',
'y'),
539 datatype=
'f4', zlib=
True)
540 mat_ncc[:] = ncc_array
541 mat_fit = grp.createVariable(varname=
"fit", dimensions=(
'x',
'y'),
542 datatype=
'f4', zlib=
True)
544 lat_array = grp.createVariable(varname=
"latGrid", dimensions=(
'x'),
545 datatype=
'f4', zlib=
True)
546 lat_array[:] = shift_lat_array
548 lon_array = grp.createVariable(varname=
"lonGrid", dimensions=(
'y'),
549 datatype=
'f4', zlib=
True)
550 lon_array[:] = shift_lon_array
552 sc_image_crop, chip_downsample =
get_match_layers(rbs, point, sc_lon, sc_lat, sc_image,
555 chip = grp.createVariable(varname=
"chip", dimensions=(
'lon',
'lat'),
556 datatype=
'f4', zlib=
True)
557 chip[:] = chip_downsample
558 crop = grp.createVariable(varname=
"crop", dimensions=(
'lon',
'lat'),
559 datatype=
'f4', zlib=
True)
560 crop[:] = sc_image_crop
561 scene = grp.createVariable(varname=
"scene",
562 dimensions=(
'lon',
'lat'),
563 datatype=
'f4', zlib=
True)
565 lat_crop = grp.createVariable(varname=
"lat",
566 dimensions=(
'lon',
'lat'),
567 datatype=
'f4', zlib=
True)
569 lon_crop = grp.createVariable(varname=
"lon",
570 dimensions=(
'lon',
'lat'),
571 datatype=
'f4', zlib=
True)
573 granule_name_len = len(os.path.basename(l1b_path))
574 chip_name_len = len(os.path.basename(chip_path))
575 data_out.append({
'scantime'.ljust(14): f
"{scantime[i_cell]:14.3f}"})
576 data_out[-1][
"granule".ljust(granule_name_len)
577 ] = os.path.basename(l1b_path)
578 data_out[-1][
'chip'.ljust(chip_name_len)] = os.path.basename(chip_path)
579 data_out[-1][
'feature_latitude'] = f
"{point.x:16.7f}"
580 data_out[-1][
'feature_longitude'] = f
"{point.y:17.7f}"
581 data_out[-1][
'delta_latitude'] = f
"{delta_latitude:14.7f}"
582 data_out[-1][
'delta_longitude'] = f
"{delta_longitude:15.7f}"
583 data_out[-1][
'pixel_number'] = f
"{j_cell:12d}"
584 data_out[-1][
'confidence_level'] = f
"{max_ncc:16.7f}"
585 data_out[-1][
'tilt'.rjust(10)] = f
"{tilt:10.5f}"
586 if abs(x0_fit) > 1.0
or abs(y0_fit) > 1.0:
587 print(f
"Fit did not converge for {x0_fit} and {y0_fit}")
589 if not np.isnan(r_squared):
590 data_out[-1][
'fit_delta_latitude'] = f
"{x0_fit:18.7f}"
591 data_out[-1][
'fit_delta_longitude'] = f
"{y0_fit:18.7f}"
592 data_out[-1][
'r_squared'.rjust(15)] = f
"{r_squared:15.7f}"
594 data_out[-1][
'fit_delta_latitude'] =
"NaN".rjust(18)
595 data_out[-1][
'fit_delta_longitude'] =
"NaN".rjust(18)
596 data_out[-1][
'r_squared'.rjust(15)] =
"NaN"
597 if len(data_out) > 0:
599 for key
in data_out[0]:
601 with open(output_file_name,
'w', newline=
'')
as output_csv:
603 for key
in data_out[0]:
605 recorder = csv.DictWriter(output_csv, fieldnames=fields)
606 recorder.writeheader()
607 recorder.writerows(data_out)
613 if __name__ ==
"__main__":
614 print(PROGRAM_NAME, VERSION)
616 print(
"You are running {}, version {}. Current time is {}".format(
617 PROGRAM_NAME, VERSION, running_time))
618 l1b_path = args.ifile
621 cloud_mask_file = args.cloudmask
622 window_size = args.window_size
623 subpixels = args.subpixels
625 l1b_path, chips_list, ofile, debug_mode=args.debug, cloud_mask_file=cloud_mask_file, window_size=window_size,
626 subpixels=subpixels, confidence=args.confidence, odebugfile=args.odebugfile)