1717from hypernets_processor .data_io .hypernets_ds_builder import HypernetsDSBuilder
1818from hypernets_processor .version import __version__
1919from hypernets_processor .data_io .dataset_util import DatasetUtil as du
20+ from hypernets_processor .data_io .hypernets_writer import HypernetsWriter
2021
2122'''___Authorship___'''
2223__author__ = "Clémence Goyens"
@@ -32,6 +33,7 @@ def __init__(self, context):
3233 self .context = context
3334 self .model = self .context .get_config_value ("model" ).split (',' )
3435 self .hdsb = HypernetsDSBuilder (context = context )
36+ self .writer = HypernetsWriter (context = context )
3537
3638 cckeys = ['mapping_vis_a' , 'mapping_vis_b' , 'mapping_vis_c' , 'mapping_vis_d' , 'mapping_vis_e' , 'mapping_vis_f' ]
3739 ccvalues = []
@@ -51,6 +53,31 @@ def plot_spectra(self, spectra, dataSpectra):
5153 plt .plot ([i for i in range (len (dataSpectra ))], dataSpectra )
5254 plt .show ()
5355
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+
5481 def read_header (self , f , headerDef ):
5582 header = {}
5683 for headLen , headName , headFormat in headerDef :
@@ -134,6 +161,7 @@ def read_wavelength(self, pixcount):
134161 return wvl
135162
136163 def read_series (self , seq_dir , series , lat , lon , metadata , flag , fileformat ):
164+ print (series )
137165
138166 model_name = self .model
139167
@@ -177,9 +205,7 @@ def read_series(self, seq_dir, series, lat, lon, metadata, flag, fileformat):
177205
178206 header = self .read_header (f , HEADER_DEF )
179207 self .context .logger .debug (header )
180-
181208 pixCount = header ['Pixel Count' ]
182-
183209 # if bool(header) == False:
184210 # print("Data corrupt go to next line")
185211 # header = self.read_header(f, HEADER_DEF)
@@ -189,6 +215,7 @@ def read_series(self, seq_dir, series, lat, lon, metadata, flag, fileformat):
189215 # look for the maximum number of lines to read-- maybe not an elegant way to do?
190216 f .seek (0 , 2 ) # go to end of file
191217 eof = f .tell ()
218+ print (eof )
192219 f .close ()
193220
194221 # 2. Create template dataset
@@ -207,6 +234,7 @@ def read_series(self, seq_dir, series, lat, lon, metadata, flag, fileformat):
207234
208235 # read all spectra (== spe files with concanated files) in a series
209236 for spectra in series :
237+
210238 model = dict (zip (model_name , spectra .split ('_' )[:- 1 ]))
211239 specBlock = model ['series_rep' ] + '_' + model ['series_id' ] + '_' + model ['vaa' ] + '_' + model [
212240 'azimuth_ref' ] + '_' + model ['vza' ]
@@ -242,6 +270,7 @@ def read_series(self, seq_dir, series, lat, lon, metadata, flag, fileformat):
242270 self .context .logger .error ("Data corrupt go to next line" )
243271 break
244272 continue
273+ # -------------------------------------------------------
245274 pixCount = header ['Pixel Count' ]
246275 scan = self .read_data (f , pixCount )
247276 # 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):
283312 ds ["solar_zenith_angle" ][scan_number ] = get_altitude (float (lat ), float (lon ), acquisitionTime )
284313 ds ["solar_azimuth_angle" ][scan_number ] = get_azimuth (float (lat ), float (lon ), acquisitionTime )
285314 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." )
287317 ds ['quality_flag' ][scan_number ] = flag
288318 ds ['integration_time' ][scan_number ] = header ['integration_time' ]
289319 ds ['temperature' ][scan_number ] = header ['temperature' ]
@@ -308,7 +338,7 @@ def read_series(self, seq_dir, series, lat, lon, metadata, flag, fileformat):
308338 ds ['digital_number' ][0 :pixCount , scan_number ] = scan
309339
310340 scan_number += 1
311-
341+ print ( f . tell ())
312342 if f .tell () == eof :
313343 nextLine = False
314344
@@ -352,7 +382,7 @@ def read_metadata(self, seq_dir):
352382 # ACTION_NONE : 0x03 (03)
353383
354384 metadata = ConfigParser ()
355- print ("seq" ,os .path .join (seq_dir , "metadata.txt" ))
385+ print ("seq" , os .path .join (seq_dir , "metadata.txt" ))
356386 if os .path .exists (os .path .join (seq_dir , "metadata.txt" )):
357387 metadata .read (os .path .join (seq_dir , "metadata.txt" ))
358388 # ------------------------------
@@ -449,7 +479,7 @@ def read_sequence(self, seq_dir, setfile=None):
449479 seq_dir )
450480
451481 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" )
453483 if self .context .get_config_value ("write_l0" ):
454484 self .writer .write (l0_irr , overwrite = True )
455485 # can't use this when non concatanted spectra
@@ -461,7 +491,7 @@ def read_sequence(self, seq_dir, setfile=None):
461491 self .context .logger .error ("No irradiance data for this sequence" )
462492
463493 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" )
465495 if self .context .get_config_value ("write_l0" ):
466496 self .writer .write (l0_rad , overwrite = True )
467497 # 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):
472502 self .context .logger .error ("No radiance data for this sequence" )
473503
474504 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" )
476506 if self .context .get_config_value ("write_l0" ):
477507 self .writer .write (l0_bla , overwrite = True )
478508 # 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):
496526 # flagint -= r
497527 # return(flags)
498528
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+
499614
500615if __name__ == '__main__' :
501616 pass
0 commit comments