#!/usr/bin/env python import os import sys from struct import * import string import math # --------------------------------- # read in binary DAT file and unpack with format string def DAT_reader(bfile_name, format_str, start_record, nrecords): ### print ('--------- DAT_reader ----------') # open the DAT for read bFile = open(bfile_name, "rb") buf = bFile.read() buf_len = len(buf) ### print ('len(buf): ', buf_len) ### print ('buf1: ', buf1) # print out basic info print ('format_str: ', format_str) fmt_size = calcsize(format_str) print ('fmt_size: ', fmt_size) print ('total number of records: ', buf_len/fmt_size) print ('number of records to print out: ', nrecords) print ('the starting record: ', start_record) # error out for improper inputs if start_record < 1 or start_record > buf_len/fmt_size: print ('Error: starting record out of bounds.') sys.exit(-1) if (nrecords < 1 or (nrecords+start_record-1) > buf_len/fmt_size) and nrecords != -1: print ('Error: number of records out of bounds, given the starting record.') sys.exit(-1) print ('') print ('') print ('\n ------------------------------ \n') nr = nrecords # when nr is -1 print out the entire records if nr is -1: start_record = 1 nr = buf_len/fmt_size ### print ('record range to be printed: ', range(start_record-1, start_record+nr-1)) for i in range(start_record-1, start_record+nr-1): st1 = i*fmt_size; ed1 = st1 + fmt_size res1 = unpack(format_str, buf[st1:ed1]) if True: print (res1) print ('\n ------------------------------ \n') st1 += fmt_size; ed1 += fmt_size # end of DAT_reader() # --------------------------------- if __name__ == '__main__': from optparse import OptionParser ### parser = OptionParser() parser = OptionParser(usage="usage: %prog [options] dat_filename; %prog -h (for help messages)") parser.add_option("-s", "--srecord", type="int", dest="start_record", help="The first record to be printed (Any number between [1, N], N being the total record number). Default is 1.", default=1) parser.add_option("-n", "--nrecords", type="int", dest="num_records", help="Number of records to be printed. Default is 1. -1 means all records.", default=1) (options, args) = parser.parse_args() ### print ('len(args): ', len(args)) ### print ('args: ', args) if len(args) is 0: parser.error('Please provide a DAT filename with path.') num_records = options.num_records ### print ('num_records: ', num_records) start_record = options.start_record ### print ('start_record: ', start_record) dat_file = args[0] ### print ('dat_file: ', dat_file) # check to see if dat_filename exists if not os.path.isfile(dat_file): print ('Error: your input dat_filename does not exist.') sys.exit(-1) # get format string from info encoded in filename dat_file_basename = os.path.basename(dat_file) if 'MMCAL_' in dat_file_basename and '_3_' in dat_file_basename and '.DAT' in dat_file_basename: # level 3 V2.0 (MMCAL and SUBMMCAL) # examples: # ftp://psa.esac.esa.int/pub/mirror/INTERNATIONAL-ROSETTA-MISSION/MIRO/RO-C-MIRO-3-PRL-67P-V2.0/DATA/CONTINUUM/MIRO_3_MMCAL_2014119.DAT # ftp://psa.esac.esa.int/pub/mirror/INTERNATIONAL-ROSETTA-MISSION/MIRO/RO-C-MIRO-3-PRL-67P-V2.0/DATA/CONTINUUM/MIRO_3_SUBMMCAL_2014154.DAT format_str = '<1d1H13s1d1d1d1d1H1H1H1H1H200d1d1d1d1d1d1H1H' print ('----------- MMCAL ------------') ### print ('format_str: ', format_str) elif '_3_CTSCAL_' in dat_file_basename and '.DAT' in dat_file_basename: # level 3 V2.0 (CTSCAL) # example: # ftp://psa.esac.esa.int/pub/mirror/INTERNATIONAL-ROSETTA-MISSION/MIRO/RO-C-MIRO-3-PRL-67P-V2.0/DATA/SPECTROSCOPIC/MIRO_3_CTSCAL_2014175.DAT format_str = '<1d13s1H1H1H1H1H1H1d1d4096d4096d4152d4152d1H1H' print ('----------- CTSCAL -----------') ### print ('format_str: ', format_str) elif ('MMGEOM_' in dat_file_basename or 'CTSGEOM_' in dat_file_basename) and '_3_' in dat_file_basename and '.DAT' in dat_file_basename: # level 3 V2.0 (CTSGEOM, MMGEOM, and SUBMMGEOM) # examples: # ftp://psa.esac.esa.int/pub/mirror/INTERNATIONAL-ROSETTA-MISSION/MIRO/RO-C-MIRO-3-PRL-67P-V2.0/DATA/GEOMETRY/MIRO_3_CTSGEOM_2014161.DAT # ftp://psa.esac.esa.int/pub/mirror/INTERNATIONAL-ROSETTA-MISSION/MIRO/RO-C-MIRO-3-PRL-67P-V2.0/DATA/GEOMETRY/MIRO_3_MMGEOM_2014175.DAT # ftp://psa.esac.esa.int/pub/mirror/INTERNATIONAL-ROSETTA-MISSION/MIRO/RO-C-MIRO-3-PRL-67P-V2.0/DATA/GEOMETRY/MIRO_3_SUBMMGEOM_2014126.DAT format_str = '<1d13s1d1d1d1d1d1d1H1d1d1i1d1d1d1d1d1d1d1d1d1d1i1d1d1d1d1d1d1d1d1d1d1d1d1d' print ('\n ----------- level 3 V2.0 MMGEOM, SUBMMGEOM, or CTSGEOM -----------\n') ### print ('format_str: ', format_str) elif '2_HSK_' in dat_file_basename and '.DAT' in dat_file_basename: # level 2 V1.0 (HSK) # example: # ftp://psa.esac.esa.int/pub/mirror/INTERNATIONAL-ROSETTA-MISSION/MIRO/RO-C-MIRO-2-PRL-67P-V1.0/DATA/ENGINEERING/MIRO_2_HSK_20141250000.DAT format_str = '<1d58f2B3H' # perl: df58C2S3 print ('\n ----------- level 2 Engineering (HSK) -----------\n') ### print ('format_str: ', format_str) elif 'MM_' in dat_file_basename and '_2_' in dat_file_basename and '.DAT' in dat_file_basename: # level 2 V1.0 (MM and SUBMM) # example: # ftp://psa.esac.esa.int/pub/mirror/INTERNATIONAL-ROSETTA-MISSION/MIRO/RO-C-MIRO-2-PRL-67P-V1.0/DATA/CONTINUUM/MIRO_2_MM_20141530000.DAT format_str = '4d4B4H200h' # perl: d4C4S4a400 print ('\n ----------- level 2 MM or SUBMM -----------\n') ### print ('format_str: ', format_str) elif 'MM_' in dat_file_basename and 'GEOM' not in dat_file_basename and '_GM_' not in dat_file_basename and '_3_' in dat_file_basename and '.DAT' in dat_file_basename: # level 3 V1.0 (MM and SUBMM) # example: # ftp://psa.esac.esa.int/pub/mirror/INTERNATIONAL-ROSETTA-MISSION/MIRO/RO-C-MIRO-3-ESC2-67P-V1.0/DATA/CONTINUUM/MIRO_3_MM_20151120000.DAT format_str = '<4d19s4B4H200f' # perl: d4a19C4S4a800 print ('\n ----------- level 3 MM or SUBMM -----------\n') ### print ('format_str: ', format_str) elif '_3_CTS_' in dat_file_basename and 'GEOM' not in dat_file_basename and '.DAT' in dat_file_basename: # level 3 V1.0 (CTS) # example: # ftp://psa.esac.esa.int/pub/mirror/INTERNATIONAL-ROSETTA-MISSION/MIRO/RO-C-MIRO-3-ESC1-67P-V1.0/DATA/SPECTROSCOPIC/MIRO_3_CTS_20143650000.DAT print ('\n ----------- level 3 CTS -----------\n') format_str = '<1d19s7B1f1c1B1c1B1f1f1f1f1f4250f' # perl: da19C7faaaCf5a17000 elif '_2_CTS_' in dat_file_basename and '.DAT' in dat_file_basename: # level 2 V1.0 (CTS) # example: # ftp://psa.esac.esa.int/pub/mirror/INTERNATIONAL-ROSETTA-MISSION/MIRO/RO-C-MIRO-2-EXT2-67P-V1.0/DATA/SPECTROSCOPIC/MIRO_2_CTS_20161040000.DAT print ('\n ----------- level 2 CTS -----------\n') format_str = '<1d7B24B1B4096i' # perl: dCCCCCCCa24Ca16384 elif ('_GEOM_' in dat_file_basename or '_GM_' in dat_file_basename) and '_3_' in dat_file_basename and '.DAT' in dat_file_basename: # level 3 V1.0 (CTS_GEOM, MM_GEOM, and SUBMM_GEOM) # examples: # ftp://psa.esac.esa.int/pub/mirror/INTERNATIONAL-ROSETTA-MISSION/MIRO/RO-C-MIRO-3-ESC1-67P-V1.0/DATA/GEOMETRY/MIRO_3_CTS_GEOM_20150490000.DAT # ftp://psa.esac.esa.int/pub/mirror/INTERNATIONAL-ROSETTA-MISSION/MIRO/RO-C-MIRO-3-ESC1-67P-V1.0/DATA/GEOMETRY/MIRO_3_MM_GEOM_20143370000.DAT # ftp://psa.esac.esa.int/pub/mirror/INTERNATIONAL-ROSETTA-MISSION/MIRO/RO-C-MIRO-3-ESC1-67P-V1.0/DATA/GEOMETRY/MIRO_3_SUBMM_GM_20143370000.DAT print ('\n ----------- level 3 V1.0 GEOM -----------\n') format_str = '<1d13f' # perl: df13 else: print ('Error: your file does not have a name that we recognize.') sys.exit(-1) # call the reader DAT_reader(dat_file, format_str, start_record, num_records)