# the following is a python script translated for the C code for LITE L1 data
#   The first part shows the structure of the data
#  the the script shows an example of how to output the 4 variable types
#     char, shor, long and float
#  Use the readme_little_endian.docx file to get the byte numbers of the desired variables

# To run this script it takes one argeumnt of the file name
#  I.e. LITElittle_endian.py LITE_L1_19940919_054004_054158 
# Created on : Jun 26, 2025

"""
/*level 1 structure*/
struct {
  short syncvalue;                /*always 12345*/
  char  majorversionnumber;
  char  minorversionnumber;
  char  datatakeid[7];            /*ascii description*/
  char  orbitnumber;
  long  idnumber;                 /*unique record id*/
  short gmtday;                   /*greenwich mean time*/
  char  gmthour;
  char  gmtmin;
  char  gmtsec;
  char  gmthund;
  short metday;                   /*mission elapsed time*/
  char  methour;
  char  metmin;
  char  metsec;
  char  methund;
  float latitude;                 /*degrees*/
  float longitude;                /*degrees */
  float shuttlealtitude;          /*kilometers*/
  float offnadirangle;            /*degrees*/
  float digitizerondelay;         /*useconds*/
  char  datatakemode;             /*0=day 1=night*/
  char  specialopsmode;           /*0=normal 1=multiscatter 2=gainchange 3=transition*/
  char  profilevalidstatus;       /*0=valid 1=355quest 2=532quest 4=064quest*/
                                  /*8=355invalid 16=532invalid 32=064invalid*/
  char  landwaterflag;            /*0=land 1=water*/
  float surfelevfootprint;        /*kilometers*/
  float metdataalts[18];          /*kilometers*/
  float mettemps[18];             /*kelvin*/
  float alttropopause;            /*kilometers*/
  float temptropopause;           /*kelvin*/
  char  laserselected;            /*0=a 1=b*/
  char  baalignmentstatus;        /*0=not aligned 1=aligned*/
  char  isdbstatus;               /*0=invalid 1=valid*/
  char  badatastatus;             /*0=invalid 1=valid*/
  char  aodatastatus;             /*0=invalid 1=valid*/
  char  motorinmotion;            /*0=stopped 1=motion*/
  char  aperwheelstatus;          /*0=closed 1=large 2=annular 3=small 4=motion*/
  char  backgroundmongain;        /*0=day 1=night*/
  char  surfacemode355;           /*0=no 1=yes*/
  char  dbattenuation355;         /*db*/
  short numbersatabovesurf355;    /*num samples*/
  float highestsatsample355;      /*kilometers*/
  short numberunderflows355;      /*num samples*/
  char  filterstatus355;          /*0=out 1=in 2=motion*/
  char  calibrationstatus355;     /*0=estimated 1=calculated*/
  float calibrationfactor355;
  char  baselinerippleremvd355;   /*0=no 1=yes*/
  char  oscillationremoved355;    /*0=no 1=yes*/
  char  backgroundvalue355;       /*raw value from instrument*/
  char  highvoltage355enabled;    /*0=disabled 1=enabled*/
  float highvoltage355;           /*volts (355 nm measured high voltage)*/
  float energymonitor355;         /*mjoules*/
  float pmtgain355;
  char  baselinesubmethod355;     /*0=slope 1 = averaged*/
  char  subregionunderflow355;    /*0=none 1=underflow in baseline subtraction region*/
  char  anomalousprof355;         /*0=normal 1=anomalous*/
  char  fillbyte1;
  char  surfacemode532;           /*0=atmospheric 1=transition 2=surface*/
  char  dbattenuation532;         /*db*/
  short numbersatabovesurf532;    /*num samples*/
  float highestsatsample532;      /*kilometers*/
  short numberunderflows532;      /*num samples*/
  char  filterstatus532;          /*0=out 1=in 2=motion*/
  char  calibrationstatus532;     /*0=estimated 1=calculated*/
  float calibrationfactor532;
  char  baselinerippleremvd532;   /*0=no 1=yes*/
  char  oscillationremoved532;    /*0=no 1=yes*/
  char  backgroundvalue532;       /*raw value from instrument*/
  char  highvoltage532enabled;    /*0=disabled 1=enabled*/
  float highvoltage532;           /*volts (532 nm measured high voltage)*/
  float energymonitor532;         /*mjoules*/
  float pmtgain532;
  char  baselinesubmethod532;     /*0=slope 1 = averaged*/
  char  subregionunderflow532;    /*0=none 1=underflow in baseline subtraction region*/
  char  anomalousprof532;         /*0=normal 1=anomalous*/
  char  fillbyte2;
  char  surfacemode064;           /*0=atmospheric 1=transition 2=surface*/
  char  dbattenuation064;         /*db*/
  short numbersatabovesurf064;    /*num samples*/
  float highestsatsample064;      /*kilometers*/
  short numberunderflows064;      /*num samples*/
  char  filterstatus064;          /*0=out 1=in 2=motion*/
  char  calibrationstatus064;     /*0=estimated 1=calculated*/
  float calibrationfactor064;
  char  baselinerippleremvd064;   /*0=no 1=yes*/
  char  oscillationremoved064;    /*0=no 1=yes*/
  char  backgroundvalue064;       /*raw value from instrument*/
  char  highvoltage064enabled;    /*0=disabled 1=enabled*/
  float highvoltage064;           /*volts*/
  float energymonitor064;         /*mjoules*/
  float pmtgain064;
  char  baselinesubmethod064;     /*0=slope 1 = averaged*/
  char  subregionunderflow064;    /*0=none 1=underflow in baseline subtraction region*/
  char  anomalousprof064;         /*0=normal 1=anomalous*/
  char  fillbyte3;
  char  timeedsinthour;           /*unadjusted eds time*/
  char  timeedsintmin;
  char  timeedsintsec;
  char  timeedsinthund;
  char  level0fileidnumber;       /*level 0 directory number*/
  char  level0fileidletter;       /*level 0 file letter*/
  char  reserved[6];
  float highvoltage355cmd;        /*volts (355 nm commanded high voltage)*/
  float highvoltage532cmd;        /*volts (532 nm commanded high voltage)*/
  char  reserved2[4];
  float b0_355;                   /*baseline subtraction value*/
  float b0_532;                   /*baseline subtraction value*/
  float b0_064;                   /*baseline subtraction value*/
  char  outofrng355abv40;         /*0=none,1=underflow,2=overflow,3=underflow and overflow*/
  char  outofrng532abv40;         /*0=none,1=underflow,2=overflow,3=underflow and overflow*/
  char  outofrng064abv40;         /*0=none,1=underflow,2=overflow,3=underflow and overflow*/
  char  outofrange355[375];       /*packed bit array for underflow or overflow*/
  char  outofrange532[375];       /*packed bit array for underflow or overflow*/
  char  outofrange064[375];       /*packed bit array for underflow or overflow*/
  short top355;                   /*index of highest valid count*/
  short bottom355;                /*index of lowest valid count*/
  short top532;                   /*index of highest valid count*/
  short bottom532;                /*index of lowest valid count*/
  short top064;                   /*index of highest valid count*/
  short bottom064;                /*index of lowest valid count*/
  float profile355[3000];         /*counts*/
  float profile532[3000];         /*counts*/
  float profile064[3000];         /*counts*/
} astruct;
"""
import sys    # used to get input argument

#  function to translate the hex number into a 32 bit float
def GetFloat32(HexNumber):
    # determine if data is negative or positive
   negative  = (HexNumber & 0x80000000)
   if negative == 0:
     sign = 1
   else:
     sign = -1
    # determine the exponent
   exponent  =   (HexNumber & 0x7f800000) >> 23
   #  Subtract 127 from the exponent
   exponent -= 127
   # Convert the mantissa into decimal using the last 23 bits
   power = -1
   total = 0.0
   for i in range(1,23) :
      c = (HexNumber & (pow(2,23-i)))>>(23-i)
      total +=  (c * (pow( 2.0, power )))
      power=power-1
   total= total + 1.0
   value = sign * ( pow( 2.0, exponent )) * total
   return (value)
   # end of GetFloat32 function

#  setup the file input and output before reading the file
# set up file name as an input argument
filnme = sys.argv[1]
f=open(filnme,'rb')
# create output filename from input name
filnmout = (filnme)+ '_64.out'
print(filnmout)
flout = open(filnmout,'w')
flout.write(" GMT_Day  Time   Latitude  Longitude \n")

#  read file by strucutre size until EOF reached
while True:
   # read one full structure of size 37500
  astruct = f.read(37500)
  if not astruct:  # continue reading until end of file
    break
  syncvalue = (astruct[0]<<8) | astruct[1]
  if syncvalue != 12345:
     printf("bad syncvalue\n")
     sys.exit(0)
  # setup the time variables of char type with one byte from structure
  gmthour = astruct[18]
  gmtmin = astruct[19]
  gmtsec = astruct[20]
  gmthund = astruct[21]

#  sample process for long variables using idnumber with 4 bytes 12, 13,14 and 15 
  idnumber = ((((((astruct[12]<<8)+astruct[13])<<8)+astruct[14])<<8)+(astruct[15])) 
#  sample process for getting GMT day of short variables of 2 bytes 16 and 17
  gmtday = ((astruct[16]<<8)+astruct[17])
#  Sample process For getting float variables of 4 bytes
    #Bytes 28, 29, 30 and 31 for latitude 
  tmplat = ((((((astruct[28]<<8)+astruct[29])<<8)+astruct[30])<<8)+astruct[31])
# For float variables need Next line to translate character into a 32-bit float  
  latitude = GetFloat32(tmplat) 
  tmplong = ((((((astruct[32]<<8)+astruct[33])<<8)+astruct[34])<<8)+astruct[35])
# For float variables need Next line to translate character into a 32-bit float 
  longitude = GetFloat32(tmplong)

  # write data to file
  flout.write(f"{gmtday:2},  {gmthour:02d}:{gmtmin:02d}:{gmtsec:02d}.{gmthund:02d}," )
  flout.write(f" {latitude:.8f},  {longitude:.8f} \n" )

# close the two files
f.close()
flout.close()

