17
17
from hypernets_processor .data_io .hypernets_ds_builder import HypernetsDSBuilder
18
18
from hypernets_processor .version import __version__
19
19
from hypernets_processor .data_io .dataset_util import DatasetUtil as du
20
+ from hypernets_processor .data_io .hypernets_writer import HypernetsWriter
20
21
21
22
'''___Authorship___'''
22
23
__author__ = "Clémence Goyens"
@@ -32,6 +33,7 @@ def __init__(self, context):
32
33
self .context = context
33
34
self .model = self .context .get_config_value ("model" ).split (',' )
34
35
self .hdsb = HypernetsDSBuilder (context = context )
36
+ self .writer = HypernetsWriter (context = context )
35
37
36
38
cckeys = ['mapping_vis_a' , 'mapping_vis_b' , 'mapping_vis_c' , 'mapping_vis_d' , 'mapping_vis_e' , 'mapping_vis_f' ]
37
39
ccvalues = []
@@ -51,6 +53,31 @@ def plot_spectra(self, spectra, dataSpectra):
51
53
plt .plot ([i for i in range (len (dataSpectra ))], dataSpectra )
52
54
plt .show ()
53
55
56
+ # def save(self, path):
57
+ # with open(path, 'w') as f:
58
+ # f.write('Dataset length: {} bytes\n'
59
+ # 'Timestamp: {} ms\n'
60
+ # 'CRC32: {} \n'
61
+ # 'Entrance: {}\n'
62
+ # 'Radiometer: {}\n'
63
+ # 'Exposure time: {} ms\n'
64
+ # 'Sensor temperature: {} \'C\n'
65
+ # 'Pixel count: {}\n'
66
+ # 'Tilt:\n'
67
+ # '\tx:{}\u00B1{}\n'
68
+ # '\t y:{}\u00B1{}\n'
69
+ # '\t z:{}\u00B1{}\n'.format(self.header.total_length, self.header.timestamp, hex(self.crc32[0]),
70
+ # self.header.spectrum_type.optics.name,
71
+ # self.header.spectrum_type.radiometer.name,
72
+ # self.header.exposure_time, self.header.temperature,
73
+ # self.header.pixel_count,
74
+ # self.header.accel_stats.mean_x,
75
+ # self.header.accel_stats.std_x,
76
+ # self.header.accel_stats.mean_y,
77
+ # self.header.accel_stats.std_y,
78
+ # self.header.accel_stats.mean_z,
79
+ # self.header.accel_stats.std_z))
80
+
54
81
def read_header (self , f , headerDef ):
55
82
header = {}
56
83
for headLen , headName , headFormat in headerDef :
@@ -134,6 +161,7 @@ def read_wavelength(self, pixcount):
134
161
return wvl
135
162
136
163
def read_series (self , seq_dir , series , lat , lon , metadata , flag , fileformat ):
164
+ print (series )
137
165
138
166
model_name = self .model
139
167
@@ -177,9 +205,7 @@ def read_series(self, seq_dir, series, lat, lon, metadata, flag, fileformat):
177
205
178
206
header = self .read_header (f , HEADER_DEF )
179
207
self .context .logger .debug (header )
180
-
181
208
pixCount = header ['Pixel Count' ]
182
-
183
209
# if bool(header) == False:
184
210
# print("Data corrupt go to next line")
185
211
# header = self.read_header(f, HEADER_DEF)
@@ -189,6 +215,7 @@ def read_series(self, seq_dir, series, lat, lon, metadata, flag, fileformat):
189
215
# look for the maximum number of lines to read-- maybe not an elegant way to do?
190
216
f .seek (0 , 2 ) # go to end of file
191
217
eof = f .tell ()
218
+ print (eof )
192
219
f .close ()
193
220
194
221
# 2. Create template dataset
@@ -207,6 +234,7 @@ def read_series(self, seq_dir, series, lat, lon, metadata, flag, fileformat):
207
234
208
235
# read all spectra (== spe files with concanated files) in a series
209
236
for spectra in series :
237
+
210
238
model = dict (zip (model_name , spectra .split ('_' )[:- 1 ]))
211
239
specBlock = model ['series_rep' ] + '_' + model ['series_id' ] + '_' + model ['vaa' ] + '_' + model [
212
240
'azimuth_ref' ] + '_' + model ['vza' ]
@@ -242,6 +270,7 @@ def read_series(self, seq_dir, series, lat, lon, metadata, flag, fileformat):
242
270
self .context .logger .error ("Data corrupt go to next line" )
243
271
break
244
272
continue
273
+ # -------------------------------------------------------
245
274
pixCount = header ['Pixel Count' ]
246
275
scan = self .read_data (f , pixCount )
247
276
# should include this back again when crc32 is in the headers!
@@ -283,7 +312,8 @@ def read_series(self, seq_dir, series, lat, lon, metadata, flag, fileformat):
283
312
ds ["solar_zenith_angle" ][scan_number ] = get_altitude (float (lat ), float (lon ), acquisitionTime )
284
313
ds ["solar_azimuth_angle" ][scan_number ] = get_azimuth (float (lat ), float (lon ), acquisitionTime )
285
314
else :
286
- self .context .logger .error ("Lattitude is not found, using default values instead for lat, lon, sza and saa." )
315
+ self .context .logger .error (
316
+ "Lattitude is not found, using default values instead for lat, lon, sza and saa." )
287
317
ds ['quality_flag' ][scan_number ] = flag
288
318
ds ['integration_time' ][scan_number ] = header ['integration_time' ]
289
319
ds ['temperature' ][scan_number ] = header ['temperature' ]
@@ -308,7 +338,7 @@ def read_series(self, seq_dir, series, lat, lon, metadata, flag, fileformat):
308
338
ds ['digital_number' ][0 :pixCount , scan_number ] = scan
309
339
310
340
scan_number += 1
311
-
341
+ print ( f . tell ())
312
342
if f .tell () == eof :
313
343
nextLine = False
314
344
@@ -352,7 +382,7 @@ def read_metadata(self, seq_dir):
352
382
# ACTION_NONE : 0x03 (03)
353
383
354
384
metadata = ConfigParser ()
355
- print ("seq" ,os .path .join (seq_dir , "metadata.txt" ))
385
+ print ("seq" , os .path .join (seq_dir , "metadata.txt" ))
356
386
if os .path .exists (os .path .join (seq_dir , "metadata.txt" )):
357
387
metadata .read (os .path .join (seq_dir , "metadata.txt" ))
358
388
# ------------------------------
@@ -449,7 +479,7 @@ def read_sequence(self, seq_dir, setfile=None):
449
479
seq_dir )
450
480
451
481
if seriesIrr :
452
- l0_irr = self .read_series (seq_dir , seriesIrr , lat , lon , metadata , flag , "L0_IRR" )
482
+ l0_irr = self .read_series_raw (seq_dir , seriesIrr , lat , lon , metadata , flag , "L0_IRR" )
453
483
if self .context .get_config_value ("write_l0" ):
454
484
self .writer .write (l0_irr , overwrite = True )
455
485
# can't use this when non concatanted spectra
@@ -461,7 +491,7 @@ def read_sequence(self, seq_dir, setfile=None):
461
491
self .context .logger .error ("No irradiance data for this sequence" )
462
492
463
493
if seriesRad :
464
- l0_rad = self .read_series (seq_dir , seriesRad , lat , lon , metadata , flag , "L0_RAD" )
494
+ l0_rad = self .read_series_raw (seq_dir , seriesRad , lat , lon , metadata , flag , "L0_RAD" )
465
495
if self .context .get_config_value ("write_l0" ):
466
496
self .writer .write (l0_rad , overwrite = True )
467
497
# if all([os.path.isfile(os.path.join(seq_dir,"RADIOMETER/",f)) for f in seriesRad]):
@@ -472,7 +502,7 @@ def read_sequence(self, seq_dir, setfile=None):
472
502
self .context .logger .error ("No radiance data for this sequence" )
473
503
474
504
if seriesBlack :
475
- l0_bla = self .read_series (seq_dir , seriesBlack , lat , lon , metadata , flag , "L0_BLA" )
505
+ l0_bla = self .read_series_raw (seq_dir , seriesBlack , lat , lon , metadata , flag , "L0_BLA" )
476
506
if self .context .get_config_value ("write_l0" ):
477
507
self .writer .write (l0_bla , overwrite = True )
478
508
# if all([os.path.isfile(os.path.join(seq_dir, "RADIOMETER/", f)) for f in seriesBlack]):
@@ -496,6 +526,91 @@ def read_sequence(self, seq_dir, setfile=None):
496
526
# flagint -= r
497
527
# return(flags)
498
528
529
+ def raw_read (spectra , n , spectra_length = 2048 ):
530
+ print ("Open %s" % spectra )
531
+ data_spectra = []
532
+ with open (spectra , "rb" ) as f :
533
+ data = []
534
+ for i in range (n ):
535
+ data = f .read (2 * int (spectra_length ))
536
+ data = list (unpack ('<' + 'H' * spectra_length , data ))
537
+ data_spectra .append (data [:])
538
+ return data_spectra
539
+
540
+ def read_series_raw (self , seq_dir , series , lat , lon , metadata , flag , fileformat , spectra_length = 2048 ):
541
+
542
+ model_name = self .model
543
+
544
+ # 1. Read header to create template dataset (including wvl and scan dimensions + end of file!!)
545
+ # ----------------------------------------
546
+
547
+ # scan dimension - to have total number of dimensions
548
+ index_scan_total = model_name .index ("scan_total" )
549
+ # series id
550
+ # ------------------------------------------
551
+ # added to consider concanated files
552
+ scanDim = sum ([int (re .split ('_|\.' , i )[index_scan_total ]) for i in series ])
553
+ # wvl dimensions
554
+ FOLDER_NAME = os .path .join (seq_dir , "RADIOMETER/" )
555
+ f = open (FOLDER_NAME + series [1 ], "rb" )
556
+
557
+ wvl = self .read_wavelength (spectra_length )
558
+
559
+ # 2. Create template dataset
560
+ # -----------------------------------
561
+ dim_sizes_dict = {"wavelength" : len (wvl ), "scan" : scanDim }
562
+
563
+ # use template from variables and metadata in format
564
+ ds = self .hdsb .create_ds_template (dim_sizes_dict = dim_sizes_dict , ds_format = fileformat )
565
+
566
+ ds ["wavelength" ] = wvl
567
+ ds ["scan" ] = np .linspace (1 , scanDim , scanDim )
568
+ scan_number = 0
569
+
570
+ # read all spectra (== spe files with concanated files) in a series
571
+ for spefile in series :
572
+
573
+ model = dict (zip (model_name , spefile .split ('_' )[:- 1 ]))
574
+ specBlock = model ['series_rep' ] + '_' + model ['series_id' ] + '_' + model ['vaa' ] + '_' + model [
575
+ 'azimuth_ref' ] + '_' + model ['vza' ]
576
+ # spectra attributes from metadata file
577
+ specattr = dict (metadata [specBlock ])
578
+
579
+ # name of spectra file
580
+ acquisitionTime = specattr [spefile ]
581
+ acquisitionTime = datetime .datetime .strptime (acquisitionTime + "UTC" , '%Y%m%dT%H%M%S%Z' )
582
+ acquisitionTime = acquisitionTime .replace (tzinfo = timezone .utc )
583
+
584
+ # -----------------------
585
+ # read the file
586
+ # -----------------------
587
+ with open (FOLDER_NAME + spefile , "rb" ) as f :
588
+ n = int (re .split ('_|\.' , spefile )[index_scan_total ])
589
+ for s in range (n ):
590
+ data = f .read (2 * int (spectra_length ))
591
+ scan = list (unpack ('<' + 'H' * spectra_length , data ))
592
+ # fill in dataset
593
+ # maybe xarray has a better way to do - check merge, concat, ...
594
+ series_id = model ['series_id' ]
595
+ ds ["series_id" ][scan_number ] = series_id
596
+ ds ["viewing_azimuth_angle" ][scan_number ] = model ['vaa' ]
597
+ ds ["viewing_zenith_angle" ][scan_number ] = model ['vza' ]
598
+ # estimate time based on timestamp
599
+ ds ["acquisition_time" ][scan_number ] = datetime .datetime .timestamp (acquisitionTime )
600
+
601
+ if lat is not None :
602
+ ds .attrs ["site_latitude" ] = lat
603
+ ds .attrs ["site_longitude" ] = lon
604
+ ds ["solar_zenith_angle" ][scan_number ] = get_altitude (float (lat ), float (lon ), acquisitionTime )
605
+ ds ["solar_azimuth_angle" ][scan_number ] = get_azimuth (float (lat ), float (lon ), acquisitionTime )
606
+ else :
607
+ self .context .logger .error (
608
+ "Latitude is not found, using default values instead for lat, lon, sza and saa." )
609
+ ds ['quality_flag' ][scan_number ] = flag
610
+ ds ['digital_number' ][0 :spectra_length , scan_number ] = scan
611
+ scan_number += 1
612
+ return ds
613
+
499
614
500
615
if __name__ == '__main__' :
501
616
pass
0 commit comments